From 68958ad7d2304c6c78ca899ddb09827bcd993891 Mon Sep 17 00:00:00 2001 From: Riza Sulistyo Date: Thu, 19 May 2016 04:30:05 +0000 Subject: Re #1918: Fixed continous looping when trying to resolve STUN server due to lock handling. Also move the unusable server to the least prioritize to be chosen on the fallback process. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5307 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/include/pjsua-lib/pjsua.h | 4 ++++ pjsip/include/pjsua-lib/pjsua_internal.h | 3 ++- pjsip/src/pjsua-lib/pjsua_core.c | 11 ++++++++++- pjsip/src/pjsua-lib/pjsua_media.c | 32 +++++++++++++++++++++++++++++--- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index 458ea379..b88aa462 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -2048,6 +2048,10 @@ struct pj_stun_resolve_result */ pj_sockaddr addr; + /** + * The index of the usable STUN server. + */ + unsigned index; }; diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h index 1c4d0a1d..1dec7c57 100644 --- a/pjsip/include/pjsua-lib/pjsua_internal.h +++ b/pjsip/include/pjsua-lib/pjsua_internal.h @@ -435,7 +435,8 @@ struct pjsua_data pj_sockaddr stun_srv; /**< Resolved STUN server address */ pj_status_t stun_status; /**< STUN server status. */ pjsua_stun_resolve stun_res; /**< List of pending STUN resolution*/ - pj_dns_resolver *resolver; /**< DNS resolver. */ + unsigned stun_srv_idx; /**< Resolved STUN server index */ + pj_dns_resolver *resolver; /**< DNS resolver. */ /* Detected NAT type */ pj_stun_nat_type nat_type; /**< NAT type. */ diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index 45918bd7..847fab51 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -1205,6 +1205,7 @@ static void stun_resolve_complete(pjsua_stun_resolve *sess) result.token = sess->token; result.status = sess->status; result.name = sess->srv[sess->idx]; + result.index = sess->idx; pj_memcpy(&result.addr, &sess->addr, sizeof(result.addr)); sess->has_result = PJ_TRUE; @@ -1508,6 +1509,7 @@ static void internal_stun_resolve_cb(const pj_stun_resolve_result *result) pjsua_var.stun_status = result->status; if ((result->status == PJ_SUCCESS) && (pjsua_var.ua_cfg.stun_srv_cnt>0)) { pj_memcpy(&pjsua_var.stun_srv, &result->addr, sizeof(result->addr)); + pjsua_var.stun_srv_idx = result->index; /* Perform NAT type detection if not yet */ if (pjsua_var.nat_type == PJ_STUN_NAT_TYPE_UNKNOWN && @@ -1554,7 +1556,12 @@ pj_status_t resolve_stun_server(pj_bool_t wait) * result. */ if (wait) { - while (pjsua_var.stun_status == PJ_EPENDING) { + pj_bool_t has_pjsua_lock = PJSUA_LOCK_IS_LOCKED(); + + if (has_pjsua_lock) + PJSUA_UNLOCK(); + + while (pjsua_var.stun_status == PJ_EPENDING) { /* If there is no worker thread or * the function is called from the only worker thread, * we have to handle the events here. @@ -1568,6 +1575,8 @@ pj_status_t resolve_stun_server(pj_bool_t wait) pj_thread_sleep(10); } } + if (has_pjsua_lock) + PJSUA_LOCK(); } } diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c index 7a8404c8..524915c7 100644 --- a/pjsip/src/pjsua-lib/pjsua_media.c +++ b/pjsip/src/pjsua-lib/pjsua_media.c @@ -393,11 +393,37 @@ static pj_status_t create_rtp_rtcp_sock(pjsua_call_media *call_med, if (status != PJ_SUCCESS && pjsua_var.ua_cfg.stun_srv_cnt > 1 && ((acc->cfg.media_stun_use & PJSUA_STUN_RETRY_ON_FAILURE)!=0)) { - PJ_LOG(4,(THIS_FILE, "Failed to get STUN mapped address, " - "retrying other STUN servers")); + pj_str_t srv = + pjsua_var.ua_cfg.stun_srv[pjsua_var.stun_srv_idx]; + + PJ_LOG(4,(THIS_FILE, "Failed to get STUN mapped address, " + "retrying other STUN servers")); + + if (pjsua_var.stun_srv_idx < pjsua_var.ua_cfg.stun_srv_cnt-1) { + PJSUA_LOCK(); + /* Move the unusable STUN server to the last position + * as the least prioritize. + */ + pj_array_erase(pjsua_var.ua_cfg.stun_srv, + sizeof(pj_str_t), + pjsua_var.ua_cfg.stun_srv_cnt, + pjsua_var.stun_srv_idx); + + pj_array_insert(pjsua_var.ua_cfg.stun_srv, + sizeof(pj_str_t), + pjsua_var.ua_cfg.stun_srv_cnt-1, + pjsua_var.ua_cfg.stun_srv_cnt-1, + &srv); + + PJSUA_UNLOCK(); + } status=pjsua_update_stun_servers(pjsua_var.ua_cfg.stun_srv_cnt, pjsua_var.ua_cfg.stun_srv, - PJ_TRUE); + PJ_FALSE); + + if (status == PJ_SUCCESS) + status = resolve_stun_server(PJ_TRUE); + if (status == PJ_SUCCESS) { if (pjsua_var.stun_srv.addr.sa_family != 0) { pj_ansi_strcpy(ip_addr, -- cgit v1.2.3