TURN episode #1
This commit is contained in:
parent
f05c0705dd
commit
4a687f2b23
|
@ -2,19 +2,19 @@
|
|||
* Copyright (C) 2010-2011 Mamadou Diop.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
|
@ -49,51 +49,51 @@
|
|||
*/
|
||||
tnet_stun_binding_t* tnet_stun_binding_create(tnet_fd_t fd, tnet_socket_type_t socket_type, const char* server_address, tnet_port_t server_port, const char* username, const char* password)
|
||||
{
|
||||
return tsk_object_new(tnet_stun_binding_def_t, fd, socket_type, server_address, server_port, username, password);
|
||||
return tsk_object_new(tnet_stun_binding_def_t, fd, socket_type, server_address, server_port, username, password);
|
||||
}
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
*
|
||||
* Create generic STUN2 request with all mandatory headers and attributes.
|
||||
* Create generic STUN2 request with all mandatory headers and attributes.
|
||||
*
|
||||
* @param [in,out] binding The binding object from which to create the request.
|
||||
* @param [in,out] binding The binding object from which to create the request.
|
||||
*
|
||||
* @retval STUN2 request if succeed and NULL otherwise.
|
||||
* @retval STUN2 request if succeed and NULL otherwise.
|
||||
**/
|
||||
tnet_stun_message_t *tnet_stun_create_request(const tnet_stun_binding_t* binding)
|
||||
{
|
||||
tnet_stun_message_t *message = tnet_stun_message_create(binding->username, binding->password);
|
||||
tnet_stun_message_t *message = tnet_stun_message_create(binding->username, binding->password);
|
||||
|
||||
if(message){
|
||||
message->realm = tsk_strdup(binding->realm);
|
||||
message->nonce = tsk_strdup(binding->nonce);
|
||||
if(message) {
|
||||
message->realm = tsk_strdup(binding->realm);
|
||||
message->nonce = tsk_strdup(binding->nonce);
|
||||
|
||||
/* Set the request type (RFC 5389 defines only one type) */
|
||||
message->type = stun_binding_request;
|
||||
/* Set the request type (RFC 5389 defines only one type) */
|
||||
message->type = stun_binding_request;
|
||||
|
||||
{ /* Create random transaction id */
|
||||
tsk_istr_t random;
|
||||
tsk_md5digest_t digest;
|
||||
{ /* Create random transaction id */
|
||||
tsk_istr_t random;
|
||||
tsk_md5digest_t digest;
|
||||
|
||||
tsk_strrandom(&random);
|
||||
TSK_MD5_DIGEST_CALC(random, sizeof(random), digest);
|
||||
tsk_strrandom(&random);
|
||||
TSK_MD5_DIGEST_CALC(random, sizeof(random), digest);
|
||||
|
||||
memcpy(message->transaction_id, digest, TNET_STUN_TRANSACID_SIZE);
|
||||
}
|
||||
memcpy(message->transaction_id, digest, TNET_STUN_TRANSACID_SIZE);
|
||||
}
|
||||
|
||||
/* Add software attribute */
|
||||
if(binding->software){
|
||||
tnet_stun_attribute_t* attribute = (tnet_stun_attribute_t*)tnet_stun_attribute_software_create(binding->software, tsk_strlen(binding->software));
|
||||
tnet_stun_message_add_attribute(message, &attribute);
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
/* Add software attribute */
|
||||
if(binding->software) {
|
||||
tnet_stun_attribute_t* attribute = (tnet_stun_attribute_t*)tnet_stun_attribute_software_create(binding->software, tsk_strlen(binding->software));
|
||||
tnet_stun_message_add_attribute(message, &attribute);
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
int tnet_stun_send_reliably(const tnet_stun_message_t* message)
|
||||
{
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,36 +102,35 @@ int tnet_stun_send_reliably(const tnet_stun_message_t* message)
|
|||
* Internal function to send a STUN message using unrealiable protocol such as UDP.
|
||||
*
|
||||
*
|
||||
* @param localFD The local file descriptor.
|
||||
* @param RTO The Retransmission TimeOut.
|
||||
* @param Rc The Number of retransmissions.
|
||||
* @param [in,out] message The message to send.
|
||||
* @param [in,out] server The destination STUN server.
|
||||
* @param localFD The local file descriptor.
|
||||
* @param RTO The Retransmission TimeOut.
|
||||
* @param Rc The Number of retransmissions.
|
||||
* @param [in,out] message The message to send.
|
||||
* @param [in,out] server The destination STUN server.
|
||||
*
|
||||
* @return The response from the server or NULL if transport error.
|
||||
* @return The response from the server or NULL if transport error.
|
||||
**/
|
||||
tnet_stun_response_t* tnet_stun_send_unreliably(tnet_fd_t localFD, uint16_t RTO, uint16_t Rc, const tnet_stun_message_t* message, struct sockaddr* server)
|
||||
{
|
||||
/* RFC 5389 - 7.2.1. Sending over UDP
|
||||
STUN indications are not retransmitted; thus, indication transactions over UDP
|
||||
are not reliable.
|
||||
*/
|
||||
//int retransmit = (message->type == stun_binding_request);
|
||||
/* RFC 5389 - 7.2.1. Sending over UDP
|
||||
STUN indications are not retransmitted; thus, indication transactions over UDP
|
||||
are not reliable.
|
||||
*/
|
||||
//int retransmit = (message->type == stun_binding_request);
|
||||
|
||||
int ret = -1;
|
||||
uint16_t i, rto = RTO;
|
||||
struct timeval tv;
|
||||
fd_set set;
|
||||
int ret = -1;
|
||||
uint16_t i, rto = RTO;
|
||||
struct timeval tv;
|
||||
fd_set set;
|
||||
|
||||
tsk_buffer_t *buffer = tnet_stun_message_serialize(message);
|
||||
tnet_stun_response_t *response = tsk_null;
|
||||
|
||||
if(!buffer)
|
||||
{
|
||||
goto bail;
|
||||
}
|
||||
|
||||
{
|
||||
tsk_buffer_t *buffer = tnet_stun_message_serialize(message);
|
||||
tnet_stun_response_t *response = tsk_null;
|
||||
|
||||
if(!buffer) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
{
|
||||
//#ifndef SIO_UDP_CONNRESET
|
||||
//# ifndef IOC_VENDOR
|
||||
//# define IOC_VENDOR 0x18000000
|
||||
|
@ -144,228 +143,227 @@ tnet_stun_response_t* tnet_stun_send_unreliably(tnet_fd_t localFD, uint16_t RTO,
|
|||
// DWORD dwBytesReturned = 0;
|
||||
// BOOL bNewBehavior = TRUE;
|
||||
// DWORD status;
|
||||
//
|
||||
//
|
||||
// // disable new behavior using
|
||||
// // IOCTL: SIO_UDP_CONNRESET
|
||||
// status = WSAIoctl(localFD, SIO_UDP_CONNRESET, &bNewBehavior, sizeof(bNewBehavior),
|
||||
// NULL, 0, &dwBytesReturned, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
/* RFC 5389 - 7.2.1. Sending over UDP
|
||||
A client SHOULD retransmit a STUN request message starting with an
|
||||
interval of RTO ("Retransmission TimeOut"), doubling after each
|
||||
retransmission.
|
||||
/* RFC 5389 - 7.2.1. Sending over UDP
|
||||
A client SHOULD retransmit a STUN request message starting with an
|
||||
interval of RTO ("Retransmission TimeOut"), doubling after each
|
||||
retransmission.
|
||||
|
||||
e.g. 0 ms, 500 ms, 1500 ms, 3500 ms, 7500ms, 15500 ms, and 31500 ms
|
||||
*/
|
||||
for(i=0; i<Rc; i++){
|
||||
tv.tv_sec += rto/1000;
|
||||
tv.tv_usec += (rto% 1000) * 1000;
|
||||
|
||||
FD_ZERO(&set);
|
||||
FD_SET(localFD, &set);
|
||||
e.g. 0 ms, 500 ms, 1500 ms, 3500 ms, 7500ms, 15500 ms, and 31500 ms
|
||||
*/
|
||||
for(i=0; i<Rc; i++) {
|
||||
tv.tv_sec += rto/1000;
|
||||
tv.tv_usec += (rto% 1000) * 1000;
|
||||
|
||||
ret = tnet_sockfd_sendto(localFD, server, buffer->data, buffer->size);
|
||||
FD_ZERO(&set);
|
||||
FD_SET(localFD, &set);
|
||||
|
||||
if((ret = select(localFD+1, &set, NULL, NULL, &tv))<0){
|
||||
goto bail;
|
||||
}
|
||||
else if(ret == 0){
|
||||
/* timeout */
|
||||
TSK_DEBUG_INFO("STUN request timedout at %d", i);
|
||||
rto *= 2;
|
||||
continue;
|
||||
}
|
||||
else if(FD_ISSET(localFD, &set)){
|
||||
/* there is data to read */
|
||||
ret = tnet_sockfd_sendto(localFD, server, buffer->data, buffer->size);
|
||||
|
||||
tsk_size_t len = 0;
|
||||
void* data = 0;
|
||||
if((ret = select(localFD+1, &set, NULL, NULL, &tv))<0) {
|
||||
goto bail;
|
||||
}
|
||||
else if(ret == 0) {
|
||||
/* timeout */
|
||||
TSK_DEBUG_INFO("STUN request timedout at %d", i);
|
||||
rto *= 2;
|
||||
continue;
|
||||
}
|
||||
else if(FD_ISSET(localFD, &set)) {
|
||||
/* there is data to read */
|
||||
|
||||
TSK_DEBUG_INFO("STUN request got response");
|
||||
tsk_size_t len = 0;
|
||||
void* data = 0;
|
||||
|
||||
/* Check how how many bytes are pending */
|
||||
if((ret = tnet_ioctlt(localFD, FIONREAD, &len))<0){
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if(len==0){
|
||||
TSK_DEBUG_INFO("tnet_ioctlt() returent zero bytes");
|
||||
continue;
|
||||
}
|
||||
TSK_DEBUG_INFO("STUN request got response");
|
||||
|
||||
/* Receive pending data */
|
||||
data = tsk_calloc(len, sizeof(uint8_t));
|
||||
if((ret = tnet_sockfd_recvfrom(localFD, data, len, 0, server))<0){
|
||||
TSK_FREE(data);
|
||||
|
||||
TSK_DEBUG_ERROR("Recving STUN dgrams failed with error code:%d", tnet_geterrno());
|
||||
goto bail;
|
||||
}
|
||||
/* Check how how many bytes are pending */
|
||||
if((ret = tnet_ioctlt(localFD, FIONREAD, &len))<0) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* Parse the incoming response. */
|
||||
response = tnet_stun_message_deserialize(data, (tsk_size_t)ret);
|
||||
TSK_FREE(data);
|
||||
if(len==0) {
|
||||
TSK_DEBUG_INFO("tnet_ioctlt() returent zero bytes");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Receive pending data */
|
||||
data = tsk_calloc(len, sizeof(uint8_t));
|
||||
if((ret = tnet_sockfd_recvfrom(localFD, data, len, 0, server))<0) {
|
||||
TSK_FREE(data);
|
||||
|
||||
TSK_DEBUG_ERROR("Recving STUN dgrams failed with error code:%d", tnet_geterrno());
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* Parse the incoming response. */
|
||||
response = tnet_stun_message_deserialize(data, (tsk_size_t)ret);
|
||||
TSK_FREE(data);
|
||||
|
||||
if(response) {
|
||||
if(tnet_stun_transacid_cmp(message->transaction_id, response->transaction_id)) {
|
||||
/* Not same transaction id */
|
||||
TSK_OBJECT_SAFE_FREE(response);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
goto bail;
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(response){
|
||||
if(tnet_stun_transacid_cmp(message->transaction_id, response->transaction_id)){
|
||||
/* Not same transaction id */
|
||||
TSK_OBJECT_SAFE_FREE(response);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
goto bail;
|
||||
}
|
||||
else{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
bail:
|
||||
TSK_OBJECT_SAFE_FREE(buffer);
|
||||
TSK_OBJECT_SAFE_FREE(buffer);
|
||||
|
||||
return response;
|
||||
return response;
|
||||
}
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* Internal function to send a STUN2 binding request over the network.
|
||||
*
|
||||
* @param [in,out] context The NAT context holding the user preferences.
|
||||
* @param [in,out] binding The STUN binding object used to create the message to send.
|
||||
* @param [in,out] context The NAT context holding the user preferences.
|
||||
* @param [in,out] binding The STUN binding object used to create the message to send.
|
||||
*
|
||||
* @return Zero if succeed and non-zero error code otherwise.
|
||||
* @return Zero if succeed and non-zero error code otherwise.
|
||||
**/
|
||||
int tnet_stun_send_bind(const tnet_nat_context_t* context, tnet_stun_binding_t *binding)
|
||||
{
|
||||
int ret = -1;
|
||||
tnet_stun_response_t *response = 0;
|
||||
tnet_stun_request_t *request = 0;
|
||||
|
||||
int ret = -1;
|
||||
tnet_stun_response_t *response = 0;
|
||||
tnet_stun_request_t *request = 0;
|
||||
|
||||
goto stun_phase0;
|
||||
|
||||
/* RFC 5389 - 10.2.1.1. First Request
|
||||
If the client has not completed a successful request/response
|
||||
transaction with the server (as identified by hostname, if the DNS
|
||||
procedures of Section 9 are used, else IP address if not), it SHOULD
|
||||
omit the USERNAME, MESSAGE-INTEGRITY, REALM, and NONCE attributes.
|
||||
In other words, the very first request is sent as if there were no
|
||||
authentication or message integrity applied.
|
||||
*/
|
||||
stun_phase0:
|
||||
{
|
||||
if(!(request = tnet_stun_create_request(binding))){
|
||||
goto bail;
|
||||
}
|
||||
goto stun_phase0;
|
||||
|
||||
if(TNET_SOCKET_TYPE_IS_DGRAM(context->socket_type)){
|
||||
response = tnet_stun_send_unreliably(binding->localFD, context->RTO, context->Rc, request, (struct sockaddr*)&binding->server);
|
||||
}
|
||||
/* RFC 5389 - 10.2.1.1. First Request
|
||||
If the client has not completed a successful request/response
|
||||
transaction with the server (as identified by hostname, if the DNS
|
||||
procedures of Section 9 are used, else IP address if not), it SHOULD
|
||||
omit the USERNAME, MESSAGE-INTEGRITY, REALM, and NONCE attributes.
|
||||
In other words, the very first request is sent as if there were no
|
||||
authentication or message integrity applied.
|
||||
*/
|
||||
stun_phase0: {
|
||||
if(!(request = tnet_stun_create_request(binding))) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if(response){
|
||||
if(TNET_STUN_RESPONSE_IS_ERROR(response)){
|
||||
short code = tnet_stun_message_get_errorcode(response);
|
||||
const char* realm = tnet_stun_message_get_realm(response);
|
||||
const char* nonce = tnet_stun_message_get_nonce(response);
|
||||
if(TNET_SOCKET_TYPE_IS_DGRAM(context->socket_type)) {
|
||||
response = tnet_stun_send_unreliably(binding->localFD, context->RTO, context->Rc, request, (struct sockaddr*)&binding->server);
|
||||
}
|
||||
|
||||
if(code == 401 && realm && nonce){
|
||||
if(!binding->nonce){
|
||||
/* First time we get a nonce */
|
||||
tsk_strupdate(&binding->nonce, nonce);
|
||||
tsk_strupdate(&binding->realm, realm);
|
||||
if(response) {
|
||||
if(TNET_STUN_RESPONSE_IS_ERROR(response)) {
|
||||
short code = tnet_stun_message_get_errorcode(response);
|
||||
const char* realm = tnet_stun_message_get_realm(response);
|
||||
const char* nonce = tnet_stun_message_get_nonce(response);
|
||||
|
||||
/* Delete the message and response before retrying*/
|
||||
TSK_OBJECT_SAFE_FREE(response);
|
||||
TSK_OBJECT_SAFE_FREE(request);
|
||||
if(code == 401 && realm && nonce) {
|
||||
if(!binding->nonce) {
|
||||
/* First time we get a nonce */
|
||||
tsk_strupdate(&binding->nonce, nonce);
|
||||
tsk_strupdate(&binding->realm, realm);
|
||||
|
||||
/* Delete the message and response before retrying*/
|
||||
TSK_OBJECT_SAFE_FREE(response);
|
||||
TSK_OBJECT_SAFE_FREE(request);
|
||||
|
||||
// Send again using new transaction identifier
|
||||
return tnet_stun_send_bind(context, binding);
|
||||
}
|
||||
else {
|
||||
ret = -3;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = -2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const tnet_stun_attribute_t *attribute;
|
||||
if((attribute= tnet_stun_message_get_attribute(response, stun_xor_mapped_address))) {
|
||||
ret = 0;
|
||||
binding->xmaddr = tsk_object_ref((void*)attribute);
|
||||
}
|
||||
else if((attribute= tnet_stun_message_get_attribute(response, stun_mapped_address))) {
|
||||
ret = 0;
|
||||
binding->maddr = tsk_object_ref((void*)attribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* END OF stun_phase0 */
|
||||
|
||||
// Send again using new transaction identifier
|
||||
return tnet_stun_send_bind(context, binding);
|
||||
}
|
||||
else{
|
||||
ret = -3;
|
||||
}
|
||||
}
|
||||
else{
|
||||
ret = -2;
|
||||
}
|
||||
}
|
||||
else{
|
||||
const tnet_stun_attribute_t *attribute;
|
||||
if((attribute= tnet_stun_message_get_attribute(response, stun_xor_mapped_address))){
|
||||
ret = 0;
|
||||
binding->xmaddr = tsk_object_ref((void*)attribute);
|
||||
}
|
||||
else if((attribute= tnet_stun_message_get_attribute(response, stun_mapped_address))){
|
||||
ret = 0;
|
||||
binding->maddr = tsk_object_ref((void*)attribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* END OF stun_phase0 */
|
||||
|
||||
bail:
|
||||
TSK_OBJECT_SAFE_FREE(response);
|
||||
TSK_OBJECT_SAFE_FREE(request);
|
||||
TSK_OBJECT_SAFE_FREE(response);
|
||||
TSK_OBJECT_SAFE_FREE(request);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
*
|
||||
* Public function to create a binding context.
|
||||
*
|
||||
* @param [in,out] nat_context The NAT context.
|
||||
* @param localFD The local file descriptor for which to create the binding context.
|
||||
* @param [in,out] nat_context The NAT context.
|
||||
* @param localFD The local file descriptor for which to create the binding context.
|
||||
*
|
||||
* @return A valid binding id if succeed and @ref TNET_STUN_INVALID_BINDING_ID otherwise. If the returned id is valid then
|
||||
* the newly created binding will contain the server reflexive address associated to the local file descriptor.
|
||||
**/
|
||||
tnet_stun_binding_id_t tnet_stun_bind(const tnet_nat_context_t* nat_context, tnet_fd_t localFD)
|
||||
{
|
||||
tnet_stun_binding_id_t id = TNET_STUN_INVALID_BINDING_ID;
|
||||
tnet_stun_binding_id_t id = TNET_STUN_INVALID_BINDING_ID;
|
||||
|
||||
tnet_stun_binding_t *binding = 0;
|
||||
tnet_stun_binding_t *binding = 0;
|
||||
|
||||
if(nat_context && localFD != TNET_INVALID_FD){
|
||||
if(!(binding = tnet_stun_binding_create(localFD, nat_context->socket_type, nat_context->server_address, nat_context->server_port, nat_context->username, nat_context->password))){
|
||||
goto bail;
|
||||
}
|
||||
if(nat_context && localFD != TNET_INVALID_FD) {
|
||||
if(!(binding = tnet_stun_binding_create(localFD, nat_context->socket_type, nat_context->server_address, nat_context->server_port, nat_context->username, nat_context->password))) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if(tnet_stun_send_bind(nat_context, binding)){
|
||||
TSK_OBJECT_SAFE_FREE(binding);
|
||||
goto bail;
|
||||
}
|
||||
if(tnet_stun_send_bind(nat_context, binding)) {
|
||||
TSK_OBJECT_SAFE_FREE(binding);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
id = binding->id;
|
||||
tsk_list_push_back_data(nat_context->stun_bindings, (void**)&binding);
|
||||
}
|
||||
id = binding->id;
|
||||
tsk_list_push_back_data(nat_context->stun_bindings, (void**)&binding);
|
||||
}
|
||||
|
||||
bail:
|
||||
return id;
|
||||
return id;
|
||||
}
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* Compares two transaction ids.
|
||||
*
|
||||
* @param id1 The first transaction identifier.
|
||||
* @param id2 The second transaction identifier.
|
||||
* @param id1 The first transaction identifier.
|
||||
* @param id2 The second transaction identifier.
|
||||
*
|
||||
* @return Zero if the two identifiers are equal and non-zero value otherwise.
|
||||
**/
|
||||
int tnet_stun_transacid_cmp(const tnet_stun_transacid_t id1, const tnet_stun_transacid_t id2)
|
||||
{
|
||||
tsk_size_t i;
|
||||
for(i=0; i<sizeof(tnet_stun_transacid_t); i++){
|
||||
if(id1[i] != id2[i]){
|
||||
return (id1[i] - id2[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
tsk_size_t i;
|
||||
for(i=0; i<sizeof(tnet_stun_transacid_t); i++) {
|
||||
if(id1[i] != id2[i]) {
|
||||
return (id1[i] - id2[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -382,61 +380,60 @@ int tnet_stun_transacid_cmp(const tnet_stun_transacid_t id1, const tnet_stun_tra
|
|||
//
|
||||
static tsk_object_t* tnet_stun_binding_ctor(tsk_object_t * self, va_list * app)
|
||||
{
|
||||
tnet_stun_binding_t *binding = self;
|
||||
if(binding){
|
||||
static tnet_stun_binding_id_t __binding_unique_id = 0;
|
||||
tnet_stun_binding_t *binding = self;
|
||||
if(binding) {
|
||||
static tnet_stun_binding_id_t __binding_unique_id = 0;
|
||||
|
||||
const char* server_address;
|
||||
tnet_port_t server_port;
|
||||
const char* server_address;
|
||||
tnet_port_t server_port;
|
||||
|
||||
binding->id = ++__binding_unique_id;
|
||||
binding->id = ++__binding_unique_id;
|
||||
|
||||
binding->localFD = va_arg(*app, tnet_fd_t);
|
||||
binding->socket_type = va_arg(*app, tnet_socket_type_t);
|
||||
|
||||
server_address = tsk_strdup(va_arg(*app, const char*));
|
||||
binding->localFD = va_arg(*app, tnet_fd_t);
|
||||
binding->socket_type = va_arg(*app, tnet_socket_type_t);
|
||||
|
||||
server_address = tsk_strdup(va_arg(*app, const char*));
|
||||
#if defined(__GNUC__)
|
||||
server_port = (tnet_port_t)va_arg(*app, unsigned);
|
||||
server_port = (tnet_port_t)va_arg(*app, unsigned);
|
||||
#else
|
||||
server_port = va_arg(*app, tnet_port_t);
|
||||
server_port = va_arg(*app, tnet_port_t);
|
||||
#endif
|
||||
|
||||
binding->username = tsk_strdup(va_arg(*app, const char*));
|
||||
binding->password = tsk_strdup(va_arg(*app, const char*));
|
||||
|
||||
if(server_address){
|
||||
tnet_sockaddr_init(server_address, server_port, binding->socket_type, &binding->server);
|
||||
}
|
||||
binding->username = tsk_strdup(va_arg(*app, const char*));
|
||||
binding->password = tsk_strdup(va_arg(*app, const char*));
|
||||
|
||||
binding->software = tsk_strdup(TNET_SOFTWARE);
|
||||
}
|
||||
return self;
|
||||
if(server_address) {
|
||||
tnet_sockaddr_init(server_address, server_port, binding->socket_type, &binding->server);
|
||||
}
|
||||
|
||||
binding->software = tsk_strdup(TNET_SOFTWARE);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
static tsk_object_t* tnet_stun_binding_dtor(tsk_object_t * self)
|
||||
{
|
||||
tnet_stun_binding_t *binding = self;
|
||||
if(binding){
|
||||
TSK_FREE(binding->username);
|
||||
TSK_FREE(binding->password);
|
||||
TSK_FREE(binding->realm);
|
||||
TSK_FREE(binding->nonce);
|
||||
{
|
||||
tnet_stun_binding_t *binding = self;
|
||||
if(binding) {
|
||||
TSK_FREE(binding->username);
|
||||
TSK_FREE(binding->password);
|
||||
TSK_FREE(binding->realm);
|
||||
TSK_FREE(binding->nonce);
|
||||
|
||||
TSK_FREE(binding->software);
|
||||
TSK_FREE(binding->software);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(binding->maddr);
|
||||
TSK_OBJECT_SAFE_FREE(binding->xmaddr);
|
||||
}
|
||||
TSK_OBJECT_SAFE_FREE(binding->maddr);
|
||||
TSK_OBJECT_SAFE_FREE(binding->xmaddr);
|
||||
}
|
||||
|
||||
return self;
|
||||
return self;
|
||||
}
|
||||
|
||||
static const tsk_object_def_t tnet_stun_binding_def_s =
|
||||
{
|
||||
sizeof(tnet_stun_binding_t),
|
||||
tnet_stun_binding_ctor,
|
||||
tnet_stun_binding_dtor,
|
||||
tsk_null,
|
||||
static const tsk_object_def_t tnet_stun_binding_def_s = {
|
||||
sizeof(tnet_stun_binding_t),
|
||||
tnet_stun_binding_ctor,
|
||||
tnet_stun_binding_dtor,
|
||||
tsk_null,
|
||||
};
|
||||
const tsk_object_def_t *tnet_stun_binding_def_t = &tnet_stun_binding_def_s;
|
||||
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
* Copyright (C) 2010-2011 Mamadou Diop.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
|
@ -77,34 +77,33 @@ typedef uint64_t tnet_stun_binding_id_t;
|
|||
/**@ingroup tnet_stun_group
|
||||
* STUN2 binding context.
|
||||
**/
|
||||
typedef struct tnet_stun_binding_s
|
||||
{
|
||||
TSK_DECLARE_OBJECT;
|
||||
typedef struct tnet_stun_binding_s {
|
||||
TSK_DECLARE_OBJECT;
|
||||
|
||||
//! A unique id to identify this binding.
|
||||
tnet_stun_binding_id_t id;
|
||||
//! A unique id to identify this binding.
|
||||
tnet_stun_binding_id_t id;
|
||||
|
||||
//! The username to authenticate to the STUN server.
|
||||
char* username;
|
||||
//! The password to authenticate to the STUN server.
|
||||
char* password;
|
||||
//! The realm.
|
||||
char* realm;
|
||||
//! The nonce.
|
||||
char* nonce;
|
||||
//! The client name.
|
||||
char* software;
|
||||
//! Local file descriptor for which to get server reflexive address.
|
||||
tnet_fd_t localFD;
|
||||
//! The type of the bound socket.
|
||||
tnet_socket_type_t socket_type;
|
||||
//! The address of the STUN server.
|
||||
struct sockaddr_storage server;
|
||||
//! Server reflexive address of the local socket(STUN1 as per RFC 3489).
|
||||
tnet_stun_attribute_mapped_addr_t *maddr;
|
||||
//! XORed server reflexive address (STUN2 as per RFC 5389).
|
||||
tnet_stun_attribute_xmapped_addr_t *xmaddr;
|
||||
}tnet_stun_binding_t;
|
||||
//! The username to authenticate to the STUN server.
|
||||
char* username;
|
||||
//! The password to authenticate to the STUN server.
|
||||
char* password;
|
||||
//! The realm.
|
||||
char* realm;
|
||||
//! The nonce.
|
||||
char* nonce;
|
||||
//! The client name.
|
||||
char* software;
|
||||
//! Local file descriptor for which to get server reflexive address.
|
||||
tnet_fd_t localFD;
|
||||
//! The type of the bound socket.
|
||||
tnet_socket_type_t socket_type;
|
||||
//! The address of the STUN server.
|
||||
struct sockaddr_storage server;
|
||||
//! Server reflexive address of the local socket(STUN1 as per RFC 3489).
|
||||
tnet_stun_attribute_mapped_addr_t *maddr;
|
||||
//! XORed server reflexive address (STUN2 as per RFC 5389).
|
||||
tnet_stun_attribute_xmapped_addr_t *xmaddr;
|
||||
} tnet_stun_binding_t;
|
||||
|
||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_binding_def_t;
|
||||
/**@ingroup tnet_stun_group
|
||||
|
|
|
@ -0,0 +1,406 @@
|
|||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#include "stun/tnet_stun_attr.h"
|
||||
#include "stun/tnet_stun_utils.h"
|
||||
|
||||
#include "tnet_endianness.h"
|
||||
|
||||
#include "tsk_memory.h"
|
||||
#include "tsk_debug.h"
|
||||
|
||||
#define kWithoutPadding tsk_false
|
||||
#define kWithPadding tsk_true
|
||||
|
||||
#define ALIGN_ON_32BITS(size_in_octes) if (((size_in_octes) & 3)) (size_in_octes) += (4 - ((size_in_octes) & 3));
|
||||
#define ALIGN_ON_32BITS_AND_SET_PADDING_ZEROS(p_buffer, size_in_octes) \
|
||||
if (((size_in_octes) & 3)) { \
|
||||
int c = (4 - ((size_in_octes) & 3)); \
|
||||
memset(p_buffer, 0, c); \
|
||||
(size_in_octes) += c; \
|
||||
}
|
||||
|
||||
#define IS_XOR(e_type) \
|
||||
(e_type == tnet_stun_attr_type_xor_mapped_address || e_type == tnet_stun_attr_type_xor_peer_address || e_type == tnet_stun_attr_type_xor_relayed_address)
|
||||
|
||||
static int _tnet_stun_attr_cmp(const tsk_object_t *_att1, const tsk_object_t *_att2)
|
||||
{
|
||||
const tnet_stun_attr_t *pc_att1 = (const tnet_stun_attr_t *)_att1;
|
||||
const tnet_stun_attr_t *pc_att2 = (const tnet_stun_attr_t *)_att2;
|
||||
|
||||
return (int)(pc_att1 - pc_att2);
|
||||
}
|
||||
|
||||
static int _tnet_stun_attr_get_size_in_octetunits(const tnet_stun_attr_t* pc_self, tsk_bool_t with_padding, tsk_size_t* p_size)
|
||||
{
|
||||
if (!pc_self || !p_size) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
switch (pc_self->hdr.e_type) {
|
||||
case tnet_stun_attr_type_mapped_address:
|
||||
case tnet_stun_attr_type_xor_mapped_address:
|
||||
case tnet_stun_attr_type_xor_peer_address:
|
||||
case tnet_stun_attr_type_xor_relayed_address: {
|
||||
extern const tsk_object_def_t *tnet_stun_attr_address_def_t;
|
||||
const tnet_stun_attr_address_t* _pc_self = (const tnet_stun_attr_address_t*)pc_self;
|
||||
if (pc_self->__def__ != tnet_stun_attr_address_def_t) {
|
||||
TSK_DEBUG_ERROR("Invalid base type");
|
||||
return -2;
|
||||
}
|
||||
*p_size = (kStunAttrHdrSizeInOctets + 1/*Ignored*/ + 1/*Family*/ + 2/*Port*/ + ((_pc_self->e_family == tnet_stun_address_family_ipv6) ? 16 : 4));
|
||||
if (with_padding) {
|
||||
ALIGN_ON_32BITS(*p_size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case tnet_stun_attr_type_username:
|
||||
case tnet_stun_attr_type_password: {
|
||||
extern const tsk_object_def_t *tnet_stun_attr_vdata_def_t;
|
||||
const tnet_stun_attr_vdata_t* _pc_self = (const tnet_stun_attr_vdata_t*)pc_self;
|
||||
if (pc_self->__def__ != tnet_stun_attr_vdata_def_t) {
|
||||
TSK_DEBUG_ERROR("Invalid base type");
|
||||
return -2;
|
||||
}
|
||||
*p_size = (kStunAttrHdrSizeInOctets + _pc_self->u_data_size);
|
||||
if (with_padding) {
|
||||
ALIGN_ON_32BITS(*p_size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
default: {
|
||||
TSK_DEBUG_WARN("Attribute type=%d is unknown. Don't be surprised if something goes wrong.", pc_self->hdr.e_type);
|
||||
*p_size = (kStunAttrHdrSizeInOctets + pc_self->hdr.u_length);
|
||||
if (with_padding) {
|
||||
ALIGN_ON_32BITS(*p_size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int _tnet_stun_attr_write(const tnet_stun_transac_id_t* pc_transac_id, const tnet_stun_attr_t* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_bool_t with_padding, tsk_size_t *p_written)
|
||||
{
|
||||
tsk_size_t n_min_req_size;
|
||||
int ret;
|
||||
if (!pc_self || !p_buff_ptr || !n_buff_size || !p_written) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if ((ret = _tnet_stun_attr_get_size_in_octetunits(pc_self, with_padding, &n_min_req_size))) {
|
||||
return ret;
|
||||
}
|
||||
if (n_min_req_size > n_buff_size) {
|
||||
TSK_DEBUG_ERROR("Buffer too short %u<%u", n_buff_size, n_min_req_size);
|
||||
return -2;
|
||||
}
|
||||
|
||||
*((uint16_t*)&p_buff_ptr[0]) = tnet_htons((unsigned short)pc_self->hdr.e_type);
|
||||
// *((uint16_t*)&p_buff_ptr[2]) = tnet_htons((unsigned short)pc_self->hdr.u_length);
|
||||
*p_written = kStunAttrHdrSizeInOctets;
|
||||
|
||||
switch (pc_self->hdr.e_type) {
|
||||
case tnet_stun_attr_type_mapped_address:
|
||||
case tnet_stun_attr_type_xor_mapped_address:
|
||||
case tnet_stun_attr_type_xor_peer_address:
|
||||
case tnet_stun_attr_type_xor_relayed_address: {
|
||||
tsk_size_t u_addr_size;
|
||||
extern const tsk_object_def_t *tnet_stun_attr_address_def_t;
|
||||
const tnet_stun_attr_address_t* _pc_self = (const tnet_stun_attr_address_t*)pc_self;
|
||||
tsk_bool_t b_xor = IS_XOR(pc_self->hdr.e_type);
|
||||
if (pc_self->__def__ != tnet_stun_attr_address_def_t) {
|
||||
TSK_DEBUG_ERROR("Invalid base type");
|
||||
return -2;
|
||||
}
|
||||
p_buff_ptr[*p_written] = 0x00; // Reserved
|
||||
p_buff_ptr[*p_written + 1] = _pc_self->e_family;
|
||||
u_addr_size = (_pc_self->e_family == tnet_stun_address_family_ipv6 ? 16 : 4);
|
||||
if (b_xor) {
|
||||
tsk_size_t u;
|
||||
*((uint16_t*)&p_buff_ptr[*p_written + 2]) = tnet_htons(_pc_self->u_port ^ kStunMagicCookieShort);
|
||||
*((uint32_t*)&p_buff_ptr[*p_written + 4]) = tnet_htonl(tnet_ntohl(*((uint32_t*)&_pc_self->address[0])) ^ kStunMagicCookieLong);
|
||||
for (u = 4; u < u_addr_size; u+=4) {
|
||||
if (pc_transac_id) {
|
||||
*((uint32_t*)&p_buff_ptr[*p_written + 4 + u]) = tnet_htonl(tnet_ntohl(*((uint32_t*)&_pc_self->address[u])) ^ tnet_ntohl(*((uint32_t*)(*pc_transac_id + u - 4))));
|
||||
}
|
||||
else {
|
||||
*((uint32_t*)&p_buff_ptr[*p_written + 4 + u]) = tnet_htonl(tnet_ntohl(*((uint32_t*)&_pc_self->address[u])) ^ 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
*((uint16_t*)&p_buff_ptr[*p_written + 2]) = tnet_htons(_pc_self->u_port);
|
||||
memcpy(&p_buff_ptr[*p_written + 4], _pc_self->address, u_addr_size);
|
||||
}
|
||||
|
||||
*p_written += 4 + u_addr_size;
|
||||
*((uint16_t*)&p_buff_ptr[2]) = tnet_htons((unsigned short)*p_written - kStunAttrHdrSizeInOctets);
|
||||
if (with_padding) {
|
||||
ALIGN_ON_32BITS_AND_SET_PADDING_ZEROS(&p_buff_ptr[*p_written], *p_written);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case tnet_stun_attr_type_username:
|
||||
case tnet_stun_attr_type_password: {
|
||||
extern const tsk_object_def_t *tnet_stun_attr_vdata_def_t;
|
||||
const tnet_stun_attr_vdata_t* _pc_self = (const tnet_stun_attr_vdata_t*)pc_self;
|
||||
if (pc_self->__def__ != tnet_stun_attr_vdata_def_t) {
|
||||
TSK_DEBUG_ERROR("Invalid base type");
|
||||
return -2;
|
||||
}
|
||||
if (_pc_self->p_data_ptr && _pc_self->u_data_size) {
|
||||
memcpy(&p_buff_ptr[*p_written], _pc_self->p_data_ptr, _pc_self->u_data_size);
|
||||
*p_written += _pc_self->u_data_size;
|
||||
}
|
||||
*((uint16_t*)&p_buff_ptr[2]) = tnet_htons((unsigned short)*p_written - kStunAttrHdrSizeInOctets);
|
||||
if (with_padding) {
|
||||
ALIGN_ON_32BITS_AND_SET_PADDING_ZEROS(&p_buff_ptr[*p_written], *p_written);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
default: {
|
||||
TSK_DEBUG_ERROR("Attribute type=%d is unknown.", pc_self->hdr.e_type);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int tnet_stun_attr_init(tnet_stun_attr_t* p_self, tnet_stun_attr_type_t e_type, uint16_t u_length)
|
||||
{
|
||||
if (!p_self) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
p_self->hdr.e_type = e_type;
|
||||
p_self->hdr.u_length = u_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tnet_stun_attr_get_size_in_octetunits_without_padding(const tnet_stun_attr_t* pc_self, tsk_size_t* p_size)
|
||||
{
|
||||
return _tnet_stun_attr_get_size_in_octetunits(pc_self, kWithoutPadding, p_size);
|
||||
}
|
||||
|
||||
int tnet_stun_attr_get_size_in_octetunits_with_padding(const tnet_stun_attr_t* pc_self, tsk_size_t* p_size)
|
||||
{
|
||||
return _tnet_stun_attr_get_size_in_octetunits(pc_self, kWithPadding, p_size);
|
||||
}
|
||||
|
||||
int tnet_stun_attr_write_without_padding(const tnet_stun_transac_id_t* pc_transac_id, const tnet_stun_attr_t* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written)
|
||||
{
|
||||
return _tnet_stun_attr_write(pc_transac_id, pc_self, p_buff_ptr, n_buff_size, kWithoutPadding, p_written);
|
||||
}
|
||||
|
||||
int tnet_stun_attr_write_with_padding(const tnet_stun_transac_id_t* pc_transac_id, const tnet_stun_attr_t* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written)
|
||||
{
|
||||
return _tnet_stun_attr_write(pc_transac_id, pc_self, p_buff_ptr, n_buff_size, kWithPadding, p_written);
|
||||
}
|
||||
|
||||
int tnet_stun_attr_read(const tnet_stun_transac_id_t* pc_transac_id, const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_consumed_octets, tnet_stun_attr_t** pp_attr)
|
||||
{
|
||||
tnet_stun_attr_type_t Type;
|
||||
uint16_t Length, PadLength;
|
||||
int ret = -1;
|
||||
static const void* kNullBuffPtr = tsk_null;
|
||||
static const tsk_size_t kNullBuffSize = 0;
|
||||
if (!pc_buff_ptr || !n_buff_size || !pp_attr || !p_consumed_octets) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if (n_buff_size < kStunAttrHdrSizeInOctets) {
|
||||
TSK_DEBUG_ERROR("Buffer too short(%u)", n_buff_size);
|
||||
return -2;
|
||||
}
|
||||
|
||||
Type = tnet_ntohs_2(&pc_buff_ptr[0]);
|
||||
Length = tnet_ntohs_2(&pc_buff_ptr[2]);
|
||||
if (Length > n_buff_size) {
|
||||
TSK_DEBUG_ERROR("Buffer too short(%u). Length=%u", n_buff_size, Length);
|
||||
return -3;
|
||||
}
|
||||
|
||||
PadLength = (Length & 0x03) ? (4 - (Length & 0x03)) : 0;
|
||||
|
||||
*pp_attr = tsk_null;
|
||||
*p_consumed_octets = kStunAttrHdrSizeInOctets + Length + PadLength;
|
||||
|
||||
switch (Type) {
|
||||
case tnet_stun_attr_type_mapped_address:
|
||||
case tnet_stun_attr_type_xor_mapped_address:
|
||||
case tnet_stun_attr_type_xor_peer_address:
|
||||
case tnet_stun_attr_type_xor_relayed_address: {
|
||||
// First 8bits must be ignored
|
||||
tnet_stun_address_family_t e_family = pc_buff_ptr[5];
|
||||
uint16_t u_port = tnet_ntohs_2(&pc_buff_ptr[6]);
|
||||
tnet_stun_attr_address_t* p_attr;
|
||||
tsk_bool_t b_xor = IS_XOR(Type);
|
||||
uint16_t u, u_addr_size = (e_family == tnet_stun_address_family_ipv6) ? 16 : 4;
|
||||
|
||||
if (b_xor) {
|
||||
u_port ^= kStunMagicCookieShort;
|
||||
}
|
||||
if ((ret = tnet_stun_attr_address_create(Type, e_family, u_port, kNullBuffPtr, &p_attr))) {
|
||||
return ret;
|
||||
}
|
||||
if (b_xor) {
|
||||
*((uint32_t*)&p_attr->address[0]) = tnet_htonl(tnet_ntohl_2(&pc_buff_ptr[8]) ^ kStunMagicCookieLong);
|
||||
for (u = 4; u < u_addr_size; u+=4) {
|
||||
if (pc_transac_id) {
|
||||
*((uint32_t*)&p_attr->address[u]) = tnet_htonl(tnet_ntohl_2(&pc_buff_ptr[8 + u]) ^ tnet_ntohl_2(((uint32_t*)(*pc_transac_id + u - 4))));
|
||||
}
|
||||
else {
|
||||
*((uint32_t*)&p_attr->address[u]) = tnet_htonl(tnet_ntohl_2(&pc_buff_ptr[8 + u]) ^ 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
memcpy(p_attr->address, &pc_buff_ptr[8], u_addr_size);
|
||||
}
|
||||
|
||||
*pp_attr = TNET_STUN_ATTR(p_attr);
|
||||
break;
|
||||
}
|
||||
|
||||
case tnet_stun_attr_type_username:
|
||||
case tnet_stun_attr_type_password:
|
||||
default: {
|
||||
tnet_stun_attr_vdata_t* p_attr;
|
||||
if ((ret = tnet_stun_attr_vdata_create(Type, &pc_buff_ptr[4], Length, &p_attr))) {
|
||||
return ret;
|
||||
}
|
||||
*pp_attr = TNET_STUN_ATTR(p_attr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ============== VDATA (USERNAME, MESSAGE-INTEGRITY, ...) ================ //
|
||||
int tnet_stun_attr_vdata_create(tnet_stun_attr_type_t e_type, const uint8_t* pc_data_ptr, uint16_t u_data_size, tnet_stun_attr_vdata_t** pp_attr)
|
||||
{
|
||||
int ret = -1;
|
||||
uint16_t u_length = pc_data_ptr ? u_data_size : 0;
|
||||
tnet_stun_attr_vdata_t* p_attr = tsk_null;
|
||||
extern const tsk_object_def_t *tnet_stun_attr_vdata_def_t;
|
||||
if (!pp_attr) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(p_attr = tsk_object_new(tnet_stun_attr_vdata_def_t))) {
|
||||
ret = -2;
|
||||
goto bail;
|
||||
}
|
||||
if ((ret = tnet_stun_attr_init(TNET_STUN_ATTR(p_attr), e_type, u_length))) {
|
||||
goto bail;
|
||||
}
|
||||
if (u_length) {
|
||||
if (!(p_attr->p_data_ptr = tsk_malloc(u_length))) {
|
||||
ret = -3;
|
||||
goto bail;
|
||||
}
|
||||
memcpy(p_attr->p_data_ptr, pc_data_ptr, u_length);
|
||||
p_attr->u_data_size = u_length;
|
||||
}
|
||||
|
||||
bail:
|
||||
if (ret) {
|
||||
TSK_OBJECT_SAFE_FREE(p_attr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static tsk_object_t* tnet_stun_attr_vdata_ctor(tsk_object_t * self, va_list * app)
|
||||
{
|
||||
tnet_stun_attr_vdata_t *p_vdata = (tnet_stun_attr_vdata_t *)self;
|
||||
if (p_vdata) {
|
||||
}
|
||||
return self;
|
||||
}
|
||||
static tsk_object_t* tnet_stun_attr_vdata_dtor(tsk_object_t * self)
|
||||
{
|
||||
tnet_stun_attr_vdata_t *p_vdata = (tnet_stun_attr_vdata_t *)self;
|
||||
if (p_vdata) {
|
||||
TSK_DEBUG_INFO("*** STUN Attribute(VDATA) destroyed ***");
|
||||
TSK_FREE(p_vdata->p_data_ptr);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
static const tsk_object_def_t tnet_stun_attr_vdata_def_s = {
|
||||
sizeof(tnet_stun_attr_vdata_t),
|
||||
tnet_stun_attr_vdata_ctor,
|
||||
tnet_stun_attr_vdata_dtor,
|
||||
_tnet_stun_attr_cmp,
|
||||
};
|
||||
const tsk_object_def_t *tnet_stun_attr_vdata_def_t = &tnet_stun_attr_vdata_def_s;
|
||||
|
||||
|
||||
// ============== ADDRESS ================ //
|
||||
int tnet_stun_attr_address_create(tnet_stun_attr_type_t e_type, tnet_stun_address_family_t e_family, uint16_t u_port, const tnet_stun_addr_t* pc_addr, tnet_stun_attr_address_t** pp_attr)
|
||||
{
|
||||
int ret = - 1;
|
||||
extern const tsk_object_def_t *tnet_stun_attr_address_def_t;
|
||||
tnet_stun_attr_address_t* p_attr = tsk_null;
|
||||
uint16_t u_length = (e_family == tnet_stun_address_family_ipv6) ? 16 : 4;
|
||||
if (!pp_attr) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if (!(p_attr = tsk_object_new(tnet_stun_attr_address_def_t))) {
|
||||
ret = -2;
|
||||
goto bail;
|
||||
}
|
||||
if ((ret = tnet_stun_attr_init(TNET_STUN_ATTR(p_attr), e_type, u_length))) {
|
||||
goto bail;
|
||||
}
|
||||
p_attr->e_family = e_family;
|
||||
p_attr->u_port = u_port;
|
||||
if (pc_addr) {
|
||||
memcpy(p_attr->address, *pc_addr, u_length);
|
||||
}
|
||||
*pp_attr = p_attr;
|
||||
|
||||
bail:
|
||||
if (ret) {
|
||||
TSK_OBJECT_SAFE_FREE(p_attr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static tsk_object_t* tnet_stun_attr_address_ctor(tsk_object_t * self, va_list * app)
|
||||
{
|
||||
tnet_stun_attr_address_t *p_addr = (tnet_stun_attr_address_t *)self;
|
||||
if (p_addr) {
|
||||
}
|
||||
return self;
|
||||
}
|
||||
static tsk_object_t* tnet_stun_attr_address_dtor(tsk_object_t * self)
|
||||
{
|
||||
tnet_stun_attr_address_t *p_addr = (tnet_stun_attr_address_t *)self;
|
||||
if (p_addr) {
|
||||
TSK_DEBUG_INFO("*** STUN Attribute(ADDRESS) destroyed ***");
|
||||
}
|
||||
return self;
|
||||
}
|
||||
static const tsk_object_def_t tnet_stun_attr_address_def_s = {
|
||||
sizeof(tnet_stun_attr_address_t),
|
||||
tnet_stun_attr_address_ctor,
|
||||
tnet_stun_attr_address_dtor,
|
||||
_tnet_stun_attr_cmp,
|
||||
};
|
||||
const tsk_object_def_t *tnet_stun_attr_address_def_t = &tnet_stun_attr_address_def_s;
|
|
@ -0,0 +1,72 @@
|
|||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#ifndef TNET_STUN_ATTR_H
|
||||
#define TNET_STUN_ATTR_H
|
||||
|
||||
#include "tinynet_config.h"
|
||||
#include "stun/tnet_stun_types.h"
|
||||
|
||||
#include "tsk_object.h"
|
||||
#include "tsk_list.h"
|
||||
|
||||
TNET_BEGIN_DECLS
|
||||
|
||||
// rfc5389 - 15. STUN Attributes
|
||||
typedef struct tnet_stun_attr_hdr_xs {
|
||||
enum tnet_stun_attr_type_e e_type; // 16bits
|
||||
uint16_t u_length; // 16bits prior to padding, measured in bytes (WITHOUT header)
|
||||
} tnet_stun_attr_hdr_xt;
|
||||
|
||||
typedef struct tnet_stun_attr_s {
|
||||
TSK_DECLARE_OBJECT;
|
||||
struct tnet_stun_attr_s* pc_base;
|
||||
struct tnet_stun_attr_hdr_xs hdr;
|
||||
} tnet_stun_attr_t;
|
||||
#define TNET_STUN_DECLARE_ATTR struct tnet_stun_attr_s __base__
|
||||
#define TNET_STUN_ATTR(p_self) ((struct tnet_stun_attr_s*)(p_self))
|
||||
typedef tsk_list_t tnet_stun_attrs_L_t;
|
||||
int tnet_stun_attr_init(struct tnet_stun_attr_s* p_self, enum tnet_stun_attr_type_e e_type, uint16_t u_length);
|
||||
TINYNET_API int tnet_stun_attr_get_size_in_octetunits_without_padding(const struct tnet_stun_attr_s* pc_self, tsk_size_t* p_size);
|
||||
TINYNET_API int tnet_stun_attr_get_size_in_octetunits_with_padding(const struct tnet_stun_attr_s* pc_self, tsk_size_t* p_size);
|
||||
TINYNET_API int tnet_stun_attr_write_without_padding(const tnet_stun_transac_id_t* pc_transac_id, const struct tnet_stun_attr_s* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written);
|
||||
TINYNET_API int tnet_stun_attr_write_with_padding(const tnet_stun_transac_id_t* pc_transac_id, const struct tnet_stun_attr_s* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written);
|
||||
TINYNET_API int tnet_stun_attr_read(const tnet_stun_transac_id_t* pc_transac_id, const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_consumed_octets, struct tnet_stun_attr_s** pp_attr);
|
||||
|
||||
// ============== VDATA (USERNAME, MESSAGE-INTEGRITY, ...) ================ //
|
||||
typedef struct tnet_stun_attr_vdata_s {
|
||||
TNET_STUN_DECLARE_ATTR;
|
||||
uint8_t *p_data_ptr;
|
||||
uint16_t u_data_size;
|
||||
} tnet_stun_attr_vdata_t;
|
||||
int tnet_stun_attr_vdata_create(enum tnet_stun_attr_type_e e_type, const uint8_t* pc_data_ptr, uint16_t u_data_size, struct tnet_stun_attr_vdata_s** pp_attr);
|
||||
|
||||
|
||||
// ============== ADDRESS ================ //
|
||||
typedef struct tnet_stun_attr_address_s {
|
||||
TNET_STUN_DECLARE_ATTR;
|
||||
enum tnet_stun_address_family e_family; // 8bits
|
||||
uint16_t u_port; // 16bits
|
||||
tnet_stun_addr_t address; // always in network byte order. Use tnet_stun_utils_inet_pton()
|
||||
} tnet_stun_attr_address_t;
|
||||
|
||||
int tnet_stun_attr_address_create(enum tnet_stun_attr_type_e e_type, enum tnet_stun_address_family e_family, uint16_t u_port, const tnet_stun_addr_t* pc_addr, struct tnet_stun_attr_address_s** pp_attr);
|
||||
|
||||
TNET_END_DECLS
|
||||
|
||||
#endif /* TNET_STUN_ATTR_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -2,19 +2,19 @@
|
|||
* Copyright (C) 2010-2011 Mamadou Diop.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
|
@ -51,58 +51,56 @@ TNET_BEGIN_DECLS
|
|||
/**@ingroup tnet_stun_group
|
||||
* STUN IP family as per RFC 5389 subclause 15.1.
|
||||
**/
|
||||
typedef enum tnet_stun_addr_family_e
|
||||
{
|
||||
stun_ipv4 = 0x01,
|
||||
stun_ipv6 = 0x02
|
||||
typedef enum tnet_stun_addr_family_e {
|
||||
stun_ipv4 = 0x01,
|
||||
stun_ipv6 = 0x02
|
||||
}
|
||||
tnet_stun_addr_family_t;
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* STUN attribute types as per RFC 5389 subclause 18.2.
|
||||
**/
|
||||
typedef enum tnet_stun_attribute_type_e
|
||||
{
|
||||
/* === RFC 5389 - Comprehension-required range (0x0000-0x7FFF) */
|
||||
stun_reserved = 0x0000, /**< (Reserved) */
|
||||
stun_mapped_address = 0x0001, /**< http://tools.ietf.org/html/rfc5389#page-32 */
|
||||
stun_response_address = 0x0002, /**< (Reserved; was RESPONSE-ADDRESS) */
|
||||
stun_change_address = 0x0003, /**< (Reserved; was CHANGE-ADDRESS) */
|
||||
stun_source_address = 0x0004, /**< (Reserved; was SOURCE-ADDRESS) */
|
||||
stun_changed_address = 0x0005, /**< (Reserved; was CHANGED-ADDRESS) */
|
||||
stun_username = 0x0006, /**< http://tools.ietf.org/html/rfc5389#page-34 */
|
||||
stun_password = 0x0007, /**< (Reserved; was PASSWORD) */
|
||||
stun_message_integrity = 0x0008, /**< http://tools.ietf.org/html/rfc5389#page-34 */
|
||||
stun_error_code = 0x0009, /**< http://tools.ietf.org/html/rfc5389#page-36 */
|
||||
stun_unknown_attributes = 0x000A, /**< http://tools.ietf.org/html/rfc5389#page-38 */
|
||||
stun_reflected_from = 0x000B, /**< (Reserved; was REFLECTED-FROM) */
|
||||
stun_realm = 0x0014, /**< http://tools.ietf.org/html/rfc5389#page-38 */
|
||||
stun_nonce = 0x0015, /**< http://tools.ietf.org/html/rfc5389#page-38 */
|
||||
stun_xor_mapped_address = 0x0020, /**< http://tools.ietf.org/html/rfc5389#page-33 */
|
||||
typedef enum tnet_stun_attribute_type_e {
|
||||
/* === RFC 5389 - Comprehension-required range (0x0000-0x7FFF) */
|
||||
stun_reserved = 0x0000, /**< (Reserved) */
|
||||
stun_mapped_address = 0x0001, /**< http://tools.ietf.org/html/rfc5389#page-32 */
|
||||
stun_response_address = 0x0002, /**< (Reserved; was RESPONSE-ADDRESS) */
|
||||
stun_change_address = 0x0003, /**< (Reserved; was CHANGE-ADDRESS) */
|
||||
stun_source_address = 0x0004, /**< (Reserved; was SOURCE-ADDRESS) */
|
||||
stun_changed_address = 0x0005, /**< (Reserved; was CHANGED-ADDRESS) */
|
||||
stun_username = 0x0006, /**< http://tools.ietf.org/html/rfc5389#page-34 */
|
||||
stun_password = 0x0007, /**< (Reserved; was PASSWORD) */
|
||||
stun_message_integrity = 0x0008, /**< http://tools.ietf.org/html/rfc5389#page-34 */
|
||||
stun_error_code = 0x0009, /**< http://tools.ietf.org/html/rfc5389#page-36 */
|
||||
stun_unknown_attributes = 0x000A, /**< http://tools.ietf.org/html/rfc5389#page-38 */
|
||||
stun_reflected_from = 0x000B, /**< (Reserved; was REFLECTED-FROM) */
|
||||
stun_realm = 0x0014, /**< http://tools.ietf.org/html/rfc5389#page-38 */
|
||||
stun_nonce = 0x0015, /**< http://tools.ietf.org/html/rfc5389#page-38 */
|
||||
stun_xor_mapped_address = 0x0020, /**< http://tools.ietf.org/html/rfc5389#page-33 */
|
||||
|
||||
/* === RFC 5389 - Comprehension-optional range (0x8000-0xFFFF) */
|
||||
stun_software = 0x8022, /**< http://tools.ietf.org/html/rfc5389#page-39 */
|
||||
stun_alternate_server = 0x8023, /**< http://tools.ietf.org/html/rfc5389#page-39 */
|
||||
stun_fingerprint = 0x8028, /**< http://tools.ietf.org/html/rfc5389#page-36 */
|
||||
/* === RFC 5389 - Comprehension-optional range (0x8000-0xFFFF) */
|
||||
stun_software = 0x8022, /**< http://tools.ietf.org/html/rfc5389#page-39 */
|
||||
stun_alternate_server = 0x8023, /**< http://tools.ietf.org/html/rfc5389#page-39 */
|
||||
stun_fingerprint = 0x8028, /**< http://tools.ietf.org/html/rfc5389#page-36 */
|
||||
|
||||
/* === draft-ietf-behave-turn-16 */
|
||||
stun_channel_number = 0x000C, /**< draft-ietf-behave-turn-16 - CHANNEL-NUMBER */
|
||||
stun_lifetime = 0x000D, /**< draft-ietf-behave-turn-16 - LIFETIME */
|
||||
stun_reserved2 = 0x0010, /**< draft-ietf-behave-turn-16 - Reserved (was BANDWIDTH) */
|
||||
stun_xor_peer_address = 0x0012, /**< draft-ietf-behave-turn-16 - XOR-PEER-ADDRESS */
|
||||
stun_data = 0x0013, /**< draft-ietf-behave-turn-16 - DATA */
|
||||
stun_xor_relayed_address = 0x0016, /**< draft-ietf-behave-turn-16 - XOR-RELAYED-ADDRESS */
|
||||
stun_even_port = 0x0018, /**< draft-ietf-behave-turn-16 - EVEN-PORT */
|
||||
stun_requested_transport = 0x0019, /**< draft-ietf-behave-turn-16 - REQUESTED-TRANSPORT */
|
||||
stun_dont_fragment = 0x001A, /**< draft-ietf-behave-turn-16 - DONT-FRAGMENT */
|
||||
stun_reserved3 = 0x0021, /**< draft-ietf-behave-turn-16 - Reserved (was TIMER-VAL) */
|
||||
stun_reservation_token = 0x0022, /**< draft-ietf-behave-turn-16 - RESERVATION-TOKEN */
|
||||
/* === draft-ietf-behave-turn-16 */
|
||||
stun_channel_number = 0x000C, /**< draft-ietf-behave-turn-16 - CHANNEL-NUMBER */
|
||||
stun_lifetime = 0x000D, /**< draft-ietf-behave-turn-16 - LIFETIME */
|
||||
stun_reserved2 = 0x0010, /**< draft-ietf-behave-turn-16 - Reserved (was BANDWIDTH) */
|
||||
stun_xor_peer_address = 0x0012, /**< draft-ietf-behave-turn-16 - XOR-PEER-ADDRESS */
|
||||
stun_data = 0x0013, /**< draft-ietf-behave-turn-16 - DATA */
|
||||
stun_xor_relayed_address = 0x0016, /**< draft-ietf-behave-turn-16 - XOR-RELAYED-ADDRESS */
|
||||
stun_even_port = 0x0018, /**< draft-ietf-behave-turn-16 - EVEN-PORT */
|
||||
stun_requested_transport = 0x0019, /**< draft-ietf-behave-turn-16 - REQUESTED-TRANSPORT */
|
||||
stun_dont_fragment = 0x001A, /**< draft-ietf-behave-turn-16 - DONT-FRAGMENT */
|
||||
stun_reserved3 = 0x0021, /**< draft-ietf-behave-turn-16 - Reserved (was TIMER-VAL) */
|
||||
stun_reservation_token = 0x0022, /**< draft-ietf-behave-turn-16 - RESERVATION-TOKEN */
|
||||
|
||||
/* RFC 5245 */
|
||||
stun_ice_priority = 0x0024, /**< 21.2. STUN Attributes */
|
||||
stun_ice_use_candidate = 0x0025, /**< 21.2. STUN Attributes */
|
||||
stun_ice_controlled = 0x8029, /**< 21.2. STUN Attributes */
|
||||
stun_ice_controlling = 0x802A, /**< 21.2. STUN Attributes */
|
||||
/* RFC 5245 */
|
||||
stun_ice_priority = 0x0024, /**< 21.2. STUN Attributes */
|
||||
stun_ice_use_candidate = 0x0025, /**< 21.2. STUN Attributes */
|
||||
stun_ice_controlled = 0x8029, /**< 21.2. STUN Attributes */
|
||||
stun_ice_controlling = 0x802A, /**< 21.2. STUN Attributes */
|
||||
}
|
||||
tnet_stun_attribute_type_t;
|
||||
|
||||
|
@ -110,20 +108,19 @@ tnet_stun_attribute_type_t;
|
|||
/**@ingroup tnet_stun_group
|
||||
RFC 5389 - 15. STUN Attributes
|
||||
*/
|
||||
typedef struct tnet_stun_attribute_s
|
||||
{
|
||||
TSK_DECLARE_OBJECT;
|
||||
/*
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Type | Length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Value (variable) ....
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
tnet_stun_attribute_type_t type;
|
||||
uint16_t length;
|
||||
typedef struct tnet_stun_attribute_s {
|
||||
TSK_DECLARE_OBJECT;
|
||||
/*
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Type | Length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Value (variable) ....
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
tnet_stun_attribute_type_t type;
|
||||
uint16_t length;
|
||||
}
|
||||
tnet_stun_attribute_t;
|
||||
|
||||
|
@ -136,24 +133,23 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_def_t;
|
|||
/**@ingroup tnet_stun_group
|
||||
*RFC 5389 - 15.1. MAPPED-ADDRESS
|
||||
*/
|
||||
typedef struct tnet_stun_attribute_mapped_addr_s
|
||||
{
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
typedef struct tnet_stun_attribute_mapped_addr_s {
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
/*
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|0 0 0 0 0 0 0 0| Family | Port |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| |
|
||||
| Address (32 bits or 128 bits) |
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
tnet_stun_addr_family_t family;
|
||||
uint16_t port;
|
||||
uint8_t address[16];
|
||||
/*
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|0 0 0 0 0 0 0 0| Family | Port |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| |
|
||||
| Address (32 bits or 128 bits) |
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
tnet_stun_addr_family_t family;
|
||||
uint16_t port;
|
||||
uint8_t address[16];
|
||||
}
|
||||
tnet_stun_attribute_mapped_addr_t;
|
||||
|
||||
|
@ -163,22 +159,21 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_mapped_addr_def_t;
|
|||
/**@ingroup tnet_stun_group
|
||||
* RFC 5389 - 15.2. XOR-MAPPED-ADDRESS
|
||||
*/
|
||||
typedef struct tnet_stun_attribute_xmapped_addr_s
|
||||
{
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
typedef struct tnet_stun_attribute_xmapped_addr_s {
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
/*
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|x x x x x x x x| Family | X-Port |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| X-Address (Variable)
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
tnet_stun_addr_family_t family;
|
||||
uint16_t xport;
|
||||
uint8_t xaddress[16];
|
||||
/*
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|x x x x x x x x| Family | X-Port |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| X-Address (Variable)
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
tnet_stun_addr_family_t family;
|
||||
uint16_t xport;
|
||||
uint8_t xaddress[16];
|
||||
}
|
||||
tnet_stun_attribute_xmapped_addr_t;
|
||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_xmapped_addr_def_t;
|
||||
|
@ -187,11 +182,10 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_xmapped_addr_def_t;
|
|||
/**@ingroup tnet_stun_group
|
||||
* RFC 5389 - 15.3. USERNAME.
|
||||
*/
|
||||
typedef struct tnet_stun_attribute_username_s
|
||||
{
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
char* value;
|
||||
typedef struct tnet_stun_attribute_username_s {
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
char* value;
|
||||
}
|
||||
tnet_stun_attribute_username_t;
|
||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_username_def_t;
|
||||
|
@ -200,11 +194,10 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_username_def_t;
|
|||
/**@ingroup tnet_stun_group
|
||||
* RFC 5389 - 15.4. MESSAGE-INTEGRITY.
|
||||
*/
|
||||
typedef struct tnet_stun_attribute_integrity_s
|
||||
{
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
tsk_sha1digest_t sha1digest;
|
||||
typedef struct tnet_stun_attribute_integrity_s {
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
tsk_sha1digest_t sha1digest;
|
||||
}
|
||||
tnet_stun_attribute_integrity_t;
|
||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_integrity_def_t;
|
||||
|
@ -213,132 +206,121 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_integrity_def_t;
|
|||
/**@ingroup tnet_stun_group
|
||||
* RFC 5389 - 15.5. FINGERPRINT.
|
||||
*/
|
||||
typedef struct tnet_stun_attribute_fingerprint_s
|
||||
{
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
uint32_t value;
|
||||
typedef struct tnet_stun_attribute_fingerprint_s {
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
uint32_t value;
|
||||
}
|
||||
tnet_stun_attribute_fingerprint_t;
|
||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_fingerprint_def_t;
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
*RFC 5389 - 15.6. ERROR-CODE
|
||||
*RFC 5389 - 15.6. ERROR-CODE
|
||||
*/
|
||||
typedef struct tnet_stun_attribute_errorcode_s
|
||||
{
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
/*
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Reserved, should be 0 |Class| Number |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Reason Phrase (variable) ..
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
uint8_t _class;
|
||||
uint8_t number;
|
||||
char* reason_phrase;
|
||||
typedef struct tnet_stun_attribute_errorcode_s {
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
/*
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Reserved, should be 0 |Class| Number |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Reason Phrase (variable) ..
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
uint8_t _class;
|
||||
uint8_t number;
|
||||
char* reason_phrase;
|
||||
}
|
||||
tnet_stun_attribute_errorcode_t;
|
||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_errorcode_def_t;
|
||||
|
||||
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
/**@ingroup tnet_stun_group
|
||||
* RFC 5389 - 15.7. REALM. */
|
||||
typedef struct tnet_stun_attribute_realm_s
|
||||
{
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
char* value;
|
||||
typedef struct tnet_stun_attribute_realm_s {
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
char* value;
|
||||
}
|
||||
tnet_stun_attribute_realm_t;
|
||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_realm_def_t;
|
||||
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
/**@ingroup tnet_stun_group
|
||||
* RFC 5389 - 15.8. NONCE. */
|
||||
typedef struct tnet_stun_attribute_nonce_s
|
||||
{
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
char* value;
|
||||
typedef struct tnet_stun_attribute_nonce_s {
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
char* value;
|
||||
}
|
||||
tnet_stun_attribute_nonce_t;
|
||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_nonce_def_t;
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* RFC 5389 - 15.9. UNKNOWN-ATTRIBUTES. */
|
||||
typedef struct tnet_stun_attribute_unknowns_s
|
||||
{
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
tsk_buffer_t *value;
|
||||
typedef struct tnet_stun_attribute_unknowns_s {
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
tsk_buffer_t *value;
|
||||
}
|
||||
tnet_stun_attribute_unknowns_t;
|
||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_unknowns_def_t;
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* RFC 5389 - 15.10. SOFTWARE. */
|
||||
typedef struct tnet_stun_attribute_software_s
|
||||
{
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
char *value;
|
||||
typedef struct tnet_stun_attribute_software_s {
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
char *value;
|
||||
}
|
||||
tnet_stun_attribute_software_t;
|
||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_software_def_t;
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* RFC 5389 - 15.11. ALTERNATE-SERVER. */
|
||||
typedef struct tnet_stun_attribute_altserver_s
|
||||
{
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
typedef struct tnet_stun_attribute_altserver_s {
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
|
||||
tnet_stun_addr_family_t family;
|
||||
uint16_t port;
|
||||
uint8_t server[128];
|
||||
tnet_stun_addr_family_t family;
|
||||
uint16_t port;
|
||||
uint8_t server[128];
|
||||
}
|
||||
tnet_stun_attribute_altserver_t;
|
||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_altserver_def_t;
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* RFC 5245 - 19.1. New Attributes */
|
||||
typedef struct tnet_stun_attribute_ice_priority_s
|
||||
{
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
uint32_t value;
|
||||
typedef struct tnet_stun_attribute_ice_priority_s {
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
uint32_t value;
|
||||
}
|
||||
tnet_stun_attribute_ice_priority_t;
|
||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_ice_priority_def_t;
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* RFC 5245 - 19.1. New Attributes */
|
||||
typedef struct tnet_stun_attribute_ice_use_candidate_s
|
||||
{
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
typedef struct tnet_stun_attribute_ice_use_candidate_s {
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
}
|
||||
tnet_stun_attribute_ice_use_candidate_t;
|
||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_ice_use_candidate_def_t;
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* RFC 5245 - 19.1. New Attributes */
|
||||
typedef struct tnet_stun_attribute_ice_controlled_s
|
||||
{
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
uint64_t value;
|
||||
typedef struct tnet_stun_attribute_ice_controlled_s {
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
uint64_t value;
|
||||
}
|
||||
tnet_stun_attribute_ice_controlled_t;
|
||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_ice_controlled_def_t;
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* RFC 5245 - 19.1. New Attributes */
|
||||
typedef struct tnet_stun_attribute_ice_controlling_s
|
||||
{
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
uint64_t value;
|
||||
typedef struct tnet_stun_attribute_ice_controlling_s {
|
||||
TNET_STUN_DECLARE_ATTRIBUTE;
|
||||
uint64_t value;
|
||||
}
|
||||
tnet_stun_attribute_ice_controlling_t;
|
||||
TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_ice_controlling_def_t;
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
* Copyright (C) 2010-2011 Mamadou Diop.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
|
@ -44,12 +44,12 @@
|
|||
|
||||
static int __pred_find_attribute_by_type(const tsk_list_item_t *item, const void *att_type)
|
||||
{
|
||||
if(item && item->data){
|
||||
tnet_stun_attribute_t *att = item->data;
|
||||
tnet_stun_attribute_type_t type = *((tnet_stun_attribute_type_t*)att_type);
|
||||
return (att->type - type);
|
||||
}
|
||||
return -1;
|
||||
if(item && item->data) {
|
||||
tnet_stun_attribute_t *att = item->data;
|
||||
tnet_stun_attribute_type_t type = *((tnet_stun_attribute_type_t*)att_type);
|
||||
return (att->type - type);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
|
@ -60,7 +60,7 @@ static int __pred_find_attribute_by_type(const tsk_list_item_t *item, const void
|
|||
|
||||
tnet_stun_message_t* tnet_stun_message_create(const char* username, const char* password)
|
||||
{
|
||||
return tsk_object_new(tnet_stun_message_def_t, username, password);
|
||||
return tsk_object_new(tnet_stun_message_def_t, username, password);
|
||||
}
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
|
@ -70,7 +70,7 @@ tnet_stun_message_t* tnet_stun_message_create(const char* username, const char*
|
|||
*/
|
||||
tnet_stun_message_t* tnet_stun_message_create_null()
|
||||
{
|
||||
return tnet_stun_message_create(tsk_null, tsk_null);
|
||||
return tnet_stun_message_create(tsk_null, tsk_null);
|
||||
}
|
||||
|
||||
#define SERIALIZE_N_ADD_ATTRIBUTE(att_name, payload, payload_size) \
|
||||
|
@ -86,18 +86,18 @@ tnet_stun_message_t* tnet_stun_message_create_null()
|
|||
**/
|
||||
tsk_buffer_t* tnet_stun_message_serialize(const tnet_stun_message_t *self)
|
||||
{
|
||||
tsk_buffer_t *output = 0;
|
||||
tnet_stun_attribute_t *attribute;
|
||||
unsigned compute_integrity = self->integrity;
|
||||
|
||||
if(!self){
|
||||
goto bail;
|
||||
}
|
||||
|
||||
output = tsk_buffer_create_null();
|
||||
tsk_buffer_t *output = 0;
|
||||
tnet_stun_attribute_t *attribute;
|
||||
unsigned compute_integrity = self->integrity;
|
||||
|
||||
/* RFC 5389 - 6. STUN Message Structure
|
||||
0 1 2 3
|
||||
if(!self) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
output = tsk_buffer_create_null();
|
||||
|
||||
/* RFC 5389 - 6. STUN Message Structure
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|0 0| STUN Message Type | Message Length |
|
||||
|
@ -108,134 +108,135 @@ tsk_buffer_t* tnet_stun_message_serialize(const tnet_stun_message_t *self)
|
|||
| Transaction ID (96 bits) |
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
*/
|
||||
|
||||
/* STUN Message Type
|
||||
*/
|
||||
{
|
||||
uint16_t type = tnet_htons(self->type);
|
||||
tsk_buffer_append(output, &(type), 2);
|
||||
}
|
||||
|
||||
/* Message Length ==> Will be updated after attributes have been added. */
|
||||
{
|
||||
static const uint16_t length = 0;
|
||||
tsk_buffer_append(output, &(length), 2);
|
||||
}
|
||||
/* STUN Message Type
|
||||
*/
|
||||
{
|
||||
uint16_t type = tnet_htons(self->type);
|
||||
tsk_buffer_append(output, &(type), 2);
|
||||
}
|
||||
|
||||
/* Magic Cookie
|
||||
*/
|
||||
{
|
||||
uint32_t cookie = tnet_htonl(self->cookie);
|
||||
tsk_buffer_append(output, &(cookie), 4);
|
||||
}
|
||||
/* Message Length ==> Will be updated after attributes have been added. */
|
||||
{
|
||||
static const uint16_t length = 0;
|
||||
tsk_buffer_append(output, &(length), 2);
|
||||
}
|
||||
|
||||
/* Magic Cookie
|
||||
*/
|
||||
{
|
||||
uint32_t cookie = tnet_htonl(self->cookie);
|
||||
tsk_buffer_append(output, &(cookie), 4);
|
||||
}
|
||||
|
||||
|
||||
/* Transaction ID (96 bits==>16bytes)
|
||||
*/
|
||||
tsk_buffer_append(output, self->transaction_id, TNET_STUN_TRANSACID_SIZE);
|
||||
/* Transaction ID (96 bits==>16bytes)
|
||||
*/
|
||||
tsk_buffer_append(output, self->transaction_id, TNET_STUN_TRANSACID_SIZE);
|
||||
|
||||
/* DONT-FRAGMENT
|
||||
*/
|
||||
if(self->dontfrag){
|
||||
attribute = (tnet_stun_attribute_t *)tnet_turn_attribute_dontfrag_create();
|
||||
tnet_stun_attribute_serialize(attribute, output);
|
||||
TSK_OBJECT_SAFE_FREE(attribute);
|
||||
}
|
||||
/* DONT-FRAGMENT
|
||||
*/
|
||||
if(self->dontfrag) {
|
||||
attribute = (tnet_stun_attribute_t *)tnet_turn_attribute_dontfrag_create();
|
||||
tnet_stun_attribute_serialize(attribute, output);
|
||||
TSK_OBJECT_SAFE_FREE(attribute);
|
||||
}
|
||||
|
||||
/* AUTHENTICATION */
|
||||
if(self->realm && self->nonce){ // long term
|
||||
SERIALIZE_N_ADD_ATTRIBUTE(realm, self->realm, tsk_strlen(self->realm));
|
||||
SERIALIZE_N_ADD_ATTRIBUTE(nonce, self->nonce, tsk_strlen(self->nonce));
|
||||
|
||||
compute_integrity = !self->nointegrity;
|
||||
}
|
||||
else if(self->password){ // short term
|
||||
compute_integrity = !self->nointegrity;
|
||||
}
|
||||
/* AUTHENTICATION */
|
||||
if(self->realm && self->nonce) { // long term
|
||||
SERIALIZE_N_ADD_ATTRIBUTE(realm, self->realm, tsk_strlen(self->realm));
|
||||
SERIALIZE_N_ADD_ATTRIBUTE(nonce, self->nonce, tsk_strlen(self->nonce));
|
||||
|
||||
if(compute_integrity && self->username){
|
||||
SERIALIZE_N_ADD_ATTRIBUTE(username, self->username, tsk_strlen(self->username));
|
||||
}
|
||||
compute_integrity = !self->nointegrity;
|
||||
}
|
||||
else if(self->password) { // short term
|
||||
compute_integrity = !self->nointegrity;
|
||||
}
|
||||
|
||||
/*=== Attributes === */
|
||||
{
|
||||
tsk_list_item_t *item;
|
||||
tsk_list_foreach(item, self->attributes)
|
||||
{
|
||||
attribute = item->data;
|
||||
tnet_stun_attribute_serialize(attribute, output);
|
||||
tnet_stun_attribute_pad(attribute, output);
|
||||
}
|
||||
}
|
||||
if(compute_integrity && self->username) {
|
||||
SERIALIZE_N_ADD_ATTRIBUTE(username, self->username, tsk_strlen(self->username));
|
||||
}
|
||||
|
||||
/* Message Length: The message length MUST contain the size, in bytes, of the message
|
||||
not including the 20-byte STUN header.
|
||||
*/
|
||||
{
|
||||
// compute length for 'MESSAGE-INTEGRITY'
|
||||
// will be computed again to store the correct value
|
||||
uint16_t length = (output->size) - TNET_STUN_HEADER_SIZE;
|
||||
/*=== Attributes === */
|
||||
{
|
||||
tsk_list_item_t *item;
|
||||
tsk_list_foreach(item, self->attributes) {
|
||||
attribute = item->data;
|
||||
tnet_stun_attribute_serialize(attribute, output);
|
||||
tnet_stun_attribute_pad(attribute, output);
|
||||
}
|
||||
}
|
||||
|
||||
/* Message Length: The message length MUST contain the size, in bytes, of the message
|
||||
not including the 20-byte STUN header.
|
||||
*/
|
||||
{
|
||||
// compute length for 'MESSAGE-INTEGRITY'
|
||||
// will be computed again to store the correct value
|
||||
uint16_t length = (output->size) - TNET_STUN_HEADER_SIZE;
|
||||
#if 0
|
||||
if(self->fingerprint)
|
||||
length += (2/* Type */ + 2 /* Length */+ 4 /* FINGERPRINT VALUE*/);
|
||||
if(self->fingerprint) {
|
||||
length += (2/* Type */ + 2 /* Length */+ 4 /* FINGERPRINT VALUE*/);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(compute_integrity)
|
||||
length += (2/* Type */ + 2 /* Length */+ TSK_SHA1_DIGEST_SIZE /* INTEGRITY VALUE*/);
|
||||
|
||||
*(((uint16_t*)output->data)+1) = tnet_htons(length);
|
||||
}
|
||||
if(compute_integrity) {
|
||||
length += (2/* Type */ + 2 /* Length */+ TSK_SHA1_DIGEST_SIZE /* INTEGRITY VALUE*/);
|
||||
}
|
||||
|
||||
/* MESSAGE-INTEGRITY */
|
||||
if(compute_integrity){
|
||||
/* RFC 5389 - 15.4. MESSAGE-INTEGRITY
|
||||
The MESSAGE-INTEGRITY attribute contains an HMAC-SHA1 [RFC2104] of the STUN message.
|
||||
*(((uint16_t*)output->data)+1) = tnet_htons(length);
|
||||
}
|
||||
|
||||
For long-term credentials ==> key = MD5(username ":" realm ":" SASLprep(password))
|
||||
For short-term credentials ==> key = SASLprep(password)
|
||||
*/
|
||||
|
||||
tsk_sha1digest_t hmac;
|
||||
|
||||
if(self->username && self->realm && self->password){ // long term
|
||||
char* keystr = tsk_null;
|
||||
tsk_md5digest_t md5;
|
||||
tsk_sprintf(&keystr, "%s:%s:%s", self->username, self->realm, self->password);
|
||||
TSK_MD5_DIGEST_CALC(keystr, tsk_strlen(keystr), md5);
|
||||
hmac_sha1digest_compute(output->data, output->size, (const char*)md5, TSK_MD5_DIGEST_SIZE, hmac);
|
||||
|
||||
TSK_FREE(keystr);
|
||||
}
|
||||
else{ // short term
|
||||
hmac_sha1digest_compute(output->data, output->size, self->password, tsk_strlen(self->password), hmac);
|
||||
}
|
||||
/* MESSAGE-INTEGRITY */
|
||||
if(compute_integrity) {
|
||||
/* RFC 5389 - 15.4. MESSAGE-INTEGRITY
|
||||
The MESSAGE-INTEGRITY attribute contains an HMAC-SHA1 [RFC2104] of the STUN message.
|
||||
|
||||
SERIALIZE_N_ADD_ATTRIBUTE(integrity, hmac, TSK_SHA1_DIGEST_SIZE);
|
||||
}
|
||||
For long-term credentials ==> key = MD5(username ":" realm ":" SASLprep(password))
|
||||
For short-term credentials ==> key = SASLprep(password)
|
||||
*/
|
||||
|
||||
// LENGTH
|
||||
*(((uint16_t*)output->data) + 1) = tnet_htons((output->size - TNET_STUN_HEADER_SIZE + (self->fingerprint ? 8 : 0)));
|
||||
tsk_sha1digest_t hmac;
|
||||
|
||||
/* FINGERPRINT */
|
||||
if(self->fingerprint){//JINGLE_ICE
|
||||
/* RFC 5389 - 15.5. FINGERPRINT
|
||||
The FINGERPRINT attribute MAY be present in all STUN messages. The
|
||||
value of the attribute is computed as the CRC-32 of the STUN message
|
||||
up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with
|
||||
the 32-bit value 0x5354554e
|
||||
*/
|
||||
uint32_t fingerprint = tsk_pppfcs32(TSK_PPPINITFCS32, output->data, output->size);
|
||||
fingerprint ^= 0x5354554e;
|
||||
fingerprint = tnet_htonl(fingerprint);
|
||||
|
||||
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_fingerprint_create(fingerprint);
|
||||
tnet_stun_attribute_serialize(attribute, output);
|
||||
TSK_OBJECT_SAFE_FREE(attribute);
|
||||
}
|
||||
if(self->username && self->realm && self->password) { // long term
|
||||
char* keystr = tsk_null;
|
||||
tsk_md5digest_t md5;
|
||||
tsk_sprintf(&keystr, "%s:%s:%s", self->username, self->realm, self->password);
|
||||
TSK_MD5_DIGEST_CALC(keystr, tsk_strlen(keystr), md5);
|
||||
hmac_sha1digest_compute(output->data, output->size, (const char*)md5, TSK_MD5_DIGEST_SIZE, hmac);
|
||||
|
||||
TSK_FREE(keystr);
|
||||
}
|
||||
else { // short term
|
||||
hmac_sha1digest_compute(output->data, output->size, self->password, tsk_strlen(self->password), hmac);
|
||||
}
|
||||
|
||||
SERIALIZE_N_ADD_ATTRIBUTE(integrity, hmac, TSK_SHA1_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
// LENGTH
|
||||
*(((uint16_t*)output->data) + 1) = tnet_htons((output->size - TNET_STUN_HEADER_SIZE + (self->fingerprint ? 8 : 0)));
|
||||
|
||||
/* FINGERPRINT */
|
||||
if(self->fingerprint) { //JINGLE_ICE
|
||||
/* RFC 5389 - 15.5. FINGERPRINT
|
||||
The FINGERPRINT attribute MAY be present in all STUN messages. The
|
||||
value of the attribute is computed as the CRC-32 of the STUN message
|
||||
up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with
|
||||
the 32-bit value 0x5354554e
|
||||
*/
|
||||
uint32_t fingerprint = tsk_pppfcs32(TSK_PPPINITFCS32, output->data, output->size);
|
||||
fingerprint ^= 0x5354554e;
|
||||
fingerprint = tnet_htonl(fingerprint);
|
||||
|
||||
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_fingerprint_create(fingerprint);
|
||||
tnet_stun_attribute_serialize(attribute, output);
|
||||
TSK_OBJECT_SAFE_FREE(attribute);
|
||||
}
|
||||
|
||||
bail:
|
||||
return output;
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
|
@ -243,81 +244,80 @@ bail:
|
|||
*
|
||||
* Deserializes a STUN message from binary data.
|
||||
*
|
||||
* @param [in,out] data A pointer to the binary data.
|
||||
* @param size The size of the binary data.
|
||||
* @param [in,out] data A pointer to the binary data.
|
||||
* @param size The size of the binary data.
|
||||
*
|
||||
* @retval A STUN message if deserialization succeed or NULL otherwise.
|
||||
**/
|
||||
tnet_stun_message_t* tnet_stun_message_deserialize(const uint8_t *data, tsk_size_t size)
|
||||
{
|
||||
tnet_stun_message_t *message = 0;
|
||||
uint8_t* dataPtr, *dataEnd;
|
||||
tnet_stun_message_t *message = 0;
|
||||
uint8_t* dataPtr, *dataEnd;
|
||||
|
||||
|
||||
if(!data || (size < TNET_STUN_HEADER_SIZE) || !TNET_IS_STUN2_MSG(data, size)){
|
||||
goto bail;
|
||||
}
|
||||
|
||||
dataPtr = (uint8_t*)data;
|
||||
dataEnd = (dataPtr + size);
|
||||
if(!data || (size < TNET_STUN_HEADER_SIZE) || !TNET_IS_STUN2_MSG(data, size)) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
message = tnet_stun_message_create_null();
|
||||
dataPtr = (uint8_t*)data;
|
||||
dataEnd = (dataPtr + size);
|
||||
|
||||
/* Message Type
|
||||
*/
|
||||
message->type = (tnet_stun_message_type_t)tnet_ntohs_2(dataPtr);
|
||||
dataPtr += 2;
|
||||
message = tnet_stun_message_create_null();
|
||||
|
||||
/* Message Length
|
||||
*/
|
||||
message->length = tnet_ntohs_2(dataPtr);
|
||||
dataPtr += 2;
|
||||
/* Message Type
|
||||
*/
|
||||
message->type = (tnet_stun_message_type_t)tnet_ntohs_2(dataPtr);
|
||||
dataPtr += 2;
|
||||
|
||||
/* Check message validity
|
||||
*/
|
||||
if((message->length + TNET_STUN_HEADER_SIZE) != size)
|
||||
{
|
||||
TSK_OBJECT_SAFE_FREE(message);
|
||||
goto bail;
|
||||
}
|
||||
/* Message Length
|
||||
*/
|
||||
message->length = tnet_ntohs_2(dataPtr);
|
||||
dataPtr += 2;
|
||||
|
||||
/* Magic Cookie
|
||||
==> already set by the constructor and checked by @ref TNET_IS_STUN2
|
||||
*/
|
||||
dataPtr += 4;
|
||||
/* Check message validity
|
||||
*/
|
||||
if((message->length + TNET_STUN_HEADER_SIZE) != size) {
|
||||
TSK_OBJECT_SAFE_FREE(message);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* Transaction ID
|
||||
*/
|
||||
memcpy(message->transaction_id, dataPtr, TNET_STUN_TRANSACID_SIZE);
|
||||
dataPtr += TNET_STUN_TRANSACID_SIZE;
|
||||
/* Magic Cookie
|
||||
==> already set by the constructor and checked by @ref TNET_IS_STUN2
|
||||
*/
|
||||
dataPtr += 4;
|
||||
|
||||
/* == Parse attributes
|
||||
*/
|
||||
while(dataPtr < dataEnd){
|
||||
tnet_stun_attribute_t *attribute = tnet_stun_attribute_deserialize(dataPtr, (dataEnd - dataPtr));
|
||||
if(attribute){
|
||||
tsk_size_t att_size = (attribute->length + 2 /* Type*/ + 2/* Length */);
|
||||
att_size += (att_size & 0x03) ? 4-(att_size & 0x03) : 0; // Skip zero bytes used to pad the attribute.
|
||||
/* Transaction ID
|
||||
*/
|
||||
memcpy(message->transaction_id, dataPtr, TNET_STUN_TRANSACID_SIZE);
|
||||
dataPtr += TNET_STUN_TRANSACID_SIZE;
|
||||
|
||||
dataPtr += att_size;
|
||||
tsk_list_push_back_data(message->attributes, (void**)&attribute);
|
||||
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* == Parse attributes
|
||||
*/
|
||||
while(dataPtr < dataEnd) {
|
||||
tnet_stun_attribute_t *attribute = tnet_stun_attribute_deserialize(dataPtr, (dataEnd - dataPtr));
|
||||
if(attribute) {
|
||||
tsk_size_t att_size = (attribute->length + 2 /* Type*/ + 2/* Length */);
|
||||
att_size += (att_size & 0x03) ? 4-(att_size & 0x03) : 0; // Skip zero bytes used to pad the attribute.
|
||||
|
||||
dataPtr += att_size;
|
||||
tsk_list_push_back_data(message->attributes, (void**)&attribute);
|
||||
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
bail:
|
||||
return message;
|
||||
return message;
|
||||
}
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
*/
|
||||
tsk_bool_t tnet_stun_message_has_attribute(const tnet_stun_message_t *self, tnet_stun_attribute_type_t type)
|
||||
{
|
||||
return (tnet_stun_message_get_attribute(self, type) != tsk_null);
|
||||
return (tnet_stun_message_get_attribute(self, type) != tsk_null);
|
||||
}
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
|
@ -328,21 +328,21 @@ tsk_bool_t tnet_stun_message_has_attribute(const tnet_stun_message_t *self, tnet
|
|||
*/
|
||||
int tnet_stun_message_add_attribute(tnet_stun_message_t *self, tnet_stun_attribute_t** attribute)
|
||||
{
|
||||
if(self && attribute && *attribute){
|
||||
tsk_list_push_back_data(self->attributes, (void**)attribute);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
if(self && attribute && *attribute) {
|
||||
tsk_list_push_back_data(self->attributes, (void**)attribute);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
*/
|
||||
int tnet_stun_message_remove_attribute(tnet_stun_message_t *self, tnet_stun_attribute_type_t type)
|
||||
{
|
||||
if(self && self->attributes){
|
||||
tsk_list_remove_item_by_pred(self->attributes, __pred_find_attribute_by_type, &type);
|
||||
}
|
||||
return 0;
|
||||
if(self && self->attributes) {
|
||||
tsk_list_remove_item_by_pred(self->attributes, __pred_find_attribute_by_type, &type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -354,17 +354,17 @@ int tnet_stun_message_remove_attribute(tnet_stun_message_t *self, tnet_stun_attr
|
|||
*/
|
||||
const tnet_stun_attribute_t* tnet_stun_message_get_attribute(const tnet_stun_message_t *self, tnet_stun_attribute_type_t type)
|
||||
{
|
||||
tnet_stun_attribute_t* attribute;
|
||||
tnet_stun_attribute_t* attribute;
|
||||
|
||||
if(self && !TSK_LIST_IS_EMPTY(self->attributes)){
|
||||
tsk_list_item_t *item;
|
||||
tsk_list_foreach(item, self->attributes){
|
||||
if((attribute = item->data) && attribute->type == type){
|
||||
return attribute;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
if(self && !TSK_LIST_IS_EMPTY(self->attributes)) {
|
||||
tsk_list_item_t *item;
|
||||
tsk_list_foreach(item, self->attributes) {
|
||||
if((attribute = item->data) && attribute->type == type) {
|
||||
return attribute;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
|
@ -374,11 +374,11 @@ const tnet_stun_attribute_t* tnet_stun_message_get_attribute(const tnet_stun_mes
|
|||
*/
|
||||
short tnet_stun_message_get_errorcode(const tnet_stun_message_t *self)
|
||||
{
|
||||
const tnet_stun_attribute_errorcode_t* error = (const tnet_stun_attribute_errorcode_t*)tnet_stun_message_get_attribute(self, stun_error_code);
|
||||
if(error){
|
||||
return ((error->_class*100) + error->number);
|
||||
}
|
||||
return -1;
|
||||
const tnet_stun_attribute_errorcode_t* error = (const tnet_stun_attribute_errorcode_t*)tnet_stun_message_get_attribute(self, stun_error_code);
|
||||
if(error) {
|
||||
return ((error->_class*100) + error->number);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
|
@ -388,11 +388,11 @@ short tnet_stun_message_get_errorcode(const tnet_stun_message_t *self)
|
|||
*/
|
||||
const char* tnet_stun_message_get_realm(const tnet_stun_message_t *self)
|
||||
{
|
||||
const tnet_stun_attribute_realm_t* realm = (const tnet_stun_attribute_realm_t*)tnet_stun_message_get_attribute(self, stun_realm);
|
||||
if(realm){
|
||||
return realm->value;
|
||||
}
|
||||
return 0;
|
||||
const tnet_stun_attribute_realm_t* realm = (const tnet_stun_attribute_realm_t*)tnet_stun_message_get_attribute(self, stun_realm);
|
||||
if(realm) {
|
||||
return realm->value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
|
@ -402,11 +402,11 @@ const char* tnet_stun_message_get_realm(const tnet_stun_message_t *self)
|
|||
*/
|
||||
const char* tnet_stun_message_get_nonce(const tnet_stun_message_t *self)
|
||||
{
|
||||
const tnet_stun_attribute_nonce_t* nonce = (const tnet_stun_attribute_nonce_t*)tnet_stun_message_get_attribute(self, stun_nonce);
|
||||
if(nonce){
|
||||
return nonce->value;
|
||||
}
|
||||
return 0;
|
||||
const tnet_stun_attribute_nonce_t* nonce = (const tnet_stun_attribute_nonce_t*)tnet_stun_message_get_attribute(self, stun_nonce);
|
||||
if(nonce) {
|
||||
return nonce->value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
|
@ -416,25 +416,25 @@ const char* tnet_stun_message_get_nonce(const tnet_stun_message_t *self)
|
|||
*/
|
||||
int32_t tnet_stun_message_get_lifetime(const tnet_stun_message_t *self)
|
||||
{
|
||||
const tnet_turn_attribute_lifetime_t* lifetime = (const tnet_turn_attribute_lifetime_t*)tnet_stun_message_get_attribute(self, stun_lifetime);
|
||||
if(lifetime){
|
||||
return lifetime->value;
|
||||
}
|
||||
return -1;
|
||||
const tnet_turn_attribute_lifetime_t* lifetime = (const tnet_turn_attribute_lifetime_t*)tnet_stun_message_get_attribute(self, stun_lifetime);
|
||||
if(lifetime) {
|
||||
return lifetime->value;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
*/
|
||||
tsk_bool_t tnet_stun_message_transac_id_equals(const tnet_stun_transacid_t id1, const tnet_stun_transacid_t id2)
|
||||
{
|
||||
tsk_size_t i;
|
||||
static const tsk_size_t size = sizeof(tnet_stun_transacid_t);
|
||||
for(i = 0; i < size; i++){
|
||||
if(id1[i] != id2[i]){
|
||||
return tsk_false;
|
||||
}
|
||||
}
|
||||
return tsk_true;
|
||||
tsk_size_t i;
|
||||
static const tsk_size_t size = sizeof(tnet_stun_transacid_t);
|
||||
for(i = 0; i < size; i++) {
|
||||
if(id1[i] != id2[i]) {
|
||||
return tsk_false;
|
||||
}
|
||||
}
|
||||
return tsk_true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -447,48 +447,48 @@ tsk_bool_t tnet_stun_message_transac_id_equals(const tnet_stun_transacid_t id1,
|
|||
//
|
||||
static tsk_object_t* tnet_stun_message_ctor(tsk_object_t * self, va_list * app)
|
||||
{
|
||||
tnet_stun_message_t *message = self;
|
||||
if(message){
|
||||
message->username = tsk_strdup(va_arg(*app, const char*));
|
||||
message->password = tsk_strdup(va_arg(*app, const char*));
|
||||
tnet_stun_message_t *message = self;
|
||||
if(message) {
|
||||
message->username = tsk_strdup(va_arg(*app, const char*));
|
||||
message->password = tsk_strdup(va_arg(*app, const char*));
|
||||
|
||||
message->cookie = TNET_STUN_MAGIC_COOKIE;
|
||||
message->attributes = tsk_list_create();
|
||||
message->cookie = TNET_STUN_MAGIC_COOKIE;
|
||||
message->attributes = tsk_list_create();
|
||||
|
||||
message->fingerprint = 1;
|
||||
message->integrity = 0;
|
||||
|
||||
{ // Create random transaction id
|
||||
int i;
|
||||
for(i = 0; i < sizeof(message->transaction_id)/sizeof(message->transaction_id[0]); ++i){
|
||||
message->transaction_id[i] = rand();
|
||||
}
|
||||
}
|
||||
}
|
||||
return self;
|
||||
message->fingerprint = 1;
|
||||
message->integrity = 0;
|
||||
|
||||
{
|
||||
// Create random transaction id
|
||||
int i;
|
||||
for(i = 0; i < sizeof(message->transaction_id)/sizeof(message->transaction_id[0]); ++i) {
|
||||
message->transaction_id[i] = rand();
|
||||
}
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
static tsk_object_t* tnet_stun_message_dtor(tsk_object_t * self)
|
||||
{
|
||||
tnet_stun_message_t *message = self;
|
||||
if(message){
|
||||
TSK_FREE(message->username);
|
||||
TSK_FREE(message->password);
|
||||
TSK_FREE(message->realm);
|
||||
TSK_FREE(message->nonce);
|
||||
{
|
||||
tnet_stun_message_t *message = self;
|
||||
if(message) {
|
||||
TSK_FREE(message->username);
|
||||
TSK_FREE(message->password);
|
||||
TSK_FREE(message->realm);
|
||||
TSK_FREE(message->nonce);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(message->attributes);
|
||||
}
|
||||
|
||||
return self;
|
||||
TSK_OBJECT_SAFE_FREE(message->attributes);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static const tsk_object_def_t tnet_stun_message_def_s =
|
||||
{
|
||||
sizeof(tnet_stun_message_t),
|
||||
tnet_stun_message_ctor,
|
||||
tnet_stun_message_dtor,
|
||||
tsk_null,
|
||||
static const tsk_object_def_t tnet_stun_message_def_s = {
|
||||
sizeof(tnet_stun_message_t),
|
||||
tnet_stun_message_ctor,
|
||||
tnet_stun_message_dtor,
|
||||
tsk_null,
|
||||
};
|
||||
const tsk_object_def_t *tnet_stun_message_def_t = &tnet_stun_message_def_s;
|
||||
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
* Copyright (C) 2010-2011 Mamadou Diop.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
|
@ -95,87 +95,84 @@ typedef uint8_t tnet_stun_transacid_t[TNET_STUN_TRANSACID_SIZE];
|
|||
/**@ingroup tnet_stun_group
|
||||
* List of all supported STUN classes as per RFC 5389 subcaluse 6.
|
||||
**/
|
||||
typedef enum tnet_stun_class_type_e
|
||||
{
|
||||
stun_class_request = 0x00, /**< Request class: 0b00 */
|
||||
stun_class_indication = 0x01, /**< Indication class: 0b01 */
|
||||
stun_class_success_response = 0x02, /**< Success response class: 0b10 */
|
||||
stun_class_error_response = 0x03, /**< Error/failure response class: 0b11 */
|
||||
typedef enum tnet_stun_class_type_e {
|
||||
stun_class_request = 0x00, /**< Request class: 0b00 */
|
||||
stun_class_indication = 0x01, /**< Indication class: 0b01 */
|
||||
stun_class_success_response = 0x02, /**< Success response class: 0b10 */
|
||||
stun_class_error_response = 0x03, /**< Error/failure response class: 0b11 */
|
||||
}
|
||||
tnet_stun_class_type_t;
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* List of all supported STUN methods.
|
||||
* List of all supported STUN methods.
|
||||
* RFC 5389 only define one method(Bining). All other methods have been defined
|
||||
* by TURN (draft-ietf-behave-turn-16 and draft-ietf-behave-turn-tcp-05).
|
||||
* by TURN (draft-ietf-behave-turn-16 and draft-ietf-behave-turn-tcp-05).
|
||||
**/
|
||||
typedef enum tnet_stun_method_type_e
|
||||
{
|
||||
stun_method_binding = 0x0001, /**< RFC 5389 - Binding method: 0b000000000001 */
|
||||
|
||||
stun_method_allocate = 0x0003, /**< draft-ietf-behave-turn-16 - Allocate (only request/response semantics defined) */
|
||||
stun_method_refresh = 0x0004, /**< draft-ietf-behave-turn-16 - Refresh (only request/response semantics defined) */
|
||||
stun_method_send = 0x0006, /**< draft-ietf-behave-turn-16 - Send (only indication semantics defined) */
|
||||
stun_method_data = 0x0007, /**< draft-ietf-behave-turn-16 - Data (only indication semantics defined) */
|
||||
stun_method_createpermission = 0x0008, /**< draft-ietf-behave-turn-16 - CreatePermission (only request/response semantics defined */
|
||||
stun_method_channelbind = 0x0009, /**< draft-ietf-behave-turn-16 - ChannelBind (only request/response semantics defined) */
|
||||
typedef enum tnet_stun_method_type_e {
|
||||
stun_method_binding = 0x0001, /**< RFC 5389 - Binding method: 0b000000000001 */
|
||||
|
||||
stun_method_allocate = 0x0003, /**< draft-ietf-behave-turn-16 - Allocate (only request/response semantics defined) */
|
||||
stun_method_refresh = 0x0004, /**< draft-ietf-behave-turn-16 - Refresh (only request/response semantics defined) */
|
||||
stun_method_send = 0x0006, /**< draft-ietf-behave-turn-16 - Send (only indication semantics defined) */
|
||||
stun_method_data = 0x0007, /**< draft-ietf-behave-turn-16 - Data (only indication semantics defined) */
|
||||
stun_method_createpermission = 0x0008, /**< draft-ietf-behave-turn-16 - CreatePermission (only request/response semantics defined */
|
||||
stun_method_channelbind = 0x0009, /**< draft-ietf-behave-turn-16 - ChannelBind (only request/response semantics defined) */
|
||||
}
|
||||
tnet_stun_method_type_t;
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* List of all supported STUN types.
|
||||
*/
|
||||
typedef enum tnet_stun_message_type_e
|
||||
{
|
||||
/* RFC 5389 - 6. STUN Message Structure
|
||||
|
||||
The message type defines the message class (request, success
|
||||
response, failure response, or indication) and the message method
|
||||
(the primary function) of the STUN message. Although there are four
|
||||
message classes, there are only two types of transactions in STUN:
|
||||
request/response transactions (which consist of a request message and
|
||||
a response message) and indication transactions (which consist of a
|
||||
single indication message). Response classes are split into error
|
||||
and success responses to aid in quickly processing the STUN message.
|
||||
typedef enum tnet_stun_message_type_e {
|
||||
/* RFC 5389 - 6. STUN Message Structure
|
||||
|
||||
The message type field is decomposed further into the following
|
||||
structure:
|
||||
The message type defines the message class (request, success
|
||||
response, failure response, or indication) and the message method
|
||||
(the primary function) of the STUN message. Although there are four
|
||||
message classes, there are only two types of transactions in STUN:
|
||||
request/response transactions (which consist of a request message and
|
||||
a response message) and indication transactions (which consist of a
|
||||
single indication message). Response classes are split into error
|
||||
and success responses to aid in quickly processing the STUN message.
|
||||
|
||||
0 1
|
||||
The message type field is decomposed further into the following
|
||||
structure:
|
||||
|
||||
0 1
|
||||
2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|M |M |M|M|M|C|M|M|M|C|M|M|M|M|
|
||||
|11|10|9|8|7|1|6|5|4|0|3|2|1|0|
|
||||
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
stun_binding_request = (stun_method_binding | TNET_STUN_CLASS_REQUEST_MASK),
|
||||
stun_binding_indication = (stun_method_binding | TNET_STUN_CLASS_INDICATION_MASK),
|
||||
stun_binding_success_response = (stun_method_binding | TNET_STUN_CLASS_SUCCESS_MASK),
|
||||
stun_binding_error_response = (stun_method_binding | TNET_STUN_CLASS_ERROR_MASK),
|
||||
*/
|
||||
stun_binding_request = (stun_method_binding | TNET_STUN_CLASS_REQUEST_MASK),
|
||||
stun_binding_indication = (stun_method_binding | TNET_STUN_CLASS_INDICATION_MASK),
|
||||
stun_binding_success_response = (stun_method_binding | TNET_STUN_CLASS_SUCCESS_MASK),
|
||||
stun_binding_error_response = (stun_method_binding | TNET_STUN_CLASS_ERROR_MASK),
|
||||
|
||||
stun_allocate_request = (stun_method_allocate | TNET_STUN_CLASS_REQUEST_MASK),
|
||||
stun_allocate_indication = (stun_method_allocate | TNET_STUN_CLASS_INDICATION_MASK),
|
||||
stun_allocate_success_response = (stun_method_allocate | TNET_STUN_CLASS_SUCCESS_MASK),
|
||||
stun_allocate_error_response = (stun_method_allocate | TNET_STUN_CLASS_ERROR_MASK),
|
||||
stun_allocate_request = (stun_method_allocate | TNET_STUN_CLASS_REQUEST_MASK),
|
||||
stun_allocate_indication = (stun_method_allocate | TNET_STUN_CLASS_INDICATION_MASK),
|
||||
stun_allocate_success_response = (stun_method_allocate | TNET_STUN_CLASS_SUCCESS_MASK),
|
||||
stun_allocate_error_response = (stun_method_allocate | TNET_STUN_CLASS_ERROR_MASK),
|
||||
|
||||
stun_refresh_request = (stun_method_refresh | TNET_STUN_CLASS_REQUEST_MASK),
|
||||
stun_refresh_indication = (stun_method_refresh | TNET_STUN_CLASS_INDICATION_MASK),
|
||||
stun_refresh_success_response = (stun_method_refresh | TNET_STUN_CLASS_SUCCESS_MASK),
|
||||
stun_refresh_error_response = (stun_method_refresh | TNET_STUN_CLASS_ERROR_MASK),
|
||||
stun_refresh_request = (stun_method_refresh | TNET_STUN_CLASS_REQUEST_MASK),
|
||||
stun_refresh_indication = (stun_method_refresh | TNET_STUN_CLASS_INDICATION_MASK),
|
||||
stun_refresh_success_response = (stun_method_refresh | TNET_STUN_CLASS_SUCCESS_MASK),
|
||||
stun_refresh_error_response = (stun_method_refresh | TNET_STUN_CLASS_ERROR_MASK),
|
||||
|
||||
stun_send_indication = (stun_method_send | TNET_STUN_CLASS_INDICATION_MASK),
|
||||
stun_send_indication = (stun_method_send | TNET_STUN_CLASS_INDICATION_MASK),
|
||||
|
||||
stun_data_indication = (stun_method_data | TNET_STUN_CLASS_INDICATION_MASK),
|
||||
stun_data_indication = (stun_method_data | TNET_STUN_CLASS_INDICATION_MASK),
|
||||
|
||||
stun_createpermission_request = (stun_method_createpermission | TNET_STUN_CLASS_REQUEST_MASK),
|
||||
stun_createpermission_indication = (stun_method_createpermission | TNET_STUN_CLASS_INDICATION_MASK),
|
||||
stun_createpermission_success_response = (stun_method_createpermission | TNET_STUN_CLASS_SUCCESS_MASK),
|
||||
stun_createpermission_error_response = (stun_method_createpermission | TNET_STUN_CLASS_ERROR_MASK),
|
||||
stun_createpermission_request = (stun_method_createpermission | TNET_STUN_CLASS_REQUEST_MASK),
|
||||
stun_createpermission_indication = (stun_method_createpermission | TNET_STUN_CLASS_INDICATION_MASK),
|
||||
stun_createpermission_success_response = (stun_method_createpermission | TNET_STUN_CLASS_SUCCESS_MASK),
|
||||
stun_createpermission_error_response = (stun_method_createpermission | TNET_STUN_CLASS_ERROR_MASK),
|
||||
|
||||
stun_channelbind_request = (stun_method_channelbind | TNET_STUN_CLASS_REQUEST_MASK),
|
||||
stun_channelbind_indication = (stun_method_channelbind | TNET_STUN_CLASS_INDICATION_MASK),
|
||||
stun_channelbind_success_response = (stun_method_channelbind | TNET_STUN_CLASS_SUCCESS_MASK),
|
||||
stun_channelbind_error_response = (stun_method_channelbind | TNET_STUN_CLASS_ERROR_MASK),
|
||||
stun_channelbind_request = (stun_method_channelbind | TNET_STUN_CLASS_REQUEST_MASK),
|
||||
stun_channelbind_indication = (stun_method_channelbind | TNET_STUN_CLASS_INDICATION_MASK),
|
||||
stun_channelbind_success_response = (stun_method_channelbind | TNET_STUN_CLASS_SUCCESS_MASK),
|
||||
stun_channelbind_error_response = (stun_method_channelbind | TNET_STUN_CLASS_ERROR_MASK),
|
||||
}
|
||||
tnet_stun_message_type_t;
|
||||
|
||||
|
@ -184,12 +181,11 @@ tnet_stun_message_type_t;
|
|||
* STUN Message structure as per RFC 5389 subclause 6.
|
||||
* http://tools.ietf.org/html/rfc5389#section-6
|
||||
*/
|
||||
typedef struct tnet_stun_message_s
|
||||
{
|
||||
TSK_DECLARE_OBJECT;
|
||||
typedef struct tnet_stun_message_s {
|
||||
TSK_DECLARE_OBJECT;
|
||||
|
||||
/*
|
||||
0 1 2 3
|
||||
/*
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|0 0| STUN Message Type | Message Length |
|
||||
|
@ -200,24 +196,24 @@ typedef struct tnet_stun_message_s
|
|||
| Transaction ID (96 bits) |
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
tnet_stun_message_type_t type;
|
||||
uint16_t length;
|
||||
uint32_t cookie;
|
||||
tnet_stun_transacid_t transaction_id;
|
||||
*/
|
||||
|
||||
unsigned fingerprint:1;
|
||||
unsigned integrity:1;
|
||||
unsigned dontfrag:1;
|
||||
unsigned nointegrity:1;
|
||||
tnet_stun_message_type_t type;
|
||||
uint16_t length;
|
||||
uint32_t cookie;
|
||||
tnet_stun_transacid_t transaction_id;
|
||||
|
||||
char* username;
|
||||
char* password;
|
||||
char* realm;
|
||||
char* nonce;
|
||||
unsigned fingerprint:1;
|
||||
unsigned integrity:1;
|
||||
unsigned dontfrag:1;
|
||||
unsigned nointegrity:1;
|
||||
|
||||
tnet_stun_attributes_L_t *attributes; /**< List of all attributes associated to this message */
|
||||
char* username;
|
||||
char* password;
|
||||
char* realm;
|
||||
char* nonce;
|
||||
|
||||
tnet_stun_attributes_L_t *attributes; /**< List of all attributes associated to this message */
|
||||
}
|
||||
tnet_stun_message_t;
|
||||
|
||||
|
|
|
@ -0,0 +1,308 @@
|
|||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#include "stun/tnet_stun_pkt.h"
|
||||
#include "stun/tnet_stun_utils.h"
|
||||
|
||||
#include "tnet_endianness.h"
|
||||
|
||||
#include "tsk_memory.h"
|
||||
#include "tsk_debug.h"
|
||||
|
||||
int tnet_stun_pkt_create(tnet_stun_pkt_type_t e_type, uint16_t u_length, const tnet_stun_transac_id_t* pc_transac_id, tnet_stun_pkt_t** pp_attr)
|
||||
{
|
||||
extern const tsk_object_def_t *tnet_stun_pkt_def_t;
|
||||
if (!pp_attr) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if(!(*pp_attr = tsk_object_new(tnet_stun_pkt_def_t))) {
|
||||
TSK_DEBUG_ERROR("Failed to create STUN pkt object");
|
||||
return -2;
|
||||
}
|
||||
if (!((*pp_attr)->p_list_attrs = tsk_list_create())) {
|
||||
TSK_OBJECT_SAFE_FREE(*pp_attr);
|
||||
return -3;
|
||||
}
|
||||
if (pc_transac_id) {
|
||||
memcpy((*pp_attr)->transac_id, *pc_transac_id, sizeof(tnet_stun_transac_id_t));
|
||||
}
|
||||
else {
|
||||
tnet_stun_utils_transac_id_rand(&(*pp_attr)->transac_id);
|
||||
}
|
||||
(*pp_attr)->e_type = e_type;
|
||||
(*pp_attr)->u_length = u_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tnet_stun_pkt_add_attr(tnet_stun_pkt_t* p_self, tnet_stun_attr_t** pp_attr)
|
||||
{
|
||||
if (!p_self || !pp_attr || !*pp_attr) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
tsk_list_push_back_data(p_self->p_list_attrs, (void**)pp_attr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tnet_stun_pkt_add_attrs(tnet_stun_pkt_t* p_self, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret = 0;
|
||||
tnet_stun_pkt_add_attr_t e_add_attr;
|
||||
if (!p_self) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
va_start(ap, p_self);
|
||||
|
||||
while ((e_add_attr = va_arg(ap, tnet_stun_pkt_add_attr_t)) != tnet_stun_pkt_add_attr_null) {
|
||||
switch (e_add_attr) {
|
||||
case tnet_stun_pkt_add_attr_vdata: {
|
||||
// (enum tnet_stun_attr_type_e)(E_TYPE), (const uint8_t*)(P_DATA_PTR), (uint16_t)(U_DATA_SIZE)
|
||||
enum tnet_stun_attr_type_e E_TYPE = va_arg(ap, enum tnet_stun_attr_type_e);
|
||||
const uint8_t* P_DATA_PTR = va_arg(ap, const uint8_t*);
|
||||
uint16_t U_DATA_SIZE = va_arg(ap, uint16_t);
|
||||
tnet_stun_attr_vdata_t *p_attr;
|
||||
if ((ret = tnet_stun_attr_vdata_create(E_TYPE, P_DATA_PTR, U_DATA_SIZE, &p_attr))) {
|
||||
goto bail;
|
||||
}
|
||||
if ((ret = tnet_stun_pkt_add_attr(p_self, (tnet_stun_attr_t**)&p_attr))) {
|
||||
TSK_OBJECT_SAFE_FREE(p_attr);
|
||||
goto bail;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case tnet_stun_pkt_add_attr_address: {
|
||||
// (enum tnet_stun_attr_type_e)(E_TYPE), (enum tnet_stun_address_family_e)(E_FAMILY), (uint16_t)(U_PORT), (const tnet_stun_addr_t*)PC_ADDR_PTR
|
||||
enum tnet_stun_attr_type_e E_TYPE = va_arg(ap, enum tnet_stun_attr_type_e);
|
||||
enum tnet_stun_address_family_e E_FAMILY = va_arg(ap, enum tnet_stun_address_family_e);
|
||||
uint16_t U_PORT = va_arg(ap, uint16_t);
|
||||
const tnet_stun_addr_t* PC_ADDR_PTR = va_arg(ap, const tnet_stun_addr_t*);
|
||||
tnet_stun_attr_address_t *p_attr;
|
||||
if ((ret = tnet_stun_attr_address_create(E_TYPE, E_FAMILY, U_PORT, PC_ADDR_PTR, &p_attr))) {
|
||||
goto bail;
|
||||
}
|
||||
if ((ret = tnet_stun_pkt_add_attr(p_self, (tnet_stun_attr_t**)&p_attr))) {
|
||||
TSK_OBJECT_SAFE_FREE(p_attr);
|
||||
goto bail;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
TSK_DEBUG_ERROR("Arguments corrupted or invalid.");
|
||||
ret = -2;
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bail:
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tnet_stun_pkt_get_size_in_octetunits_without_padding(const tnet_stun_pkt_t* pc_self, tsk_size_t* p_size)
|
||||
{
|
||||
const tsk_list_item_t* pc_item;
|
||||
const tnet_stun_attr_t* pc_attr;
|
||||
tsk_size_t n_size;
|
||||
int ret;
|
||||
if (!pc_self || !p_size) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
*p_size = kStunPktHdrSizeInOctets;
|
||||
tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
|
||||
if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
|
||||
if ((ret = tnet_stun_attr_get_size_in_octetunits_without_padding(pc_attr, &n_size))) {
|
||||
return ret;
|
||||
}
|
||||
*p_size += n_size;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tnet_stun_pkt_get_size_in_octetunits_with_padding(const tnet_stun_pkt_t* pc_self, tsk_size_t* p_size)
|
||||
{
|
||||
const tsk_list_item_t* pc_item;
|
||||
const tnet_stun_attr_t* pc_attr;
|
||||
tsk_size_t n_size;
|
||||
int ret;
|
||||
if (!pc_self || !p_size) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
*p_size = kStunPktHdrSizeInOctets;
|
||||
tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
|
||||
if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
|
||||
if ((ret = tnet_stun_attr_get_size_in_octetunits_with_padding(pc_attr, &n_size))) {
|
||||
return ret;
|
||||
}
|
||||
*p_size += n_size;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tnet_stun_pkt_write_with_padding(const tnet_stun_pkt_t* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written)
|
||||
{
|
||||
const tsk_list_item_t* pc_item;
|
||||
const tnet_stun_attr_t* pc_attr;
|
||||
tsk_size_t n_size;
|
||||
int ret;
|
||||
if (!pc_self || !p_buff_ptr || !n_buff_size || !p_written) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if ((ret = tnet_stun_pkt_get_size_in_octetunits_with_padding(pc_self, p_written))) {
|
||||
return ret;
|
||||
}
|
||||
if ((n_buff_size < *p_written)) {
|
||||
TSK_DEBUG_ERROR("Buffer too short: %u<%u", n_buff_size, *p_written);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// write header
|
||||
*((uint16_t*)&p_buff_ptr[0]) = tnet_htons((unsigned short)pc_self->e_type);
|
||||
*((uint32_t*)&p_buff_ptr[4]) = tnet_htonl(kStunMagicCookie);
|
||||
memcpy(&p_buff_ptr[8], pc_self->transac_id, sizeof(pc_self->transac_id));
|
||||
|
||||
p_buff_ptr += kStunPktHdrSizeInOctets;
|
||||
n_buff_size -= kStunPktHdrSizeInOctets;
|
||||
|
||||
// write attributes
|
||||
|
||||
tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
|
||||
if (pc_attr = (const tnet_stun_attr_t*)pc_item->data) {
|
||||
if ((ret = tnet_stun_attr_write_with_padding(&pc_self->transac_id, pc_attr, p_buff_ptr, n_buff_size, &n_size))) {
|
||||
return ret;
|
||||
}
|
||||
p_buff_ptr += n_size;
|
||||
n_buff_size -= n_size;
|
||||
}
|
||||
}
|
||||
|
||||
// Length
|
||||
*((uint16_t*)&p_buff_ptr[2-*p_written]) = tnet_htons(*p_written - kStunPktHdrSizeInOctets);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tnet_stun_pkt_is_complete(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tsk_bool_t *pb_is_complete)
|
||||
{
|
||||
if (!pb_is_complete) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
*pb_is_complete = tsk_false;
|
||||
if (pc_buff_ptr && n_buff_size >= kStunPktHdrSizeInOctets) {
|
||||
tsk_size_t n_paylen_in_octets = tnet_ntohs_2(&pc_buff_ptr[2]);
|
||||
*pb_is_complete = ((n_buff_size - kStunPktHdrSizeInOctets) >= n_paylen_in_octets);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tnet_stun_pkt_read(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tnet_stun_pkt_t** pp_pkt)
|
||||
{
|
||||
tsk_bool_t b_is_complete;
|
||||
tsk_size_t PayloadLengthInOctets;
|
||||
tnet_stun_pkt_type_t Type;
|
||||
tnet_stun_transac_id_t transac_id;
|
||||
uint32_t MagicCookie;
|
||||
int ret;
|
||||
|
||||
if (!pc_buff_ptr || !n_buff_size || !pp_pkt) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if (!TNET_STUN_PKT_IS_STUN2(pc_buff_ptr, n_buff_size)) {
|
||||
TSK_DEBUG_ERROR("Buffer doesn't contain a valid STUN2 pkt");
|
||||
return -2;
|
||||
}
|
||||
if ((ret = tnet_stun_pkt_is_complete(pc_buff_ptr, n_buff_size, &b_is_complete))) {
|
||||
return ret;
|
||||
}
|
||||
if (!b_is_complete) {
|
||||
TSK_DEBUG_ERROR("Buffer too short(%u)", n_buff_size);
|
||||
return -3;
|
||||
}
|
||||
|
||||
// read the header
|
||||
Type = tnet_ntohs_2(&pc_buff_ptr[0]);
|
||||
PayloadLengthInOctets = tnet_ntohs_2(&pc_buff_ptr[2]);
|
||||
MagicCookie = tnet_ntohl_2(&pc_buff_ptr[4]);
|
||||
if (MagicCookie != kStunMagicCookieLong) {
|
||||
TSK_DEBUG_ERROR("%x not a valid STUN2 magic cookie");
|
||||
return -4;
|
||||
}
|
||||
memcpy(transac_id, &pc_buff_ptr[8], sizeof(tnet_stun_transac_id_t));
|
||||
// create the pkt
|
||||
if((ret = tnet_stun_pkt_create(Type, PayloadLengthInOctets, &transac_id, pp_pkt))) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (PayloadLengthInOctets > 0) {
|
||||
tnet_stun_attr_t* p_attr;
|
||||
tsk_size_t n_consumed_octets;
|
||||
pc_buff_ptr += kStunPktHdrSizeInOctets;
|
||||
do {
|
||||
if ((ret = tnet_stun_attr_read(&(*pp_pkt)->transac_id, pc_buff_ptr, PayloadLengthInOctets, &n_consumed_octets, &p_attr))) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = tnet_stun_pkt_add_attr((*pp_pkt), &p_attr))) {
|
||||
TSK_OBJECT_SAFE_FREE((*pp_pkt));
|
||||
return ret;
|
||||
}
|
||||
PayloadLengthInOctets -= n_consumed_octets;
|
||||
pc_buff_ptr += n_consumed_octets;
|
||||
}
|
||||
while (PayloadLengthInOctets >= kStunAttrHdrSizeInOctets);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static tsk_object_t* tnet_stun_pkt_ctor(tsk_object_t * self, va_list * app)
|
||||
{
|
||||
tnet_stun_pkt_t *p_pkt = (tnet_stun_pkt_t *)self;
|
||||
if (p_pkt) {
|
||||
}
|
||||
return self;
|
||||
}
|
||||
static tsk_object_t* tnet_stun_pkt_dtor(tsk_object_t * self)
|
||||
{
|
||||
tnet_stun_pkt_t *p_pkt = (tnet_stun_pkt_t *)self;
|
||||
if (p_pkt) {
|
||||
TSK_DEBUG_INFO("*** STUN pkt destroyed ***");
|
||||
TSK_OBJECT_SAFE_FREE(p_pkt->p_list_attrs);
|
||||
TSK_FREE(p_pkt->auth.p_username);
|
||||
TSK_FREE(p_pkt->auth.p_password);
|
||||
TSK_FREE(p_pkt->auth.p_realm);
|
||||
TSK_FREE(p_pkt->auth.p_nonce);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
static const tsk_object_def_t tnet_stun_pkt_def_s = {
|
||||
sizeof(tnet_stun_pkt_t),
|
||||
tnet_stun_pkt_ctor,
|
||||
tnet_stun_pkt_dtor,
|
||||
tsk_null,
|
||||
};
|
||||
const tsk_object_def_t *tnet_stun_pkt_def_t = &tnet_stun_pkt_def_s;
|
|
@ -0,0 +1,110 @@
|
|||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#ifndef TNET_STUN_PKT_H
|
||||
#define TNET_STUN_PKT_H
|
||||
|
||||
#include "tinynet_config.h"
|
||||
#include "stun/tnet_stun_attr.h"
|
||||
|
||||
#include "tsk_object.h"
|
||||
#include "tsk_list.h"
|
||||
|
||||
TNET_BEGIN_DECLS
|
||||
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* @def TNET_STUN_PKT_IS_REQ
|
||||
* Checks whether the STUN message is a request or not.
|
||||
*/
|
||||
/**@ingroup tnet_stun_group
|
||||
* @def TNET_STUN_PKT_IS_INDICATION
|
||||
* Checks whether the STUN message is an indicaton message or not.
|
||||
*/
|
||||
/**@ingroup tnet_stun_group
|
||||
* @def TNET_STUN_RESP_IS_SUCCESS
|
||||
* Checks whether the STUN message is a success response or not.
|
||||
*/
|
||||
/**@ingroup tnet_stun_group
|
||||
* @def TNET_STUN_RESP_IS_ERROR
|
||||
* Checks whether the STUN message is an error response or not.
|
||||
*/
|
||||
#define TNET_STUN_PKT_IS_REQ(p_self) ((p_self) && (((p_self)->e_type & 0x0110) == tnet_stun_mask_request))
|
||||
#define TNET_STUN_PKT_IS_RESP(p_self) (TNET_STUN_PKT_RESP_IS_SUCCESS((p_self)) || TNET_STUN_PKT_RESP_IS_ERROR((self)))
|
||||
#define TNET_STUN_PKT_IS_INDICATION(p_self) ((p_self) && (((p_self)->e_type & 0x0110) == tnet_stun_mask_indication))
|
||||
#define TNET_STUN_PKT_RESP_IS_SUCCESS(p_self) ((p_self) && (((p_self)->e_type & 0x0110) == tnet_stun_mask_success))
|
||||
#define TNET_STUN_PKT_RESP_IS_ERROR(p_self) ((p_self) && (((p_self)->e_type & 0x0110) == tnet_stun_mask_error))
|
||||
|
||||
typedef enum tnet_stun_pkt_add_attr_e {
|
||||
tnet_stun_pkt_add_attr_null = 0,
|
||||
tnet_stun_pkt_add_attr_none = tnet_stun_pkt_add_attr_null,
|
||||
tnet_stun_pkt_add_attr_vdata,
|
||||
tnet_stun_pkt_add_attr_address
|
||||
}
|
||||
tnet_stun_pkt_add_attr_t;
|
||||
|
||||
#define TNET_STUN_PKT_ADD_ATTR_NULL() tnet_stun_pkt_add_attr_null
|
||||
#define TNET_STUN_PKT_ADD_ATTR_VDATA(E_TYPE, P_DATA_PTR, U_DATA_SIZE) tnet_stun_pkt_add_attr_vdata, (enum tnet_stun_attr_type_e)(E_TYPE), (const uint8_t*)(P_DATA_PTR), (uint16_t)(U_DATA_SIZE)
|
||||
#define TNET_STUN_PKT_ADD_ATTR_ADDRESS(E_TYPE, E_FAMILY, U_PORT, PC_ADDR_PTR) tnet_stun_pkt_add_attr_address, (enum tnet_stun_attr_type_e)(E_TYPE), (enum tnet_stun_address_family_e)(E_FAMILY), (uint16_t)(U_PORT), (const tnet_stun_addr_t*)PC_ADDR_PTR
|
||||
#define TNET_STUN_PKT_ADD_ATTR_ADDRESS_V4(E_TYPE, U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_ADDRESS((E_TYPE), tnet_stun_address_family_ipv4, (U_PORT), (PC_ADDR_PTR))
|
||||
#define TNET_STUN_PKT_ADD_ATTR_ADDRESS_V6(E_TYPE, U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_ADDRESS((E_TYPE), tnet_stun_address_family_ipv6, (U_PORT), (PC_ADDR_PTR))
|
||||
// rfc5389 - 15.1. MAPPED-ADDRESS
|
||||
#define TNET_STUN_PKT_ADD_ATTR_MAPPED_ADDRESS(E_FAMILY, U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_ADDRESS(tnet_stun_attr_type_mapped_address, (E_FAMILY), (U_PORT), (PC_ADDR_PTR))
|
||||
#define TNET_STUN_PKT_ADD_ATTR_MAPPED_ADDRESS_V4(U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_MAPPED_ADDRESS(tnet_stun_address_family_ipv4, (U_PORT), (PC_ADDR_PTR))
|
||||
#define TNET_STUN_PKT_ADD_ATTR_MAPPED_ADDRESS_V6(U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_MAPPED_ADDRESS(tnet_stun_address_family_ipv6, (U_PORT), (PC_ADDR_PTR))
|
||||
// rfc5389 - 15.2. XOR-MAPPED-ADDRESS
|
||||
#define TNET_STUN_PKT_ADD_ATTR_XOR_MAPPED_ADDRESS(E_FAMILY, U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_ADDRESS(tnet_stun_attr_type_xor_mapped_address, (E_FAMILY), (U_PORT), (PC_ADDR_PTR))
|
||||
#define TNET_STUN_PKT_ADD_ATTR_XOR_MAPPED_ADDRESS_V4(U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_XOR_MAPPED_ADDRESS(tnet_stun_address_family_ipv4, (U_PORT), (PC_ADDR_PTR))
|
||||
#define TNET_STUN_PKT_ADD_ATTR_XOR_MAPPED_ADDRESS_V6(U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_XOR_MAPPED_ADDRESS(tnet_stun_address_family_ipv6, (U_PORT), (PC_ADDR_PTR))
|
||||
|
||||
typedef struct tnet_stun_pkt_s {
|
||||
TSK_DECLARE_OBJECT;
|
||||
enum tnet_stun_pkt_type_e e_type;
|
||||
uint16_t u_length; // 16bits: contain the size, in bytes, of the message not including the 20-byte STUN header
|
||||
tnet_stun_transac_id_t transac_id; // 96bits : always in network byte-order
|
||||
tnet_stun_attrs_L_t* p_list_attrs;
|
||||
struct {
|
||||
unsigned fingerprint:1;
|
||||
unsigned integrity:1;
|
||||
unsigned dontfrag:1;
|
||||
unsigned nointegrity:1;
|
||||
} opt;
|
||||
struct {
|
||||
char* p_username;
|
||||
char* p_password;
|
||||
char* p_realm;
|
||||
char* p_nonce;
|
||||
} auth;
|
||||
} tnet_stun_pkt_t;
|
||||
#define TNET_STUN_DECLARE_PKT struct tnet_stun_pkt_s __base__
|
||||
#define TNET_STUN_PKT(p_self) ((struct tnet_stun_pkt_s*)(p_self))
|
||||
typedef tsk_list_t tnet_stun_pkts_L_t;
|
||||
|
||||
TINYNET_API int tnet_stun_pkt_create(enum tnet_stun_pkt_type_e e_type, uint16_t u_length, const tnet_stun_transac_id_t* pc_transac_id, struct tnet_stun_pkt_s** pp_attr);
|
||||
#define tnet_stun_pkt_create_empty(e_type, pp_attr) tnet_stun_pkt_create((e_type), 0, tsk_null, (pp_attr))
|
||||
TINYNET_API int tnet_stun_pkt_add_attr(struct tnet_stun_pkt_s* p_self, struct tnet_stun_attr_s** pp_attr);
|
||||
TINYNET_API int tnet_stun_pkt_add_attrs(struct tnet_stun_pkt_s* p_self, ...);
|
||||
TINYNET_API int tnet_stun_pkt_get_size_in_octetunits_without_padding(const struct tnet_stun_pkt_s* pc_self, tsk_size_t* p_size);
|
||||
TINYNET_API int tnet_stun_pkt_get_size_in_octetunits_with_padding(const struct tnet_stun_pkt_s* pc_self, tsk_size_t* p_size);
|
||||
TINYNET_API int tnet_stun_pkt_write_with_padding(const struct tnet_stun_pkt_s* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written);
|
||||
TINYNET_API int tnet_stun_pkt_is_complete(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tsk_bool_t *pb_is_complete);
|
||||
TINYNET_API int tnet_stun_pkt_read(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, struct tnet_stun_pkt_s** pp_pkt);
|
||||
|
||||
TNET_END_DECLS
|
||||
|
||||
#endif /* TNET_STUN_PKT_H */
|
|
@ -0,0 +1,234 @@
|
|||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#ifndef TNET_STUN_TYPES_H
|
||||
#define TNET_STUN_TYPES_H
|
||||
|
||||
#include "tinynet_config.h"
|
||||
|
||||
TNET_BEGIN_DECLS
|
||||
|
||||
typedef uint8_t tnet_stun_addr_t[16]; // IPv4(32bits) or IPv6(128bits)
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* Checks if the pointer to the buffer hold a STUN header by checking that it starts with 0b00 and contain the magic cookie.
|
||||
* As per RFC 5389 subclause 19: Explicitly point out that the most significant 2 bits of STUN are
|
||||
* 0b00, allowing easy differentiation with RTP packets when used with ICE.
|
||||
* As per RFC 5389 subclause 6: The magic cookie field MUST contain the fixed value 0x2112A442 in
|
||||
* network byte order.
|
||||
*
|
||||
* @param PU8 The pointer to the buffer holding the STUN raw data.
|
||||
**/
|
||||
#define TNET_STUN_PKT_IS_STUN2(PU8, SIZE) \
|
||||
( \
|
||||
((PU8)) && \
|
||||
((SIZE) >= kStunPktHdrSizeInOctets) && \
|
||||
(((PU8)[0] & 0xc0) == 0x00) && \
|
||||
( PU8[4] == 0x21 && PU8[5] == 0x12 && PU8[6] == 0xA4 && PU8[7] == 0x42 ) \
|
||||
)
|
||||
|
||||
#if !defined(kStunPortDefaultTcpUdp)
|
||||
# define kStunPortDefaultTcpUdp 3478
|
||||
#endif /* kStunPortDefaultTcpUdp */
|
||||
|
||||
#if !defined(kStunPortDefaultTls)
|
||||
# define kStunPortDefaultTls 5349
|
||||
#endif /* kStunPortDefaultTls */
|
||||
|
||||
// rfc5389 - 15. STUN Attributes
|
||||
#if !defined(kStunAttrHdrSizeInOctets)
|
||||
# define kStunAttrHdrSizeInOctets 4
|
||||
#endif /* kStunAttrHdrSizeInOctets */
|
||||
|
||||
// rfc5389 - 6. STUN Message Structure
|
||||
#if !defined(kStunPktHdrSizeInOctets)
|
||||
# define kStunPktHdrSizeInOctets 20
|
||||
#endif /* kStunPktHdrSizeInOctets */
|
||||
|
||||
// STUN2 magic cookie value in network byte order as per RFC 5389 subclause 6.
|
||||
#if !defined(kStunMagicCookieLong)
|
||||
# define kStunMagicCookieLong 0x2112A442
|
||||
#endif /* kStunMagicCookieLong */
|
||||
#if !defined(kStunMagicCookie)
|
||||
# define kStunMagicCookie kStunMagicCookieLong
|
||||
#endif /* kStunMagicCookie */
|
||||
#if !defined(kStunMagicCookieShort)
|
||||
# define kStunMagicCookieShort 0x2112
|
||||
#endif /* kStunMagicCookieShort */
|
||||
|
||||
#if !defined (kStunFingerprintXorConst)
|
||||
# define kStunFingerprintXorConst 0x5354554e
|
||||
#endif kStunFingerprintXorConst /* kStunFingerprintXorConst */
|
||||
|
||||
// STUN trasactionn ID size (96bits = 12bytes)
|
||||
#if !defined(kStunTransacIdSize)
|
||||
# define kStunTransacIdSize 12
|
||||
#endif
|
||||
typedef uint8_t tnet_stun_transac_id_t[kStunTransacIdSize];
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* List of all supported STUN classes as per RFC 5389 subcaluse 6.
|
||||
**/
|
||||
typedef enum tnet_stun_class_e {
|
||||
tnet_stun_class_request = 0x00, /**< Request class: 0b00 */
|
||||
tnet_stun_class_indication = 0x01, /**< Indication class: 0b01 */
|
||||
tnet_stun_class_success_response = 0x02, /**< Success response class: 0b10 */
|
||||
tnet_stun_class_error_response = 0x03, /**< Error/failure response class: 0b11 */
|
||||
}
|
||||
tnet_stun_class_t;
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* List of all supported STUN methods.
|
||||
* RFC 5389 defines only one method(Bining). All other methods have been defined by TURN (rfc5766 section 13).
|
||||
**/
|
||||
typedef enum tnet_stun_method_e {
|
||||
tnet_stun_method_binding = 0x0001, /**< RFC 5389 - Binding method: 0b000000000001 */
|
||||
|
||||
tnet_stun_method_allocate = 0x0003, /**< rfc5766 - Allocate (only request/response semantics defined) */
|
||||
tnet_stun_method_refresh = 0x0004, /**< rfc5766 - Refresh (only request/response semantics defined) */
|
||||
tnet_stun_method_send = 0x0006, /**< rfc5766 - Send (only indication semantics defined) */
|
||||
tnet_stun_method_data = 0x0007, /**< rfc5766 - Data (only indication semantics defined) */
|
||||
tnet_stun_method_createpermission = 0x0008, /**< rfc5766 - CreatePermission (only request/response semantics defined */
|
||||
tnet_stun_method_channelbind = 0x0009, /**< rfc5766 - ChannelBind (only request/response semantics defined) */
|
||||
}
|
||||
tnet_stun_method_t;
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
*/
|
||||
typedef enum tnet_stun_mask_e {
|
||||
tnet_stun_mask_request = 0x0000,
|
||||
tnet_stun_mask_indication = 0x0010,
|
||||
tnet_stun_mask_success = 0x0100,
|
||||
tnet_stun_mask_error = 0x0110
|
||||
}
|
||||
tnet_stun_mask_t;
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* STUN IP family as per RFC 5389 subclause 15.1.
|
||||
**/
|
||||
typedef enum tnet_stun_address_family_e {
|
||||
tnet_stun_address_family_ipv4 = 0x01,
|
||||
tnet_stun_address_family_ipv6 = 0x02
|
||||
} tnet_stun_address_family_t;
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* STUN attr types as per RFC 5389 subclause 18.2.
|
||||
**/
|
||||
typedef enum tnet_stun_attr_type_e {
|
||||
/* === RFC 5389 - Comprehension-required range (0x0000-0x7FFF) */
|
||||
tnet_stun_attr_type_reserved = 0x0000, /**< (Reserved) */
|
||||
tnet_stun_attr_type_mapped_address = 0x0001, /**< http://tools.ietf.org/html/rfc5389#page-32 */
|
||||
tnet_stun_attr_type_response_address = 0x0002, /**< (Reserved; was RESPONSE-ADDRESS) */
|
||||
tnet_stun_attr_type_change_address = 0x0003, /**< (Reserved; was CHANGE-ADDRESS) */
|
||||
tnet_stun_attr_type_source_address = 0x0004, /**< (Reserved; was SOURCE-ADDRESS) */
|
||||
tnet_stun_attr_type_changed_address = 0x0005, /**< (Reserved; was CHANGED-ADDRESS) */
|
||||
tnet_stun_attr_type_username = 0x0006, /**< http://tools.ietf.org/html/rfc5389#page-34 */
|
||||
tnet_stun_attr_type_password = 0x0007, /**< (Reserved; was PASSWORD) */
|
||||
tnet_stun_attr_type_message_integrity = 0x0008, /**< http://tools.ietf.org/html/rfc5389#page-34 */
|
||||
tnet_stun_attr_type_error_code = 0x0009, /**< http://tools.ietf.org/html/rfc5389#page-36 */
|
||||
tnet_stun_attr_type_unknown_attrs = 0x000A, /**< http://tools.ietf.org/html/rfc5389#page-38 */
|
||||
tnet_stun_attr_type_reflected_from = 0x000B, /**< (Reserved; was REFLECTED-FROM) */
|
||||
tnet_stun_attr_type_realm = 0x0014, /**< http://tools.ietf.org/html/rfc5389#page-38 */
|
||||
tnet_stun_attr_type_nonce = 0x0015, /**< http://tools.ietf.org/html/rfc5389#page-38 */
|
||||
tnet_stun_attr_type_xor_mapped_address = 0x0020, /**< http://tools.ietf.org/html/rfc5389#page-33 */
|
||||
|
||||
/* === RFC 5389 - Comprehension-optional range (0x8000-0xFFFF) */
|
||||
tnet_stun_attr_type_software = 0x8022, /**< http://tools.ietf.org/html/rfc5389#page-39 */
|
||||
tnet_stun_attr_type_alternate_server = 0x8023, /**< http://tools.ietf.org/html/rfc5389#page-39 */
|
||||
tnet_stun_attr_type_fingerprint = 0x8028, /**< http://tools.ietf.org/html/rfc5389#page-36 */
|
||||
|
||||
/* === rfc5766 */
|
||||
tnet_stun_attr_type_channel_number = 0x000C, /**< rfc5766 - CHANNEL-NUMBER */
|
||||
tnet_stun_attr_type_lifetime = 0x000D, /**< rfc5766 - LIFETIME */
|
||||
tnet_stun_attr_type_reserved2 = 0x0010, /**< rfc5766 - Reserved (was BANDWIDTH) */
|
||||
tnet_stun_attr_type_xor_peer_address = 0x0012, /**< rfc5766 - XOR-PEER-ADDRESS */
|
||||
tnet_stun_attr_type_data = 0x0013, /**< rfc5766 - DATA */
|
||||
tnet_stun_attr_type_xor_relayed_address = 0x0016, /**< rfc5766 - XOR-RELAYED-ADDRESS */
|
||||
tnet_stun_attr_type_even_port = 0x0018, /**< rfc5766 - EVEN-PORT */
|
||||
tnet_stun_attr_type_requested_transport = 0x0019, /**< rfc5766 - REQUESTED-TRANSPORT */
|
||||
tnet_stun_attr_type_dont_fragment = 0x001A, /**< rfc5766 - DONT-FRAGMENT */
|
||||
tnet_stun_attr_type_reserved3 = 0x0021, /**< rfc5766 - Reserved (was TIMER-VAL) */
|
||||
tnet_stun_attr_type_reservation_token = 0x0022, /**< rfc5766 - RESERVATION-TOKEN */
|
||||
|
||||
/* RFC 5245 */
|
||||
tnet_stun_attr_type_ice_priority = 0x0024, /**< 21.2. STUN Attributes */
|
||||
tnet_stun_attr_type_ice_use_candidate = 0x0025, /**< 21.2. STUN Attributes */
|
||||
tnet_stun_attr_type_ice_controlled = 0x8029, /**< 21.2. STUN Attributes */
|
||||
tnet_stun_attr_type_ice_controlling = 0x802A, /**< 21.2. STUN Attributes */
|
||||
} tnet_stun_attr_type_t;
|
||||
|
||||
|
||||
/**@ingroup tnet_stun_group
|
||||
* List of all supported STUN message types.
|
||||
*/
|
||||
typedef enum tnet_stun_pkt_type_e {
|
||||
/* RFC 5389 - 6. STUN Message Structure
|
||||
|
||||
The message type defines the message class (request, success
|
||||
response, failure response, or indication) and the message method
|
||||
(the primary function) of the STUN message. Although there are four
|
||||
message classes, there are only two types of transactions in STUN:
|
||||
request/response transactions (which consist of a request message and
|
||||
a response message) and indication transactions (which consist of a
|
||||
single indication message). Response classes are split into error
|
||||
and success responses to aid in quickly processing the STUN message.
|
||||
|
||||
The message type field is decomposed further into the following
|
||||
structure:
|
||||
|
||||
0 1
|
||||
2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|M |M |M|M|M|C|M|M|M|C|M|M|M|M|
|
||||
|11|10|9|8|7|1|6|5|4|0|3|2|1|0|
|
||||
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
tnet_stun_pkt_type_binding_request = (tnet_stun_method_binding | tnet_stun_mask_request),
|
||||
tnet_stun_pkt_type_binding_indication = (tnet_stun_method_binding | tnet_stun_mask_indication),
|
||||
tnet_stun_pkt_type_binding_success_response = (tnet_stun_method_binding | tnet_stun_mask_success),
|
||||
tnet_stun_pkt_type_binding_error_response = (tnet_stun_method_binding | tnet_stun_mask_error),
|
||||
|
||||
tnet_stun_pkt_type_allocate_request = (tnet_stun_method_allocate | tnet_stun_mask_request),
|
||||
tnet_stun_pkt_type_allocate_indication = (tnet_stun_method_allocate | tnet_stun_mask_indication),
|
||||
tnet_stun_pkt_type_allocate_success_response = (tnet_stun_method_allocate | tnet_stun_mask_success),
|
||||
tnet_stun_pkt_type_allocate_error_response = (tnet_stun_method_allocate | tnet_stun_mask_error),
|
||||
|
||||
tnet_stun_pkt_type_refresh_request = (tnet_stun_method_refresh | tnet_stun_mask_request),
|
||||
tnet_stun_pkt_type_refresh_indication = (tnet_stun_method_refresh | tnet_stun_mask_indication),
|
||||
tnet_stun_pkt_type_refresh_success_response = (tnet_stun_method_refresh | tnet_stun_mask_success),
|
||||
tnet_stun_pkt_type_refresh_error_response = (tnet_stun_method_refresh | tnet_stun_mask_error),
|
||||
|
||||
tnet_stun_pkt_type_send_indication = (tnet_stun_method_send | tnet_stun_mask_indication),
|
||||
|
||||
tnet_stun_pkt_type_data_indication = (tnet_stun_method_data | tnet_stun_mask_indication),
|
||||
|
||||
tnet_stun_pkt_type_createpermission_request = (tnet_stun_method_createpermission | tnet_stun_mask_request),
|
||||
tnet_stun_pkt_type_createpermission_indication = (tnet_stun_method_createpermission | tnet_stun_mask_indication),
|
||||
tnet_stun_pkt_type_createpermission_success_response = (tnet_stun_method_createpermission | tnet_stun_mask_success),
|
||||
tnet_stun_pkt_type_createpermission_error_response = (tnet_stun_method_createpermission | tnet_stun_mask_error),
|
||||
|
||||
tnet_stun_pkt_type_channelbind_request = (tnet_stun_method_channelbind | tnet_stun_mask_request),
|
||||
tnet_stun_pkt_type_channelbind_indication = (tnet_stun_method_channelbind | tnet_stun_mask_indication),
|
||||
tnet_stun_pkt_type_channelbind_success_response = (tnet_stun_method_channelbind | tnet_stun_mask_success),
|
||||
tnet_stun_pkt_type_channelbind_error_response = (tnet_stun_method_channelbind | tnet_stun_mask_error),
|
||||
}
|
||||
tnet_stun_pkt_type_t;
|
||||
|
||||
TNET_END_DECLS
|
||||
|
||||
#endif /* TNET_STUN_TYPES_H */
|
|
@ -0,0 +1,63 @@
|
|||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#include "stun/tnet_stun_utils.h"
|
||||
|
||||
#include "tnet_utils.h"
|
||||
|
||||
#include "tsk_debug.h"
|
||||
|
||||
int tnet_stun_utils_inet_pton(tsk_bool_t b_v6, const char* p_src, tnet_stun_addr_t* p_dst)
|
||||
{
|
||||
int ret;
|
||||
if (!p_src || !p_dst) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if ((ret = tnet_inet_pton(b_v6 ? AF_INET6 : AF_INET, p_src, *p_dst) != 1)) { // success == 1
|
||||
TSK_DEBUG_ERROR("tnet_inet_pton() with error code = %d", ret);
|
||||
return -3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tnet_stun_utils_inet_ntop(tsk_bool_t b_v6, const tnet_stun_addr_t* pc_src, tnet_ip_t* p_dst)
|
||||
{
|
||||
if (!pc_src || !p_dst) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if (tnet_inet_ntop(b_v6 ? AF_INET6 : AF_INET, *pc_src, *p_dst, sizeof(*p_dst)) == tsk_null) {
|
||||
TSK_DEBUG_ERROR("tnet_inet_ntop() failed");
|
||||
return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tnet_stun_utils_transac_id_rand(tnet_stun_transac_id_t* p_transac_id)
|
||||
{
|
||||
tsk_size_t u, s = sizeof(*p_transac_id);
|
||||
if (!p_transac_id) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
for (u = 0; u < s; ++u) {
|
||||
*(((uint8_t*)p_transac_id) + u) = rand() ^ rand();
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#ifndef TNET_STUN_UTILS_H
|
||||
#define TNET_STUN_UTILS_H
|
||||
|
||||
#include "tinynet_config.h"
|
||||
#include "stun/tnet_stun_types.h"
|
||||
|
||||
#include "tnet_types.h"
|
||||
|
||||
TNET_BEGIN_DECLS
|
||||
|
||||
TINYNET_API int tnet_stun_utils_inet_pton(tsk_bool_t b_v6, const char* p_src, tnet_stun_addr_t* p_dst);
|
||||
#define tnet_stun_utils_inet_pton_v4(p_src, p_dst) tnet_stun_utils_inet_pton(tsk_false, (p_src), (p_dst))
|
||||
#define tnet_stun_utils_inet_pton_v6(p_src, p_dst) tnet_stun_utils_inet_pton(tsk_true, (p_src), (p_dst))
|
||||
TINYNET_API int tnet_stun_utils_inet_ntop(tsk_bool_t b_v6, const tnet_stun_addr_t* pc_src, tnet_ip_t* p_dst);
|
||||
#define tnet_stun_utils_inet_ntop_v4(pc_src, p_dst) tnet_stun_utils_inet_ntop(tsk_false, (pc_src), (p_dst))
|
||||
#define tnet_stun_utils_inet_ntop_v6(pc_src, p_dst) tnet_stun_utils_inet_ntop(tsk_true, (pc_src), (p_dst))
|
||||
TINYNET_API int tnet_stun_utils_transac_id_rand(tnet_stun_transac_id_t* p_transac_id);
|
||||
|
||||
TNET_END_DECLS
|
||||
|
||||
#endif /* TNET_STUN_UTILS_H */
|
|
@ -1,63 +1,63 @@
|
|||
/*
|
||||
* Copyright (C) 2010-2011 Mamadou Diop.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
|
||||
/**@file tinynet.h
|
||||
* @brief API functions.
|
||||
*
|
||||
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
|
||||
*/
|
||||
#ifndef TNET_TINYNET_H
|
||||
#define TNET_TINYNET_H
|
||||
|
||||
/* === tinySAK === */
|
||||
#include "tsk.h"
|
||||
|
||||
/* === tinyNET === */
|
||||
|
||||
#include "tnet.h"
|
||||
#include "tnet_endianness.h"
|
||||
#include "tnet_nat.h"
|
||||
#include "tnet_socket.h"
|
||||
#include "tnet_transport.h"
|
||||
|
||||
#include "stun/tnet_stun.h"
|
||||
|
||||
#include "ice/tnet_ice_event.h"
|
||||
#include "ice/tnet_ice_candidate.h"
|
||||
#include "ice/tnet_ice_ctx.h"
|
||||
|
||||
#include "dns/tnet_dns.h"
|
||||
#include "dns/tnet_dns_naptr.h"
|
||||
#include "dns/tnet_dns_regexp.h"
|
||||
#include "dns/tnet_dns_resolvconf.h"
|
||||
|
||||
#include "dhcp/tnet_dhcp.h"
|
||||
#include "dhcp/tnet_dhcp_option_sip.h"
|
||||
|
||||
#include "dhcp6/tnet_dhcp6.h"
|
||||
#include "dhcp6/tnet_dhcp6_option.h"
|
||||
|
||||
|
||||
#endif /* TNET_TINYNET_H */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Mamadou Diop.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
|
||||
/**@file tinynet.h
|
||||
* @brief API functions.
|
||||
*
|
||||
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
|
||||
*/
|
||||
#ifndef TNET_TINYNET_H
|
||||
#define TNET_TINYNET_H
|
||||
|
||||
/* === tinySAK === */
|
||||
#include "tsk.h"
|
||||
|
||||
/* === tinyNET === */
|
||||
|
||||
#include "tnet.h"
|
||||
#include "tnet_endianness.h"
|
||||
#include "tnet_nat.h"
|
||||
#include "tnet_socket.h"
|
||||
#include "tnet_transport.h"
|
||||
|
||||
#include "stun/tnet_stun.h"
|
||||
|
||||
#include "ice/tnet_ice_event.h"
|
||||
#include "ice/tnet_ice_candidate.h"
|
||||
#include "ice/tnet_ice_ctx.h"
|
||||
|
||||
#include "dns/tnet_dns.h"
|
||||
#include "dns/tnet_dns_naptr.h"
|
||||
#include "dns/tnet_dns_regexp.h"
|
||||
#include "dns/tnet_dns_resolvconf.h"
|
||||
|
||||
#include "dhcp/tnet_dhcp.h"
|
||||
#include "dhcp/tnet_dhcp_option_sip.h"
|
||||
|
||||
#include "dhcp6/tnet_dhcp6.h"
|
||||
#include "dhcp6/tnet_dhcp6_option.h"
|
||||
|
||||
|
||||
#endif /* TNET_TINYNET_H */
|
||||
|
||||
|
|
|
@ -84,6 +84,10 @@ extern Platform::String^ rt_tsk_str_to_managed(char const* str);
|
|||
# include <fcntl.h>
|
||||
#endif /* HAVE_FCNTL_H */
|
||||
|
||||
#if HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
#endif /* HAVE_ARPA_INET_H */
|
||||
|
||||
#ifndef AF_LINK
|
||||
# define AF_LINK AF_PACKET
|
||||
#endif /* AF_LINK */
|
||||
|
@ -1253,6 +1257,133 @@ int tnet_gethostname(tnet_host_t* result)
|
|||
return gethostname(*result, sizeof(*result));
|
||||
}
|
||||
|
||||
/**@ingroup tnet_utils_group
|
||||
* see http://man7.org/linux/man-pages/man3/inet_pton.3.html
|
||||
* @retval 1 if succeed.
|
||||
*/
|
||||
int tnet_inet_pton(int af, const char* src, void* dst)
|
||||
{
|
||||
if (!src || !dst) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
#if HAVE_INET_PTON
|
||||
return inet_pton(af, src, dst);
|
||||
#elif TNET_UNDER_WINDOWS
|
||||
# if (_WIN32_WINNT <= 0x0501)
|
||||
{
|
||||
struct sockaddr_storage addr = { 0 };
|
||||
int addr_len = sizeof(addr);
|
||||
if (WSAStringToAddressA((LPSTR)src, af, NULL, (struct sockaddr *)&addr, &addr_len) == 0) {
|
||||
if (af == AF_INET6) {
|
||||
*((struct in6_addr *)dst) = ((struct sockaddr_in6 *)&addr)->sin6_addr;
|
||||
}
|
||||
else {
|
||||
*((struct in_addr *)dst) = ((struct sockaddr_in *)&addr)->sin_addr;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
TNET_PRINT_LAST_ERROR("WSAStringToAddressA failed");
|
||||
return -2;
|
||||
}
|
||||
# else
|
||||
return InetPton(af, src, dst);
|
||||
# endif // TNET_UNDER_WINDOWS
|
||||
#else
|
||||
{
|
||||
struct sockaddr_storage addr = { 0 };
|
||||
int ret;
|
||||
if ((ret = tnet_sockaddr_init(src, 0, (af == AF_INET6 ? tnet_socket_type_udp_ipv6 : tnet_socket_type_udp_ipv4), &addr))) {
|
||||
return -2;
|
||||
}
|
||||
if (af == AF_INET6) {
|
||||
*((struct in6_addr *)dst) = ((struct sockaddr_in6 *)&addr)->sin6_addr;
|
||||
}
|
||||
else {
|
||||
*((struct in_addr *)dst) = ((struct sockaddr_in *)&addr)->sin_addr;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**@ingroup tnet_utils_group
|
||||
* see http://pubs.opengroup.org/onlinepubs/009695399/functions/inet_ntop.html
|
||||
*/
|
||||
const char *tnet_inet_ntop(int af, const void *src, char *dst, int size)
|
||||
{
|
||||
if (!src || !dst || size <= 0) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return tsk_null;
|
||||
}
|
||||
memset(dst, 0, size);
|
||||
#if HAVE_INET_NTOP
|
||||
return inet_ntop(af, src, dst, size);
|
||||
#elif TNET_UNDER_WINDOWS
|
||||
# if (_WIN32_WINNT <= 0x0501)
|
||||
{
|
||||
struct sockaddr_storage addr = { 0 };
|
||||
int addr_len = sizeof(addr);
|
||||
if (af == AF_INET6) {
|
||||
if (size < INET6_ADDRSTRLEN) {
|
||||
TSK_DEBUG_ERROR("Destination size too short(%d)", size);
|
||||
return tsk_null;
|
||||
}
|
||||
addr.ss_family = AF_INET6;
|
||||
((struct sockaddr_in6 *)&addr)->sin6_addr = *((struct in6_addr *)src);
|
||||
}
|
||||
else {
|
||||
if (size < INET_ADDRSTRLEN) {
|
||||
TSK_DEBUG_ERROR("Destination size too short(%d)", size);
|
||||
return tsk_null;
|
||||
}
|
||||
addr.ss_family = AF_INET;
|
||||
((struct sockaddr_in *)&addr)->sin_addr = *((struct in_addr *)src);
|
||||
}
|
||||
if (WSAAddressToStringA((struct sockaddr*)&addr, addr_len, NULL, dst, &size) == 0) {
|
||||
return dst;
|
||||
}
|
||||
TNET_PRINT_LAST_ERROR("WSAAddressToStringA failed");
|
||||
return tsk_null;
|
||||
}
|
||||
# else
|
||||
return InetNtop(af, src, dst, size);
|
||||
# endif // TNET_UNDER_WINDOWS
|
||||
#else
|
||||
{
|
||||
struct sockaddr_storage addr = { 0 };
|
||||
tnet_ip_t ip;
|
||||
if (af == AF_INET6) {
|
||||
if (size < INET6_ADDRSTRLEN) {
|
||||
TSK_DEBUG_ERROR("Destination size too short(%d)", size);
|
||||
return tsk_null;
|
||||
}
|
||||
addr.ss_family = AF_INET6;
|
||||
((struct sockaddr_in6 *)&addr)->sin6_addr = *((struct in6_addr *)src);
|
||||
|
||||
if (tnet_get_sockip((const struct sockaddr *)&addr, &ip)) {
|
||||
return tsk_null;
|
||||
}
|
||||
memcpy(dst, ip, INET6_ADDRSTRLEN);
|
||||
return dst;
|
||||
}
|
||||
else {
|
||||
if (size < INET_ADDRSTRLEN) {
|
||||
TSK_DEBUG_ERROR("Destination size too short(%d)", size);
|
||||
return tsk_null;
|
||||
}
|
||||
addr.ss_family = AF_INET;
|
||||
((struct sockaddr_in *)&addr)->sin_addr = *((struct in_addr *)src);
|
||||
if (tnet_get_sockip((const struct sockaddr *)&addr, &ip)) {
|
||||
return tsk_null;
|
||||
}
|
||||
memcpy(dst, ip, INET_ADDRSTRLEN);
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**@ingroup tnet_utils_group
|
||||
* Waits until the socket becomes writable/readable or @a timeout milliseconds passed.
|
||||
* This function could be used just after you have @a connect()ed a non-blocking socket.
|
||||
|
|
|
@ -130,6 +130,9 @@ TINYNET_API int tnet_get_fd_opened_count(tsk_size_t* count);
|
|||
TINYNET_API int tnet_getnameinfo(const struct sockaddr *sa, socklen_t salen, char* node, socklen_t nodelen, char* service, socklen_t servicelen, int flags);
|
||||
TINYNET_API int tnet_gethostname(tnet_host_t* result);
|
||||
|
||||
TINYNET_API int tnet_inet_pton(int af, const char* src, void* dst);
|
||||
TINYNET_API const char *tnet_inet_ntop(int af, const void *src, char * dst, int size);
|
||||
|
||||
TINYNET_API int tnet_sockfd_waitUntil(tnet_fd_t fd, long timeout, tsk_bool_t writable);
|
||||
#define tnet_sockfd_waitUntilWritable(fd, timeout) tnet_sockfd_waitUntil(fd, timeout, tsk_true)
|
||||
#define tnet_sockfd_waitUntilReadable(fd, timeout) tnet_sockfd_waitUntil(fd, timeout, tsk_false)
|
||||
|
|
|
@ -1,26 +1,23 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Mamadou Diop.
|
||||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||
|
|
|
@ -1,38 +1,35 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Mamadou Diop.
|
||||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TEST_TNET_STDAFX_H
|
||||
#define TEST_TNET_STDAFX_H
|
||||
|
||||
#ifdef WIN32
|
||||
#include "targetver.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
//#include <tchar.h>
|
||||
|
||||
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
|
||||
#endif /* TEST_TNET_STDAFX_H */
|
||||
*/
|
||||
|
||||
#ifndef TEST_TNET_STDAFX_H
|
||||
#define TEST_TNET_STDAFX_H
|
||||
|
||||
#ifdef WIN32
|
||||
#include "targetver.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
//#include <tchar.h>
|
||||
|
||||
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
|
||||
#endif /* TEST_TNET_STDAFX_H */
|
||||
|
|
|
@ -1,15 +1,33 @@
|
|||
#ifndef TNET_TEST_TARGETVER_H
|
||||
#define TNET_TEST_TARGETVER_H
|
||||
|
||||
// The following macros define the minimum required platform. The minimum required platform
|
||||
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
|
||||
// your application. The macros work by enabling all features available on platform versions up to and
|
||||
// including the version specified.
|
||||
|
||||
// Modify the following defines if you have to target a platform prior to the ones specified below.
|
||||
// Refer to MSDN for the latest info on corresponding values for different platforms.
|
||||
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
|
||||
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
|
||||
#endif
|
||||
|
||||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#ifndef TNET_TEST_TARGETVER_H
|
||||
#define TNET_TEST_TARGETVER_H
|
||||
|
||||
// The following macros define the minimum required platform. The minimum required platform
|
||||
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
|
||||
// your application. The macros work by enabling all features available on platform versions up to and
|
||||
// including the version specified.
|
||||
|
||||
// Modify the following defines if you have to target a platform prior to the ones specified below.
|
||||
// Refer to MSDN for the latest info on corresponding values for different platforms.
|
||||
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
|
||||
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
|
||||
#endif
|
||||
|
||||
#endif /* TNET_TEST_TARGETVER_H */
|
|
@ -1,122 +1,121 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Mamadou Diop.
|
||||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "tsk.h"
|
||||
|
||||
#include "tinynet.h"
|
||||
|
||||
#include "test_sockets.h"
|
||||
#include "test_transport.h"
|
||||
#include "test_auth.h"
|
||||
#include "test_stun.h"
|
||||
#include "test_nat.h"
|
||||
#include "test_ifaces.h"
|
||||
#include "test_dns.h"
|
||||
#include "test_ice.h"
|
||||
#include "test_dhcp.h"
|
||||
#include "test_dhcp6.h"
|
||||
#include "test_tls.h"
|
||||
|
||||
#define RUN_TEST_LOOP 0
|
||||
|
||||
#define RUN_TEST_ALL 0
|
||||
#define RUN_TEST_SOCKETS 0 /* FIXME: Android */
|
||||
#define RUN_TEST_TRANSPORT 0
|
||||
#define RUN_TEST_AUTH 0
|
||||
#define RUN_TEST_STUN 1
|
||||
#define RUN_TEST_ICE 0
|
||||
#define RUN_TEST_NAT 0
|
||||
#define RUN_TEST_IFACES 0
|
||||
#define RUN_TEST_DNS 0
|
||||
#define RUN_TEST_DHCP 0
|
||||
#define RUN_TEST_DHCP6 0
|
||||
#define RUN_TEST_TLS 0
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
int _tmain(int argc, _TCHAR* argv[])
|
||||
#else
|
||||
int main()
|
||||
#endif
|
||||
{
|
||||
/* Startup the network stack. */
|
||||
if(tnet_startup()){
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if RUN_TEST_LOOP
|
||||
for(;;)
|
||||
#endif
|
||||
{
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_SOCKETS
|
||||
test_sockets();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_TRANSPORT
|
||||
test_transport();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_AUTH
|
||||
test_auth();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_STUN
|
||||
test_stun();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_ICE
|
||||
test_ice();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_NAT
|
||||
test_nat();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_IFACES
|
||||
test_ifaces();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_DNS
|
||||
test_dns();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_DHCP
|
||||
test_dhcp();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_DHCP6
|
||||
test_dhcp6();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_TLS
|
||||
test_tls();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Cleanup the network stack */
|
||||
tnet_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
|
||||
#define BAIL_IF_ERR(expr) { int _ret_; if ((_ret_) = (expr)) { TSK_DEBUG_ERROR("Error %d", (_ret_)); goto bail; } }
|
||||
|
||||
#include "tsk.h"
|
||||
|
||||
#include "tinynet.h"
|
||||
|
||||
#include "test_sockets.h"
|
||||
#include "test_transport.h"
|
||||
#include "test_auth.h"
|
||||
#include "test_stun.h"
|
||||
#include "test_nat.h"
|
||||
#include "test_ifaces.h"
|
||||
#include "test_dns.h"
|
||||
#include "test_ice.h"
|
||||
#include "test_dhcp.h"
|
||||
#include "test_dhcp6.h"
|
||||
#include "test_tls.h"
|
||||
|
||||
#define RUN_TEST_LOOP 0
|
||||
|
||||
#define RUN_TEST_ALL 0
|
||||
#define RUN_TEST_SOCKETS 0 /* FIXME: Android */
|
||||
#define RUN_TEST_TRANSPORT 0
|
||||
#define RUN_TEST_AUTH 0
|
||||
#define RUN_TEST_STUN 1
|
||||
#define RUN_TEST_ICE 0
|
||||
#define RUN_TEST_NAT 0
|
||||
#define RUN_TEST_IFACES 0
|
||||
#define RUN_TEST_DNS 0
|
||||
#define RUN_TEST_DHCP 0
|
||||
#define RUN_TEST_DHCP6 0
|
||||
#define RUN_TEST_TLS 0
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
int _tmain(int argc, _TCHAR* argv[])
|
||||
#else
|
||||
int main()
|
||||
#endif
|
||||
{
|
||||
/* Startup the network stack. */
|
||||
if(tnet_startup()){
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if RUN_TEST_LOOP
|
||||
for(;;)
|
||||
#endif
|
||||
{
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_SOCKETS
|
||||
test_sockets();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_TRANSPORT
|
||||
test_transport();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_AUTH
|
||||
test_auth();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_STUN
|
||||
test_stun();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_ICE
|
||||
test_ice();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_NAT
|
||||
test_nat();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_IFACES
|
||||
test_ifaces();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_DNS
|
||||
test_dns();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_DHCP
|
||||
test_dhcp();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_DHCP6
|
||||
test_dhcp6();
|
||||
#endif
|
||||
|
||||
#if RUN_TEST_ALL || RUN_TEST_TLS
|
||||
test_tls();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Cleanup the network stack */
|
||||
tnet_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,31 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Mamadou Diop.
|
||||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#ifndef TNET_TEST_AUTH_H
|
||||
#define TNET_TEST_AUTH_H
|
||||
|
||||
void test_auth()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif /* TNET_TEST_AUTH_H */
|
||||
|
||||
*/
|
||||
#ifndef TNET_TEST_AUTH_H
|
||||
#define TNET_TEST_AUTH_H
|
||||
|
||||
void test_auth()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif /* TNET_TEST_AUTH_H */
|
||||
|
||||
|
|
|
@ -1,121 +1,118 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Mamadou Diop.
|
||||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#ifndef TNET_TEST_DHCP_H
|
||||
#define TNET_TEST_DHCP_H
|
||||
|
||||
|
||||
|
||||
void test_dhcp_discover(tnet_dhcp_ctx_t *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void test_dhcp_offer(tnet_dhcp_ctx_t *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void test_dhcp_request(tnet_dhcp_ctx_t *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void test_dhcp_inform(tnet_dhcp_ctx_t *ctx)
|
||||
{
|
||||
tnet_dhcp_params_t *params = tsk_null;
|
||||
tnet_dhcp_reply_t *reply = tsk_null;
|
||||
|
||||
params = tnet_dhcp_params_create();
|
||||
tnet_dhcp_params_add_code(params, dhcp_code_SIP_Servers_DHCP_Option); /* SIP Servers */
|
||||
tnet_dhcp_params_add_code(params, dhcp_code_Domain_Server); /* DNS Server */
|
||||
|
||||
reply = tnet_dhcp_query_inform(ctx, params);
|
||||
|
||||
if(reply && !TNET_DHCP_MESSAGE_IS_REPLY(reply)){
|
||||
TSK_DEBUG_ERROR("DHCP request is not expected in response to a request.");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if(reply){
|
||||
switch(reply->type)
|
||||
{
|
||||
case dhcp_type_ack:
|
||||
{
|
||||
tsk_list_item_t *item;
|
||||
TSK_DEBUG_INFO("DHCP response type ==> ACK.");
|
||||
|
||||
tsk_list_foreach(item, reply->options)
|
||||
{
|
||||
const tnet_dhcp_option_t *option = item->data;
|
||||
|
||||
/* SIP SERVERS */
|
||||
if(option->code == dhcp_code_SIP_Servers_DHCP_Option)
|
||||
{
|
||||
tsk_list_item_t *item2;
|
||||
const tnet_dhcp_option_sip_t *option_sip4 = (const tnet_dhcp_option_sip_t*)option;;
|
||||
tsk_list_foreach(item2, option_sip4->servers)
|
||||
{
|
||||
const tsk_string_t *str = item2->data;
|
||||
TSK_DEBUG_INFO("DHCP-SIP_SERVER ==>%s", str->value);
|
||||
}
|
||||
}
|
||||
|
||||
/* DNS SERVERS */
|
||||
if(option->code == dhcp_code_Domain_Server)
|
||||
{
|
||||
tsk_list_item_t *item2;
|
||||
const tnet_dhcp_option_dns_t *option_dns = (const tnet_dhcp_option_dns_t*)option;;
|
||||
tsk_list_foreach(item2, option_dns->servers)
|
||||
{
|
||||
const tsk_string_t *str = item2->data;
|
||||
TSK_DEBUG_INFO("DHCP-DNS_SERVER ==>%s", str->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TSK_DEBUG_ERROR("DHCP reply is NULL.");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
bail:
|
||||
TSK_OBJECT_SAFE_FREE(reply);
|
||||
TSK_OBJECT_SAFE_FREE(params);
|
||||
|
||||
//tsk_thread_sleep(1000);
|
||||
}
|
||||
|
||||
void test_dhcp()
|
||||
{
|
||||
tnet_dhcp_ctx_t *ctx = tnet_dhcp_ctx_create();
|
||||
test_dhcp_inform(ctx);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(ctx);
|
||||
}
|
||||
|
||||
#endif /* TNET_TEST_DHCP_H */
|
||||
*/
|
||||
#ifndef TNET_TEST_DHCP_H
|
||||
#define TNET_TEST_DHCP_H
|
||||
|
||||
|
||||
|
||||
void test_dhcp_discover(tnet_dhcp_ctx_t *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void test_dhcp_offer(tnet_dhcp_ctx_t *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void test_dhcp_request(tnet_dhcp_ctx_t *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void test_dhcp_inform(tnet_dhcp_ctx_t *ctx)
|
||||
{
|
||||
tnet_dhcp_params_t *params = tsk_null;
|
||||
tnet_dhcp_reply_t *reply = tsk_null;
|
||||
|
||||
params = tnet_dhcp_params_create();
|
||||
tnet_dhcp_params_add_code(params, dhcp_code_SIP_Servers_DHCP_Option); /* SIP Servers */
|
||||
tnet_dhcp_params_add_code(params, dhcp_code_Domain_Server); /* DNS Server */
|
||||
|
||||
reply = tnet_dhcp_query_inform(ctx, params);
|
||||
|
||||
if(reply && !TNET_DHCP_MESSAGE_IS_REPLY(reply)){
|
||||
TSK_DEBUG_ERROR("DHCP request is not expected in response to a request.");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if(reply){
|
||||
switch(reply->type)
|
||||
{
|
||||
case dhcp_type_ack:
|
||||
{
|
||||
tsk_list_item_t *item;
|
||||
TSK_DEBUG_INFO("DHCP response type ==> ACK.");
|
||||
|
||||
tsk_list_foreach(item, reply->options)
|
||||
{
|
||||
const tnet_dhcp_option_t *option = item->data;
|
||||
|
||||
/* SIP SERVERS */
|
||||
if(option->code == dhcp_code_SIP_Servers_DHCP_Option)
|
||||
{
|
||||
tsk_list_item_t *item2;
|
||||
const tnet_dhcp_option_sip_t *option_sip4 = (const tnet_dhcp_option_sip_t*)option;;
|
||||
tsk_list_foreach(item2, option_sip4->servers)
|
||||
{
|
||||
const tsk_string_t *str = item2->data;
|
||||
TSK_DEBUG_INFO("DHCP-SIP_SERVER ==>%s", str->value);
|
||||
}
|
||||
}
|
||||
|
||||
/* DNS SERVERS */
|
||||
if(option->code == dhcp_code_Domain_Server)
|
||||
{
|
||||
tsk_list_item_t *item2;
|
||||
const tnet_dhcp_option_dns_t *option_dns = (const tnet_dhcp_option_dns_t*)option;;
|
||||
tsk_list_foreach(item2, option_dns->servers)
|
||||
{
|
||||
const tsk_string_t *str = item2->data;
|
||||
TSK_DEBUG_INFO("DHCP-DNS_SERVER ==>%s", str->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TSK_DEBUG_ERROR("DHCP reply is NULL.");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
bail:
|
||||
TSK_OBJECT_SAFE_FREE(reply);
|
||||
TSK_OBJECT_SAFE_FREE(params);
|
||||
|
||||
//tsk_thread_sleep(1000);
|
||||
}
|
||||
|
||||
void test_dhcp()
|
||||
{
|
||||
tnet_dhcp_ctx_t *ctx = tnet_dhcp_ctx_create();
|
||||
test_dhcp_inform(ctx);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(ctx);
|
||||
}
|
||||
|
||||
#endif /* TNET_TEST_DHCP_H */
|
||||
|
|
|
@ -1,51 +1,48 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Mamadou Diop.
|
||||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#ifndef TNET_TEST_DHCP6_H
|
||||
#define TNET_TEST_DHCP6_H
|
||||
|
||||
|
||||
|
||||
void test_dhcp6_requestinfo(tnet_dhcp6_ctx_t *ctx)
|
||||
{
|
||||
tnet_dhcp6_option_orequest_t *orequest = tnet_dhcp6_option_orequest_create_null();
|
||||
tnet_dhcp6_reply_t* reply = 0;
|
||||
|
||||
tnet_dhcp6_option_orequest_add_code(orequest, 24);
|
||||
tnet_dhcp6_option_orequest_add_code(orequest, 23);
|
||||
tnet_dhcp6_option_orequest_add_code(orequest, 21); /* SIP Servers Domain Name List */
|
||||
tnet_dhcp6_option_orequest_add_code(orequest, 22); /* SIP Servers IPv6 Address List */
|
||||
|
||||
reply = tnet_dhcp6_requestinfo(ctx, orequest);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(orequest);
|
||||
TSK_OBJECT_SAFE_FREE(reply);
|
||||
}
|
||||
|
||||
void test_dhcp6()
|
||||
{
|
||||
tnet_dhcp6_ctx_t *ctx = tnet_dhcp6_ctx_create();
|
||||
test_dhcp6_requestinfo(ctx);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(ctx);
|
||||
}
|
||||
|
||||
#endif /* TNET_TEST_DHCP6_H */
|
||||
*/
|
||||
#ifndef TNET_TEST_DHCP6_H
|
||||
#define TNET_TEST_DHCP6_H
|
||||
|
||||
|
||||
|
||||
void test_dhcp6_requestinfo(tnet_dhcp6_ctx_t *ctx)
|
||||
{
|
||||
tnet_dhcp6_option_orequest_t *orequest = tnet_dhcp6_option_orequest_create_null();
|
||||
tnet_dhcp6_reply_t* reply = 0;
|
||||
|
||||
tnet_dhcp6_option_orequest_add_code(orequest, 24);
|
||||
tnet_dhcp6_option_orequest_add_code(orequest, 23);
|
||||
tnet_dhcp6_option_orequest_add_code(orequest, 21); /* SIP Servers Domain Name List */
|
||||
tnet_dhcp6_option_orequest_add_code(orequest, 22); /* SIP Servers IPv6 Address List */
|
||||
|
||||
reply = tnet_dhcp6_requestinfo(ctx, orequest);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(orequest);
|
||||
TSK_OBJECT_SAFE_FREE(reply);
|
||||
}
|
||||
|
||||
void test_dhcp6()
|
||||
{
|
||||
tnet_dhcp6_ctx_t *ctx = tnet_dhcp6_ctx_create();
|
||||
test_dhcp6_requestinfo(ctx);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(ctx);
|
||||
}
|
||||
|
||||
#endif /* TNET_TEST_DHCP6_H */
|
||||
|
|
|
@ -1,227 +1,224 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Mamadou Diop.
|
||||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#ifndef TNET_TEST_DNS_H
|
||||
#define TNET_TEST_DNS_H
|
||||
|
||||
//#include "tnet_utils.h" /* tnet_address_t */
|
||||
|
||||
void test_dns_query()
|
||||
{
|
||||
tnet_dns_ctx_t *ctx = tnet_dns_ctx_create();
|
||||
tnet_dns_response_t *response = tsk_null;
|
||||
const tsk_list_item_t* item;
|
||||
const tnet_dns_rr_t* rr;
|
||||
|
||||
//if((response = tnet_dns_resolve(ctx, "_sip._udp.sip2sip.info", qclass_in, qtype_srv)))
|
||||
if((response = tnet_dns_resolve(ctx, "sip2sip.info", qclass_in, qtype_naptr)))
|
||||
{
|
||||
if(TNET_DNS_RESPONSE_IS_SUCCESS(response)){
|
||||
TSK_DEBUG_INFO("We got a success response from the DNS server.");
|
||||
// loop through the answers
|
||||
tsk_list_foreach(item, response->Answers){
|
||||
rr = item->data;
|
||||
if(rr->qtype == qtype_naptr){
|
||||
const tnet_dns_naptr_t *naptr = (const tnet_dns_naptr_t*)rr;
|
||||
|
||||
TSK_DEBUG_INFO("order=%u pref=%u flags=%s services=%s regexp=%s replacement=%s",
|
||||
naptr->order,
|
||||
naptr->preference,
|
||||
naptr->flags,
|
||||
naptr->services,
|
||||
naptr->regexp,
|
||||
naptr->replacement);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("We got an error response from the DNS server. Erro code: %u", response->Header.RCODE);
|
||||
}
|
||||
}
|
||||
|
||||
tnet_dns_cache_clear(ctx);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(response);
|
||||
TSK_OBJECT_SAFE_FREE(ctx);
|
||||
|
||||
|
||||
tsk_thread_sleep(2000);
|
||||
}
|
||||
|
||||
void test_dns_srv()
|
||||
{
|
||||
tnet_dns_ctx_t *ctx = tnet_dns_ctx_create();
|
||||
char* hostname = 0;
|
||||
tnet_port_t port = 0;
|
||||
|
||||
if(!tnet_dns_query_srv(ctx, "_sip._udp.sip2sip.info", &hostname, &port)){
|
||||
TSK_DEBUG_INFO("DNS SRV succeed ==> hostname=%s and port=%u", hostname, port);
|
||||
}
|
||||
|
||||
TSK_FREE(hostname);
|
||||
TSK_OBJECT_SAFE_FREE(ctx);
|
||||
|
||||
tsk_thread_sleep(2000);
|
||||
}
|
||||
|
||||
void test_dns_naptr_srv()
|
||||
{
|
||||
tnet_dns_ctx_t *ctx = tnet_dns_ctx_create();
|
||||
char* hostname = tsk_null;
|
||||
tnet_port_t port = 0;
|
||||
|
||||
if(!tnet_dns_query_naptr_srv(ctx, "sip2sip.info", "SIP+D2U", &hostname, &port)){
|
||||
TSK_DEBUG_INFO("DNS NAPTR+SRV succeed ==> hostname=%s and port=%u", hostname, port);
|
||||
}
|
||||
|
||||
TSK_FREE(hostname);
|
||||
TSK_OBJECT_SAFE_FREE(ctx);
|
||||
|
||||
tsk_thread_sleep(2000);
|
||||
}
|
||||
|
||||
void test_enum()
|
||||
{
|
||||
tnet_dns_ctx_t *ctx = tnet_dns_ctx_create();
|
||||
tnet_dns_response_t* response = tsk_null;
|
||||
// const tsk_list_item_t* item;
|
||||
// const tnet_dns_naptr_t* record;
|
||||
char* uri = tsk_null;
|
||||
const char* e164num = "+1-800-555-5555";
|
||||
//const char* e164num = "+33660188661";
|
||||
|
||||
//tnet_dns_add_server(ctx, "192.168.16.9");
|
||||
|
||||
//if((uri = tnet_dns_enum_2(ctx, "E2U+SIP", e164num, "e164.org"))){
|
||||
if((uri = tnet_dns_enum_2(ctx, "E2U+SIP", e164num, "e164.org"))){
|
||||
TSK_DEBUG_INFO("URI=%s", uri);
|
||||
TSK_FREE(uri);
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("ENUM(%s) failed", e164num);
|
||||
}
|
||||
|
||||
/*if((response = tnet_dns_enum(ctx, "+1-800-555-5555", "e164.org"))){
|
||||
if(TNET_DNS_RESPONSE_IS_SUCCESS(response)){
|
||||
TSK_DEBUG_INFO("We got a success response from the DNS server.");
|
||||
// loop through the answers
|
||||
tsk_list_foreach(item, response->Answers){
|
||||
record = item->data;
|
||||
|
||||
TSK_DEBUG_INFO("order=%u pref=%u flags=%s services=%s regexp=%s replacement=%s",
|
||||
record->order,
|
||||
record->preference,
|
||||
record->flags,
|
||||
record->services,
|
||||
record->regexp,
|
||||
record->replacement);
|
||||
}
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("We got an error response from the DNS server. Erro code: %u", response->Header.RCODE);
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(response);
|
||||
TSK_OBJECT_SAFE_FREE(ctx);
|
||||
|
||||
tsk_thread_sleep(2000);
|
||||
}
|
||||
|
||||
|
||||
typedef struct regexp_test_s{
|
||||
const char* e164num;
|
||||
const char* regexp;
|
||||
const char* xres;
|
||||
}
|
||||
regexp_test_t;
|
||||
|
||||
regexp_test_t regexp_tests[] = {
|
||||
"+18005551234", "!^.*$!sip:customer-service@example.com!i", "sip:customer-service@example.com",
|
||||
"+18005551234", "!^.*$!mailto:information@example.com!i", "mailto:information@example.com",
|
||||
|
||||
"+18005555555", "!^\\+1800(.*)$!sip:1641641800\\1@tollfree.sip-happens.com!", "sip:16416418005555555@tollfree.sip-happens.com",
|
||||
"+18005555555", "!^\\+1800(.*)$!sip:1641641800\\1@sip.tollfreegateway.com!", "sip:16416418005555555@sip.tollfreegateway.com",
|
||||
|
||||
"+468971234", "!^+46(.*)$!ldap://ldap.telco.se/cn=0\\1!", "ldap://ldap.telco.se/cn=08971234",
|
||||
"+468971234", "!^+46(.*)$!mailto:spam@paf.se!", "mailto:spam@paf.se",
|
||||
|
||||
"urn:cid:199606121851.1@bar.example.com", "!!^urn:cid:.+@([^\\.]+\\.)(.*)$!\\2!i", "example.com",
|
||||
};
|
||||
|
||||
void test_regex()
|
||||
{
|
||||
char* ret;
|
||||
size_t i;
|
||||
|
||||
for(i=0; i< sizeof(regexp_tests)/sizeof(regexp_test_t); i++)
|
||||
{
|
||||
if((ret = tnet_dns_regex_parse(regexp_tests[i].e164num, regexp_tests[i].regexp))){
|
||||
TSK_DEBUG_INFO("ENUM(%s) = %s", regexp_tests[i].e164num, ret);
|
||||
if(!tsk_strequals(ret, regexp_tests[i].xres)){
|
||||
TSK_DEBUG_ERROR("Failed to match ENUM(%s)", regexp_tests[i].e164num);
|
||||
}
|
||||
TSK_FREE(ret);
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("Failed to parse ENUM(%s)", regexp_tests[i].e164num);
|
||||
}
|
||||
|
||||
TSK_DEBUG_INFO("---------");
|
||||
}
|
||||
}
|
||||
|
||||
void test_resolvconf()
|
||||
{
|
||||
tnet_addresses_L_t * servers;
|
||||
const tnet_address_t* address;
|
||||
const tsk_list_item_t* item;
|
||||
const char* path = "C:\\tmp\\resolv32.conf";
|
||||
//const char* path = "C:\\tmp\\resolv.conf";
|
||||
//const char* path = "/etc/resolv.conf";
|
||||
|
||||
if((servers = tnet_dns_resolvconf_parse(path))){
|
||||
tsk_list_foreach(item, servers){
|
||||
address = item->data;
|
||||
|
||||
TSK_DEBUG_INFO("DNS Server host=%s Family=%d", address->ip, address->family);
|
||||
}
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(servers);
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("Failed to parse DNS servers from %s.", path);
|
||||
}
|
||||
}
|
||||
|
||||
void test_dns()
|
||||
{
|
||||
test_dns_naptr_srv();
|
||||
//test_dns_srv();
|
||||
//test_dns_query();
|
||||
//test_enum();
|
||||
//test_regex();
|
||||
//test_resolvconf();
|
||||
}
|
||||
|
||||
|
||||
#endif /* TNET_TEST_DNS_H */
|
||||
*/
|
||||
#ifndef TNET_TEST_DNS_H
|
||||
#define TNET_TEST_DNS_H
|
||||
|
||||
//#include "tnet_utils.h" /* tnet_address_t */
|
||||
|
||||
void test_dns_query()
|
||||
{
|
||||
tnet_dns_ctx_t *ctx = tnet_dns_ctx_create();
|
||||
tnet_dns_response_t *response = tsk_null;
|
||||
const tsk_list_item_t* item;
|
||||
const tnet_dns_rr_t* rr;
|
||||
|
||||
//if((response = tnet_dns_resolve(ctx, "_sip._udp.sip2sip.info", qclass_in, qtype_srv)))
|
||||
if((response = tnet_dns_resolve(ctx, "sip2sip.info", qclass_in, qtype_naptr)))
|
||||
{
|
||||
if(TNET_DNS_RESPONSE_IS_SUCCESS(response)){
|
||||
TSK_DEBUG_INFO("We got a success response from the DNS server.");
|
||||
// loop through the answers
|
||||
tsk_list_foreach(item, response->Answers){
|
||||
rr = item->data;
|
||||
if(rr->qtype == qtype_naptr){
|
||||
const tnet_dns_naptr_t *naptr = (const tnet_dns_naptr_t*)rr;
|
||||
|
||||
TSK_DEBUG_INFO("order=%u pref=%u flags=%s services=%s regexp=%s replacement=%s",
|
||||
naptr->order,
|
||||
naptr->preference,
|
||||
naptr->flags,
|
||||
naptr->services,
|
||||
naptr->regexp,
|
||||
naptr->replacement);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("We got an error response from the DNS server. Erro code: %u", response->Header.RCODE);
|
||||
}
|
||||
}
|
||||
|
||||
tnet_dns_cache_clear(ctx);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(response);
|
||||
TSK_OBJECT_SAFE_FREE(ctx);
|
||||
|
||||
|
||||
tsk_thread_sleep(2000);
|
||||
}
|
||||
|
||||
void test_dns_srv()
|
||||
{
|
||||
tnet_dns_ctx_t *ctx = tnet_dns_ctx_create();
|
||||
char* hostname = 0;
|
||||
tnet_port_t port = 0;
|
||||
|
||||
if(!tnet_dns_query_srv(ctx, "_sip._udp.sip2sip.info", &hostname, &port)){
|
||||
TSK_DEBUG_INFO("DNS SRV succeed ==> hostname=%s and port=%u", hostname, port);
|
||||
}
|
||||
|
||||
TSK_FREE(hostname);
|
||||
TSK_OBJECT_SAFE_FREE(ctx);
|
||||
|
||||
tsk_thread_sleep(2000);
|
||||
}
|
||||
|
||||
void test_dns_naptr_srv()
|
||||
{
|
||||
tnet_dns_ctx_t *ctx = tnet_dns_ctx_create();
|
||||
char* hostname = tsk_null;
|
||||
tnet_port_t port = 0;
|
||||
|
||||
if(!tnet_dns_query_naptr_srv(ctx, "sip2sip.info", "SIP+D2U", &hostname, &port)){
|
||||
TSK_DEBUG_INFO("DNS NAPTR+SRV succeed ==> hostname=%s and port=%u", hostname, port);
|
||||
}
|
||||
|
||||
TSK_FREE(hostname);
|
||||
TSK_OBJECT_SAFE_FREE(ctx);
|
||||
|
||||
tsk_thread_sleep(2000);
|
||||
}
|
||||
|
||||
void test_enum()
|
||||
{
|
||||
tnet_dns_ctx_t *ctx = tnet_dns_ctx_create();
|
||||
tnet_dns_response_t* response = tsk_null;
|
||||
// const tsk_list_item_t* item;
|
||||
// const tnet_dns_naptr_t* record;
|
||||
char* uri = tsk_null;
|
||||
const char* e164num = "+1-800-555-5555";
|
||||
//const char* e164num = "+33660188661";
|
||||
|
||||
//tnet_dns_add_server(ctx, "192.168.16.9");
|
||||
|
||||
//if((uri = tnet_dns_enum_2(ctx, "E2U+SIP", e164num, "e164.org"))){
|
||||
if((uri = tnet_dns_enum_2(ctx, "E2U+SIP", e164num, "e164.org"))){
|
||||
TSK_DEBUG_INFO("URI=%s", uri);
|
||||
TSK_FREE(uri);
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("ENUM(%s) failed", e164num);
|
||||
}
|
||||
|
||||
/*if((response = tnet_dns_enum(ctx, "+1-800-555-5555", "e164.org"))){
|
||||
if(TNET_DNS_RESPONSE_IS_SUCCESS(response)){
|
||||
TSK_DEBUG_INFO("We got a success response from the DNS server.");
|
||||
// loop through the answers
|
||||
tsk_list_foreach(item, response->Answers){
|
||||
record = item->data;
|
||||
|
||||
TSK_DEBUG_INFO("order=%u pref=%u flags=%s services=%s regexp=%s replacement=%s",
|
||||
record->order,
|
||||
record->preference,
|
||||
record->flags,
|
||||
record->services,
|
||||
record->regexp,
|
||||
record->replacement);
|
||||
}
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("We got an error response from the DNS server. Erro code: %u", response->Header.RCODE);
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(response);
|
||||
TSK_OBJECT_SAFE_FREE(ctx);
|
||||
|
||||
tsk_thread_sleep(2000);
|
||||
}
|
||||
|
||||
|
||||
typedef struct regexp_test_s{
|
||||
const char* e164num;
|
||||
const char* regexp;
|
||||
const char* xres;
|
||||
}
|
||||
regexp_test_t;
|
||||
|
||||
regexp_test_t regexp_tests[] = {
|
||||
"+18005551234", "!^.*$!sip:customer-service@example.com!i", "sip:customer-service@example.com",
|
||||
"+18005551234", "!^.*$!mailto:information@example.com!i", "mailto:information@example.com",
|
||||
|
||||
"+18005555555", "!^\\+1800(.*)$!sip:1641641800\\1@tollfree.sip-happens.com!", "sip:16416418005555555@tollfree.sip-happens.com",
|
||||
"+18005555555", "!^\\+1800(.*)$!sip:1641641800\\1@sip.tollfreegateway.com!", "sip:16416418005555555@sip.tollfreegateway.com",
|
||||
|
||||
"+468971234", "!^+46(.*)$!ldap://ldap.telco.se/cn=0\\1!", "ldap://ldap.telco.se/cn=08971234",
|
||||
"+468971234", "!^+46(.*)$!mailto:spam@paf.se!", "mailto:spam@paf.se",
|
||||
|
||||
"urn:cid:199606121851.1@bar.example.com", "!!^urn:cid:.+@([^\\.]+\\.)(.*)$!\\2!i", "example.com",
|
||||
};
|
||||
|
||||
void test_regex()
|
||||
{
|
||||
char* ret;
|
||||
size_t i;
|
||||
|
||||
for(i=0; i< sizeof(regexp_tests)/sizeof(regexp_test_t); i++)
|
||||
{
|
||||
if((ret = tnet_dns_regex_parse(regexp_tests[i].e164num, regexp_tests[i].regexp))){
|
||||
TSK_DEBUG_INFO("ENUM(%s) = %s", regexp_tests[i].e164num, ret);
|
||||
if(!tsk_strequals(ret, regexp_tests[i].xres)){
|
||||
TSK_DEBUG_ERROR("Failed to match ENUM(%s)", regexp_tests[i].e164num);
|
||||
}
|
||||
TSK_FREE(ret);
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("Failed to parse ENUM(%s)", regexp_tests[i].e164num);
|
||||
}
|
||||
|
||||
TSK_DEBUG_INFO("---------");
|
||||
}
|
||||
}
|
||||
|
||||
void test_resolvconf()
|
||||
{
|
||||
tnet_addresses_L_t * servers;
|
||||
const tnet_address_t* address;
|
||||
const tsk_list_item_t* item;
|
||||
const char* path = "C:\\tmp\\resolv32.conf";
|
||||
//const char* path = "C:\\tmp\\resolv.conf";
|
||||
//const char* path = "/etc/resolv.conf";
|
||||
|
||||
if((servers = tnet_dns_resolvconf_parse(path))){
|
||||
tsk_list_foreach(item, servers){
|
||||
address = item->data;
|
||||
|
||||
TSK_DEBUG_INFO("DNS Server host=%s Family=%d", address->ip, address->family);
|
||||
}
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(servers);
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("Failed to parse DNS servers from %s.", path);
|
||||
}
|
||||
}
|
||||
|
||||
void test_dns()
|
||||
{
|
||||
test_dns_naptr_srv();
|
||||
//test_dns_srv();
|
||||
//test_dns_query();
|
||||
//test_enum();
|
||||
//test_regex();
|
||||
//test_resolvconf();
|
||||
}
|
||||
|
||||
|
||||
#endif /* TNET_TEST_DNS_H */
|
||||
|
|
|
@ -1,146 +1,144 @@
|
|||
/*
|
||||
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
|
||||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*/
|
||||
|
||||
#ifndef TNET_TEST_ICE_H
|
||||
#define TNET_TEST_ICE_H
|
||||
|
||||
#define ICE_CANDIDATES "1 1 udp 1 192.168.196.1 57806 typ host name video_rtcp network_name {0C0137CC-DB78-46B6-9B6C-7E097FFA79FE} username StFEVThMK2DHThkv password qkhKUDr4WqKRwZTo generation 0\r\n" \
|
||||
"1 2 udp 1 192.168.211.1 57808 typ srflx name video_rtcp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username 9ONjPsYvSFh0JvAc password rDHSkokdvp9dyXqQ generation 0\r\n" \
|
||||
"1 1 udp 1 192.168.196.1 57809 typ prflx name video_rtp network_name {0C0137CC-DB78-46B6-9B6C-7E097FFA79FE} username S1vDZTVVky3r0pT+ password XgLb+H9uofxuWg7G generation 0\r\n" \
|
||||
"1 2 udp 1 192.168.211.1 57811 typ relay name video_rtp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username x64BhO4BXjBFkpz2 password ZwHhRhu0KU9R6iWd generation 0\r\n" \
|
||||
"1 1 udp 1 192.168.211.1 57811 typ token name video_rtp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username x64BhO4BXjBFkpz2 password ZwHhRhu0KU9R6iWd generation 0\r\n"
|
||||
|
||||
static int tnet_ice_callback(const tnet_ice_event_t *e)
|
||||
{
|
||||
TSK_DEBUG_INFO("ICE callback: %s", e->phrase);
|
||||
|
||||
switch(e->type)
|
||||
{
|
||||
case tnet_ice_event_type_gathering_completed:
|
||||
{
|
||||
struct tnet_ice_ctx_s *ctx;
|
||||
if((ctx = (struct tnet_ice_ctx_s *)e->userdata)){
|
||||
tnet_ice_ctx_set_remote_candidates(ctx, ICE_CANDIDATES, "ice-ufrag", "ice-pwd", tsk_true, tsk_false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_ice()
|
||||
{
|
||||
struct tnet_ice_ctx_s *ctx;
|
||||
int ret;
|
||||
static const tsk_bool_t use_ipv6 = tsk_false;
|
||||
static const tsk_bool_t use_rtcp = tsk_true;
|
||||
static const tsk_bool_t use_ice_jingle = tsk_false;
|
||||
static const tsk_bool_t use_video = tsk_false;
|
||||
|
||||
long a = tnet_htonl(0x6b0c76a7);
|
||||
long b = tnet_htonl(0x034aa76b);
|
||||
long c = tnet_htonl(0x510da598);
|
||||
|
||||
ctx = tnet_ice_ctx_create(use_ice_jingle, use_ipv6, use_rtcp, use_video, tnet_ice_callback, tsk_null);
|
||||
tnet_ice_ctx_set_userdata(ctx, ctx);
|
||||
ret = tnet_ice_ctx_set_stun(ctx, "numb.viagenie.ca", 3478, "Doubango", "bossiel@yahoo.fr", "stun-password");
|
||||
ret = tnet_ice_ctx_start(ctx);
|
||||
// ret = tnet_ice_ctx_set_remote_candidates(ctx, ICE_CANDIDATES);
|
||||
|
||||
getchar();
|
||||
|
||||
ret = tnet_ice_ctx_stop(ctx);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(ctx);
|
||||
}
|
||||
|
||||
|
||||
#endif /* TNET_TEST_ICE_H */
|
||||
/*
|
||||
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*/
|
||||
|
||||
#ifndef TNET_TEST_ICE_H
|
||||
#define TNET_TEST_ICE_H
|
||||
|
||||
#define ICE_CANDIDATES "1 1 udp 1 192.168.196.1 57806 typ host name video_rtcp network_name {0C0137CC-DB78-46B6-9B6C-7E097FFA79FE} username StFEVThMK2DHThkv password qkhKUDr4WqKRwZTo generation 0\r\n" \
|
||||
"1 2 udp 1 192.168.211.1 57808 typ srflx name video_rtcp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username 9ONjPsYvSFh0JvAc password rDHSkokdvp9dyXqQ generation 0\r\n" \
|
||||
"1 1 udp 1 192.168.196.1 57809 typ prflx name video_rtp network_name {0C0137CC-DB78-46B6-9B6C-7E097FFA79FE} username S1vDZTVVky3r0pT+ password XgLb+H9uofxuWg7G generation 0\r\n" \
|
||||
"1 2 udp 1 192.168.211.1 57811 typ relay name video_rtp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username x64BhO4BXjBFkpz2 password ZwHhRhu0KU9R6iWd generation 0\r\n" \
|
||||
"1 1 udp 1 192.168.211.1 57811 typ token name video_rtp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username x64BhO4BXjBFkpz2 password ZwHhRhu0KU9R6iWd generation 0\r\n"
|
||||
|
||||
static int tnet_ice_callback(const tnet_ice_event_t *e)
|
||||
{
|
||||
TSK_DEBUG_INFO("ICE callback: %s", e->phrase);
|
||||
|
||||
switch(e->type)
|
||||
{
|
||||
case tnet_ice_event_type_gathering_completed:
|
||||
{
|
||||
struct tnet_ice_ctx_s *ctx;
|
||||
if((ctx = (struct tnet_ice_ctx_s *)e->userdata)){
|
||||
tnet_ice_ctx_set_remote_candidates(ctx, ICE_CANDIDATES);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_ice()
|
||||
{
|
||||
struct tnet_ice_ctx_s *ctx;
|
||||
int ret;
|
||||
static const tsk_bool_t use_ipv6 = tsk_false;
|
||||
static const tsk_bool_t use_rtcp = tsk_true;
|
||||
|
||||
ctx = tnet_ice_ctx_create(use_ipv6, use_rtcp, tnet_ice_callback, tsk_null);
|
||||
tnet_ice_ctx_set_userdata(ctx, ctx);
|
||||
ret = tnet_ice_ctx_stun_configure(ctx, "numb.viagenie.ca", 3478, "Doubango", "bossiel@yahoo.fr", "stun-password");
|
||||
ret = tnet_ice_ctx_start(ctx);
|
||||
// ret = tnet_ice_ctx_set_remote_candidates(ctx, ICE_CANDIDATES);
|
||||
|
||||
getchar();
|
||||
|
||||
ret = tnet_ice_ctx_stop(ctx);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(ctx);
|
||||
}
|
||||
|
||||
|
||||
#endif /* TNET_TEST_ICE_H */
|
||||
*/
|
||||
|
||||
#ifndef TNET_TEST_ICE_H
|
||||
#define TNET_TEST_ICE_H
|
||||
|
||||
#define ICE_CANDIDATES "1 1 udp 1 192.168.196.1 57806 typ host name video_rtcp network_name {0C0137CC-DB78-46B6-9B6C-7E097FFA79FE} username StFEVThMK2DHThkv password qkhKUDr4WqKRwZTo generation 0\r\n" \
|
||||
"1 2 udp 1 192.168.211.1 57808 typ srflx name video_rtcp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username 9ONjPsYvSFh0JvAc password rDHSkokdvp9dyXqQ generation 0\r\n" \
|
||||
"1 1 udp 1 192.168.196.1 57809 typ prflx name video_rtp network_name {0C0137CC-DB78-46B6-9B6C-7E097FFA79FE} username S1vDZTVVky3r0pT+ password XgLb+H9uofxuWg7G generation 0\r\n" \
|
||||
"1 2 udp 1 192.168.211.1 57811 typ relay name video_rtp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username x64BhO4BXjBFkpz2 password ZwHhRhu0KU9R6iWd generation 0\r\n" \
|
||||
"1 1 udp 1 192.168.211.1 57811 typ token name video_rtp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username x64BhO4BXjBFkpz2 password ZwHhRhu0KU9R6iWd generation 0\r\n"
|
||||
|
||||
static int tnet_ice_callback(const tnet_ice_event_t *e)
|
||||
{
|
||||
TSK_DEBUG_INFO("ICE callback: %s", e->phrase);
|
||||
|
||||
switch(e->type)
|
||||
{
|
||||
case tnet_ice_event_type_gathering_completed:
|
||||
{
|
||||
struct tnet_ice_ctx_s *ctx;
|
||||
if((ctx = (struct tnet_ice_ctx_s *)e->userdata)){
|
||||
tnet_ice_ctx_set_remote_candidates(ctx, ICE_CANDIDATES, "ice-ufrag", "ice-pwd", tsk_true, tsk_false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_ice()
|
||||
{
|
||||
struct tnet_ice_ctx_s *ctx;
|
||||
int ret;
|
||||
static const tsk_bool_t use_ipv6 = tsk_false;
|
||||
static const tsk_bool_t use_rtcp = tsk_true;
|
||||
static const tsk_bool_t use_ice_jingle = tsk_false;
|
||||
static const tsk_bool_t use_video = tsk_false;
|
||||
|
||||
long a = tnet_htonl(0x6b0c76a7);
|
||||
long b = tnet_htonl(0x034aa76b);
|
||||
long c = tnet_htonl(0x510da598);
|
||||
|
||||
ctx = tnet_ice_ctx_create(use_ice_jingle, use_ipv6, use_rtcp, use_video, tnet_ice_callback, tsk_null);
|
||||
tnet_ice_ctx_set_userdata(ctx, ctx);
|
||||
ret = tnet_ice_ctx_set_stun(ctx, "numb.viagenie.ca", 3478, "Doubango", "bossiel@yahoo.fr", "stun-password");
|
||||
ret = tnet_ice_ctx_start(ctx);
|
||||
// ret = tnet_ice_ctx_set_remote_candidates(ctx, ICE_CANDIDATES);
|
||||
|
||||
getchar();
|
||||
|
||||
ret = tnet_ice_ctx_stop(ctx);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(ctx);
|
||||
}
|
||||
|
||||
|
||||
#endif /* TNET_TEST_ICE_H */
|
||||
/*
|
||||
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*/
|
||||
|
||||
#ifndef TNET_TEST_ICE_H
|
||||
#define TNET_TEST_ICE_H
|
||||
|
||||
#define ICE_CANDIDATES "1 1 udp 1 192.168.196.1 57806 typ host name video_rtcp network_name {0C0137CC-DB78-46B6-9B6C-7E097FFA79FE} username StFEVThMK2DHThkv password qkhKUDr4WqKRwZTo generation 0\r\n" \
|
||||
"1 2 udp 1 192.168.211.1 57808 typ srflx name video_rtcp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username 9ONjPsYvSFh0JvAc password rDHSkokdvp9dyXqQ generation 0\r\n" \
|
||||
"1 1 udp 1 192.168.196.1 57809 typ prflx name video_rtp network_name {0C0137CC-DB78-46B6-9B6C-7E097FFA79FE} username S1vDZTVVky3r0pT+ password XgLb+H9uofxuWg7G generation 0\r\n" \
|
||||
"1 2 udp 1 192.168.211.1 57811 typ relay name video_rtp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username x64BhO4BXjBFkpz2 password ZwHhRhu0KU9R6iWd generation 0\r\n" \
|
||||
"1 1 udp 1 192.168.211.1 57811 typ token name video_rtp network_name {F53974D9-C92C-4644-AF7A-EA09D29BD5A5} username x64BhO4BXjBFkpz2 password ZwHhRhu0KU9R6iWd generation 0\r\n"
|
||||
|
||||
static int tnet_ice_callback(const tnet_ice_event_t *e)
|
||||
{
|
||||
TSK_DEBUG_INFO("ICE callback: %s", e->phrase);
|
||||
|
||||
switch(e->type)
|
||||
{
|
||||
case tnet_ice_event_type_gathering_completed:
|
||||
{
|
||||
struct tnet_ice_ctx_s *ctx;
|
||||
if((ctx = (struct tnet_ice_ctx_s *)e->userdata)){
|
||||
tnet_ice_ctx_set_remote_candidates(ctx, ICE_CANDIDATES);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_ice()
|
||||
{
|
||||
struct tnet_ice_ctx_s *ctx;
|
||||
int ret;
|
||||
static const tsk_bool_t use_ipv6 = tsk_false;
|
||||
static const tsk_bool_t use_rtcp = tsk_true;
|
||||
|
||||
ctx = tnet_ice_ctx_create(use_ipv6, use_rtcp, tnet_ice_callback, tsk_null);
|
||||
tnet_ice_ctx_set_userdata(ctx, ctx);
|
||||
ret = tnet_ice_ctx_stun_configure(ctx, "numb.viagenie.ca", 3478, "Doubango", "bossiel@yahoo.fr", "stun-password");
|
||||
ret = tnet_ice_ctx_start(ctx);
|
||||
// ret = tnet_ice_ctx_set_remote_candidates(ctx, ICE_CANDIDATES);
|
||||
|
||||
getchar();
|
||||
|
||||
ret = tnet_ice_ctx_stop(ctx);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(ctx);
|
||||
}
|
||||
|
||||
|
||||
#endif /* TNET_TEST_ICE_H */
|
||||
|
|
|
@ -1,102 +1,99 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Mamadou Diop.
|
||||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#ifndef TNET_TEST_IFACES_H
|
||||
#define TNET_TEST_IFACES_H
|
||||
|
||||
void test_faces_bestsource()
|
||||
{
|
||||
tnet_ip_t source;
|
||||
|
||||
// IPv6
|
||||
if(!tnet_getbestsource("fe80::fe4c:3ea1", 5060, tnet_socket_type_udp_ipv6, &source)){
|
||||
TSK_DEBUG_INFO("Best IPv6 source is [%s]", source);
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("Failed to get best IPv6 source.");
|
||||
}
|
||||
// IPv6
|
||||
if(!tnet_getbestsource("2a01:e35:8b32:7050:212:f0ff:fe4c:3ea1", 5060, tnet_socket_type_udp_ipv6, &source)){
|
||||
TSK_DEBUG_INFO("Best IPv6 source is [%s]", source);
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("Failed to get best IPv6 source.");
|
||||
}
|
||||
// IPv4
|
||||
if(!tnet_getbestsource("192.168.0.11", 5060, tnet_socket_type_udp_ipv4, &source)){
|
||||
TSK_DEBUG_INFO("Best IPv4 source is [%s]", source);
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("Failed to get best IPv4 source.");
|
||||
}
|
||||
}
|
||||
|
||||
void test_ifaces_dump_ifaces()
|
||||
{
|
||||
tnet_interfaces_L_t* ifaces = tnet_get_interfaces();
|
||||
tsk_list_item_t *item;
|
||||
|
||||
tsk_list_foreach(item, ifaces)
|
||||
{
|
||||
const tnet_interface_t *iface = item->data;
|
||||
TSK_DEBUG_INFO("Interface: %s", iface->description);
|
||||
}
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(ifaces);
|
||||
}
|
||||
|
||||
void test_ifaces_dump_addresses()
|
||||
{
|
||||
tnet_addresses_L_t* addresses = tnet_get_addresses_all();
|
||||
tsk_list_item_t *item;
|
||||
|
||||
tsk_list_foreach(item, addresses)
|
||||
{
|
||||
const tnet_address_t *address = item->data;
|
||||
if(address->anycast)
|
||||
{
|
||||
TSK_DEBUG_INFO("ANYCAST address: %s", address->ip);
|
||||
}
|
||||
else if(address->unicast)
|
||||
{
|
||||
TSK_DEBUG_INFO("UNICAST address: %s", address->ip);
|
||||
}
|
||||
else if(address->multicast)
|
||||
{
|
||||
TSK_DEBUG_INFO("MULTICAST address: %s", address->ip);
|
||||
}
|
||||
else if(address->dnsserver)
|
||||
{
|
||||
TSK_DEBUG_INFO("DNSSERVER address: %s", address->ip);
|
||||
}
|
||||
}
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(addresses);
|
||||
}
|
||||
|
||||
void test_ifaces()
|
||||
{
|
||||
test_faces_bestsource();
|
||||
test_ifaces_dump_ifaces();
|
||||
test_ifaces_dump_addresses();
|
||||
}
|
||||
|
||||
#endif /* TNET_TEST_IFACES_H */
|
||||
*/
|
||||
#ifndef TNET_TEST_IFACES_H
|
||||
#define TNET_TEST_IFACES_H
|
||||
|
||||
void test_faces_bestsource()
|
||||
{
|
||||
tnet_ip_t source;
|
||||
|
||||
// IPv6
|
||||
if(!tnet_getbestsource("fe80::fe4c:3ea1", 5060, tnet_socket_type_udp_ipv6, &source)){
|
||||
TSK_DEBUG_INFO("Best IPv6 source is [%s]", source);
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("Failed to get best IPv6 source.");
|
||||
}
|
||||
// IPv6
|
||||
if(!tnet_getbestsource("2a01:e35:8b32:7050:212:f0ff:fe4c:3ea1", 5060, tnet_socket_type_udp_ipv6, &source)){
|
||||
TSK_DEBUG_INFO("Best IPv6 source is [%s]", source);
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("Failed to get best IPv6 source.");
|
||||
}
|
||||
// IPv4
|
||||
if(!tnet_getbestsource("192.168.0.11", 5060, tnet_socket_type_udp_ipv4, &source)){
|
||||
TSK_DEBUG_INFO("Best IPv4 source is [%s]", source);
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("Failed to get best IPv4 source.");
|
||||
}
|
||||
}
|
||||
|
||||
void test_ifaces_dump_ifaces()
|
||||
{
|
||||
tnet_interfaces_L_t* ifaces = tnet_get_interfaces();
|
||||
tsk_list_item_t *item;
|
||||
|
||||
tsk_list_foreach(item, ifaces)
|
||||
{
|
||||
const tnet_interface_t *iface = item->data;
|
||||
TSK_DEBUG_INFO("Interface: %s", iface->description);
|
||||
}
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(ifaces);
|
||||
}
|
||||
|
||||
void test_ifaces_dump_addresses()
|
||||
{
|
||||
tnet_addresses_L_t* addresses = tnet_get_addresses_all();
|
||||
tsk_list_item_t *item;
|
||||
|
||||
tsk_list_foreach(item, addresses)
|
||||
{
|
||||
const tnet_address_t *address = item->data;
|
||||
if(address->anycast)
|
||||
{
|
||||
TSK_DEBUG_INFO("ANYCAST address: %s", address->ip);
|
||||
}
|
||||
else if(address->unicast)
|
||||
{
|
||||
TSK_DEBUG_INFO("UNICAST address: %s", address->ip);
|
||||
}
|
||||
else if(address->multicast)
|
||||
{
|
||||
TSK_DEBUG_INFO("MULTICAST address: %s", address->ip);
|
||||
}
|
||||
else if(address->dnsserver)
|
||||
{
|
||||
TSK_DEBUG_INFO("DNSSERVER address: %s", address->ip);
|
||||
}
|
||||
}
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(addresses);
|
||||
}
|
||||
|
||||
void test_ifaces()
|
||||
{
|
||||
test_faces_bestsource();
|
||||
test_ifaces_dump_ifaces();
|
||||
test_ifaces_dump_addresses();
|
||||
}
|
||||
|
||||
#endif /* TNET_TEST_IFACES_H */
|
||||
|
|
|
@ -1,219 +1,216 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Mamadou Diop.
|
||||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#ifndef TNET_TEST_NAT_H
|
||||
#define TNET_TEST_NAT_H
|
||||
|
||||
//stun.ekiga.net
|
||||
//#define STUN_SERVER_IP "numb.viagenie.ca"
|
||||
#define STUN_SERVER_IP "numb.viagenie.ca"
|
||||
#define STUN_USERNAME "xxxxx"
|
||||
#define STUN_PASSWORD "xxxxx"
|
||||
#define STUN_SERVER_PORT TNET_STUN_TCP_UDP_DEFAULT_PORT
|
||||
#define STUN_SERVER_PROTO tnet_socket_type_udp_ipv4
|
||||
|
||||
void test_nat_stun()
|
||||
{
|
||||
tnet_socket_t *socket1 = 0, *socket2 = 0;
|
||||
tnet_nat_context_handle_t *context = 0;
|
||||
|
||||
tnet_stun_binding_id_t bind_id1, bind_id2;
|
||||
|
||||
char* public_ip1 = 0, *public_ip2 = 0;
|
||||
tnet_port_t public_port1 = 0, public_port2 = 0;
|
||||
|
||||
if(!(socket1 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO))
|
||||
|| !(socket2 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO)))
|
||||
{
|
||||
goto bail;
|
||||
}
|
||||
|
||||
context = tnet_nat_context_create(STUN_SERVER_PROTO, STUN_USERNAME, STUN_PASSWORD);
|
||||
|
||||
if(tnet_nat_set_server_address(context, STUN_SERVER_IP))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to set STUN/TURN address.");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* == BIND
|
||||
*/
|
||||
bind_id1 = tnet_nat_stun_bind(context, socket1->fd);
|
||||
bind_id2 = tnet_nat_stun_bind(context, socket2->fd);
|
||||
|
||||
if(!TNET_STUN_IS_VALID_BINDING_ID(bind_id1) ||!TNET_STUN_IS_VALID_BINDING_ID(bind_id2))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to get public IP/port using stun");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if(!tnet_nat_stun_get_reflexive_address(context, bind_id1, &public_ip1, &public_port1))
|
||||
{
|
||||
TSK_DEBUG_INFO("Public IP1/Port1 ==> %s:%u", public_ip1, public_port1);
|
||||
}
|
||||
|
||||
if(!tnet_nat_stun_get_reflexive_address(context, bind_id2, &public_ip2, &public_port2))
|
||||
{
|
||||
TSK_DEBUG_INFO("Public IP2/Port2 ==> %s:%u", public_ip2, public_port2);
|
||||
}
|
||||
|
||||
/* == UNBIND
|
||||
*/
|
||||
tnet_nat_stun_unbind(context, bind_id1);
|
||||
tnet_nat_stun_unbind(context, bind_id2);
|
||||
|
||||
bail:
|
||||
TSK_OBJECT_SAFE_FREE(socket1);
|
||||
TSK_OBJECT_SAFE_FREE(socket2);
|
||||
|
||||
TSK_FREE(public_ip1);
|
||||
TSK_FREE(public_ip1);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(context);
|
||||
}
|
||||
|
||||
void test_nat_turn()
|
||||
{
|
||||
tnet_socket_t *socket1 = 0, *socket2 = 0;
|
||||
tnet_nat_context_handle_t *context = 0;
|
||||
tnet_turn_allocation_id_t alloc_id1, alloc_id2;
|
||||
|
||||
char* public_ip1 = 0, *public_ip2 = 0;
|
||||
tnet_port_t public_port1 = 0, public_port2 = 0;
|
||||
|
||||
tnet_turn_channel_binding_id_t channel_id;
|
||||
|
||||
int ret;
|
||||
|
||||
if(!(socket1 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO))
|
||||
|| !(socket2 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO)))
|
||||
{
|
||||
goto bail;
|
||||
}
|
||||
|
||||
context = tnet_nat_context_create(STUN_SERVER_PROTO, STUN_USERNAME, STUN_PASSWORD);
|
||||
|
||||
if(tnet_nat_set_server_address(context, STUN_SERVER_IP))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to set STUN/TURN address.");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* == ALLOC
|
||||
*/
|
||||
alloc_id1 = tnet_nat_turn_allocate(context, socket1->fd);
|
||||
alloc_id2 = tnet_nat_turn_allocate(context, socket2->fd);
|
||||
if(!TNET_TURN_IS_VALID_ALLOCATION_ID(alloc_id1) || !TNET_TURN_IS_VALID_ALLOCATION_ID(alloc_id2))
|
||||
{
|
||||
TSK_DEBUG_ERROR("TURN allocation failed.");
|
||||
goto bail;
|
||||
}
|
||||
else
|
||||
{
|
||||
TSK_DEBUG_INFO("TURN allocation succeeded and id1=%llu and id2=%llu", alloc_id1, alloc_id2);
|
||||
}
|
||||
|
||||
tsk_thread_sleep(2000);
|
||||
|
||||
/* == RETRIEVE STUN SERVER REFLEXIVE ADDRESSES
|
||||
*/
|
||||
if(!tnet_nat_turn_get_reflexive_address(context, alloc_id1, &public_ip1, &public_port1))
|
||||
{
|
||||
TSK_DEBUG_INFO("Public IP1/Port1 ==> %s:%u", public_ip1, public_port1);
|
||||
}
|
||||
|
||||
if(!tnet_nat_turn_get_reflexive_address(context, alloc_id2, &public_ip2, &public_port2))
|
||||
{
|
||||
TSK_DEBUG_INFO("Public IP2/Port2 ==> %s:%u", public_ip2, public_port2);
|
||||
}
|
||||
|
||||
/* == CREATE PERMISSION
|
||||
*/
|
||||
//tnet_nat_turn_add_permission(context, alloc_id1, "192.168.0.11", 300);
|
||||
|
||||
/* == CHANNEL BINDING
|
||||
*/
|
||||
{
|
||||
/* Try to bind (channel binding) to the socket1 to socket2 */
|
||||
struct sockaddr_storage peer;
|
||||
if((ret = tnet_sockaddr_init(public_ip2, public_port2, STUN_SERVER_PROTO, &peer)))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to init peer with error code %d.", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
channel_id = tnet_nat_turn_channel_bind(context, alloc_id1,&peer);
|
||||
if(TNET_TURN_IS_VALID_CHANNEL_BINDING_ID(channel_id))
|
||||
{
|
||||
TSK_DEBUG_INFO("TURN channel binding succeeded.");
|
||||
|
||||
/* Try to send data using the newly create channel */
|
||||
if(tnet_nat_turn_channel_senddata(context, channel_id, "Doubango", strlen("Doubango")))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to send data using channel id [%u].", channel_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
TSK_DEBUG_INFO("Data successfuly sent using channel if[%u].", channel_id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TSK_DEBUG_ERROR("TURN channel binding failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tsk_thread_sleep(2000);
|
||||
|
||||
/* == UNALLOC
|
||||
*/
|
||||
if((ret = tnet_nat_turn_unallocate(context, alloc_id1)) || (ret = tnet_nat_turn_unallocate(context, alloc_id2)))
|
||||
{
|
||||
TSK_DEBUG_ERROR("TURN unallocation failed with error code: %d.", ret);
|
||||
goto bail;
|
||||
}
|
||||
else
|
||||
{
|
||||
TSK_DEBUG_INFO("TURN unallocation succeeded.");
|
||||
}
|
||||
|
||||
bail:
|
||||
TSK_OBJECT_SAFE_FREE(socket1);
|
||||
TSK_OBJECT_SAFE_FREE(socket2);
|
||||
|
||||
TSK_FREE(public_ip1);
|
||||
TSK_FREE(public_ip1);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(context);
|
||||
}
|
||||
|
||||
|
||||
void test_nat()
|
||||
{
|
||||
test_nat_stun();
|
||||
//test_nat_turn();
|
||||
//tsk_thread_sleep(1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* TNET_TEST_NAT_H */
|
||||
*/
|
||||
#ifndef TNET_TEST_NAT_H
|
||||
#define TNET_TEST_NAT_H
|
||||
|
||||
//stun.ekiga.net
|
||||
//#define STUN_SERVER_IP "numb.viagenie.ca"
|
||||
#define STUN_SERVER_IP "numb.viagenie.ca"
|
||||
#define STUN_USERNAME "xxxxx"
|
||||
#define STUN_PASSWORD "xxxxx"
|
||||
#define STUN_SERVER_PORT TNET_STUN_TCP_UDP_DEFAULT_PORT
|
||||
#define STUN_SERVER_PROTO tnet_socket_type_udp_ipv4
|
||||
|
||||
void test_nat_stun()
|
||||
{
|
||||
tnet_socket_t *socket1 = 0, *socket2 = 0;
|
||||
tnet_nat_context_handle_t *context = 0;
|
||||
|
||||
tnet_stun_binding_id_t bind_id1, bind_id2;
|
||||
|
||||
char* public_ip1 = 0, *public_ip2 = 0;
|
||||
tnet_port_t public_port1 = 0, public_port2 = 0;
|
||||
|
||||
if(!(socket1 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO))
|
||||
|| !(socket2 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO)))
|
||||
{
|
||||
goto bail;
|
||||
}
|
||||
|
||||
context = tnet_nat_context_create(STUN_SERVER_PROTO, STUN_USERNAME, STUN_PASSWORD);
|
||||
|
||||
if(tnet_nat_set_server_address(context, STUN_SERVER_IP))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to set STUN/TURN address.");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* == BIND
|
||||
*/
|
||||
bind_id1 = tnet_nat_stun_bind(context, socket1->fd);
|
||||
bind_id2 = tnet_nat_stun_bind(context, socket2->fd);
|
||||
|
||||
if(!TNET_STUN_IS_VALID_BINDING_ID(bind_id1) ||!TNET_STUN_IS_VALID_BINDING_ID(bind_id2))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to get public IP/port using stun");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if(!tnet_nat_stun_get_reflexive_address(context, bind_id1, &public_ip1, &public_port1))
|
||||
{
|
||||
TSK_DEBUG_INFO("Public IP1/Port1 ==> %s:%u", public_ip1, public_port1);
|
||||
}
|
||||
|
||||
if(!tnet_nat_stun_get_reflexive_address(context, bind_id2, &public_ip2, &public_port2))
|
||||
{
|
||||
TSK_DEBUG_INFO("Public IP2/Port2 ==> %s:%u", public_ip2, public_port2);
|
||||
}
|
||||
|
||||
/* == UNBIND
|
||||
*/
|
||||
tnet_nat_stun_unbind(context, bind_id1);
|
||||
tnet_nat_stun_unbind(context, bind_id2);
|
||||
|
||||
bail:
|
||||
TSK_OBJECT_SAFE_FREE(socket1);
|
||||
TSK_OBJECT_SAFE_FREE(socket2);
|
||||
|
||||
TSK_FREE(public_ip1);
|
||||
TSK_FREE(public_ip1);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(context);
|
||||
}
|
||||
|
||||
void test_nat_turn()
|
||||
{
|
||||
tnet_socket_t *socket1 = 0, *socket2 = 0;
|
||||
tnet_nat_context_handle_t *context = 0;
|
||||
tnet_turn_allocation_id_t alloc_id1, alloc_id2;
|
||||
|
||||
char* public_ip1 = 0, *public_ip2 = 0;
|
||||
tnet_port_t public_port1 = 0, public_port2 = 0;
|
||||
|
||||
tnet_turn_channel_binding_id_t channel_id;
|
||||
|
||||
int ret;
|
||||
|
||||
if(!(socket1 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO))
|
||||
|| !(socket2 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO)))
|
||||
{
|
||||
goto bail;
|
||||
}
|
||||
|
||||
context = tnet_nat_context_create(STUN_SERVER_PROTO, STUN_USERNAME, STUN_PASSWORD);
|
||||
|
||||
if(tnet_nat_set_server_address(context, STUN_SERVER_IP))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to set STUN/TURN address.");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* == ALLOC
|
||||
*/
|
||||
alloc_id1 = tnet_nat_turn_allocate(context, socket1->fd);
|
||||
alloc_id2 = tnet_nat_turn_allocate(context, socket2->fd);
|
||||
if(!TNET_TURN_IS_VALID_ALLOCATION_ID(alloc_id1) || !TNET_TURN_IS_VALID_ALLOCATION_ID(alloc_id2))
|
||||
{
|
||||
TSK_DEBUG_ERROR("TURN allocation failed.");
|
||||
goto bail;
|
||||
}
|
||||
else
|
||||
{
|
||||
TSK_DEBUG_INFO("TURN allocation succeeded and id1=%llu and id2=%llu", alloc_id1, alloc_id2);
|
||||
}
|
||||
|
||||
tsk_thread_sleep(2000);
|
||||
|
||||
/* == RETRIEVE STUN SERVER REFLEXIVE ADDRESSES
|
||||
*/
|
||||
if(!tnet_nat_turn_get_reflexive_address(context, alloc_id1, &public_ip1, &public_port1))
|
||||
{
|
||||
TSK_DEBUG_INFO("Public IP1/Port1 ==> %s:%u", public_ip1, public_port1);
|
||||
}
|
||||
|
||||
if(!tnet_nat_turn_get_reflexive_address(context, alloc_id2, &public_ip2, &public_port2))
|
||||
{
|
||||
TSK_DEBUG_INFO("Public IP2/Port2 ==> %s:%u", public_ip2, public_port2);
|
||||
}
|
||||
|
||||
/* == CREATE PERMISSION
|
||||
*/
|
||||
//tnet_nat_turn_add_permission(context, alloc_id1, "192.168.0.11", 300);
|
||||
|
||||
/* == CHANNEL BINDING
|
||||
*/
|
||||
{
|
||||
/* Try to bind (channel binding) to the socket1 to socket2 */
|
||||
struct sockaddr_storage peer;
|
||||
if((ret = tnet_sockaddr_init(public_ip2, public_port2, STUN_SERVER_PROTO, &peer)))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to init peer with error code %d.", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
channel_id = tnet_nat_turn_channel_bind(context, alloc_id1,&peer);
|
||||
if(TNET_TURN_IS_VALID_CHANNEL_BINDING_ID(channel_id))
|
||||
{
|
||||
TSK_DEBUG_INFO("TURN channel binding succeeded.");
|
||||
|
||||
/* Try to send data using the newly create channel */
|
||||
if(tnet_nat_turn_channel_senddata(context, channel_id, "Doubango", strlen("Doubango")))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to send data using channel id [%u].", channel_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
TSK_DEBUG_INFO("Data successfuly sent using channel if[%u].", channel_id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TSK_DEBUG_ERROR("TURN channel binding failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tsk_thread_sleep(2000);
|
||||
|
||||
/* == UNALLOC
|
||||
*/
|
||||
if((ret = tnet_nat_turn_unallocate(context, alloc_id1)) || (ret = tnet_nat_turn_unallocate(context, alloc_id2)))
|
||||
{
|
||||
TSK_DEBUG_ERROR("TURN unallocation failed with error code: %d.", ret);
|
||||
goto bail;
|
||||
}
|
||||
else
|
||||
{
|
||||
TSK_DEBUG_INFO("TURN unallocation succeeded.");
|
||||
}
|
||||
|
||||
bail:
|
||||
TSK_OBJECT_SAFE_FREE(socket1);
|
||||
TSK_OBJECT_SAFE_FREE(socket2);
|
||||
|
||||
TSK_FREE(public_ip1);
|
||||
TSK_FREE(public_ip1);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(context);
|
||||
}
|
||||
|
||||
|
||||
void test_nat()
|
||||
{
|
||||
test_nat_stun();
|
||||
//test_nat_turn();
|
||||
//tsk_thread_sleep(1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* TNET_TEST_NAT_H */
|
||||
|
|
|
@ -1,64 +1,61 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Mamadou Diop.
|
||||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#ifndef TNET_TEST_SOCKETS_H
|
||||
#define TNET_TEST_SOCKETS_H
|
||||
|
||||
void test_sockets()
|
||||
{
|
||||
int test;
|
||||
tnet_socket_tcp_t * tcp_socket;
|
||||
tnet_socket_type_t type = tnet_socket_type_udp_ipv4;
|
||||
struct sockaddr_storage to;
|
||||
|
||||
TNET_SOCKET_TYPE_SET_IPV4(type);
|
||||
TNET_SOCKET_TYPE_SET_IPV6(type);
|
||||
TNET_SOCKET_TYPE_SET_IPV4Only(type);
|
||||
TNET_SOCKET_TYPE_SET_IPV6Only(type);
|
||||
TNET_SOCKET_TYPE_SET_IPV6Only(type);
|
||||
TNET_SOCKET_TYPE_SET_IPV4(type);
|
||||
TNET_SOCKET_TYPE_SET_IPV6(type);
|
||||
|
||||
TNET_SOCKET_TYPE_SET_TLS(type);
|
||||
TNET_SOCKET_TYPE_SET_UDP(type);
|
||||
TNET_SOCKET_TYPE_SET_SCTP(type);
|
||||
TNET_SOCKET_TYPE_SET_TCP(type);
|
||||
|
||||
tcp_socket = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, type);
|
||||
|
||||
if(!TNET_SOCKET_IS_VALID(tcp_socket))
|
||||
{
|
||||
TSK_OBJECT_SAFE_FREE(tcp_socket);
|
||||
return;
|
||||
}
|
||||
|
||||
//if(!(test = tnet_sockaddr_init("www.google.com", 80, type, &to))){
|
||||
// test = tnet_sockfd_connetto(tcp_socket->fd, (const struct sockaddr_storage *)&to);
|
||||
//}
|
||||
|
||||
if(!(test = tnet_sockaddr_init("ipv6.google.com", 80, type, &to))){
|
||||
test = tnet_sockfd_connectto(tcp_socket->fd, (const struct sockaddr_storage *)&to);
|
||||
}
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(tcp_socket);
|
||||
}
|
||||
|
||||
#endif /* TNET_TEST_SOCKETS_H */
|
||||
*/
|
||||
#ifndef TNET_TEST_SOCKETS_H
|
||||
#define TNET_TEST_SOCKETS_H
|
||||
|
||||
void test_sockets()
|
||||
{
|
||||
int test;
|
||||
tnet_socket_tcp_t * tcp_socket;
|
||||
tnet_socket_type_t type = tnet_socket_type_udp_ipv4;
|
||||
struct sockaddr_storage to;
|
||||
|
||||
TNET_SOCKET_TYPE_SET_IPV4(type);
|
||||
TNET_SOCKET_TYPE_SET_IPV6(type);
|
||||
TNET_SOCKET_TYPE_SET_IPV4Only(type);
|
||||
TNET_SOCKET_TYPE_SET_IPV6Only(type);
|
||||
TNET_SOCKET_TYPE_SET_IPV6Only(type);
|
||||
TNET_SOCKET_TYPE_SET_IPV4(type);
|
||||
TNET_SOCKET_TYPE_SET_IPV6(type);
|
||||
|
||||
TNET_SOCKET_TYPE_SET_TLS(type);
|
||||
TNET_SOCKET_TYPE_SET_UDP(type);
|
||||
TNET_SOCKET_TYPE_SET_SCTP(type);
|
||||
TNET_SOCKET_TYPE_SET_TCP(type);
|
||||
|
||||
tcp_socket = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, type);
|
||||
|
||||
if(!TNET_SOCKET_IS_VALID(tcp_socket))
|
||||
{
|
||||
TSK_OBJECT_SAFE_FREE(tcp_socket);
|
||||
return;
|
||||
}
|
||||
|
||||
//if(!(test = tnet_sockaddr_init("www.google.com", 80, type, &to))){
|
||||
// test = tnet_sockfd_connetto(tcp_socket->fd, (const struct sockaddr_storage *)&to);
|
||||
//}
|
||||
|
||||
if(!(test = tnet_sockaddr_init("ipv6.google.com", 80, type, &to))){
|
||||
test = tnet_sockfd_connectto(tcp_socket->fd, (const struct sockaddr_storage *)&to);
|
||||
}
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(tcp_socket);
|
||||
}
|
||||
|
||||
#endif /* TNET_TEST_SOCKETS_H */
|
||||
|
|
|
@ -1,124 +1,159 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Mamadou Diop.
|
||||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#ifndef TNET_TEST_STUN_H
|
||||
#define TNET_TEST_STUN_H
|
||||
|
||||
#define STUN_SERVER_IP "numb.viagenie.ca"
|
||||
#define STUN_SERVER_PORT TNET_STUN_TCP_UDP_DEFAULT_PORT
|
||||
#define STUN_SERVER_PROTO tnet_socket_type_udp_ipv4
|
||||
|
||||
// http://tools.ietf.org/html/draft-ietf-behave-stun-test-vectors-04
|
||||
|
||||
void test_stun_dump_transacid(tnet_stun_transacid_t transcid)
|
||||
*/
|
||||
#ifndef TNET_TEST_STUN_H
|
||||
#define TNET_TEST_STUN_H
|
||||
|
||||
#include "stun/tnet_stun_pkt.h"
|
||||
#include "stun/tnet_stun_utils.h"
|
||||
|
||||
#define kStunServerIP "numb.viagenie.ca"
|
||||
#define kStunServerPort kStunPortDefaultTcpUdp
|
||||
#define kStunServerProto tnet_socket_type_udp_ipv4
|
||||
|
||||
#define TNET_TEST_STUN_SEND_BUFF(buff_ptr, buff_size) \
|
||||
{ \
|
||||
struct sockaddr_storage addr_to; \
|
||||
tnet_socket_t* socket = tnet_socket_create(0, 0, kStunServerProto); \
|
||||
tnet_sockaddr_init(kStunServerIP, kStunServerPort, kStunServerProto, &addr_to); \
|
||||
tnet_sockfd_sendto(socket->fd, (const struct sockaddr *)&addr_to, (buff_ptr), (buff_size)); \
|
||||
TSK_OBJECT_SAFE_FREE(socket); \
|
||||
} \
|
||||
|
||||
uint8_t __parse_buff_write_ptr[1200];
|
||||
static const tsk_size_t __parse_buff_write_size = sizeof(__parse_buff_write_ptr)/sizeof(__parse_buff_write_ptr[0]);
|
||||
uint8_t __parse_buff_read_ptr[1200];
|
||||
static const tsk_size_t __parse_buff_read_size = sizeof(__parse_buff_read_ptr)/sizeof(__parse_buff_read_ptr[0]);
|
||||
|
||||
// http://tools.ietf.org/html/draft-ietf-behave-stun-test-vectors-04
|
||||
|
||||
static int test_stun_buff_cmp(const uint8_t* pc_buf1_ptr, tsk_size_t n_buff1_size, const uint8_t* pc_buf2_ptr, tsk_size_t n_buff2_size)
|
||||
{
|
||||
char transac_idstriing[TNET_STUN_TRANSACID_SIZE*2+1];
|
||||
tsk_str_from_hex(transcid, TNET_STUN_TRANSACID_SIZE, transac_idstriing);
|
||||
int ret;
|
||||
tsk_size_t u;
|
||||
if (!pc_buf1_ptr || !pc_buf2_ptr || (n_buff1_size != n_buff2_size)) {
|
||||
return -1;
|
||||
}
|
||||
for (u = 0; u < n_buff1_size; ++u) {
|
||||
if ((ret = (pc_buf1_ptr[u] - pc_buf2_ptr[u]))) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_stun_dump_transacid(tnet_stun_transacid_t transcid)
|
||||
{
|
||||
char transac_idstriing[TNET_STUN_TRANSACID_SIZE*2+1];
|
||||
tsk_str_from_hex(transcid, TNET_STUN_TRANSACID_SIZE, transac_idstriing);
|
||||
|
||||
transac_idstriing[sizeof(transac_idstriing)-1] = '\0';
|
||||
|
||||
TSK_DEBUG_INFO("STUN transac id:%s", transac_idstriing);
|
||||
}
|
||||
|
||||
static void test_sun_parser()
|
||||
{
|
||||
tnet_stun_pkt_t* p_pkt = tsk_null;
|
||||
tsk_size_t n_written_bytes, n_read_bytes;
|
||||
static const char* __pc_mapped_addr_ipv4 = "192.168.0.37";
|
||||
static const char* __pc_mapped_addr_ipv6 = "fdf8:f53b:82e4::53";
|
||||
static const uint16_t __u_mapped_addr_port = 5060;
|
||||
tnet_stun_addr_t addr_ipv4, addr_ipv6;
|
||||
|
||||
transac_idstriing[sizeof(transac_idstriing)-1] = '\0';
|
||||
|
||||
TSK_DEBUG_INFO("STUN transac id:%s", transac_idstriing);
|
||||
}
|
||||
|
||||
void test_sun_sendMessage()
|
||||
{
|
||||
tnet_stun_message_t *message = tsk_null;
|
||||
tsk_buffer_t *buffer = tsk_null;
|
||||
tnet_socket_t *socket = tsk_null;
|
||||
struct sockaddr_storage to;
|
||||
tnet_stun_attribute_t* stun_att;
|
||||
|
||||
// iWHr7ZwbQ1F4wmtk6scSEz0n (INVITE)
|
||||
// HAfDCVGhskSe63eww0F3Y (200: audio)
|
||||
// TN1KUcINJorcx8PISekSL (200: video)
|
||||
|
||||
message = tnet_stun_message_create("mI5gMSVZWlt6oZ7:wqQxm4bcpPM6cUTd", "HAfDCVGhskSe63eww0F3Y");
|
||||
message->type = stun_binding_request;
|
||||
// ICE-CONTROLLING
|
||||
if((stun_att = (tnet_stun_attribute_t*)tnet_stun_attribute_ice_controlling_create(11131939471334912422))){
|
||||
tnet_stun_message_add_attribute(message, &stun_att);
|
||||
}
|
||||
// USE-CANDIDATE
|
||||
if((stun_att = (tnet_stun_attribute_t*)tnet_stun_attribute_ice_use_candidate_create())){
|
||||
tnet_stun_message_add_attribute(message, &stun_att);
|
||||
}
|
||||
// PRIORITY
|
||||
if((stun_att = (tnet_stun_attribute_t*)tnet_stun_attribute_ice_priority_create(1845501695))){
|
||||
tnet_stun_message_add_attribute(message, &stun_att);
|
||||
}
|
||||
|
||||
if(!(buffer = tnet_stun_message_serialize(message))){
|
||||
goto bail;
|
||||
}
|
||||
|
||||
// Create blocking socket and bind it
|
||||
socket = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO);
|
||||
if(!TNET_SOCKET_IS_VALID(socket)){
|
||||
goto bail;
|
||||
}
|
||||
|
||||
// Create stun server's sockaddr structure
|
||||
if(tnet_sockaddr_init(STUN_SERVER_IP, STUN_SERVER_PORT, STUN_SERVER_PROTO, &to)){
|
||||
goto bail;
|
||||
}
|
||||
|
||||
tnet_sockfd_sendto(socket->fd, (struct sockaddr*)&to, buffer->data, buffer->size);
|
||||
|
||||
bail:
|
||||
TSK_OBJECT_SAFE_FREE(message);
|
||||
TSK_OBJECT_SAFE_FREE(socket);
|
||||
TSK_OBJECT_SAFE_FREE(buffer);
|
||||
}
|
||||
|
||||
void test_stun_context()
|
||||
{
|
||||
// tnet_socket_t *localSocket = 0;
|
||||
// tnet_stun_context_t *context = 0;
|
||||
//
|
||||
// /* Somewhere in Your application ==> Create and bind your local socket
|
||||
// */
|
||||
// if(!(localSocket = tnet_socket_create_EX(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO, 0)))
|
||||
// {
|
||||
// goto bail;
|
||||
// }
|
||||
//
|
||||
// /* Create your STUN2 context
|
||||
// */
|
||||
// if(!(context = TNET_STUN_CONTEXT_CREATE("myusername", "mypassword", localSocket->fd)))
|
||||
// {
|
||||
// goto bail;
|
||||
// }
|
||||
//
|
||||
// tnet_stun_resolve(context, STUN_SERVER_IP, STUN_SERVER_PORT, STUN_SERVER_PROTO);
|
||||
//
|
||||
//bail:
|
||||
// TNET_OBJECT_SAFE_FREE(localSocket);
|
||||
// TNET_OBJECT_SAFE_FREE(context);
|
||||
}
|
||||
|
||||
void test_stun()
|
||||
{
|
||||
//test_stun_transacid();
|
||||
test_sun_sendMessage();
|
||||
//test_stun_context();
|
||||
}
|
||||
|
||||
#endif /* TNET_TEST_STUN_H */
|
||||
(n_read_bytes);
|
||||
|
||||
BAIL_IF_ERR(tnet_stun_pkt_create_empty(tnet_stun_pkt_type_binding_request, &p_pkt));
|
||||
BAIL_IF_ERR(tnet_stun_utils_inet_pton_v4(__pc_mapped_addr_ipv4, &addr_ipv4));
|
||||
BAIL_IF_ERR(tnet_stun_utils_inet_pton_v6(__pc_mapped_addr_ipv6, &addr_ipv6));
|
||||
BAIL_IF_ERR(tnet_stun_pkt_add_attrs(p_pkt,
|
||||
TNET_STUN_PKT_ADD_ATTR_MAPPED_ADDRESS_V4(__u_mapped_addr_port, &addr_ipv4),
|
||||
TNET_STUN_PKT_ADD_ATTR_MAPPED_ADDRESS_V6(__u_mapped_addr_port, &addr_ipv6),
|
||||
TNET_STUN_PKT_ADD_ATTR_XOR_MAPPED_ADDRESS_V4(__u_mapped_addr_port, &addr_ipv4),
|
||||
TNET_STUN_PKT_ADD_ATTR_XOR_MAPPED_ADDRESS_V6(__u_mapped_addr_port, &addr_ipv6),
|
||||
TNET_STUN_PKT_ADD_ATTR_NULL()));
|
||||
BAIL_IF_ERR(tnet_stun_pkt_write_with_padding(p_pkt, __parse_buff_write_ptr, __parse_buff_write_size, &n_written_bytes));
|
||||
// TNET_TEST_STUN_SEND_BUFF(__parse_buff_write_ptr, n_written_bytes);
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(p_pkt);
|
||||
BAIL_IF_ERR(tnet_stun_pkt_read(__parse_buff_write_ptr, n_written_bytes, &p_pkt));
|
||||
BAIL_IF_ERR(tnet_stun_pkt_write_with_padding(p_pkt, __parse_buff_read_ptr, __parse_buff_read_size, &n_read_bytes));
|
||||
TNET_TEST_STUN_SEND_BUFF(__parse_buff_read_ptr, n_read_bytes);
|
||||
|
||||
BAIL_IF_ERR(test_stun_buff_cmp(__parse_buff_write_ptr, n_written_bytes, __parse_buff_read_ptr, n_read_bytes));
|
||||
TSK_DEBUG_INFO("test_sun_parser...OK");
|
||||
|
||||
bail:
|
||||
TSK_OBJECT_SAFE_FREE(p_pkt);
|
||||
|
||||
#if 0
|
||||
tnet_stun_message_t *message = tsk_null;
|
||||
tsk_buffer_t *buffer = tsk_null;
|
||||
tnet_socket_t *socket = tsk_null;
|
||||
struct sockaddr_storage to;
|
||||
tnet_stun_attribute_t* stun_att;
|
||||
|
||||
// iWHr7ZwbQ1F4wmtk6scSEz0n (INVITE)
|
||||
// HAfDCVGhskSe63eww0F3Y (200: audio)
|
||||
// TN1KUcINJorcx8PISekSL (200: video)
|
||||
|
||||
message = tnet_stun_message_create("mI5gMSVZWlt6oZ7:wqQxm4bcpPM6cUTd", "HAfDCVGhskSe63eww0F3Y");
|
||||
message->type = stun_binding_request;
|
||||
// ICE-CONTROLLING
|
||||
if((stun_att = (tnet_stun_attribute_t*)tnet_stun_attribute_ice_controlling_create(11131939471334912422))){
|
||||
tnet_stun_message_add_attribute(message, &stun_att);
|
||||
}
|
||||
// USE-CANDIDATE
|
||||
if((stun_att = (tnet_stun_attribute_t*)tnet_stun_attribute_ice_use_candidate_create())){
|
||||
tnet_stun_message_add_attribute(message, &stun_att);
|
||||
}
|
||||
// PRIORITY
|
||||
if((stun_att = (tnet_stun_attribute_t*)tnet_stun_attribute_ice_priority_create(1845501695))){
|
||||
tnet_stun_message_add_attribute(message, &stun_att);
|
||||
}
|
||||
|
||||
if(!(buffer = tnet_stun_message_serialize(message))){
|
||||
goto bail;
|
||||
}
|
||||
|
||||
// Create blocking socket and bind it
|
||||
socket = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, kStunServerProto);
|
||||
if(!TNET_SOCKET_IS_VALID(socket)){
|
||||
goto bail;
|
||||
}
|
||||
|
||||
// Create stun server's sockaddr structure
|
||||
if(tnet_sockaddr_init(kStunServerIP, kStunServerPort, kStunServerProto, &to)){
|
||||
goto bail;
|
||||
}
|
||||
|
||||
tnet_sockfd_sendto(socket->fd, (struct sockaddr*)&to, buffer->data, buffer->size);
|
||||
|
||||
bail:
|
||||
TSK_OBJECT_SAFE_FREE(message);
|
||||
TSK_OBJECT_SAFE_FREE(socket);
|
||||
TSK_OBJECT_SAFE_FREE(buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test_stun()
|
||||
{
|
||||
test_sun_parser();
|
||||
}
|
||||
|
||||
#endif /* TNET_TEST_STUN_H */
|
||||
|
|
|
@ -1,108 +1,105 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Mamadou Diop.
|
||||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#ifndef TNET_TEST_TLS_H
|
||||
#define TNET_TEST_TLS_H
|
||||
|
||||
#define TEST_TLS_REMOTE_IP "192.168.16.225"
|
||||
#define TEST_TLS_REMOTE_PORT 4061
|
||||
|
||||
#define TLS_TEST_SIP_MESSAGE \
|
||||
"REGISTER sip:micromethod.com SIP/2.0\r\n" \
|
||||
"Via: SIP/2.0/%s %s:%d;rport;branch=z9hG4bK1245420841406%d\r\n" \
|
||||
"From: <sip:mamadou@micromethod.com>;tag=29358\r\n" \
|
||||
"To: <sip:mamadou@micromethod.com>\r\n" \
|
||||
"Call-ID: M-fa53180346f7f55ceb8d8670f9223dbb\r\n" \
|
||||
"CSeq: 201 REGISTER\r\n" \
|
||||
"Max-Forwards: 70\r\n" \
|
||||
"Contact: <sip:mamadou@%s:%d;transport=%s>\r\n" \
|
||||
"Expires: 10\r\n" \
|
||||
"\r\n"
|
||||
|
||||
static int tnet_tls_cb(const tnet_transport_event_t* e)
|
||||
{
|
||||
switch(e->type){
|
||||
case event_data:
|
||||
{
|
||||
TSK_DEBUG_INFO("--- TLS ---\n%s\n", (const char*)e->data);
|
||||
break;
|
||||
}
|
||||
case event_closed:
|
||||
case event_connected:
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void test_tls()
|
||||
{
|
||||
tnet_transport_handle_t *transport = tnet_transport_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, tnet_socket_type_tls_ipv4, "TLS/IPV4 TRANSPORT");
|
||||
|
||||
tnet_ip_t ip;
|
||||
tnet_port_t port;
|
||||
tnet_fd_t fd = TNET_INVALID_FD;
|
||||
|
||||
if(tnet_transport_start(transport)){
|
||||
TSK_DEBUG_ERROR("Failed to create %s.", tnet_transport_get_description(transport));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set our callback function */
|
||||
tnet_transport_set_callback(transport, tnet_tls_cb, "callbackdata");
|
||||
|
||||
|
||||
|
||||
/* Connect to the SIP Registrar */
|
||||
if((fd = tnet_transport_connectto_2(transport, TEST_TLS_REMOTE_IP, TEST_TLS_REMOTE_PORT)) == TNET_INVALID_FD){
|
||||
TSK_DEBUG_ERROR("Failed to connect %s.", tnet_transport_get_description(transport));
|
||||
return;
|
||||
}
|
||||
|
||||
if(tnet_sockfd_waitUntilWritable(fd, TNET_CONNECT_TIMEOUT)){
|
||||
TSK_DEBUG_ERROR("%d milliseconds elapsed and the socket is still not connected.", TNET_CONNECT_TIMEOUT);
|
||||
tnet_transport_remove_socket(transport, &fd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send our SIP message */
|
||||
{
|
||||
char* message = 0;
|
||||
tnet_transport_get_ip_n_port(transport, fd, &ip, &port);
|
||||
tsk_sprintf(&message, TLS_TEST_SIP_MESSAGE, "TLS", ip, port, port, ip, port, "tls");
|
||||
|
||||
if(!tnet_transport_send(transport, fd, message, strlen(message)))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to send data using TCP/IPv4 transport.");
|
||||
TSK_FREE(message);
|
||||
return;
|
||||
}
|
||||
TSK_FREE(message);
|
||||
}
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(transport);
|
||||
}
|
||||
|
||||
#endif /* TNET_TEST_TLS_H */
|
||||
|
||||
*/
|
||||
#ifndef TNET_TEST_TLS_H
|
||||
#define TNET_TEST_TLS_H
|
||||
|
||||
#define TEST_TLS_REMOTE_IP "192.168.16.225"
|
||||
#define TEST_TLS_REMOTE_PORT 4061
|
||||
|
||||
#define TLS_TEST_SIP_MESSAGE \
|
||||
"REGISTER sip:micromethod.com SIP/2.0\r\n" \
|
||||
"Via: SIP/2.0/%s %s:%d;rport;branch=z9hG4bK1245420841406%d\r\n" \
|
||||
"From: <sip:mamadou@micromethod.com>;tag=29358\r\n" \
|
||||
"To: <sip:mamadou@micromethod.com>\r\n" \
|
||||
"Call-ID: M-fa53180346f7f55ceb8d8670f9223dbb\r\n" \
|
||||
"CSeq: 201 REGISTER\r\n" \
|
||||
"Max-Forwards: 70\r\n" \
|
||||
"Contact: <sip:mamadou@%s:%d;transport=%s>\r\n" \
|
||||
"Expires: 10\r\n" \
|
||||
"\r\n"
|
||||
|
||||
static int tnet_tls_cb(const tnet_transport_event_t* e)
|
||||
{
|
||||
switch(e->type){
|
||||
case event_data:
|
||||
{
|
||||
TSK_DEBUG_INFO("--- TLS ---\n%s\n", (const char*)e->data);
|
||||
break;
|
||||
}
|
||||
case event_closed:
|
||||
case event_connected:
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void test_tls()
|
||||
{
|
||||
tnet_transport_handle_t *transport = tnet_transport_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, tnet_socket_type_tls_ipv4, "TLS/IPV4 TRANSPORT");
|
||||
|
||||
tnet_ip_t ip;
|
||||
tnet_port_t port;
|
||||
tnet_fd_t fd = TNET_INVALID_FD;
|
||||
|
||||
if(tnet_transport_start(transport)){
|
||||
TSK_DEBUG_ERROR("Failed to create %s.", tnet_transport_get_description(transport));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set our callback function */
|
||||
tnet_transport_set_callback(transport, tnet_tls_cb, "callbackdata");
|
||||
|
||||
|
||||
|
||||
/* Connect to the SIP Registrar */
|
||||
if((fd = tnet_transport_connectto_2(transport, TEST_TLS_REMOTE_IP, TEST_TLS_REMOTE_PORT)) == TNET_INVALID_FD){
|
||||
TSK_DEBUG_ERROR("Failed to connect %s.", tnet_transport_get_description(transport));
|
||||
return;
|
||||
}
|
||||
|
||||
if(tnet_sockfd_waitUntilWritable(fd, TNET_CONNECT_TIMEOUT)){
|
||||
TSK_DEBUG_ERROR("%d milliseconds elapsed and the socket is still not connected.", TNET_CONNECT_TIMEOUT);
|
||||
tnet_transport_remove_socket(transport, &fd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send our SIP message */
|
||||
{
|
||||
char* message = 0;
|
||||
tnet_transport_get_ip_n_port(transport, fd, &ip, &port);
|
||||
tsk_sprintf(&message, TLS_TEST_SIP_MESSAGE, "TLS", ip, port, port, ip, port, "tls");
|
||||
|
||||
if(!tnet_transport_send(transport, fd, message, strlen(message)))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to send data using TCP/IPv4 transport.");
|
||||
TSK_FREE(message);
|
||||
return;
|
||||
}
|
||||
TSK_FREE(message);
|
||||
}
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(transport);
|
||||
}
|
||||
|
||||
#endif /* TNET_TEST_TLS_H */
|
||||
|
||||
|
|
|
@ -1,220 +1,217 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Mamadou Diop.
|
||||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* DOUBANGO is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#ifndef TNET_TEST_TRANSPORT_H
|
||||
#define TNET_TEST_TRANSPORT_H
|
||||
|
||||
//#define REMOTE_IP4 "proxy.sipthor.net"//"192.168.0.15"
|
||||
#define REMOTE_IP4 "192.168.0.13"
|
||||
#define REMOTE_IP6 "2a01:e35:8632:7050:6122:2706:2124:32cb"
|
||||
#define REMOTE_IP REMOTE_IP4
|
||||
#define REMOTE_PORT 5083
|
||||
|
||||
#if defined(ANDROID) /* FIXME */
|
||||
# define LOCAL_IP4 "10.0.2.15"
|
||||
#else
|
||||
# define LOCAL_IP4 TNET_SOCKET_HOST_ANY
|
||||
#endif
|
||||
#define LOCAL_IP6 TNET_SOCKET_HOST_ANY
|
||||
|
||||
#if defined(ANDROID)
|
||||
# define LOCAL_PORT 5060
|
||||
#else
|
||||
# define LOCAL_PORT TNET_SOCKET_PORT_ANY
|
||||
#endif
|
||||
|
||||
#define SIP_MESSAGE \
|
||||
"REGISTER sip:micromethod.com SIP/2.0\r\n" \
|
||||
"Via: SIP/2.0/%s %s:%d;rport;branch=z9hG4bK1245420841406%d\r\n" \
|
||||
"From: <sip:mamadou@micromethod.com>;tag=29358\r\n" \
|
||||
"To: <sip:mamadou@micromethod.com>\r\n" \
|
||||
"Call-ID: M-fa53180346f7f55ceb8d8670f9223dbb\r\n" \
|
||||
"CSeq: 201 REGISTER\r\n" \
|
||||
"Max-Forwards: 70\r\n" \
|
||||
"Contact: <sip:mamadou@%s:%d;transport=%s>\r\n" \
|
||||
"Expires: 10\r\n" \
|
||||
"\r\n"
|
||||
|
||||
|
||||
static int tnet_tcp_cb(const tnet_transport_event_t* e)
|
||||
{
|
||||
switch(e->type){
|
||||
case event_data:
|
||||
{
|
||||
TSK_DEBUG_INFO("--- TCP ---\n%s\n", (const char*)e->data);
|
||||
break;
|
||||
}
|
||||
case event_closed:
|
||||
case event_connected:
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tnet_udp_cb(const tnet_transport_event_t* e)
|
||||
{
|
||||
switch(e->type){
|
||||
case event_data:
|
||||
{
|
||||
TSK_DEBUG_INFO("--- UDP ---\n%s\n", (const char*)e->data);
|
||||
break;
|
||||
}
|
||||
case event_closed:
|
||||
case event_connected:
|
||||
default: break;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_transport_tcp_ipv4(tnet_transport_handle_t *transport)
|
||||
{
|
||||
//tnet_socket_type_t type = tnet_socket_type_tcp_ipv4;
|
||||
tnet_ip_t ip;
|
||||
tnet_port_t port;
|
||||
tnet_fd_t fd = TNET_INVALID_FD;
|
||||
|
||||
/* Set our callback function */
|
||||
tnet_transport_set_callback(transport, tnet_tcp_cb, "callbackdata");
|
||||
|
||||
if(tnet_transport_start(transport)){
|
||||
TSK_DEBUG_ERROR("Failed to create %s.", tnet_transport_get_description(transport));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Connect to the SIP Registrar */
|
||||
if((fd = tnet_transport_connectto_2(transport, REMOTE_IP, REMOTE_PORT)) == TNET_INVALID_FD){
|
||||
TSK_DEBUG_ERROR("Failed to connect %s.", tnet_transport_get_description(transport));
|
||||
return;
|
||||
}
|
||||
|
||||
if(tnet_sockfd_waitUntilWritable(fd, TNET_CONNECT_TIMEOUT)){
|
||||
TSK_DEBUG_ERROR("%d milliseconds elapsed and the socket is still not connected.", TNET_CONNECT_TIMEOUT);
|
||||
tnet_transport_remove_socket(transport, &fd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Send our SIP message */
|
||||
{
|
||||
char* message = 0;
|
||||
tnet_transport_get_ip_n_port(transport, fd, &ip, &port);
|
||||
tsk_sprintf(&message, SIP_MESSAGE, "TCP", ip, port, port, ip, port, "tcp");
|
||||
|
||||
if(!tnet_transport_send(transport, fd, message, strlen(message)))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to send data using %s.", tnet_transport_get_description(transport));
|
||||
TSK_FREE(message);
|
||||
return;
|
||||
}
|
||||
TSK_FREE(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int test_transport_udp_ipv4(tnet_transport_handle_t *transport)
|
||||
{
|
||||
//tnet_socket_type_t type = tnet_socket_type_udp_ipv4;
|
||||
tnet_ip_t ip;
|
||||
tnet_port_t port;
|
||||
tnet_fd_t fd = TNET_INVALID_FD;
|
||||
|
||||
/* Set our callback function */
|
||||
tnet_transport_set_callback(transport, tnet_udp_cb, "callbackdata");
|
||||
|
||||
if(tnet_transport_start(transport)){
|
||||
TSK_DEBUG_ERROR("Failed to create %s.", tnet_transport_get_description(transport));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Connect to our SIP REGISTRAR */
|
||||
if((fd = tnet_transport_connectto_2(transport, REMOTE_IP, REMOTE_PORT)) == TNET_INVALID_FD){
|
||||
TSK_DEBUG_ERROR("Failed to connect %s.", tnet_transport_get_description(transport));
|
||||
//tnet_transport_shutdown(transport);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if(tnet_sockfd_waitUntilWritable(fd, TNET_CONNECT_TIMEOUT)){
|
||||
TSK_DEBUG_ERROR("%d milliseconds elapsed and the socket is still not connected.", TNET_CONNECT_TIMEOUT);
|
||||
tnet_transport_remove_socket(transport, &fd);
|
||||
return -3;
|
||||
}
|
||||
|
||||
//tsk_thread_sleep(2000);
|
||||
|
||||
/* Send our SIP message */
|
||||
/*while(1)*/{
|
||||
char* message = 0;
|
||||
tnet_transport_get_ip_n_port(transport, fd, &ip, &port);
|
||||
//memset(ip, 0, sizeof(ip));
|
||||
//memcpy(ip, "192.168.0.12", 12);
|
||||
tsk_sprintf(&message, SIP_MESSAGE, "UDP", ip, port, port, ip, port, "udp");
|
||||
|
||||
if(!tnet_transport_send(transport, fd, message, strlen(message)))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to send data using %s.", tnet_transport_get_description(transport));
|
||||
//tnet_transport_shutdown(transport);
|
||||
TSK_FREE(message);
|
||||
return -4;
|
||||
}
|
||||
TSK_FREE(message);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_transport()
|
||||
{
|
||||
#define TEST_TCP 1
|
||||
#define TEST_UDP 0
|
||||
|
||||
|
||||
#if TEST_UDP
|
||||
tnet_transport_handle_t *udp = tnet_transport_create(LOCAL_IP4, LOCAL_PORT, tnet_socket_type_udp_ipv4, "UDP/IPV4 TRANSPORT");
|
||||
test_transport_udp_ipv4(udp);
|
||||
#endif
|
||||
|
||||
#if TEST_TCP
|
||||
tnet_transport_handle_t *tcp = tnet_transport_create(LOCAL_IP4, LOCAL_PORT, tnet_socket_type_tcp_ipv4, "TCP/IPV4 TRANSPORT");
|
||||
test_transport_tcp_ipv4(tcp);
|
||||
#endif
|
||||
|
||||
//#if defined(ANDROID)
|
||||
tsk_thread_sleep(1000000);
|
||||
//#else
|
||||
getchar();
|
||||
//#endif
|
||||
|
||||
#if TEST_UDP
|
||||
TSK_OBJECT_SAFE_FREE(udp);
|
||||
#endif
|
||||
|
||||
#if TEST_TCP
|
||||
TSK_OBJECT_SAFE_FREE(tcp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif /* TNET_TEST_TRANSPORT_H*/
|
||||
*/
|
||||
#ifndef TNET_TEST_TRANSPORT_H
|
||||
#define TNET_TEST_TRANSPORT_H
|
||||
|
||||
//#define REMOTE_IP4 "proxy.sipthor.net"//"192.168.0.15"
|
||||
#define REMOTE_IP4 "192.168.0.13"
|
||||
#define REMOTE_IP6 "2a01:e35:8632:7050:6122:2706:2124:32cb"
|
||||
#define REMOTE_IP REMOTE_IP4
|
||||
#define REMOTE_PORT 5083
|
||||
|
||||
#if defined(ANDROID) /* FIXME */
|
||||
# define LOCAL_IP4 "10.0.2.15"
|
||||
#else
|
||||
# define LOCAL_IP4 TNET_SOCKET_HOST_ANY
|
||||
#endif
|
||||
#define LOCAL_IP6 TNET_SOCKET_HOST_ANY
|
||||
|
||||
#if defined(ANDROID)
|
||||
# define LOCAL_PORT 5060
|
||||
#else
|
||||
# define LOCAL_PORT TNET_SOCKET_PORT_ANY
|
||||
#endif
|
||||
|
||||
#define SIP_MESSAGE \
|
||||
"REGISTER sip:micromethod.com SIP/2.0\r\n" \
|
||||
"Via: SIP/2.0/%s %s:%d;rport;branch=z9hG4bK1245420841406%d\r\n" \
|
||||
"From: <sip:mamadou@micromethod.com>;tag=29358\r\n" \
|
||||
"To: <sip:mamadou@micromethod.com>\r\n" \
|
||||
"Call-ID: M-fa53180346f7f55ceb8d8670f9223dbb\r\n" \
|
||||
"CSeq: 201 REGISTER\r\n" \
|
||||
"Max-Forwards: 70\r\n" \
|
||||
"Contact: <sip:mamadou@%s:%d;transport=%s>\r\n" \
|
||||
"Expires: 10\r\n" \
|
||||
"\r\n"
|
||||
|
||||
|
||||
static int tnet_tcp_cb(const tnet_transport_event_t* e)
|
||||
{
|
||||
switch(e->type){
|
||||
case event_data:
|
||||
{
|
||||
TSK_DEBUG_INFO("--- TCP ---\n%s\n", (const char*)e->data);
|
||||
break;
|
||||
}
|
||||
case event_closed:
|
||||
case event_connected:
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tnet_udp_cb(const tnet_transport_event_t* e)
|
||||
{
|
||||
switch(e->type){
|
||||
case event_data:
|
||||
{
|
||||
TSK_DEBUG_INFO("--- UDP ---\n%s\n", (const char*)e->data);
|
||||
break;
|
||||
}
|
||||
case event_closed:
|
||||
case event_connected:
|
||||
default: break;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_transport_tcp_ipv4(tnet_transport_handle_t *transport)
|
||||
{
|
||||
//tnet_socket_type_t type = tnet_socket_type_tcp_ipv4;
|
||||
tnet_ip_t ip;
|
||||
tnet_port_t port;
|
||||
tnet_fd_t fd = TNET_INVALID_FD;
|
||||
|
||||
/* Set our callback function */
|
||||
tnet_transport_set_callback(transport, tnet_tcp_cb, "callbackdata");
|
||||
|
||||
if(tnet_transport_start(transport)){
|
||||
TSK_DEBUG_ERROR("Failed to create %s.", tnet_transport_get_description(transport));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Connect to the SIP Registrar */
|
||||
if((fd = tnet_transport_connectto_2(transport, REMOTE_IP, REMOTE_PORT)) == TNET_INVALID_FD){
|
||||
TSK_DEBUG_ERROR("Failed to connect %s.", tnet_transport_get_description(transport));
|
||||
return;
|
||||
}
|
||||
|
||||
if(tnet_sockfd_waitUntilWritable(fd, TNET_CONNECT_TIMEOUT)){
|
||||
TSK_DEBUG_ERROR("%d milliseconds elapsed and the socket is still not connected.", TNET_CONNECT_TIMEOUT);
|
||||
tnet_transport_remove_socket(transport, &fd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Send our SIP message */
|
||||
{
|
||||
char* message = 0;
|
||||
tnet_transport_get_ip_n_port(transport, fd, &ip, &port);
|
||||
tsk_sprintf(&message, SIP_MESSAGE, "TCP", ip, port, port, ip, port, "tcp");
|
||||
|
||||
if(!tnet_transport_send(transport, fd, message, strlen(message)))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to send data using %s.", tnet_transport_get_description(transport));
|
||||
TSK_FREE(message);
|
||||
return;
|
||||
}
|
||||
TSK_FREE(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int test_transport_udp_ipv4(tnet_transport_handle_t *transport)
|
||||
{
|
||||
//tnet_socket_type_t type = tnet_socket_type_udp_ipv4;
|
||||
tnet_ip_t ip;
|
||||
tnet_port_t port;
|
||||
tnet_fd_t fd = TNET_INVALID_FD;
|
||||
|
||||
/* Set our callback function */
|
||||
tnet_transport_set_callback(transport, tnet_udp_cb, "callbackdata");
|
||||
|
||||
if(tnet_transport_start(transport)){
|
||||
TSK_DEBUG_ERROR("Failed to create %s.", tnet_transport_get_description(transport));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Connect to our SIP REGISTRAR */
|
||||
if((fd = tnet_transport_connectto_2(transport, REMOTE_IP, REMOTE_PORT)) == TNET_INVALID_FD){
|
||||
TSK_DEBUG_ERROR("Failed to connect %s.", tnet_transport_get_description(transport));
|
||||
//tnet_transport_shutdown(transport);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if(tnet_sockfd_waitUntilWritable(fd, TNET_CONNECT_TIMEOUT)){
|
||||
TSK_DEBUG_ERROR("%d milliseconds elapsed and the socket is still not connected.", TNET_CONNECT_TIMEOUT);
|
||||
tnet_transport_remove_socket(transport, &fd);
|
||||
return -3;
|
||||
}
|
||||
|
||||
//tsk_thread_sleep(2000);
|
||||
|
||||
/* Send our SIP message */
|
||||
/*while(1)*/{
|
||||
char* message = 0;
|
||||
tnet_transport_get_ip_n_port(transport, fd, &ip, &port);
|
||||
//memset(ip, 0, sizeof(ip));
|
||||
//memcpy(ip, "192.168.0.12", 12);
|
||||
tsk_sprintf(&message, SIP_MESSAGE, "UDP", ip, port, port, ip, port, "udp");
|
||||
|
||||
if(!tnet_transport_send(transport, fd, message, strlen(message)))
|
||||
{
|
||||
TSK_DEBUG_ERROR("Failed to send data using %s.", tnet_transport_get_description(transport));
|
||||
//tnet_transport_shutdown(transport);
|
||||
TSK_FREE(message);
|
||||
return -4;
|
||||
}
|
||||
TSK_FREE(message);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_transport()
|
||||
{
|
||||
#define TEST_TCP 1
|
||||
#define TEST_UDP 0
|
||||
|
||||
|
||||
#if TEST_UDP
|
||||
tnet_transport_handle_t *udp = tnet_transport_create(LOCAL_IP4, LOCAL_PORT, tnet_socket_type_udp_ipv4, "UDP/IPV4 TRANSPORT");
|
||||
test_transport_udp_ipv4(udp);
|
||||
#endif
|
||||
|
||||
#if TEST_TCP
|
||||
tnet_transport_handle_t *tcp = tnet_transport_create(LOCAL_IP4, LOCAL_PORT, tnet_socket_type_tcp_ipv4, "TCP/IPV4 TRANSPORT");
|
||||
test_transport_tcp_ipv4(tcp);
|
||||
#endif
|
||||
|
||||
//#if defined(ANDROID)
|
||||
tsk_thread_sleep(1000000);
|
||||
//#else
|
||||
getchar();
|
||||
//#endif
|
||||
|
||||
#if TEST_UDP
|
||||
TSK_OBJECT_SAFE_FREE(udp);
|
||||
#endif
|
||||
|
||||
#if TEST_TCP
|
||||
TSK_OBJECT_SAFE_FREE(tcp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif /* TNET_TEST_TRANSPORT_H*/
|
||||
|
|
|
@ -228,6 +228,10 @@
|
|||
RelativePath=".\src\stun\tnet_stun.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\stun\tnet_stun_attr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\stun\tnet_stun_attribute.c"
|
||||
>
|
||||
|
@ -236,6 +240,14 @@
|
|||
RelativePath=".\src\stun\tnet_stun_message.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\stun\tnet_stun_pkt.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\stun\tnet_stun_utils.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="turn"
|
||||
|
@ -460,6 +472,10 @@
|
|||
RelativePath=".\src\stun\tnet_stun.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\stun\tnet_stun_attr.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\stun\tnet_stun_attribute.h"
|
||||
>
|
||||
|
@ -468,6 +484,18 @@
|
|||
RelativePath=".\src\stun\tnet_stun_message.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\stun\tnet_stun_pkt.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\stun\tnet_stun_types.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\stun\tnet_stun_utils.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="turn"
|
||||
|
|
Loading…
Reference in New Issue