diff options
author | Mamadou DIOP <bossiel@yahoo.fr> | 2016-02-23 22:00:35 +0100 |
---|---|---|
committer | Mamadou DIOP <bossiel@yahoo.fr> | 2016-02-23 22:00:35 +0100 |
commit | 50dfb4359619563012997bc3ddafb7667741066c (patch) | |
tree | db234c1edc3240a653363b5735fc4077af4b8720 /tinyNET/src/tnet_nat.c | |
parent | 94b2219209038e05dd26395f6fb700be4d1062c0 (diff) | |
download | doubango-50dfb4359619563012997bc3ddafb7667741066c.zip doubango-50dfb4359619563012997bc3ddafb7667741066c.tar.gz |
Add new QoS implementation
Code formatting
Diffstat (limited to 'tinyNET/src/tnet_nat.c')
-rwxr-xr-x | tinyNET/src/tnet_nat.c | 380 |
1 files changed, 189 insertions, 191 deletions
diff --git a/tinyNET/src/tnet_nat.c b/tinyNET/src/tnet_nat.c index 53a009a..7e536c1 100755 --- a/tinyNET/src/tnet_nat.c +++ b/tinyNET/src/tnet_nat.c @@ -7,12 +7,12 @@ * 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. * @@ -40,24 +40,23 @@ /**@defgroup tnet_nat_group NAT Traversal API (STUN, TURN and ICE). */ -typedef struct tnet_nat_ctx_s -{ - TSK_DECLARE_OBJECT; +typedef struct tnet_nat_ctx_s { + TSK_DECLARE_OBJECT; - tnet_socket_type_t socket_type; + tnet_socket_type_t socket_type; - char* username; /**< The username to use to authenticate against the TURN/STUN server. */ - char* password; /**< The password to use to authenticate against the TURN/STUN server. */ + char* username; /**< The username to use to authenticate against the TURN/STUN server. */ + char* password; /**< The password to use to authenticate against the TURN/STUN server. */ - char* server_address; /**< TURN/STUN server address (could be FQDN or IP) */ - tnet_port_t server_port; /**< TURN/STUN server port. */ + char* server_address; /**< TURN/STUN server address (could be FQDN or IP) */ + tnet_port_t server_port; /**< TURN/STUN server port. */ - uint16_t RTO; /**< Estimate of the round-trip time (RTT) in millisecond. */ - uint16_t Rc; /**< Number of retransmissions for UDP in millisecond. */ + uint16_t RTO; /**< Estimate of the round-trip time (RTT) in millisecond. */ + uint16_t Rc; /**< Number of retransmissions for UDP in millisecond. */ - unsigned use_dnsquery:1; /**< Indicates whether to use DNS SRV query to find the stun/turn ip address. */ - - tnet_stun_bindings_L_t *stun_bindings; /**< List of all STUN2 bindings associated to this context. */ + unsigned use_dnsquery:1; /**< Indicates whether to use DNS SRV query to find the stun/turn ip address. */ + + tnet_stun_bindings_L_t *stun_bindings; /**< List of all STUN2 bindings associated to this context. */ } tnet_nat_ctx_t; @@ -67,88 +66,88 @@ tnet_nat_ctx_t; */ struct tnet_nat_ctx_s* tnet_nat_context_create(tnet_socket_type_t socket_type, const char* pc_username, const char* pc_password) { - extern const tsk_object_def_t *tnet_nat_context_def_t; - struct tnet_nat_ctx_s* p_ctx; - - if (!(p_ctx = tsk_object_new(tnet_nat_context_def_t)) || !(p_ctx->stun_bindings = tsk_list_create())) { - TSK_OBJECT_SAFE_FREE(p_ctx); - TSK_DEBUG_ERROR("Failed to create NAT context"); - return tsk_null; - } - - p_ctx->socket_type = socket_type; - p_ctx->username = tsk_strdup(pc_username); - p_ctx->password = tsk_strdup(pc_password); - p_ctx->server_port = kStunPortDefaultTcpUdp; - /* 7.2.1. Sending over UDP - In fixed-line access links, a value of 500 ms is RECOMMENDED. - */ - p_ctx->RTO = kStunRTO; - /* 7.2.1. Sending over UDP - Rc SHOULD be configurable and SHOULD have a default of 7. - */ - p_ctx->Rc = kStunRC; - - return p_ctx; + extern const tsk_object_def_t *tnet_nat_context_def_t; + struct tnet_nat_ctx_s* p_ctx; + + if (!(p_ctx = tsk_object_new(tnet_nat_context_def_t)) || !(p_ctx->stun_bindings = tsk_list_create())) { + TSK_OBJECT_SAFE_FREE(p_ctx); + TSK_DEBUG_ERROR("Failed to create NAT context"); + return tsk_null; + } + + p_ctx->socket_type = socket_type; + p_ctx->username = tsk_strdup(pc_username); + p_ctx->password = tsk_strdup(pc_password); + p_ctx->server_port = kStunPortDefaultTcpUdp; + /* 7.2.1. Sending over UDP + In fixed-line access links, a value of 500 ms is RECOMMENDED. + */ + p_ctx->RTO = kStunRTO; + /* 7.2.1. Sending over UDP + Rc SHOULD be configurable and SHOULD have a default of 7. + */ + p_ctx->Rc = kStunRC; + + return p_ctx; } -/** Predicate function to find stun binding by id. +/** Predicate function to find stun binding by id. * - * @param [in,out] item The current list item. - * @param [in,out] id A pointer to the binding identifier. + * @param [in,out] item The current list item. + * @param [in,out] id A pointer to the binding identifier. * - * @return Zero if current list item hold a binding with the same id and -1 otherwise. + * @return Zero if current list item hold a binding with the same id and -1 otherwise. **/ int __pred_find_stun_binding(const tsk_list_item_t* item, const void* id) { - if(item) { - tnet_stun_binding_t *p_bind = item->data; - if (p_bind) { - tnet_stun_binding_id_t binding_id = *((tnet_stun_binding_id_t*)id); - return (p_bind->id == binding_id) ? 0 : -1; - } - } - return -1; + if(item) { + tnet_stun_binding_t *p_bind = item->data; + if (p_bind) { + tnet_stun_binding_id_t binding_id = *((tnet_stun_binding_id_t*)id); + return (p_bind->id == binding_id) ? 0 : -1; + } + } + return -1; } /**@ingroup tnet_nat_group * * Sets the address of the STUN/TURN server. * - * @param [in,out] p_self The NAT context. - * @param [in,out] pc_server_address The address of server. + * @param [in,out] p_self The NAT context. + * @param [in,out] pc_server_address The address of server. * - * @return Zero if succeed and non zero error code otherwise. + * @return Zero if succeed and non zero error code otherwise. **/ int tnet_nat_set_server_address(struct tnet_nat_ctx_s* p_self, const char* pc_server_address) { - if (!p_self) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - tsk_strupdate(&(p_self->server_address), pc_server_address); - return 0; + if (!p_self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + tsk_strupdate(&(p_self->server_address), pc_server_address); + return 0; } /**@ingroup tnet_nat_group * * Sets the address and port of the STUN/TURN server. * - * @param [in,out] p_self The NAT context. - * @param [in,out] pc_server_address The address of server. - * @param u_server_port The server port. + * @param [in,out] p_self The NAT context. + * @param [in,out] pc_server_address The address of server. + * @param u_server_port The server port. * - * @return Zero if succeed and non zero error code otherwise. + * @return Zero if succeed and non zero error code otherwise. **/ int tnet_nat_set_server(struct tnet_nat_ctx_s* p_self, const char* pc_server_address, tnet_port_t u_server_port) { - if (!p_self) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - tsk_strupdate(&(p_self->server_address), pc_server_address); - p_self->server_port = u_server_port; - return 0; + if (!p_self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + tsk_strupdate(&(p_self->server_address), pc_server_address); + p_self->server_port = u_server_port; + return 0; } /**@ingroup tnet_nat_group @@ -156,7 +155,7 @@ int tnet_nat_set_server(struct tnet_nat_ctx_s* p_self, const char* pc_server_add * Creates and sends a STUN2 binding request to the STUN/TURN server in order to get the server reflexive * address associated to this file descriptor (or socket). The caller should call @ref tnet_nat_stun_unbind to destroy the binding. * - * @param [in,out] p_self The NAT context. + * @param [in,out] p_self The NAT context. * @param localFD The local file descriptor (or socket) for which to get the reflexive server address. * * @return A valid binding id if succeed and @ref kStunBindingInvalidId otherwise. If the returned id is valid then @@ -166,13 +165,13 @@ int tnet_nat_set_server(struct tnet_nat_ctx_s* p_self, const char* pc_server_add **/ tnet_stun_binding_id_t tnet_nat_stun_bind(const struct tnet_nat_ctx_s* p_self, const tnet_fd_t localFD) { - tnet_stun_binding_id_t id = kStunBindingInvalidId; - tnet_stun_binding_t *p_binding = tsk_null; - int ret; - if (!p_self || localFD == TNET_INVALID_FD) { - TSK_DEBUG_ERROR("Invalid parameter"); - goto bail; - } + tnet_stun_binding_id_t id = kStunBindingInvalidId; + tnet_stun_binding_t *p_binding = tsk_null; + int ret; + if (!p_self || localFD == TNET_INVALID_FD) { + TSK_DEBUG_ERROR("Invalid parameter"); + goto bail; + } if ((ret = tnet_stun_binding_create(localFD, p_self->socket_type, p_self->server_address, p_self->server_port, p_self->username, p_self->password, &p_binding))) { goto bail; } @@ -183,7 +182,7 @@ tnet_stun_binding_id_t tnet_nat_stun_bind(const struct tnet_nat_ctx_s* p_self, c tsk_list_push_back_data(p_self->stun_bindings, (void**)&p_binding); bail: - TSK_OBJECT_SAFE_FREE(p_binding); + TSK_OBJECT_SAFE_FREE(p_binding); return id; } @@ -198,19 +197,19 @@ bail: **/ int tnet_nat_stun_send_bind(const struct tnet_nat_ctx_s* pc_self, struct tnet_stun_binding_s *p_binding) { - int ret = -1; + int ret = -1; tnet_stun_pkt_resp_t *p_pkt_resp = tsk_null; tnet_stun_pkt_req_t *p_pkt_req = tsk_null; - if (!pc_self || !p_binding) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if (!pc_self || !p_binding) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } - if (!TNET_SOCKET_TYPE_IS_DGRAM(p_binding->socket_type)) { - TSK_DEBUG_ERROR("Only DGRAM could be used for STUN transport"); - return -2; - } + if (!TNET_SOCKET_TYPE_IS_DGRAM(p_binding->socket_type)) { + TSK_DEBUG_ERROR("Only DGRAM could be used for STUN transport"); + return -2; + } if ((ret = tnet_stun_binding_create_req(p_binding, &p_pkt_req))) { goto bail; @@ -225,51 +224,51 @@ int tnet_nat_stun_send_bind(const struct tnet_nat_ctx_s* pc_self, struct tnet_st authentication or message integrity applied. */ stun_phase0: { - if ((ret = tnet_stun_utils_send_unreliably(p_binding->localFD, pc_self->RTO, pc_self->Rc, p_pkt_req, (struct sockaddr*)&p_binding->addr_server, &p_pkt_resp))) { - goto bail; - } + if ((ret = tnet_stun_utils_send_unreliably(p_binding->localFD, pc_self->RTO, pc_self->Rc, p_pkt_req, (struct sockaddr*)&p_binding->addr_server, &p_pkt_resp))) { + goto bail; + } if (p_pkt_resp) { if (TNET_STUN_PKT_RESP_IS_ERROR(p_pkt_resp)) { - uint16_t u_code; - if ((ret = tnet_stun_pkt_get_errorcode(p_pkt_resp, &u_code))) { - goto bail; - } - if (u_code == kStunErrCodeUnauthorized || u_code == kStunErrCodeStaleNonce) { - if (u_code == kStunErrCodeUnauthorized) { - // Make sure this is not an authentication failure (#2 401) - // Do not send another req to avoid endless messages - if ((tnet_stun_pkt_attr_exists(p_pkt_req, tnet_stun_attr_type_message_integrity))) { // already has a MESSAGE-INTEGRITY? - TSK_DEBUG_ERROR("STUN authentication failed"); - goto bail; - } - } - if ((ret = tnet_stun_pkt_auth_prepare_2(p_pkt_req, p_binding->p_username, p_binding->p_password, p_pkt_resp))) { - goto bail; - } - // Try to send again now that authinfo is up2date - goto stun_phase0; - } - else if (u_code == kStunErrCodeUnknownAttributes) { - if((ret = tnet_stun_pkt_process_err420(p_pkt_req, p_pkt_resp))) { - goto bail; - } - // Try to send again now that authinfo is up2date - goto stun_phase0; - } - ret = -3; + uint16_t u_code; + if ((ret = tnet_stun_pkt_get_errorcode(p_pkt_resp, &u_code))) { + goto bail; + } + if (u_code == kStunErrCodeUnauthorized || u_code == kStunErrCodeStaleNonce) { + if (u_code == kStunErrCodeUnauthorized) { + // Make sure this is not an authentication failure (#2 401) + // Do not send another req to avoid endless messages + if ((tnet_stun_pkt_attr_exists(p_pkt_req, tnet_stun_attr_type_message_integrity))) { // already has a MESSAGE-INTEGRITY? + TSK_DEBUG_ERROR("STUN authentication failed"); + goto bail; + } + } + if ((ret = tnet_stun_pkt_auth_prepare_2(p_pkt_req, p_binding->p_username, p_binding->p_password, p_pkt_resp))) { + goto bail; + } + // Try to send again now that authinfo is up2date + goto stun_phase0; + } + else if (u_code == kStunErrCodeUnknownAttributes) { + if((ret = tnet_stun_pkt_process_err420(p_pkt_req, p_pkt_resp))) { + goto bail; + } + // Try to send again now that authinfo is up2date + goto stun_phase0; + } + ret = -3; } else { - const tnet_stun_attr_address_t* pc_addr; - if ((ret = tnet_stun_pkt_attr_find_first(p_pkt_resp, tnet_stun_attr_type_xor_mapped_address, (const tnet_stun_attr_t**)&pc_addr)) == 0 && pc_addr) { - TSK_OBJECT_SAFE_FREE(p_binding->p_xmaddr); - p_binding->p_xmaddr = tsk_object_ref(TSK_OBJECT(pc_addr)); - } - if ((ret = tnet_stun_pkt_attr_find_first(p_pkt_resp, tnet_stun_attr_type_mapped_address, (const tnet_stun_attr_t**)&pc_addr)) == 0 && pc_addr) { - TSK_OBJECT_SAFE_FREE(p_binding->p_maddr); - p_binding->p_maddr = tsk_object_ref(TSK_OBJECT(pc_addr)); - } - } + const tnet_stun_attr_address_t* pc_addr; + if ((ret = tnet_stun_pkt_attr_find_first(p_pkt_resp, tnet_stun_attr_type_xor_mapped_address, (const tnet_stun_attr_t**)&pc_addr)) == 0 && pc_addr) { + TSK_OBJECT_SAFE_FREE(p_binding->p_xmaddr); + p_binding->p_xmaddr = tsk_object_ref(TSK_OBJECT(pc_addr)); + } + if ((ret = tnet_stun_pkt_attr_find_first(p_pkt_resp, tnet_stun_attr_type_mapped_address, (const tnet_stun_attr_t**)&pc_addr)) == 0 && pc_addr) { + TSK_OBJECT_SAFE_FREE(p_binding->p_maddr); + p_binding->p_maddr = tsk_object_ref(TSK_OBJECT(pc_addr)); + } + } } } /* END OF stun_phase0 */ @@ -285,51 +284,51 @@ bail: * Gets the server reflexive address associated to this STUN2 binding. * * - * @param [in,out] p_self The NAT context. - * @param id The id of the STUN2 binding conetxt (obtained using @ref tnet_nat_stun_bind) holding the server-reflexive address. - * @param [in,out] pp_ip The reflexive IP address. It is up the the caller to free the returned string - * @param [in,out] pu_port The reflexive port. + * @param [in,out] p_self The NAT context. + * @param id The id of the STUN2 binding conetxt (obtained using @ref tnet_nat_stun_bind) holding the server-reflexive address. + * @param [in,out] pp_ip The reflexive IP address. It is up the the caller to free the returned string + * @param [in,out] pu_port The reflexive port. * - * @return Zero if succeed and non zero error code otherwise. + * @return Zero if succeed and non zero error code otherwise. **/ int tnet_nat_stun_get_reflexive_address(const struct tnet_nat_ctx_s* p_self, tnet_stun_binding_id_t id, char** pp_ip, tnet_port_t *pu_port) { - const tsk_list_item_t* item; - if (!p_self) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if (!pp_ip && !pu_port) { - return 0; - } - - if ((item = tsk_list_find_item_by_pred(p_self->stun_bindings, __pred_find_stun_binding, &id)) && item->data) { - const tnet_stun_binding_t *pc_bind = (const tnet_stun_binding_t *)item->data; - const struct tnet_stun_attr_address_s *pc_addr = pc_bind->p_xmaddr ? pc_bind->p_xmaddr : pc_bind->p_maddr; - if (pc_addr) { - tnet_ip_t ip; - int ret; - if ((ret = tnet_stun_utils_inet_ntop((pc_addr->e_family == tnet_stun_address_family_ipv6), &pc_addr->address, &ip))) { - return ret; - } - if (pp_ip) { - tsk_strupdate(pp_ip, ip); - } - if (pu_port) { - *pu_port = pc_addr->u_port; - } - return 0; - } - } - return -2; + const tsk_list_item_t* item; + if (!p_self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if (!pp_ip && !pu_port) { + return 0; + } + + if ((item = tsk_list_find_item_by_pred(p_self->stun_bindings, __pred_find_stun_binding, &id)) && item->data) { + const tnet_stun_binding_t *pc_bind = (const tnet_stun_binding_t *)item->data; + const struct tnet_stun_attr_address_s *pc_addr = pc_bind->p_xmaddr ? pc_bind->p_xmaddr : pc_bind->p_maddr; + if (pc_addr) { + tnet_ip_t ip; + int ret; + if ((ret = tnet_stun_utils_inet_ntop((pc_addr->e_family == tnet_stun_address_family_ipv6), &pc_addr->address, &ip))) { + return ret; + } + if (pp_ip) { + tsk_strupdate(pp_ip, ip); + } + if (pu_port) { + *pu_port = pc_addr->u_port; + } + return 0; + } + } + return -2; } /**@ingroup tnet_nat_group * * Removes a STUN2 binding from the NAT context. * - * @param [in,out] p_self The NAT context from which to remove the STUN2 binding. - * @param id The id of the STUN2 binding to remove. + * @param [in,out] p_self The NAT context from which to remove the STUN2 binding. + * @param id The id of the STUN2 binding to remove. * * @return Zero if succeed and non zero error code otherwise. * @@ -338,12 +337,12 @@ int tnet_nat_stun_get_reflexive_address(const struct tnet_nat_ctx_s* p_self, tne **/ int tnet_nat_stun_unbind(const struct tnet_nat_ctx_s* p_self, tnet_stun_binding_id_t id) { - if (!p_self) { - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - tsk_list_remove_item_by_pred(p_self->stun_bindings, __pred_find_stun_binding, &id); - return 0; + if (!p_self) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + tsk_list_remove_item_by_pred(p_self->stun_bindings, __pred_find_stun_binding, &id); + return 0; } @@ -352,30 +351,29 @@ int tnet_nat_stun_unbind(const struct tnet_nat_ctx_s* p_self, tnet_stun_binding_ // static tsk_object_t* tnet_nat_context_ctor(tsk_object_t * self, va_list * app) { - tnet_nat_ctx_t *p_ctx = (tnet_nat_ctx_t*)self; - if (p_ctx) { - } - return self; + tnet_nat_ctx_t *p_ctx = (tnet_nat_ctx_t*)self; + if (p_ctx) { + } + return self; } static tsk_object_t* tnet_nat_context_dtor(tsk_object_t * self) -{ - tnet_nat_ctx_t *p_ctx = (tnet_nat_ctx_t*)self; - if (p_ctx) { - TSK_FREE(p_ctx->username); - TSK_FREE(p_ctx->password); - TSK_FREE(p_ctx->server_address); - - TSK_OBJECT_SAFE_FREE(p_ctx->stun_bindings); - TSK_DEBUG_INFO("*** NAT context destroyed ***"); - } - - return self; -} -static const tsk_object_def_t tnet_nat_context_def_s = { - sizeof(tnet_nat_ctx_t), - tnet_nat_context_ctor, - tnet_nat_context_dtor, - tsk_null, + tnet_nat_ctx_t *p_ctx = (tnet_nat_ctx_t*)self; + if (p_ctx) { + TSK_FREE(p_ctx->username); + TSK_FREE(p_ctx->password); + TSK_FREE(p_ctx->server_address); + + TSK_OBJECT_SAFE_FREE(p_ctx->stun_bindings); + TSK_DEBUG_INFO("*** NAT context destroyed ***"); + } + + return self; +} +static const tsk_object_def_t tnet_nat_context_def_s = { + sizeof(tnet_nat_ctx_t), + tnet_nat_context_ctor, + tnet_nat_context_dtor, + tsk_null, }; const tsk_object_def_t *tnet_nat_context_def_t = &tnet_nat_context_def_s; |