summaryrefslogtreecommitdiff
path: root/res/res_pjsip/pjsip_resolver.c
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2016-11-09 21:14:09 +0000
committerJoshua Colp <jcolp@digium.com>2016-11-10 10:11:13 -0500
commitbdb6d928c50942be88c0cf58532d4be7424464ad (patch)
treec11c24dc40ddfb3cdb4b24b8093911343154e2da /res/res_pjsip/pjsip_resolver.c
parent5cd03f6a7d4075d10ea4bb8dc2e13c8ed470ba8a (diff)
res_pjsip: Perform resolution when explicit IPv6 transport is used.
This change fixes the SIP resolver such that if an IPv6 transport is explicitly used it will resolve NAPTR, SRV, and AAAA records. You can explicitly use one by specifying it on an endpoint. ASTERISK-26571 Change-Id: I2ed3ce81b43a6a8a937c0ebc1b8ed2da5ac2ef36
Diffstat (limited to 'res/res_pjsip/pjsip_resolver.c')
-rw-r--r--res/res_pjsip/pjsip_resolver.c73
1 files changed, 52 insertions, 21 deletions
diff --git a/res/res_pjsip/pjsip_resolver.c b/res/res_pjsip/pjsip_resolver.c
index 4d4d36e27..5a902466e 100644
--- a/res/res_pjsip/pjsip_resolver.c
+++ b/res/res_pjsip/pjsip_resolver.c
@@ -231,8 +231,13 @@ static int sip_resolve_handle_naptr(struct sip_resolve *resolve, const struct as
return -1;
}
+ /* It is possible for us to receive an explicit transport that is already IPv6, in that case
+ * we can't turn it into an IPv6 transport and check. If it's not IPv6 though we need to check
+ * for both IPv4 and IPv6 as PJSIP does not provide enough differentiation to know that we
+ * want only IPv4.
+ */
if (!sip_transport_is_available(transport) &&
- !sip_transport_is_available(transport + PJSIP_TRANSPORT_IPV6)) {
+ (!(transport & PJSIP_TRANSPORT_IPV6) && !sip_transport_is_available(transport + PJSIP_TRANSPORT_IPV6))) {
ast_debug(2, "[%p] NAPTR service %s skipped as transport is unavailable\n",
resolve, service);
return -1;
@@ -343,13 +348,19 @@ static void sip_resolve_callback(const struct ast_dns_query_set *query_set)
/* SRV records just create new queries for AAAA+A, nothing fancy */
ast_debug(2, "[%p] SRV record received on target '%s'\n", resolve, ast_dns_query_get_name(query));
- if (sip_transport_is_available(target->transport + PJSIP_TRANSPORT_IPV6)) {
+ /* If an explicit IPv6 target transport has been requested look for only AAAA records */
+ if (target->transport & PJSIP_TRANSPORT_IPV6) {
+ sip_resolve_add(resolve, ast_dns_srv_get_host(record), ns_t_aaaa, ns_c_in, target->transport,
+ ast_dns_srv_get_port(record));
+ have_srv = 1;
+ } else if (sip_transport_is_available(target->transport + PJSIP_TRANSPORT_IPV6)) {
sip_resolve_add(resolve, ast_dns_srv_get_host(record), ns_t_aaaa, ns_c_in, target->transport + PJSIP_TRANSPORT_IPV6,
ast_dns_srv_get_port(record));
have_srv = 1;
}
- if (sip_transport_is_available(target->transport)) {
+ if (!(target->transport & PJSIP_TRANSPORT_IPV6) &&
+ sip_transport_is_available(target->transport)) {
sip_resolve_add(resolve, ast_dns_srv_get_host(record), ns_t_a, ns_c_in, target->transport,
ast_dns_srv_get_port(record));
have_srv = 1;
@@ -365,14 +376,20 @@ static void sip_resolve_callback(const struct ast_dns_query_set *query_set)
continue;
}
- if (target->transport == PJSIP_TRANSPORT_UNSPECIFIED || target->transport == PJSIP_TRANSPORT_UDP) {
- added = sip_resolve_handle_naptr(resolve, record, "sip+d2u", PJSIP_TRANSPORT_UDP);
+ if (target->transport == PJSIP_TRANSPORT_UNSPECIFIED || target->transport == PJSIP_TRANSPORT_UDP ||
+ target->transport == PJSIP_TRANSPORT_UDP6) {
+ added = sip_resolve_handle_naptr(resolve, record, "sip+d2u",
+ target->transport == PJSIP_TRANSPORT_UNSPECIFIED ? PJSIP_TRANSPORT_UDP : target->transport);
}
- if (target->transport == PJSIP_TRANSPORT_UNSPECIFIED || target->transport == PJSIP_TRANSPORT_TCP) {
- added = sip_resolve_handle_naptr(resolve, record, "sip+d2t", PJSIP_TRANSPORT_TCP);
+ if (target->transport == PJSIP_TRANSPORT_UNSPECIFIED || target->transport == PJSIP_TRANSPORT_TCP ||
+ target->transport == PJSIP_TRANSPORT_TCP6) {
+ added = sip_resolve_handle_naptr(resolve, record, "sip+d2t",
+ target->transport == PJSIP_TRANSPORT_UNSPECIFIED ? PJSIP_TRANSPORT_TCP : target->transport);
}
- if (target->transport == PJSIP_TRANSPORT_UNSPECIFIED || target->transport == PJSIP_TRANSPORT_TLS) {
- added = sip_resolve_handle_naptr(resolve, record, "sips+d2t", PJSIP_TRANSPORT_TLS);
+ if (target->transport == PJSIP_TRANSPORT_UNSPECIFIED || target->transport == PJSIP_TRANSPORT_TLS ||
+ target->transport == PJSIP_TRANSPORT_TLS6) {
+ added = sip_resolve_handle_naptr(resolve, record, "sips+d2t",
+ target->transport == PJSIP_TRANSPORT_UNSPECIFIED ? PJSIP_TRANSPORT_TLS : target->transport);
}
/* If this record was successfully handled then we need to limit ourselves to this order */
@@ -533,25 +550,39 @@ static void sip_resolve(pjsip_resolver_t *resolver, pj_pool_t *pool, const pjsip
if (!target->addr.port) {
char srv[NI_MAXHOST];
+ /* When resolving addresses PJSIP can request an explicit transport type. It will explicitly
+ * request an IPv6 transport if a message has been tagged to use an explicitly IPv6 transport.
+ * For other cases it can be left unspecified OR an explicit non-IPv6 transport can be requested.
+ * In the case where a non-IPv6 transport is requested there is no way to differentiate between
+ * a transport being requested as part of a SIP URI (sip:test.com;transport=tcp) and a message
+ * being tagged with a specific IPv4 transport. In this case we look for both IPv4 and IPv6 addresses.
+ * If a message has been tagged with a specific IPv4 transport the IPv6 addresses will simply
+ * be discarded. The code below and elsewhere handles the case where we know they requested IPv6
+ * explicitly and only looks for IPv6 records.
+ */
+
res |= sip_resolve_add(resolve, host, ns_t_naptr, ns_c_in, type, 0);
- if ((type == PJSIP_TRANSPORT_TLS || type == PJSIP_TRANSPORT_UNSPECIFIED) &&
- (sip_transport_is_available(PJSIP_TRANSPORT_TLS) ||
- sip_transport_is_available(PJSIP_TRANSPORT_TLS6))) {
+ if (type == PJSIP_TRANSPORT_UNSPECIFIED ||
+ (type == PJSIP_TRANSPORT_TLS && sip_transport_is_available(PJSIP_TRANSPORT_TLS)) ||
+ (type == PJSIP_TRANSPORT_TLS6 && sip_transport_is_available(PJSIP_TRANSPORT_TLS6))) {
snprintf(srv, sizeof(srv), "_sips._tcp.%s", host);
- res |= sip_resolve_add(resolve, srv, ns_t_srv, ns_c_in, PJSIP_TRANSPORT_TLS, 0);
+ res |= sip_resolve_add(resolve, srv, ns_t_srv, ns_c_in,
+ type == PJSIP_TRANSPORT_UNSPECIFIED ? PJSIP_TRANSPORT_TLS : type, 0);
}
- if ((type == PJSIP_TRANSPORT_TCP || type == PJSIP_TRANSPORT_UNSPECIFIED) &&
- (sip_transport_is_available(PJSIP_TRANSPORT_TCP) ||
- sip_transport_is_available(PJSIP_TRANSPORT_TCP6))) {
+ if (type == PJSIP_TRANSPORT_UNSPECIFIED ||
+ (type == PJSIP_TRANSPORT_TCP && sip_transport_is_available(PJSIP_TRANSPORT_TCP)) ||
+ (type == PJSIP_TRANSPORT_TCP6 && sip_transport_is_available(PJSIP_TRANSPORT_TCP6))) {
snprintf(srv, sizeof(srv), "_sip._tcp.%s", host);
- res |= sip_resolve_add(resolve, srv, ns_t_srv, ns_c_in, PJSIP_TRANSPORT_TCP, 0);
+ res |= sip_resolve_add(resolve, srv, ns_t_srv, ns_c_in,
+ type == PJSIP_TRANSPORT_UNSPECIFIED ? PJSIP_TRANSPORT_TCP : type, 0);
}
- if ((type == PJSIP_TRANSPORT_UDP || type == PJSIP_TRANSPORT_UNSPECIFIED) &&
- (sip_transport_is_available(PJSIP_TRANSPORT_UDP) ||
- sip_transport_is_available(PJSIP_TRANSPORT_UDP6))) {
+ if (type == PJSIP_TRANSPORT_UNSPECIFIED ||
+ (type == PJSIP_TRANSPORT_UDP && sip_transport_is_available(PJSIP_TRANSPORT_UDP)) ||
+ (type == PJSIP_TRANSPORT_UDP6 && sip_transport_is_available(PJSIP_TRANSPORT_UDP6))) {
snprintf(srv, sizeof(srv), "_sip._udp.%s", host);
- res |= sip_resolve_add(resolve, srv, ns_t_srv, ns_c_in, PJSIP_TRANSPORT_UDP, 0);
+ res |= sip_resolve_add(resolve, srv, ns_t_srv, ns_c_in,
+ type == PJSIP_TRANSPORT_UNSPECIFIED ? PJSIP_TRANSPORT_UDP : type, 0);
}
}