summaryrefslogtreecommitdiffstats
path: root/tinyNET/src/ice/tnet_ice_pair.c
diff options
context:
space:
mode:
Diffstat (limited to 'tinyNET/src/ice/tnet_ice_pair.c')
-rwxr-xr-xtinyNET/src/ice/tnet_ice_pair.c1136
1 files changed, 573 insertions, 563 deletions
diff --git a/tinyNET/src/ice/tnet_ice_pair.c b/tinyNET/src/ice/tnet_ice_pair.c
index 33e71a5..f917ea2 100755
--- a/tinyNET/src/ice/tnet_ice_pair.c
+++ b/tinyNET/src/ice/tnet_ice_pair.c
@@ -58,7 +58,7 @@
static int __pred_find_by_pair(const tsk_list_item_t *item, const void *pair)
{
- if(item && item->data){
+ if(item && item->data) {
int ret;
tsk_subsat_int32_ptr(item->data, pair, &ret);
return ret;
@@ -70,7 +70,7 @@ static int __pred_find_by_pair(const tsk_list_item_t *item, const void *pair)
static tsk_object_t* tnet_ice_pair_ctor(tsk_object_t * self, va_list * app)
{
tnet_ice_pair_t *pair = self;
- if(pair){
+ if(pair) {
pair->state_offer = tnet_ice_pair_state_frozen;
pair->state_answer = tnet_ice_pair_state_frozen;
}
@@ -90,7 +90,7 @@ static int tnet_ice_pair_cmp(const tsk_object_t *_p1, const tsk_object_t *_p2)
{
const tnet_ice_pair_t *p1 = _p1;
const tnet_ice_pair_t *p2 = _p2;
-
+
if (p1 && p2) {
#if 0
// This is not correct and most differences (if not all) will be equal to "INT_MIN" or "INT_MAX" and this will produce invalid sorting.
@@ -102,11 +102,14 @@ static int tnet_ice_pair_cmp(const tsk_object_t *_p1, const tsk_object_t *_p2)
return (p1->priority == p2->priority) ? 0 : (p1->priority > p2->priority ? 1 : -1);
#endif
}
- else if (!p1 && !p2) return 0;
- else return -1;
+ else if (!p1 && !p2) {
+ return 0;
+ }
+ else {
+ return -1;
+ }
}
-static const tsk_object_def_t tnet_ice_pair_def_s =
-{
+static const tsk_object_def_t tnet_ice_pair_def_s = {
sizeof(tnet_ice_pair_t),
tnet_ice_pair_ctor,
tnet_ice_pair_dtor,
@@ -117,11 +120,11 @@ tnet_ice_pair_t* tnet_ice_pair_create(const tnet_ice_candidate_t* candidate_offe
{
static uint64_t __unique_id = 0;
tnet_ice_pair_t *pair;
- if(!candidate_offer || !candidate_answer){
+ if(!candidate_offer || !candidate_answer) {
TSK_DEBUG_ERROR("Invalid parameter");
return tsk_null;
}
-
+
if ((pair = tsk_object_new(&tnet_ice_pair_def_s))) {
uint64_t G, D;
pair->id = ++__unique_id; // not part of the standard, used to ease debugging
@@ -136,7 +139,7 @@ tnet_ice_pair_t* tnet_ice_pair_create(const tnet_ice_candidate_t* candidate_offe
pair->priority = ((TSK_MIN(G, D)) << 32) + (TSK_MAX(G, D) << 1) + ((G > D) ? 1 : 0);
pair->turn_peer_id = kTurnPeerIdInvalid;
}
-
+
return pair;
}
@@ -148,12 +151,12 @@ tnet_ice_pair_t* tnet_ice_pair_prflx_create(tnet_ice_pairs_L_t* pairs, tnet_fd_t
const tnet_ice_pair_t *pair_local = tsk_null, *pair = tsk_null;
tnet_ip_t remote_ip;
tnet_port_t remote_port;
-
+
if (!pairs || !remote_addr) {
TSK_DEBUG_ERROR("Invalid parameter");
return tsk_null;
}
-
+
tsk_list_foreach(item, pairs) {
if (!(pair = item->data) || !pair->candidate_offer || !pair->candidate_answer || !pair->candidate_offer->socket || pair->candidate_offer->socket->fd != local_fd) {
continue;
@@ -161,12 +164,12 @@ tnet_ice_pair_t* tnet_ice_pair_prflx_create(tnet_ice_pairs_L_t* pairs, tnet_fd_t
pair_local = pair;
break;
}
-
+
if ((ret = tnet_get_sockip_n_port((const struct sockaddr*)remote_addr, &remote_ip, &remote_port))) {
TNET_PRINT_LAST_ERROR("tnet_get_sockip_n_port() failed");
return tsk_null;
}
-
+
if (!pair_local) {
TSK_DEBUG_ERROR("Cannot create prflx candidate with remote ip = %s, remote port = %u and local_fd = %d", remote_ip, remote_port, local_fd);
return tsk_null;
@@ -182,42 +185,42 @@ tnet_ice_pair_t* tnet_ice_pair_prflx_create(tnet_ice_pairs_L_t* pairs, tnet_fd_t
cand_remote->comp_id = pair_local->candidate_offer->comp_id;
memcpy(cand_remote->connection_addr, remote_ip, sizeof(tnet_ip_t));
cand_remote->port = remote_port;
-
+
TSK_DEBUG_INFO("ICE Pair Reflexive Candidate (%llu, %llu): [%s %u %u %s %d] -> [%s %u %u %s %d]",
pair->id,
pair->priority,
-
+
cand_local->foundation,
cand_local->priority,
cand_local->comp_id,
cand_local->connection_addr,
cand_local->port,
-
+
cand_remote->foundation,
cand_remote->priority,
cand_remote->comp_id,
cand_remote->connection_addr,
cand_remote->port);
-
+
pair_peer = tnet_ice_pair_create(cand_local, cand_remote, pair_local->is_controlling, pair_local->tie_breaker, pair_local->is_ice_jingle);
}
TSK_OBJECT_SAFE_FREE(cand_local);
TSK_OBJECT_SAFE_FREE(cand_remote);
return pair_peer;
}
-
+
return tsk_null;
}
int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
{
int ret;
-
- if(!self){
+
+ if(!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
if (self->candidate_offer->turn.ss) {
enum tnet_stun_state_e e_state;
enum tnet_turn_transport_e e_req_transport;
@@ -228,7 +231,7 @@ int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
TSK_DEBUG_INFO("TURN CreatePerm not ready yet... to send STUN ConnCheck (peer-id=%ld)", self->turn_peer_id);
goto bail;
}
-
+
if ((ret = tnet_turn_session_get_req_transport(self->candidate_offer->turn.ss, &e_req_transport))) {
goto bail;
}
@@ -244,16 +247,16 @@ int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
}
}
}
-
+
if (!self->last_request) {
uint32_t priority;
-
+
// Init remote address
if ((ret = tnet_sockaddr_init(self->candidate_answer->connection_addr, self->candidate_answer->port, self->candidate_offer->socket->type, &self->remote_addr))) {
TNET_PRINT_LAST_ERROR("tnet_sockaddr_init(%s:%d) failed", self->candidate_answer->connection_addr, self->candidate_answer->port);
goto bail;
}
-
+
if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_binding_request, &self->last_request))) {
goto bail;
}
@@ -266,7 +269,7 @@ int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
if (self->is_ice_jingle) {
tsk_sprintf(&p_uname, "%s%s", tnet_ice_candidate_get_ufrag(self->candidate_answer), tnet_ice_candidate_get_ufrag(self->candidate_offer));
}
- else{
+ else {
tsk_sprintf(&p_uname, "%s:%s", tnet_ice_candidate_get_ufrag(self->candidate_answer), tnet_ice_candidate_get_ufrag(self->candidate_offer));
}
pc_pwd = tnet_ice_candidate_get_pwd(self->candidate_answer);
@@ -276,7 +279,7 @@ int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
goto bail;
}
}
-
+
priority = tnet_ice_utils_get_priority(tnet_ice_cand_type_prflx, self->candidate_offer->local_pref, self->candidate_offer->is_rtp);
// add attributes
self->last_request->opt.dontfrag = 0;
@@ -333,176 +336,176 @@ int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
#if TNET_ICE_AGGRESSIVE_NOMINATION
if (!tnet_stun_pkt_attr_exists(self->last_request, tnet_stun_attr_type_ice_use_candidate)) {
#else
- if (self->is_nominated && !tnet_stun_pkt_attr_exists(self->last_request, tnet_stun_attr_type_ice_use_candidate)) {
+ if (self->is_nominated && !tnet_stun_pkt_attr_exists(self->last_request, tnet_stun_attr_type_ice_use_candidate)) {
#endif
- ret = tnet_stun_pkt_attrs_add(self->last_request,
- TNET_STUN_PKT_ATTR_ADD_ICE_USE_CANDIDATE(),
+ ret = tnet_stun_pkt_attrs_add(self->last_request,
+ TNET_STUN_PKT_ATTR_ADD_ICE_USE_CANDIDATE(),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+
+ if (ret) {
+ goto bail;
+ }
+ b_changed = tsk_true;
+ }
+ }
+ else {
+ tnet_stun_pkt_attr_remove(self->last_request, tnet_stun_attr_type_ice_use_candidate);
+ tnet_stun_pkt_attr_remove(self->last_request, tnet_stun_attr_type_ice_controlling);
+ if (!tnet_stun_pkt_attr_exists(self->last_request, tnet_stun_attr_type_ice_controlled)) {
+ ret = tnet_stun_pkt_attrs_add(self->last_request,
+ TNET_STUN_PKT_ATTR_ADD_ICE_CONTROLLED(self->tie_breaker),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+ b_changed = tsk_true;
+ }
+ }
+ // update transac-id if the request structure changed
+ if ((b_changed && (ret = tnet_stun_utils_transac_id_rand(&self->last_request->transac_id)))) {
+ goto bail;
+ }
+ }
+
+ // Send request
+ {
+ tsk_buffer_t *req_buffer = tsk_null;
+ self->last_request->opt.fingerprint = !self->is_ice_jingle;
+ if ((ret = tnet_stun_pkt_write_with_padding_2(self->last_request, &req_buffer))) {
+ goto bail;
+ }
+ if (self->candidate_offer->turn.ss) {
+ // Send using TURN session. Above, we already checked that the TURN session is ready (Alloc=OK, Permission=OK)
+ ret = tnet_turn_session_send_data(self->candidate_offer->turn.ss, self->turn_peer_id, req_buffer->data, (uint16_t)req_buffer->size);
+ }
+ else {
+ int sendBytes = tnet_sockfd_sendto(self->candidate_offer->socket->fd, (const struct sockaddr*)&self->remote_addr, req_buffer->data, req_buffer->size);
+ ret = (sendBytes == req_buffer->size) ? 0 : -9;
+ }
+ TSK_OBJECT_SAFE_FREE(req_buffer);
+ if (ret) {
+ goto bail;
+ }
+ }
+
+bail:
+ if (ret == 0 && self->state_offer == tnet_ice_pair_state_frozen) {
+ self->state_offer = tnet_ice_pair_state_in_progress;
+ }
+ return ret;
+}
+
+int tnet_ice_pair_send_response(tnet_ice_pair_t *self, const tnet_stun_pkt_req_t* request, const short code, const char* phrase, const struct sockaddr_storage *remote_addr)
+{
+ tnet_stun_pkt_t* message = tsk_null;
+ const char *password, *username;
+ int ret = -1;
+ tsk_bool_t is_error = ((code / 100) != 2);
+
+ if(!self || !phrase || !request || !self->candidate_offer || !self->candidate_answer) {
+ TSK_DEBUG_ERROR("Invalid paramter");
+ return -1;
+ }
+
+ username = tsk_null;
+ password = tnet_ice_candidate_get_pwd(self->candidate_offer);
+
+ if ((ret = tnet_stun_pkt_create_empty(is_error ? tnet_stun_pkt_type_binding_error_response : tnet_stun_pkt_type_binding_success_response, &message)) == 0) {
+ tsk_buffer_t *req_buffer = tsk_null;
+ memcpy(message->transac_id, request->transac_id, sizeof(request->transac_id));
+ message->opt.fingerprint = !self->is_ice_jingle;
+ message->opt.dontfrag = 0;
+
+ // SOFWARE
+ ret = tnet_stun_pkt_attrs_add(message,
+ TNET_STUN_PKT_ATTR_ADD_SOFTWARE_ZT(kStunSoftware),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+
+ // SHORT-TERM authentication even for responses
+ if ((ret = tnet_stun_pkt_auth_prepare_shortterm_2(message, password))) {
+ goto bail;
+ }
+
+ // ERROR
+ if (is_error) {
+ ret = tnet_stun_pkt_attrs_add(message,
+ TNET_STUN_PKT_ATTR_ADD_ERROR_CODE(((code / 100) & 0x07), (code - ((code / 100) * 100)), phrase),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+ }
+ else {
+ tnet_ip_t remote_ip;
+ tnet_port_t remote_port;
+ if (self->is_ice_jingle) {
+ const tnet_stun_attr_vdata_t *pc_attr_vdata;
+ // USERNAME
+ if ((ret = tnet_stun_pkt_attr_find_first(request, tnet_stun_attr_type_username, (const tnet_stun_attr_t **)&pc_attr_vdata)) == 0 && pc_attr_vdata) {
+ ret = tnet_stun_pkt_attrs_add(message,
+ TNET_STUN_PKT_ATTR_ADD_USERNAME(pc_attr_vdata->p_data_ptr, pc_attr_vdata->u_data_size),
TNET_STUN_PKT_ATTR_ADD_NULL());
-
if (ret) {
goto bail;
}
- b_changed = tsk_true;
}
}
- else {
- tnet_stun_pkt_attr_remove(self->last_request, tnet_stun_attr_type_ice_use_candidate);
- tnet_stun_pkt_attr_remove(self->last_request, tnet_stun_attr_type_ice_controlling);
- if (!tnet_stun_pkt_attr_exists(self->last_request, tnet_stun_attr_type_ice_controlled)) {
- ret = tnet_stun_pkt_attrs_add(self->last_request,
- TNET_STUN_PKT_ATTR_ADD_ICE_CONTROLLED(self->tie_breaker),
+ // MAPPED-ADDRESS and XOR-MAPPED-ADDRESS
+ if ((ret = tnet_get_sockip_n_port((const struct sockaddr*)remote_addr, &remote_ip, &remote_port)) == 0) {
+ tnet_stun_addr_t _addr;
+ tnet_stun_address_family_t _familly = (remote_addr->ss_family == AF_INET6) ? tnet_stun_address_family_ipv6 : tnet_stun_address_family_ipv4;
+ if ((ret = tnet_stun_utils_inet_pton((_familly == tnet_stun_address_family_ipv6), remote_ip, &_addr)) == 0) {
+ ret = tnet_stun_pkt_attrs_add(message,
+ TNET_STUN_PKT_ATTR_ADD_MAPPED_ADDRESS(_familly, remote_port, &_addr),
+ TNET_STUN_PKT_ATTR_ADD_XOR_MAPPED_ADDRESS(_familly, remote_port, &_addr),
TNET_STUN_PKT_ATTR_ADD_NULL());
if (ret) {
goto bail;
}
- b_changed = tsk_true;
}
}
- // update transac-id if the request structure changed
- if ((b_changed && (ret = tnet_stun_utils_transac_id_rand(&self->last_request->transac_id)))) {
- goto bail;
- }
}
-
- // Send request
- {
- tsk_buffer_t *req_buffer = tsk_null;
- self->last_request->opt.fingerprint = !self->is_ice_jingle;
- if ((ret = tnet_stun_pkt_write_with_padding_2(self->last_request, &req_buffer))) {
+
+ if (self->candidate_offer->turn.ss) {
+ enum tnet_stun_state_e e_state;
+ if ((ret = tnet_turn_session_get_state_createperm(self->candidate_offer->turn.ss, self->turn_peer_id, &e_state))) {
goto bail;
}
- if (self->candidate_offer->turn.ss) {
- // Send using TURN session. Above, we already checked that the TURN session is ready (Alloc=OK, Permission=OK)
- ret = tnet_turn_session_send_data(self->candidate_offer->turn.ss, self->turn_peer_id, req_buffer->data, (uint16_t)req_buffer->size);
+ if (e_state != tnet_stun_state_ok) {
+ TSK_DEBUG_INFO("TURN CreatePerm not ready yet... to send STUN response (peer-id=%ld)", self->turn_peer_id);
+ goto bail;
}
- else {
- int sendBytes = tnet_sockfd_sendto(self->candidate_offer->socket->fd, (const struct sockaddr*)&self->remote_addr, req_buffer->data, req_buffer->size);
- ret = (sendBytes == req_buffer->size) ? 0 : -9;
+ if ((ret = tnet_stun_pkt_write_with_padding_2(message, &req_buffer))) {
+ goto bail;
}
- TSK_OBJECT_SAFE_FREE(req_buffer);
- if (ret) {
+ if ((ret = tnet_turn_session_send_data(self->candidate_offer->turn.ss, self->turn_peer_id, req_buffer->data, (uint16_t)req_buffer->size))) {
goto bail;
}
}
-
- bail:
- if (ret == 0 && self->state_offer == tnet_ice_pair_state_frozen) {
- self->state_offer = tnet_ice_pair_state_in_progress;
- }
- return ret;
- }
-
- int tnet_ice_pair_send_response(tnet_ice_pair_t *self, const tnet_stun_pkt_req_t* request, const short code, const char* phrase, const struct sockaddr_storage *remote_addr)
- {
- tnet_stun_pkt_t* message = tsk_null;
- const char *password, *username;
- int ret = -1;
- tsk_bool_t is_error = ((code / 100) != 2);
-
- if(!self || !phrase || !request || !self->candidate_offer || !self->candidate_answer){
- TSK_DEBUG_ERROR("Invalid paramter");
- return -1;
- }
-
- username = tsk_null;
- password = tnet_ice_candidate_get_pwd(self->candidate_offer);
-
- if ((ret = tnet_stun_pkt_create_empty(is_error ? tnet_stun_pkt_type_binding_error_response : tnet_stun_pkt_type_binding_success_response, &message)) == 0) {
- tsk_buffer_t *req_buffer = tsk_null;
- memcpy(message->transac_id, request->transac_id, sizeof(request->transac_id));
- message->opt.fingerprint = !self->is_ice_jingle;
- message->opt.dontfrag = 0;
-
- // SOFWARE
- ret = tnet_stun_pkt_attrs_add(message,
- TNET_STUN_PKT_ATTR_ADD_SOFTWARE_ZT(kStunSoftware),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
+ else {
+ struct sockaddr_storage dest_addr;
+ int sendBytes;
+ if ((ret = tnet_sockaddr_init(self->candidate_answer->connection_addr, self->candidate_answer->port, self->candidate_offer->socket->type, &dest_addr))) {
+ TNET_PRINT_LAST_ERROR("tnet_sockaddr_init(%s:%d) failed", self->candidate_answer->connection_addr, self->candidate_answer->port);
goto bail;
}
-
- // SHORT-TERM authentication even for responses
- if ((ret = tnet_stun_pkt_auth_prepare_shortterm_2(message, password))) {
+ if ((ret = tnet_stun_pkt_write_with_padding_2(message, &req_buffer))) {
goto bail;
}
-
- // ERROR
- if (is_error) {
- ret = tnet_stun_pkt_attrs_add(message,
- TNET_STUN_PKT_ATTR_ADD_ERROR_CODE(((code / 100) & 0x07), (code - ((code / 100) * 100)), phrase),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- }
- else {
- tnet_ip_t remote_ip;
- tnet_port_t remote_port;
- if (self->is_ice_jingle) {
- const tnet_stun_attr_vdata_t *pc_attr_vdata;
- // USERNAME
- if ((ret = tnet_stun_pkt_attr_find_first(request, tnet_stun_attr_type_username, (const tnet_stun_attr_t **)&pc_attr_vdata)) == 0 && pc_attr_vdata) {
- ret = tnet_stun_pkt_attrs_add(message,
- TNET_STUN_PKT_ATTR_ADD_USERNAME(pc_attr_vdata->p_data_ptr, pc_attr_vdata->u_data_size),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- }
- }
- // MAPPED-ADDRESS and XOR-MAPPED-ADDRESS
- if ((ret = tnet_get_sockip_n_port((const struct sockaddr*)remote_addr, &remote_ip, &remote_port)) == 0) {
- tnet_stun_addr_t _addr;
- tnet_stun_address_family_t _familly = (remote_addr->ss_family == AF_INET6) ? tnet_stun_address_family_ipv6 : tnet_stun_address_family_ipv4;
- if ((ret = tnet_stun_utils_inet_pton((_familly == tnet_stun_address_family_ipv6), remote_ip, &_addr)) == 0) {
- ret = tnet_stun_pkt_attrs_add(message,
- TNET_STUN_PKT_ATTR_ADD_MAPPED_ADDRESS(_familly, remote_port, &_addr),
- TNET_STUN_PKT_ATTR_ADD_XOR_MAPPED_ADDRESS(_familly, remote_port, &_addr),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- }
- }
- }
-
- if (self->candidate_offer->turn.ss) {
- enum tnet_stun_state_e e_state;
- if ((ret = tnet_turn_session_get_state_createperm(self->candidate_offer->turn.ss, self->turn_peer_id, &e_state))) {
- goto bail;
- }
- if (e_state != tnet_stun_state_ok) {
- TSK_DEBUG_INFO("TURN CreatePerm not ready yet... to send STUN response (peer-id=%ld)", self->turn_peer_id);
- goto bail;
- }
- if ((ret = tnet_stun_pkt_write_with_padding_2(message, &req_buffer))) {
- goto bail;
- }
- if ((ret = tnet_turn_session_send_data(self->candidate_offer->turn.ss, self->turn_peer_id, req_buffer->data, (uint16_t)req_buffer->size))) {
- goto bail;
- }
- }
- else {
- struct sockaddr_storage dest_addr;
- int sendBytes;
- if ((ret = tnet_sockaddr_init(self->candidate_answer->connection_addr, self->candidate_answer->port, self->candidate_offer->socket->type, &dest_addr))) {
- TNET_PRINT_LAST_ERROR("tnet_sockaddr_init(%s:%d) failed", self->candidate_answer->connection_addr, self->candidate_answer->port);
- goto bail;
- }
- if ((ret = tnet_stun_pkt_write_with_padding_2(message, &req_buffer))) {
- goto bail;
- }
- sendBytes = tnet_sockfd_sendto(self->candidate_offer->socket->fd, (const struct sockaddr*)&dest_addr, req_buffer->data, req_buffer->size);
- TSK_OBJECT_SAFE_FREE(req_buffer);
- ret = (sendBytes > 0) ? 0 : -2;
- if (ret != 0) {
- TSK_DEBUG_ERROR("ICE pair-answer: failed to send response");
- }
+ sendBytes = tnet_sockfd_sendto(self->candidate_offer->socket->fd, (const struct sockaddr*)&dest_addr, req_buffer->data, req_buffer->size);
+ TSK_OBJECT_SAFE_FREE(req_buffer);
+ ret = (sendBytes > 0) ? 0 : -2;
+ if (ret != 0) {
+ TSK_DEBUG_ERROR("ICE pair-answer: failed to send response");
}
}
-
- if (ret == 0 && !is_error) {
- tsk_bool_t change_state =
+ }
+
+ if (ret == 0 && !is_error) {
+ tsk_bool_t change_state =
self->is_ice_jingle // ICE-JINGLE don't have ICE-CONTROLLING/ICE-CONTROLLED attributes
|| (!self->is_controlling && tnet_stun_pkt_attr_exists(request, tnet_stun_attr_type_ice_use_candidate)) // Sender is controlling and uses "ICE-USE-CANDIDATE" attribute
#if TNET_ICE_AGGRESSIVE_NOMINATION || 1 // This is not a typo but a *must*. We've to change the answer state regardless the nomination mode otherwise we'll never get a nominee. Only the offer state is controlled based on the mode and depends on "is_nominated".
@@ -511,301 +514,300 @@ int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
|| (self->is_controlling && self->is_nominated) // We're controlling and using regular mode
#endif
;
- TNET_ICE_PAIR_DEBUG_INFO("ICE pair-answer changing state to 'succeed' ? %s, comp-id=%d, found=%s, addr=%s",
- change_state?"yes":"no",
- self->candidate_answer->comp_id,
- self->candidate_answer->foundation,
- self->candidate_answer->connection_addr
- );
- if (change_state) {
- self->state_answer = tnet_ice_pair_state_succeed;
- }
- }
-
-
- bail:
- TSK_OBJECT_SAFE_FREE(message);
- return ret;
+ TNET_ICE_PAIR_DEBUG_INFO("ICE pair-answer changing state to 'succeed' ? %s, comp-id=%d, found=%s, addr=%s",
+ change_state?"yes":"no",
+ self->candidate_answer->comp_id,
+ self->candidate_answer->foundation,
+ self->candidate_answer->connection_addr
+ );
+ if (change_state) {
+ self->state_answer = tnet_ice_pair_state_succeed;
+ }
}
-
- int tnet_ice_pair_auth_conncheck(const tnet_ice_pair_t *self, const tnet_stun_pkt_req_t* request, const void* request_buff, tsk_size_t request_buff_size, short* resp_code, char** resp_phrase)
- {
- const uint8_t* _request_buff = (const uint8_t*)request_buff;
-
- const tnet_stun_attr_t* stun_att;
- const tnet_stun_attr_vdata_t *stun_att_usr_name;
- const tnet_stun_attr_vdata_t *stun_att_fingerprint;
- const tnet_stun_attr_vdata_t *stun_att_integrity;
-
- const tsk_list_item_t *item;
- tsk_sha1digest_t hmac;
- const char* pwd;
-
- tsk_size_t msg_integrity_start = 0, length, i;
-
- if(!self || !request || !request_buff || !request_buff_size || !resp_code || !resp_phrase){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- if(!TNET_STUN_BUFF_IS_STUN2(_request_buff, request_buff_size)){
- TSK_DEBUG_ERROR("Not STUN buffer");
- return -1;
- }
-
- pwd = tnet_ice_candidate_get_pwd(self->candidate_offer);
- stun_att_usr_name = tsk_null;
- stun_att_fingerprint = tsk_null;
- stun_att_integrity = tsk_null;
-
- tsk_list_foreach(item, request->p_list_attrs) {
- if ((!(stun_att = (const tnet_stun_attr_t*)item->data))) {
- continue;
- }
-
- switch (stun_att->hdr.e_type) {
- case tnet_stun_attr_type_username:
- {
- stun_att_usr_name = (const tnet_stun_attr_vdata_t *)stun_att;
- break;
- }
- case tnet_stun_attr_type_fingerprint:
- {
- stun_att_fingerprint = (const tnet_stun_attr_vdata_t *)stun_att;
- break;
- }
- case tnet_stun_attr_type_message_integrity:
- {
- stun_att_integrity = (const tnet_stun_attr_vdata_t *)stun_att;
- break;
- }
- default: break;
- }
-
- if (!stun_att_integrity) {
- if ((length = (kStunAttrHdrSizeInOctets + stun_att->hdr.u_length)) & 0x03) {
- length += (4 - (length & 0x03));
- }
- msg_integrity_start += length;
- }
+
+
+bail:
+ TSK_OBJECT_SAFE_FREE(message);
+ return ret;
+}
+
+int tnet_ice_pair_auth_conncheck(const tnet_ice_pair_t *self, const tnet_stun_pkt_req_t* request, const void* request_buff, tsk_size_t request_buff_size, short* resp_code, char** resp_phrase)
+{
+ const uint8_t* _request_buff = (const uint8_t*)request_buff;
+
+ const tnet_stun_attr_t* stun_att;
+ const tnet_stun_attr_vdata_t *stun_att_usr_name;
+ const tnet_stun_attr_vdata_t *stun_att_fingerprint;
+ const tnet_stun_attr_vdata_t *stun_att_integrity;
+
+ const tsk_list_item_t *item;
+ tsk_sha1digest_t hmac;
+ const char* pwd;
+
+ tsk_size_t msg_integrity_start = 0, length, i;
+
+ if(!self || !request || !request_buff || !request_buff_size || !resp_code || !resp_phrase) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ if(!TNET_STUN_BUFF_IS_STUN2(_request_buff, request_buff_size)) {
+ TSK_DEBUG_ERROR("Not STUN buffer");
+ return -1;
+ }
+
+ pwd = tnet_ice_candidate_get_pwd(self->candidate_offer);
+ stun_att_usr_name = tsk_null;
+ stun_att_fingerprint = tsk_null;
+ stun_att_integrity = tsk_null;
+
+ tsk_list_foreach(item, request->p_list_attrs) {
+ if ((!(stun_att = (const tnet_stun_attr_t*)item->data))) {
+ continue;
}
-
- if (!stun_att_usr_name) {
- TSK_DEBUG_ERROR("USERNAME is missing");
- *resp_code = 400;
- tsk_strupdate(resp_phrase, "USERNAME is missing");
- return -2;
- }
-
- if (!stun_att_integrity || stun_att_integrity->u_data_size != TSK_SHA1_DIGEST_SIZE) {
- if (self->is_ice_jingle) { // Bug introduced in Chrome 20.0.1120.0 (Not security issue as ICE-JINGLE is deprecated and will never be ON)
- *resp_code = 200;
- tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY is missing but accepted");
- return 0;
- }
- else {
- TSK_DEBUG_ERROR("MESSAGE-INTEGRITY is missing");
- *resp_code = 400;
- tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY is missing");
- return -3;
+
+ switch (stun_att->hdr.e_type) {
+ case tnet_stun_attr_type_username: {
+ stun_att_usr_name = (const tnet_stun_attr_vdata_t *)stun_att;
+ break;
+ }
+ case tnet_stun_attr_type_fingerprint: {
+ stun_att_fingerprint = (const tnet_stun_attr_vdata_t *)stun_att;
+ break;
+ }
+ case tnet_stun_attr_type_message_integrity: {
+ stun_att_integrity = (const tnet_stun_attr_vdata_t *)stun_att;
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (!stun_att_integrity) {
+ if ((length = (kStunAttrHdrSizeInOctets + stun_att->hdr.u_length)) & 0x03) {
+ length += (4 - (length & 0x03));
}
+ msg_integrity_start += length;
}
-
- if ((kStunPktHdrSizeInOctets + msg_integrity_start) >= request_buff_size) {
- TSK_DEBUG_ERROR("Invalid length");
- *resp_code = 400;
- tsk_strupdate(resp_phrase, "Invalid length");
- return -20;
- }
-
- if (request->u_length != msg_integrity_start) {
- tsk_size_t size = (kStunPktHdrSizeInOctets + msg_integrity_start);
- uint8_t* new_buffer = (uint8_t*)tsk_calloc(size, 1);
- if (!new_buffer) {
- TSK_DEBUG_ERROR("Failed to allocate buffer with size = %u", (unsigned)msg_integrity_start);
- return -30;
- }
- memcpy(new_buffer, request_buff, size);
- length = msg_integrity_start + (kStunAttrHdrSizeInOctets + TSK_SHA1_DIGEST_SIZE /* INTEGRITY VALUE*/);
- new_buffer[2] = (length >> 8) & 0xFF;
- new_buffer[3] = (length & 0xFF);
- hmac_sha1digest_compute(new_buffer, size, pwd, tsk_strlen(pwd), hmac);
- TSK_FREE(new_buffer);
+ }
+
+ if (!stun_att_usr_name) {
+ TSK_DEBUG_ERROR("USERNAME is missing");
+ *resp_code = 400;
+ tsk_strupdate(resp_phrase, "USERNAME is missing");
+ return -2;
+ }
+
+ if (!stun_att_integrity || stun_att_integrity->u_data_size != TSK_SHA1_DIGEST_SIZE) {
+ if (self->is_ice_jingle) { // Bug introduced in Chrome 20.0.1120.0 (Not security issue as ICE-JINGLE is deprecated and will never be ON)
+ *resp_code = 200;
+ tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY is missing but accepted");
+ return 0;
}
else {
- // must never happen
- hmac_sha1digest_compute(request_buff, request_buff_size, pwd, tsk_strlen(pwd), hmac);
- }
-
- for (i = 0; i < TSK_SHA1_DIGEST_SIZE; ++i) {
- if (hmac[i] != stun_att_integrity->p_data_ptr[i]) {
- TSK_DEBUG_ERROR("MESSAGE-INTEGRITY mismatch");
- *resp_code = 401;
- tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY mismatch");
- return -40;
- }
- }
-
- *resp_code = 200;
- tsk_strupdate(resp_phrase, "Ok");
-
- return 0;
+ TSK_DEBUG_ERROR("MESSAGE-INTEGRITY is missing");
+ *resp_code = 400;
+ tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY is missing");
+ return -3;
+ }
}
-
- int tnet_ice_pair_recv_response(tnet_ice_pair_t *self, const tnet_stun_pkt_resp_t* response, tsk_bool_t is_4conncheck)
- {
- if (self && response && TNET_STUN_PKT_IS_RESP(response)) {
- if (self->last_request && tnet_stun_utils_transac_id_equals(self->last_request->transac_id, response->transac_id)){
- // ignore errors (e.g. STALE-CREDENTIALS) which could happen in some special cases before success
- if (TNET_STUN_PKT_RESP_IS_SUCCESS(response)) {
- if (is_4conncheck) {
- self->state_offer = tnet_ice_pair_state_succeed; // we must not change the state after connection cheking to make sure another pair won't be picked as nominated
- TNET_ICE_PAIR_DEBUG_INFO("ICE pair-offer changing state to 'succeed', comp-id=%d, found=%s, addr=%s",
- self->candidate_offer->comp_id,
- self->candidate_offer->foundation,
- self->candidate_offer->connection_addr
- );
- }
+
+ if ((kStunPktHdrSizeInOctets + msg_integrity_start) >= request_buff_size) {
+ TSK_DEBUG_ERROR("Invalid length");
+ *resp_code = 400;
+ tsk_strupdate(resp_phrase, "Invalid length");
+ return -20;
+ }
+
+ if (request->u_length != msg_integrity_start) {
+ tsk_size_t size = (kStunPktHdrSizeInOctets + msg_integrity_start);
+ uint8_t* new_buffer = (uint8_t*)tsk_calloc(size, 1);
+ if (!new_buffer) {
+ TSK_DEBUG_ERROR("Failed to allocate buffer with size = %u", (unsigned)msg_integrity_start);
+ return -30;
+ }
+ memcpy(new_buffer, request_buff, size);
+ length = msg_integrity_start + (kStunAttrHdrSizeInOctets + TSK_SHA1_DIGEST_SIZE /* INTEGRITY VALUE*/);
+ new_buffer[2] = (length >> 8) & 0xFF;
+ new_buffer[3] = (length & 0xFF);
+ hmac_sha1digest_compute(new_buffer, size, pwd, tsk_strlen(pwd), hmac);
+ TSK_FREE(new_buffer);
+ }
+ else {
+ // must never happen
+ hmac_sha1digest_compute(request_buff, request_buff_size, pwd, tsk_strlen(pwd), hmac);
+ }
+
+ for (i = 0; i < TSK_SHA1_DIGEST_SIZE; ++i) {
+ if (hmac[i] != stun_att_integrity->p_data_ptr[i]) {
+ TSK_DEBUG_ERROR("MESSAGE-INTEGRITY mismatch");
+ *resp_code = 401;
+ tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY mismatch");
+ return -40;
+ }
+ }
+
+ *resp_code = 200;
+ tsk_strupdate(resp_phrase, "Ok");
+
+ return 0;
+}
+
+int tnet_ice_pair_recv_response(tnet_ice_pair_t *self, const tnet_stun_pkt_resp_t* response, tsk_bool_t is_4conncheck)
+{
+ if (self && response && TNET_STUN_PKT_IS_RESP(response)) {
+ if (self->last_request && tnet_stun_utils_transac_id_equals(self->last_request->transac_id, response->transac_id)) {
+ // ignore errors (e.g. STALE-CREDENTIALS) which could happen in some special cases before success
+ if (TNET_STUN_PKT_RESP_IS_SUCCESS(response)) {
+ if (is_4conncheck) {
+ self->state_offer = tnet_ice_pair_state_succeed; // we must not change the state after connection cheking to make sure another pair won't be picked as nominated
+ TNET_ICE_PAIR_DEBUG_INFO("ICE pair-offer changing state to 'succeed', comp-id=%d, found=%s, addr=%s",
+ self->candidate_offer->comp_id,
+ self->candidate_offer->foundation,
+ self->candidate_offer->connection_addr
+ );
}
- else {
- // The response is an error
- uint16_t u_code;
- int ret;
- if ((ret = tnet_stun_pkt_get_errorcode(response, &u_code)) == 0 && u_code == kStunErrCodeIceConflict) {
- TSK_DEBUG_INFO("ICE Pair %llu received conflict error message", self->id);
- // If this code is called this means that we have lower tie-breaker and we must toggle our role
- self->is_controlling = !self->is_controlling;
- TSK_OBJECT_SAFE_FREE(self->last_request); // delete the "last_request" to make sure a new one will be created with right attributes
- }
+ }
+ else {
+ // The response is an error
+ uint16_t u_code;
+ int ret;
+ if ((ret = tnet_stun_pkt_get_errorcode(response, &u_code)) == 0 && u_code == kStunErrCodeIceConflict) {
+ TSK_DEBUG_INFO("ICE Pair %llu received conflict error message", self->id);
+ // If this code is called this means that we have lower tie-breaker and we must toggle our role
+ self->is_controlling = !self->is_controlling;
+ TSK_OBJECT_SAFE_FREE(self->last_request); // delete the "last_request" to make sure a new one will be created with right attributes
}
}
}
- return 0;
}
-
- const tnet_ice_pair_t* tnet_ice_pairs_find_by_response(tnet_ice_pairs_L_t* pairs, const tnet_stun_pkt_t* response)
- {
- if(pairs && response){
- const tsk_list_item_t *item;
- const tnet_ice_pair_t *pair;
- tnet_port_t mapped_port;
- tnet_ip_t mapped_ip;
- tsk_list_foreach(item, pairs){
- if(!(pair = item->data) || !pair->candidate_answer || !pair->candidate_offer){
- continue;
+ return 0;
+}
+
+const tnet_ice_pair_t* tnet_ice_pairs_find_by_response(tnet_ice_pairs_L_t* pairs, const tnet_stun_pkt_t* response)
+{
+ if(pairs && response) {
+ const tsk_list_item_t *item;
+ const tnet_ice_pair_t *pair;
+ tnet_port_t mapped_port;
+ tnet_ip_t mapped_ip;
+ tsk_list_foreach(item, pairs) {
+ if(!(pair = item->data) || !pair->candidate_answer || !pair->candidate_offer) {
+ continue;
+ }
+ if(pair->last_request && tnet_stun_utils_transac_id_equals(pair->last_request->transac_id, response->transac_id)) {
+ // check that mapped/xmapped address match destination
+ const tnet_stun_attr_address_t *xmapped_addr = tsk_null;
+ const tnet_stun_attr_address_t* mapped_addr = tsk_null;
+ const tnet_stun_attr_address_t* _addr;
+
+ tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_xor_mapped_address, (const tnet_stun_attr_t **)&xmapped_addr);
+ tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_mapped_address, (const tnet_stun_attr_t **)&mapped_addr);
+ _addr = xmapped_addr ? xmapped_addr : mapped_addr;
+
+ if (!_addr) {
+ return pair; // do nothing if the client doesn't return mapped address STUN attribute
}
- if(pair->last_request && tnet_stun_utils_transac_id_equals(pair->last_request->transac_id, response->transac_id)){
- // check that mapped/xmapped address match destination
- const tnet_stun_attr_address_t *xmapped_addr = tsk_null;
- const tnet_stun_attr_address_t* mapped_addr = tsk_null;
- const tnet_stun_attr_address_t* _addr;
-
- tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_xor_mapped_address, (const tnet_stun_attr_t **)&xmapped_addr);
- tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_mapped_address, (const tnet_stun_attr_t **)&mapped_addr);
- _addr = xmapped_addr ? xmapped_addr : mapped_addr;
-
- if (!_addr) {
- return pair; // do nothing if the client doesn't return mapped address STUN attribute
- }
- /* rfc 5245 7.1.3.2.1. Discovering Peer Reflexive Candidates
-
- The agent checks the mapped address from the STUN response. If the
- transport address does not match any of the local candidates that the
- agent knows about, the mapped address represents a new candidate -- a
- peer reflexive candidate. Like other candidates, it has a type,
- base, priority, and foundation. They are computed as follows:
-
- o Its type is equal to peer reflexive.
-
- o Its base is set equal to the local candidate of the candidate pair
- from which the STUN check was sent.
-
- o Its priority is set equal to the value of the PRIORITY attribute
- in the Binding request.
-
- o Its foundation is selected as described in Section 4.1.1.3.
-
- This peer reflexive candidate is then added to the list of local
- candidates for the media stream. Its username fragment and password
- are the same as all other local candidates for that media stream.
- */
-
- tnet_stun_utils_inet_ntop((_addr->e_family == tnet_stun_address_family_ipv6), &_addr->address, &mapped_ip);
- mapped_port = _addr->u_port;
- if (pair->candidate_offer->type_e != tnet_ice_cand_type_host && (mapped_port != pair->candidate_offer->port || !tsk_striequals(mapped_ip, pair->candidate_offer->connection_addr))) {
- TSK_DEBUG_INFO("Mapped address different than local connection address...probably symetric NAT: %s#%s or %u#%u",
- pair->candidate_offer->connection_addr, mapped_ip,
- pair->candidate_offer->port, mapped_port);
- // do we really need to add new local candidate?
- // continue;
- }
- return pair;
+ /* rfc 5245 7.1.3.2.1. Discovering Peer Reflexive Candidates
+
+ The agent checks the mapped address from the STUN response. If the
+ transport address does not match any of the local candidates that the
+ agent knows about, the mapped address represents a new candidate -- a
+ peer reflexive candidate. Like other candidates, it has a type,
+ base, priority, and foundation. They are computed as follows:
+
+ o Its type is equal to peer reflexive.
+
+ o Its base is set equal to the local candidate of the candidate pair
+ from which the STUN check was sent.
+
+ o Its priority is set equal to the value of the PRIORITY attribute
+ in the Binding request.
+
+ o Its foundation is selected as described in Section 4.1.1.3.
+
+ This peer reflexive candidate is then added to the list of local
+ candidates for the media stream. Its username fragment and password
+ are the same as all other local candidates for that media stream.
+ */
+
+ tnet_stun_utils_inet_ntop((_addr->e_family == tnet_stun_address_family_ipv6), &_addr->address, &mapped_ip);
+ mapped_port = _addr->u_port;
+ if (pair->candidate_offer->type_e != tnet_ice_cand_type_host && (mapped_port != pair->candidate_offer->port || !tsk_striequals(mapped_ip, pair->candidate_offer->connection_addr))) {
+ TSK_DEBUG_INFO("Mapped address different than local connection address...probably symetric NAT: %s#%s or %u#%u",
+ pair->candidate_offer->connection_addr, mapped_ip,
+ pair->candidate_offer->port, mapped_port);
+ // do we really need to add new local candidate?
+ // continue;
}
+ return pair;
}
}
+ }
+ return tsk_null;
+}
+
+const tnet_ice_pair_t* tnet_ice_pairs_find_by_fd_and_addr(tnet_ice_pairs_L_t* pairs, tnet_fd_t local_fd, const struct sockaddr_storage *remote_addr)
+{
+ int ret;
+ const tsk_list_item_t *item;
+ const tnet_ice_pair_t *pair;
+ tnet_ip_t remote_ip;
+ tnet_port_t remote_port;
+
+ if(!pairs || !remote_addr) {
+ TSK_DEBUG_ERROR("Invalid parameter");
return tsk_null;
}
-
- const tnet_ice_pair_t* tnet_ice_pairs_find_by_fd_and_addr(tnet_ice_pairs_L_t* pairs, tnet_fd_t local_fd, const struct sockaddr_storage *remote_addr)
- {
- int ret;
+
+ if((ret = tnet_get_sockip_n_port((const struct sockaddr*)remote_addr, &remote_ip, &remote_port))) {
+ TNET_PRINT_LAST_ERROR("tnet_get_sockip_n_port() failed");
+ return tsk_null;
+ }
+
+ tsk_list_foreach(item, pairs) {
+ if (!(pair = item->data) || !pair->candidate_offer || !pair->candidate_offer->socket || pair->candidate_offer->socket->fd != local_fd) {
+ continue;
+ }
+ if (!tsk_striequals(pair->candidate_answer->connection_addr, remote_ip) || pair->candidate_answer->port != remote_port) {
+ continue;
+ }
+
+ return pair;
+ }
+
+ TSK_DEBUG_INFO("No ICE candidate with remote ip = %s, port = %u and local_fd = %d could be found...probably symetric NAT", remote_ip, remote_port, local_fd);
+
+ return tsk_null;
+}
+
+
+static tsk_bool_t _tnet_ice_pairs_none_succeed(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id, const char* foundation, tsk_bool_t answer)
+{
+ if(pairs && foundation) {
const tsk_list_item_t *item;
const tnet_ice_pair_t *pair;
- tnet_ip_t remote_ip;
- tnet_port_t remote_port;
-
- if(!pairs || !remote_addr){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_null;
- }
-
- if((ret = tnet_get_sockip_n_port((const struct sockaddr*)remote_addr, &remote_ip, &remote_port))){
- TNET_PRINT_LAST_ERROR("tnet_get_sockip_n_port() failed");
- return tsk_null;
- }
-
- tsk_list_foreach(item, pairs){
- if (!(pair = item->data) || !pair->candidate_offer || !pair->candidate_offer->socket || pair->candidate_offer->socket->fd != local_fd) {
+ const tnet_ice_candidate_t* candidate;
+ tsk_list_foreach(item, pairs) {
+ if(!(pair = item->data) || !(candidate = (answer ? pair->candidate_answer : pair->candidate_offer))) {
continue;
}
- if (!tsk_striequals(pair->candidate_answer->connection_addr, remote_ip) || pair->candidate_answer->port != remote_port) {
+ if(candidate->comp_id != comp_id || !tsk_striequals(candidate->foundation, foundation)) {
continue;
}
-
- return pair;
- }
-
- TSK_DEBUG_INFO("No ICE candidate with remote ip = %s, port = %u and local_fd = %d could be found...probably symetric NAT", remote_ip, remote_port, local_fd);
-
- return tsk_null;
- }
-
-
- static tsk_bool_t _tnet_ice_pairs_none_succeed(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id, const char* foundation, tsk_bool_t answer){
- if(pairs && foundation){
- const tsk_list_item_t *item;
- const tnet_ice_pair_t *pair;
- const tnet_ice_candidate_t* candidate;
- tsk_list_foreach(item, pairs){
- if(!(pair = item->data) || !(candidate = (answer ? pair->candidate_answer : pair->candidate_offer))){
- continue;
- }
- if(candidate->comp_id != comp_id || !tsk_striequals(candidate->foundation, foundation)){
- continue;
- }
- if((answer ? pair->state_answer : pair->state_offer) == tnet_ice_pair_state_succeed){
- TNET_ICE_PAIR_DEBUG_INFO("_tnet_ice_pairs_none_succeed_%s(%u, %s):false", answer?"anwser":"offer", comp_id, foundation);
- return tsk_false;
- }
+ if((answer ? pair->state_answer : pair->state_offer) == tnet_ice_pair_state_succeed) {
+ TNET_ICE_PAIR_DEBUG_INFO("_tnet_ice_pairs_none_succeed_%s(%u, %s):false", answer?"anwser":"offer", comp_id, foundation);
+ return tsk_false;
}
}
- TNET_ICE_PAIR_DEBUG_INFO("_tnet_ice_pairs_none_succeed_%s(%u, %s):true", answer?"anwser":"offer", comp_id, foundation);
- return tsk_true;
}
+ TNET_ICE_PAIR_DEBUG_INFO("_tnet_ice_pairs_none_succeed_%s(%u, %s):true", answer?"anwser":"offer", comp_id, foundation);
+ return tsk_true;
+}
#define _tnet_ice_pairs_none_succeed_answer(pairs, comp_id, foundation) _tnet_ice_pairs_none_succeed((pairs), (comp_id), (foundation), tsk_true)
#define _tnet_ice_pairs_none_succeed_offer(pairs, comp_id, foundation) _tnet_ice_pairs_none_succeed((pairs), (comp_id), (foundation), tsk_false)
-
- // both RTP and RTCP have succeeded
+
+// both RTP and RTCP have succeeded
#define _tnet_ice_pairs_get_nominated_offer_at(pairs, index, comp_id, check_fullness, ret) _tnet_ice_pairs_get_nominated_at((pairs), offer, answer, (index), (comp_id), (check_fullness), (ret))
#define _tnet_ice_pairs_get_nominated_answer_at(pairs, index, comp_id, check_fullness, ret) _tnet_ice_pairs_get_nominated_at((pairs), answer, offer, (index), (comp_id), (check_fullness), (ret))
#define _tnet_ice_pairs_get_nominated_at(pairs, dir_1, dir_2, index, _comp_id, check_fullness, ret) \
@@ -851,138 +853,146 @@ break; \
} \
} \
} \
+
+// true only if both RTP and RTCP are nominated
+tsk_bool_t tnet_ice_pairs_have_nominated_offer(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp)
+{
+ const tnet_ice_pair_t *pair_ = tsk_null;
+ tsk_bool_t is_nominated_rtp, is_nominated_rtcp = tsk_true;
+ TNET_ICE_PAIR_DEBUG_INFO("tnet_ice_pairs_have_nominated_offer()");
+ _tnet_ice_pairs_get_nominated_offer_at((pairs), 0, TNET_ICE_CANDIDATE_COMPID_RTP, check_rtcp, (pair_));
+ if((is_nominated_rtp = (pair_ != tsk_null)) && check_rtcp) {
+ _tnet_ice_pairs_get_nominated_offer_at((pairs), 0, TNET_ICE_CANDIDATE_COMPID_RTCP, check_rtcp, (pair_));
+ is_nominated_rtcp =(pair_ != tsk_null);
+ }
+ TNET_ICE_PAIR_DEBUG_INFO("is_nominated_rtp_offer=%s, is_nominated_rtcp_offer=%s", is_nominated_rtp?"yes":"no", is_nominated_rtcp?"yes":"no");
+ return (is_nominated_rtp && is_nominated_rtcp);
+}
- // true only if both RTP and RTCP are nominated
- tsk_bool_t tnet_ice_pairs_have_nominated_offer(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp)
- {
- const tnet_ice_pair_t *pair_ = tsk_null;
- tsk_bool_t is_nominated_rtp, is_nominated_rtcp = tsk_true;
- TNET_ICE_PAIR_DEBUG_INFO("tnet_ice_pairs_have_nominated_offer()");
- _tnet_ice_pairs_get_nominated_offer_at((pairs), 0, TNET_ICE_CANDIDATE_COMPID_RTP, check_rtcp, (pair_));
- if((is_nominated_rtp = (pair_ != tsk_null)) && check_rtcp){
- _tnet_ice_pairs_get_nominated_offer_at((pairs), 0, TNET_ICE_CANDIDATE_COMPID_RTCP, check_rtcp, (pair_));
- is_nominated_rtcp =(pair_ != tsk_null);
- }
- TNET_ICE_PAIR_DEBUG_INFO("is_nominated_rtp_offer=%s, is_nominated_rtcp_offer=%s", is_nominated_rtp?"yes":"no", is_nominated_rtcp?"yes":"no");
- return (is_nominated_rtp && is_nominated_rtcp);
- }
-
- // true only if both RTP and RTCP are nominated
- tsk_bool_t tnet_ice_pairs_have_nominated_answer(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp)
- {
- const tnet_ice_pair_t *pair_ = tsk_null;
- tsk_bool_t is_nominated_rtp, is_nominated_rtcp = tsk_true;
- TNET_ICE_PAIR_DEBUG_INFO("tnet_ice_pairs_have_nominated_answer()");
- _tnet_ice_pairs_get_nominated_answer_at((pairs), 0, TNET_ICE_CANDIDATE_COMPID_RTP, check_rtcp, (pair_));
- if((is_nominated_rtp = (pair_ != tsk_null)) && check_rtcp){
- _tnet_ice_pairs_get_nominated_answer_at((pairs), 0, TNET_ICE_CANDIDATE_COMPID_RTCP, check_rtcp, (pair_));
- is_nominated_rtcp =(pair_ != tsk_null);
- }
- TNET_ICE_PAIR_DEBUG_INFO("is_nominated_rtp_answer=%s, is_nominated_rtcp_answer=%s", is_nominated_rtp?"yes":"no", is_nominated_rtcp?"yes":"no");
- return (is_nominated_rtp && is_nominated_rtcp);
- }
-
- // true only if both RTP and RTCP are nominated in symetric way
- tsk_bool_t tnet_ice_pairs_have_nominated_symetric_2(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp, tsk_bool_t *got_hosts)
- {
- const tnet_ice_candidate_t *candidate_offer, *candidate_answer_src, *candidate_answer_dest;
- tsk_bool_t is_nominated_rtp, is_nominated_rtcp = tsk_true;
- int ret;
-
- if (got_hosts) {
- *got_hosts = tsk_false;
- }
- ret = tnet_ice_pairs_get_nominated_symetric_candidates(pairs, TNET_ICE_CANDIDATE_COMPID_RTP, &candidate_offer, &candidate_answer_src, &candidate_answer_dest);
- if ((is_nominated_rtp = (ret == 0 && candidate_offer && candidate_answer_src && candidate_answer_dest)) && got_hosts) {
- *got_hosts = (candidate_offer->type_e == tnet_ice_cand_type_host
- && candidate_answer_src->type_e == tnet_ice_cand_type_host
- && candidate_answer_dest->type_e == tnet_ice_cand_type_host);
- }
- if(is_nominated_rtp && check_rtcp){
- ret = tnet_ice_pairs_get_nominated_symetric_candidates(pairs, TNET_ICE_CANDIDATE_COMPID_RTCP, &candidate_offer, &candidate_answer_src, &candidate_answer_dest);
- if ((is_nominated_rtcp = (ret == 0 && candidate_offer && candidate_answer_src && candidate_answer_dest)) && got_hosts) {
- *got_hosts &= (candidate_offer->type_e == tnet_ice_cand_type_host
- && candidate_answer_src->type_e == tnet_ice_cand_type_host
- && candidate_answer_dest->type_e == tnet_ice_cand_type_host);
- }
+// true only if both RTP and RTCP are nominated
+tsk_bool_t tnet_ice_pairs_have_nominated_answer(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp)
+{
+ const tnet_ice_pair_t *pair_ = tsk_null;
+ tsk_bool_t is_nominated_rtp, is_nominated_rtcp = tsk_true;
+ TNET_ICE_PAIR_DEBUG_INFO("tnet_ice_pairs_have_nominated_answer()");
+ _tnet_ice_pairs_get_nominated_answer_at((pairs), 0, TNET_ICE_CANDIDATE_COMPID_RTP, check_rtcp, (pair_));
+ if((is_nominated_rtp = (pair_ != tsk_null)) && check_rtcp) {
+ _tnet_ice_pairs_get_nominated_answer_at((pairs), 0, TNET_ICE_CANDIDATE_COMPID_RTCP, check_rtcp, (pair_));
+ is_nominated_rtcp =(pair_ != tsk_null);
+ }
+ TNET_ICE_PAIR_DEBUG_INFO("is_nominated_rtp_answer=%s, is_nominated_rtcp_answer=%s", is_nominated_rtp?"yes":"no", is_nominated_rtcp?"yes":"no");
+ return (is_nominated_rtp && is_nominated_rtcp);
+}
+
+// true only if both RTP and RTCP are nominated in symetric way
+tsk_bool_t tnet_ice_pairs_have_nominated_symetric_2(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp, tsk_bool_t *got_hosts)
+{
+ const tnet_ice_candidate_t *candidate_offer, *candidate_answer_src, *candidate_answer_dest;
+ tsk_bool_t is_nominated_rtp, is_nominated_rtcp = tsk_true;
+ int ret;
+
+ if (got_hosts) {
+ *got_hosts = tsk_false;
+ }
+ ret = tnet_ice_pairs_get_nominated_symetric_candidates(pairs, TNET_ICE_CANDIDATE_COMPID_RTP, &candidate_offer, &candidate_answer_src, &candidate_answer_dest);
+ if ((is_nominated_rtp = (ret == 0 && candidate_offer && candidate_answer_src && candidate_answer_dest)) && got_hosts) {
+ *got_hosts = (candidate_offer->type_e == tnet_ice_cand_type_host
+ && candidate_answer_src->type_e == tnet_ice_cand_type_host
+ && candidate_answer_dest->type_e == tnet_ice_cand_type_host);
+ }
+ if(is_nominated_rtp && check_rtcp) {
+ ret = tnet_ice_pairs_get_nominated_symetric_candidates(pairs, TNET_ICE_CANDIDATE_COMPID_RTCP, &candidate_offer, &candidate_answer_src, &candidate_answer_dest);
+ if ((is_nominated_rtcp = (ret == 0 && candidate_offer && candidate_answer_src && candidate_answer_dest)) && got_hosts) {
+ *got_hosts &= (candidate_offer->type_e == tnet_ice_cand_type_host
+ && candidate_answer_src->type_e == tnet_ice_cand_type_host
+ && candidate_answer_dest->type_e == tnet_ice_cand_type_host);
}
- return (is_nominated_rtp && is_nominated_rtcp);
}
-
- // true only if both RTP and RTCP are nominated in symetric way
- tsk_bool_t tnet_ice_pairs_have_nominated_symetric(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp)
- {
+ return (is_nominated_rtp && is_nominated_rtcp);
+}
+
+// true only if both RTP and RTCP are nominated in symetric way
+tsk_bool_t tnet_ice_pairs_have_nominated_symetric(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp)
+{
#define got_hosts tsk_null
- return tnet_ice_pairs_have_nominated_symetric_2(pairs, check_rtcp, got_hosts);
- }
-
- // gets symetric nominated candidates with the highest priority
- // will succeed only if both RTP and RTCP are ok
- int tnet_ice_pairs_get_nominated_symetric_candidates(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id,
- const tnet_ice_candidate_t** candidate_offer,
- const tnet_ice_candidate_t** candidate_answer_src,
- const tnet_ice_candidate_t** candidate_answer_dest)
- {
- int ret;
- const tnet_ice_pair_t *pair_offer = tsk_null, *pair_answer_src = tsk_null, *pair_answer_dest = tsk_null;
- if (!pairs || !candidate_offer || !candidate_answer_src || !candidate_answer_dest) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- *candidate_offer = tsk_null;
- *candidate_answer_src = tsk_null;
- *candidate_answer_dest = tsk_null;
-
- if ((ret = tnet_ice_pairs_get_nominated_symetric_pairs(pairs, comp_id, &pair_offer, &pair_answer_src, &pair_answer_dest)) == 0) {
- *candidate_offer = pair_offer ? pair_offer->candidate_offer : tsk_null;
- *candidate_answer_src = pair_answer_src ? pair_answer_src->candidate_answer : tsk_null;
- *candidate_answer_dest = pair_answer_dest ? pair_answer_dest->candidate_answer : tsk_null;
- }
- return ret;
+ return tnet_ice_pairs_have_nominated_symetric_2(pairs, check_rtcp, got_hosts);
+}
+
+// gets symetric nominated candidates with the highest priority
+// will succeed only if both RTP and RTCP are ok
+int tnet_ice_pairs_get_nominated_symetric_candidates(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id,
+ const tnet_ice_candidate_t** candidate_offer,
+ const tnet_ice_candidate_t** candidate_answer_src,
+ const tnet_ice_candidate_t** candidate_answer_dest)
+{
+ int ret;
+ const tnet_ice_pair_t *pair_offer = tsk_null, *pair_answer_src = tsk_null, *pair_answer_dest = tsk_null;
+ if (!pairs || !candidate_offer || !candidate_answer_src || !candidate_answer_dest) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
}
-
- int tnet_ice_pairs_get_nominated_symetric_pairs(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id,
- const struct tnet_ice_pair_s** _pair_offer,
- const struct tnet_ice_pair_s** _pair_answer_src,
- const struct tnet_ice_pair_s** _pair_answer_dest)
- {
- const tnet_ice_pair_t *pair_offer = tsk_null;
- const tnet_ice_pair_t *pair_answer = tsk_null;
- tsk_size_t i_offer, i_answer;
- static const tsk_bool_t __check_fullness = tsk_false; // pairs will be checked seperatly
-
- if (!pairs || !_pair_offer || !_pair_answer_src || !_pair_answer_dest) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- *_pair_offer = tsk_null;
- *_pair_answer_src = tsk_null;
- *_pair_answer_dest = tsk_null;
-
- i_offer = 0;
+
+ *candidate_offer = tsk_null;
+ *candidate_answer_src = tsk_null;
+ *candidate_answer_dest = tsk_null;
+
+ if ((ret = tnet_ice_pairs_get_nominated_symetric_pairs(pairs, comp_id, &pair_offer, &pair_answer_src, &pair_answer_dest)) == 0) {
+ *candidate_offer = pair_offer ? pair_offer->candidate_offer : tsk_null;
+ *candidate_answer_src = pair_answer_src ? pair_answer_src->candidate_answer : tsk_null;
+ *candidate_answer_dest = pair_answer_dest ? pair_answer_dest->candidate_answer : tsk_null;
+ }
+ return ret;
+}
+
+int tnet_ice_pairs_get_nominated_symetric_pairs(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id,
+ const struct tnet_ice_pair_s** _pair_offer,
+ const struct tnet_ice_pair_s** _pair_answer_src,
+ const struct tnet_ice_pair_s** _pair_answer_dest)
+{
+ const tnet_ice_pair_t *pair_offer = tsk_null;
+ const tnet_ice_pair_t *pair_answer = tsk_null;
+ tsk_size_t i_offer, i_answer;
+ static const tsk_bool_t __check_fullness = tsk_false; // pairs will be checked seperatly
+
+ if (!pairs || !_pair_offer || !_pair_answer_src || !_pair_answer_dest) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ *_pair_offer = tsk_null;
+ *_pair_answer_src = tsk_null;
+ *_pair_answer_dest = tsk_null;
+
+ i_offer = 0;
+ while (1) {
+ _tnet_ice_pairs_get_nominated_offer_at((pairs), i_offer, comp_id, __check_fullness, (pair_offer)); // pair with socket SO as sender
+ if(!pair_offer) {
+ return 0;
+ }
+ ++i_offer;
+ if (pair_offer->candidate_offer->comp_id != comp_id) {
+ continue;
+ }
+ // find another pair with socket SO as receiver
+
+ i_answer = 0;
while (1) {
- _tnet_ice_pairs_get_nominated_offer_at((pairs), i_offer, comp_id, __check_fullness, (pair_offer)); // pair with socket SO as sender
- if(!pair_offer) return 0;
- ++i_offer;
- if (pair_offer->candidate_offer->comp_id != comp_id) continue;
- // find another pair with socket SO as receiver
-
- i_answer = 0;
- while (1) {
- _tnet_ice_pairs_get_nominated_answer_at((pairs), i_answer, comp_id, __check_fullness, (pair_answer));
- if (!pair_answer) break;
- ++i_answer;
- if (pair_answer->candidate_offer->comp_id != comp_id) continue;
- if (pair_answer->candidate_offer == pair_offer->candidate_offer) {
- *_pair_offer = pair_offer;
- *_pair_answer_src = pair_answer;
- *_pair_answer_dest = pair_offer;
- return 0;
- }
+ _tnet_ice_pairs_get_nominated_answer_at((pairs), i_answer, comp_id, __check_fullness, (pair_answer));
+ if (!pair_answer) {
+ break;
+ }
+ ++i_answer;
+ if (pair_answer->candidate_offer->comp_id != comp_id) {
+ continue;
+ }
+ if (pair_answer->candidate_offer == pair_offer->candidate_offer) {
+ *_pair_offer = pair_offer;
+ *_pair_answer_src = pair_answer;
+ *_pair_answer_dest = pair_offer;
+ return 0;
}
}
- return 0;
-
}
+ return 0;
+
+}
OpenPOWER on IntegriCloud