summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2016-06-08 02:49:56 +0000
committerNanang Izzuddin <nanang@teluu.com>2016-06-08 02:49:56 +0000
commitc95f39268f6c4a0833249db7d2cbd8748a3561ae (patch)
tree0f409a93f06a8b690999ba4e10143ae1e1035d2b /pjsip
parentc95d1a0f5bbf0d68ba6ab45416d482165bb7c8dc (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.h5
-rw-r--r--pjsip/src/pjsip/sip_resolve.c28
-rw-r--r--pjsip/src/pjsip/sip_util.c8
-rw-r--r--pjsip/src/pjsua-lib/pjsua_acc.c76
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;
}