summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiong Sauw Ming <ming@teluu.com>2016-10-28 03:57:55 +0000
committerLiong Sauw Ming <ming@teluu.com>2016-10-28 03:57:55 +0000
commit62469d7d94fc19619d7fef8b07d284624c8e997e (patch)
tree805e7742aa13b810ef113a818d0f5112166cb06f
parenta6c3cdc2206c6e0482ea8f129fa69f97309ad688 (diff)
Re #1972: ICE initialization issues when creating a component/candidate fails.
Fixed ICE stuck if TURN creation fails in resolved state, assertions when trying to access other components/candidates, and crash when trying to access destroyed TURN socket. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5474 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjnath/src/pjnath/ice_strans.c26
-rw-r--r--pjnath/src/pjnath/turn_sock.c4
2 files changed, 25 insertions, 5 deletions
diff --git a/pjnath/src/pjnath/ice_strans.c b/pjnath/src/pjnath/ice_strans.c
index 7ef22a99..19e3bb12 100644
--- a/pjnath/src/pjnath/ice_strans.c
+++ b/pjnath/src/pjnath/ice_strans.c
@@ -164,6 +164,7 @@ typedef struct pj_ice_strans_comp
unsigned err_cnt; /**< TURN disconnected count. */
} turn[PJ_ICE_MAX_TURN];
+ pj_bool_t creating; /**< Is creating the candidates?*/
unsigned cand_cnt; /**< # of candidates/aliaes. */
pj_ice_sess_cand cand_list[PJ_ICE_ST_MAX_CAND]; /**< Cand array */
@@ -665,6 +666,7 @@ static pj_status_t create_comp(pj_ice_strans *ice_st, unsigned comp_id)
comp = PJ_POOL_ZALLOC_T(ice_st->pool, pj_ice_strans_comp);
comp->ice_st = ice_st;
comp->comp_id = comp_id;
+ comp->creating = PJ_TRUE;
ice_st->comp[comp_id-1] = comp;
@@ -693,6 +695,9 @@ static pj_status_t create_comp(pj_ice_strans *ice_st, unsigned comp_id)
}
}
+ /* Done creating all the candidates */
+ comp->creating = PJ_FALSE;
+
/* It's possible that we end up without any candidates */
if (comp->cand_cnt == 0) {
PJ_LOG(4,(ice_st->obj_name,
@@ -932,6 +937,11 @@ static void sess_init_update(pj_ice_strans *ice_st)
unsigned j;
pj_ice_strans_comp *comp = ice_st->comp[i];
+ /* This function can be called when all components or candidates
+ * have not been created.
+ */
+ if (!comp || comp->creating) return;
+
for (j=0; j<comp->cand_cnt; ++j) {
pj_ice_sess_cand *cand = &comp->cand_list[j];
@@ -1307,7 +1317,7 @@ PJ_DEF(pj_status_t) pj_ice_strans_start_ice( pj_ice_strans *ice_st,
}
}
- if (count) {
+ if (count && !comp->turn[n].err_cnt && comp->turn[n].sock) {
status = pj_turn_sock_set_perm(comp->turn[n].sock, count,
addrs, 0);
if (status != PJ_SUCCESS) {
@@ -1989,13 +1999,16 @@ static void turn_on_state(pj_turn_sock *turn_sock, pj_turn_state_t old_state,
sess_init_update(comp->ice_st);
- } else if (old_state == PJ_TURN_STATE_RESOLVING &&
+ } else if ((old_state == PJ_TURN_STATE_RESOLVING ||
+ old_state == PJ_TURN_STATE_RESOLVED) &&
new_state == PJ_TURN_STATE_DESTROYING)
{
pj_ice_sess_cand *cand = NULL;
unsigned i;
- /* DNS resolution has failed! */
+ /* DNS resolution or TURN transport creation/allocation
+ * has failed.
+ */
++comp->turn[tp_idx].err_cnt;
/* Unregister ourself from the TURN relay */
@@ -2014,11 +2027,14 @@ static void turn_on_state(pj_turn_sock *turn_sock, pj_turn_state_t old_state,
break;
}
}
- pj_assert(cand != NULL);
pj_grp_lock_release(comp->ice_st->grp_lock);
- cand->status = PJ_ERESOLVE;
+ /* If the error happens during pj_turn_sock_create() or
+ * pj_turn_sock_alloc(), the candidate hasn't been added
+ * to the list.
+ */
+ if (cand) cand->status = PJ_ERESOLVE;
sess_init_update(comp->ice_st);
diff --git a/pjnath/src/pjnath/turn_sock.c b/pjnath/src/pjnath/turn_sock.c
index 541175c6..f1f5bb6d 100644
--- a/pjnath/src/pjnath/turn_sock.c
+++ b/pjnath/src/pjnath/turn_sock.c
@@ -890,6 +890,10 @@ static void turn_on_state(pj_turn_session *sess,
if (status == PJ_SUCCESS) {
on_connect_complete(turn_sock->active_sock, PJ_SUCCESS);
} else if (status != PJ_EPENDING) {
+ pj_perror(3, turn_sock->pool->obj_name, status,
+ "Failed to connect to %s",
+ pj_sockaddr_print(&info.server, addrtxt,
+ sizeof(addrtxt), 3));
pj_turn_sock_destroy(turn_sock);
return;
}