diff --git a/sflphone-common/libs/pjproject/pjlib-util/include/pjlib-util/srv_resolver.h b/sflphone-common/libs/pjproject/pjlib-util/include/pjlib-util/srv_resolver.h index 216e91b9e5d525d9807b1d26cd4896b639fba186..45e05357896f975ce8c393a55d7d446b38bf9b39 100644 --- a/sflphone-common/libs/pjproject/pjlib-util/include/pjlib-util/srv_resolver.h +++ b/sflphone-common/libs/pjproject/pjlib-util/include/pjlib-util/srv_resolver.h @@ -104,7 +104,19 @@ typedef enum pj_dns_srv_option * this option is not specified, the SRV resolver will query * the DNS A record for the target instead. */ - PJ_DNS_SRV_RESOLVE_AAAA = 4 + PJ_DNS_SRV_RESOLVE_AAAA = 4, + + /** + * Specify if the resolver should fallback to getaddrinfo + * under IPV4 mode if DNS A fails after DNS SRV. + */ + PJ_DNS_SRV_FALLBACK_GETADDRINFO_IPV4 = 8, + + /** + * Specify if the resolver should fallback to getaddrinfo + * under IPV6 mode if DNS A fails after DNS SRV. + */ + PJ_DNS_SRV_FALLBACK_GETADDRINFO_IPV6 = 16, } pj_dns_srv_option; diff --git a/sflphone-common/libs/pjproject/pjlib-util/src/pjlib-util/srv_resolver.c b/sflphone-common/libs/pjproject/pjlib-util/src/pjlib-util/srv_resolver.c index 83963495574d53a1b9cfdaa596d02629eda89e1d..df15eb903318d0b0459962fb0678f8516bbd40b4 100644 --- a/sflphone-common/libs/pjproject/pjlib-util/src/pjlib-util/srv_resolver.c +++ b/sflphone-common/libs/pjproject/pjlib-util/src/pjlib-util/srv_resolver.c @@ -19,6 +19,7 @@ */ #include <pjlib-util/srv_resolver.h> #include <pjlib-util/errno.h> +#include <pj/addr_resolv.h> #include <pj/array.h> #include <pj/assert.h> #include <pj/log.h> @@ -583,13 +584,53 @@ static void dns_callback(void *user_data, } else if (status != PJ_SUCCESS) { char errmsg[PJ_ERR_MSG_SIZE]; - /* Update last error */ - query_job->last_error = status; - - /* Log error */ - pj_strerror(status, errmsg, sizeof(errmsg)); - PJ_LOG(4,(query_job->objname, "DNS A record resolution failed: %s", - errmsg)); + if ((query_job->option & + (PJ_DNS_SRV_FALLBACK_GETADDRINFO_IPV4 | PJ_DNS_SRV_FALLBACK_GETADDRINFO_IPV6))) + { + pj_strerror(status, errmsg, sizeof(errmsg)); + PJ_LOG(4,(query_job->objname, + "DNS A record resolution failed: %s," + " trying getaddrinfo()", + errmsg)); + + pj_addrinfo ai; + unsigned count; + int af; + + if ((query_job->option & PJ_DNS_SRV_FALLBACK_GETADDRINFO_IPV6)) { + af = pj_AF_INET6(); + } else { + af = pj_AF_INET(); + } + + count = 1; + status = pj_getaddrinfo(af, &query_job->domain_part, &count, &ai); + if (status != PJ_SUCCESS) { + query_job->last_error = status; + pj_strerror(status, errmsg, sizeof(errmsg)); + PJ_LOG(4,(query_job->objname, "DNS resolution failed with getaddrinfo(): %s", + errmsg)); + } else { + + if (srv->addr_cnt < ADDR_MAX_COUNT) { + srv->addr[srv->addr_cnt++].s_addr = ai.ai_addr.ipv4.sin_addr.s_addr; + } + + PJ_LOG(5,(query_job->objname, + "DNS getaddrinfo() for %.*s: %s", + (int)srv->target_name.slen, + srv->target_name.ptr, + pj_inet_ntoa(srv->addr[srv->addr_cnt]))); + } + } else { + /* Update last error */ + query_job->last_error = status; + + /* Log error */ + pj_strerror(status, errmsg, sizeof(errmsg)); + PJ_LOG(4,(query_job->objname, "DNS A record resolution failed: %s", + errmsg)); + } } ++query_job->host_resolved; diff --git a/sflphone-common/libs/pjproject/pjsip/src/pjsip/sip_resolve.c b/sflphone-common/libs/pjproject/pjsip/src/pjsip/sip_resolve.c index 3c9e610af87da4540fc32d37ecb45a594919ac4f..a7293f688f66104db2b7bc92fce8e2dbcfe497f9 100644 --- a/sflphone-common/libs/pjproject/pjsip/src/pjsip/sip_resolve.c +++ b/sflphone-common/libs/pjproject/pjsip/src/pjsip/sip_resolve.c @@ -361,14 +361,21 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver, if (query->query_type == PJ_DNS_TYPE_SRV) { - status = pj_dns_srv_resolve(&query->naptr[0].name, - &query->naptr[0].res_type, - query->req.def_port, pool, resolver->res, - PJ_TRUE, query, &srv_resolver_cb, NULL); + unsigned option = PJ_TRUE; + if (type & PJSIP_TRANSPORT_IPV6) { + option |= PJ_DNS_SRV_FALLBACK_GETADDRINFO_IPV6; + } else { + option |= PJ_DNS_SRV_FALLBACK_GETADDRINFO_IPV4; + } + + status = pj_dns_srv_resolve(&query->naptr[0].name, + &query->naptr[0].res_type, + query->req.def_port, pool, resolver->res, + option, query, &srv_resolver_cb, NULL); } else if (query->query_type == PJ_DNS_TYPE_A) { - status = pj_dns_resolver_start_query(resolver->res, + status = pj_dns_resolver_start_query(resolver->res, &query->naptr[0].name, PJ_DNS_TYPE_A, 0, &dns_a_callback,