diff options
author | Nanang Izzuddin <nanang@teluu.com> | 2016-06-08 02:49:56 +0000 |
---|---|---|
committer | Nanang Izzuddin <nanang@teluu.com> | 2016-06-08 02:49:56 +0000 |
commit | c95f39268f6c4a0833249db7d2cbd8748a3561ae (patch) | |
tree | 0f409a93f06a8b690999ba4e10143ae1e1035d2b /pjsip | |
parent | c95d1a0f5bbf0d68ba6ab45416d482165bb7c8dc (diff) |
Close #1926: Support IPv6 address resolution without DNS resolver.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5337 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua_internal.h | 5 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_resolve.c | 28 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_util.c | 8 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_acc.c | 76 |
4 files changed, 83 insertions, 34 deletions
diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h index 8a4f6c84..e6cc824e 100644 --- a/pjsip/include/pjsua-lib/pjsua_internal.h +++ b/pjsip/include/pjsua-lib/pjsua_internal.h @@ -283,6 +283,8 @@ typedef struct pjsua_acc pjsip_dialog *mwi_dlg; /**< Dialog for MWI sub. */ pj_uint16_t next_rtp_port; /**< Next RTP port to be used. */ + pjsip_transport_type_e tp_type; /**< Transport type (for local acc or + transport binding) */ } pjsua_acc; @@ -622,6 +624,9 @@ pj_status_t normalize_route_uri(pj_pool_t *pool, pj_str_t *uri); pj_bool_t pjsua_sip_acc_is_using_stun(pjsua_acc_id acc_id); pj_bool_t pjsua_media_acc_is_using_stun(pjsua_acc_id acc_id); +/* acc use IPv6? */ +pj_bool_t pjsua_sip_acc_is_using_ipv6(pjsua_acc_id acc_id); + /* Get local transport address suitable to be used for Via or Contact address * to send request to the specified destination URI. */ diff --git a/pjsip/src/pjsip/sip_resolve.c b/pjsip/src/pjsip/sip_resolve.c index 23dab442..d05a02f2 100644 --- a/pjsip/src/pjsip/sip_resolve.c +++ b/pjsip/src/pjsip/sip_resolve.c @@ -195,6 +195,7 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver, int ip_addr_ver; struct query *query; pjsip_transport_type_e type = target->type; + int af = pj_AF_UNSPEC(); /* If an external implementation has been provided use it instead */ if (resolver->ext_res) { @@ -205,6 +206,12 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver, /* Is it IP address or hostname? And if it's an IP, which version? */ ip_addr_ver = get_ip_addr_ver(&target->addr.host); + /* Initialize address family type */ + if ((ip_addr_ver == 6) || (type & PJSIP_TRANSPORT_IPV6)) + af = pj_AF_INET6(); + else if (ip_addr_ver == 4) + af = pj_AF_INET(); + /* Set the transport type if not explicitly specified. * RFC 3263 section 4.1 specify rules to set up this. */ @@ -241,10 +248,6 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver, type = PJSIP_TRANSPORT_UDP; } } - - /* Add IPv6 flag for IPv6 address */ - if (ip_addr_ver == 6) - type = (pjsip_transport_type_e)((int)type + PJSIP_TRANSPORT_IPV6); } @@ -271,7 +274,6 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver, } else { pj_addrinfo ai; unsigned count; - int af; PJ_LOG(5,(THIS_FILE, "DNS resolver not available, target '%.*s:%d' type=%s " @@ -281,12 +283,6 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver, target->addr.port, pjsip_transport_get_type_name(target->type))); - if (type & PJSIP_TRANSPORT_IPV6) { - af = pj_AF_INET6(); - } else { - af = pj_AF_INET(); - } - /* Resolve */ count = 1; status = pj_getaddrinfo(af, &target->addr.host, &count, &ai); @@ -299,11 +295,15 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver, goto on_error; } - svr_addr.entry[0].addr.addr.sa_family = (pj_uint16_t)af; - pj_memcpy(&svr_addr.entry[0].addr, &ai.ai_addr, - sizeof(pj_sockaddr)); + pj_sockaddr_cp(&svr_addr.entry[0].addr, &ai.ai_addr); + if (af == pj_AF_UNSPEC()) + af = ai.ai_addr.addr.sa_family; } + /* After address resolution, update IPv6 bitflag in transport type. */ + if (af == pj_AF_INET6()) + type |= PJSIP_TRANSPORT_IPV6; + /* Set the port number */ if (target->addr.port == 0) { srv_port = (pj_uint16_t) diff --git a/pjsip/src/pjsip/sip_util.c b/pjsip/src/pjsip/sip_util.c index 21ea2375..6b8fa508 100644 --- a/pjsip/src/pjsip/sip_util.c +++ b/pjsip/src/pjsip/sip_util.c @@ -1016,6 +1016,14 @@ PJ_DEF(pj_status_t) pjsip_process_route_set(pjsip_tx_data *tdata, if (status != PJ_SUCCESS) return status; + /* If transport selector is set, set destination type accordingly */ + if (tdata->tp_sel.type != PJSIP_TPSELECTOR_NONE && tdata->tp_sel.u.ptr) { + if (tdata->tp_sel.type == PJSIP_TPSELECTOR_TRANSPORT) + dest_info->type = tdata->tp_sel.u.transport->key.type; + else if (tdata->tp_sel.type == PJSIP_TPSELECTOR_LISTENER) + dest_info->type = tdata->tp_sel.u.listener->type; + } + /* If target URI is different than request URI, replace * request URI add put the original URI in the last Route header. */ diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c index 87f14398..3923be3e 100644 --- a/pjsip/src/pjsua-lib/pjsua_acc.c +++ b/pjsip/src/pjsua-lib/pjsua_acc.c @@ -381,6 +381,9 @@ static pj_status_t initialize_acc(unsigned acc_id) pj_array_insert(pjsua_var.acc_ids, sizeof(pjsua_var.acc_ids[0]), pjsua_var.acc_cnt, i, &acc_id); + if (acc_cfg->transport_id != PJSUA_INVALID_ID) + acc->tp_type = pjsua_var.tpdata[acc_cfg->transport_id].type; + return PJ_SUCCESS; } @@ -512,6 +515,8 @@ PJ_DEF(pj_status_t) pjsua_acc_add_local( pjsua_transport_id tid, const char *beginquote, *endquote; char transport_param[32]; char uri[PJSIP_MAX_URL_SIZE]; + pjsua_acc_id acc_id; + pj_status_t status; /* ID must be valid */ PJ_ASSERT_RETURN(tid>=0 && tid<(int)PJ_ARRAY_SIZE(pjsua_var.tpdata), @@ -554,7 +559,14 @@ PJ_DEF(pj_status_t) pjsua_acc_add_local( pjsua_transport_id tid, cfg.id = pj_str(uri); - return pjsua_acc_add(&cfg, is_default, p_acc_id); + status = pjsua_acc_add(&cfg, is_default, &acc_id); + if (status == PJ_SUCCESS) { + pjsua_var.acc[acc_id].tp_type = t->type; + if (p_acc_id) + *p_acc_id = acc_id; + } + + return status; } @@ -2480,6 +2492,13 @@ static pj_status_t pjsua_regc_init(int acc_id) return PJ_SUCCESS; } +pj_bool_t pjsua_sip_acc_is_using_ipv6(pjsua_acc_id acc_id) +{ + pjsua_acc *acc = &pjsua_var.acc[acc_id]; + + return (acc->tp_type & PJSIP_TRANSPORT_IPV6) == PJSIP_TRANSPORT_IPV6; +} + pj_bool_t pjsua_sip_acc_is_using_stun(pjsua_acc_id acc_id) { pjsua_acc *acc = &pjsua_var.acc[acc_id]; @@ -2919,15 +2938,10 @@ PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata) pjsua_acc *acc = &pjsua_var.acc[acc_id]; if (acc->valid && pj_stricmp(&acc->user_part, &sip_uri->user)==0) { - - if (acc->cfg.transport_id != PJSUA_INVALID_ID) { - pjsip_transport_type_e type; - type = pjsip_transport_get_type_from_name(&sip_uri->transport_param); - if (type == PJSIP_TRANSPORT_UNSPECIFIED) - type = PJSIP_TRANSPORT_UDP; - - if (pjsua_var.tpdata[acc->cfg.transport_id].type != type) - continue; + if (acc->tp_type != PJSIP_TRANSPORT_UNSPECIFIED && + acc->tp_type != rdata->tp_info.transport->key.type) + { + continue; } /* Match ! */ @@ -3100,10 +3114,10 @@ pj_status_t pjsua_acc_get_uac_addr(pjsua_acc_id acc_id, if (tp_type == PJSIP_TRANSPORT_UNSPECIFIED) return PJSIP_EUNSUPTRANSPORT; - /* If destination URI specifies IPv6, then set transport type - * to use IPv6 as well. + /* If destination URI specifies IPv6 or account is configured to use IPv6, + * then set transport type to use IPv6 as well. */ - if (pj_strchr(&sip_uri->host, ':')) + if (pj_strchr(&sip_uri->host, ':') || pjsua_sip_acc_is_using_ipv6(acc_id)) tp_type = (pjsip_transport_type_e)(((int)tp_type) | PJSIP_TRANSPORT_IPV6); @@ -3166,11 +3180,26 @@ pj_status_t pjsua_acc_get_uac_addr(pjsua_acc_id acc_id, if (status == PJ_SUCCESS) { unsigned cnt=1; - int af; + int af = pj_AF_UNSPEC(); - af = (dinfo.type & PJSIP_TRANSPORT_IPV6)? PJ_AF_INET6 : PJ_AF_INET; + if (pjsua_sip_acc_is_using_ipv6(acc_id) || + (dinfo.type & PJSIP_TRANSPORT_IPV6)) + { + af = pj_AF_INET6(); + } status = pj_getaddrinfo(af, &dinfo.addr.host, &cnt, &ai); - if (cnt == 0) status = PJ_ENOTSUP; + if (cnt == 0) { + status = PJ_ENOTSUP; + } else if ((dinfo.type & PJSIP_TRANSPORT_IPV6)==0 && + ai.ai_addr.addr.sa_family == pj_AF_INET6()) + { + /* Destination is a hostname and account is not bound to IPv6, + * but hostname resolution reveals that it has IPv6 address, + * so let's use IPv6 transport type. + */ + dinfo.type |= PJSIP_TRANSPORT_IPV6; + tp_type |= PJSIP_TRANSPORT_IPV6; + } } if (status == PJ_SUCCESS) { @@ -3416,11 +3445,17 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uas_contact( pj_pool_t *pool, if (tp_type == PJSIP_TRANSPORT_UNSPECIFIED) return PJSIP_EUNSUPTRANSPORT; - /* If destination URI specifies IPv6, then set transport type - * to use IPv6 as well. + /* If destination URI specifies IPv6 or account is configured to use IPv6 + * or the transport being used to receive data is an IPv6 transport, + * then set transport type to use IPv6 as well. */ - if (pj_strchr(&sip_uri->host, ':')) - tp_type = (pjsip_transport_type_e)(((int)tp_type) + PJSIP_TRANSPORT_IPV6); + if (pj_strchr(&sip_uri->host, ':') || + pjsua_sip_acc_is_using_ipv6(acc_id) || + (rdata->tp_info.transport->key.type & PJSIP_TRANSPORT_IPV6)) + { + tp_type = (pjsip_transport_type_e) + (((int)tp_type) | PJSIP_TRANSPORT_IPV6); + } flag = pjsip_transport_get_flag_from_type(tp_type); secure = (flag & PJSIP_TRANSPORT_SECURE) != 0; @@ -3504,6 +3539,7 @@ PJ_DEF(pj_status_t) pjsua_acc_set_transport( pjsua_acc_id acc_id, PJ_EINVAL); acc->cfg.transport_id = tp_id; + acc->tp_type = pjsua_var.tpdata[tp_id].type; return PJ_SUCCESS; } |