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..d1a292f1f61aca71fc200d9d3c4feedba19685b1 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..06abdd7a70d8c6d1fcc7112114d3309eac0a1040 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 746506d606c993d7f3f055cd8101747f9cfcf174..251bbb9e8b3fa96e03eefc0ed7e89fb82a07e9d9 100644 --- a/sflphone-common/libs/pjproject/pjsip/src/pjsip/sip_resolve.c +++ b/sflphone-common/libs/pjproject/pjsip/src/pjsip/sip_resolve.c @@ -369,14 +369,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, diff --git a/sflphone-common/src/sip/sipvoiplink.cpp b/sflphone-common/src/sip/sipvoiplink.cpp index a7cca643c030feb8a0e79895c9990d1373fe3d2e..07f7d70481deade5f63c15f25c9aed56efd4d918 100644 --- a/sflphone-common/src/sip/sipvoiplink.cpp +++ b/sflphone-common/src/sip/sipvoiplink.cpp @@ -560,11 +560,8 @@ int SIPVoIPLink::sendRegister (AccountID id) // Creates URI std::string fromUri; - std::string contactUri; - std::string srvUri; - std::string address; fromUri = account->getFromUri(); @@ -1772,7 +1769,7 @@ bool get_dns_server_addresses (std::vector<std::string> *servers) // Read configuration files if (res_init () != 0) { - _debug ("Resolver initialization failed"); + _debug ("UserAgent: Resolver initialization failed"); return false; } @@ -1797,44 +1794,43 @@ pj_status_t SIPVoIPLink::enable_dns_srv_resolver (pjsip_endpoint *endpt, pj_dns_ std::vector <std::string> dns_servers; int scount, i; + _debug("UserAgent: Enable DNS SRV resolver"); + // Create the DNS resolver instance status = pjsip_endpt_create_resolver (endpt, &resv); - if (status != PJ_SUCCESS) { - _debug ("Error creating the DNS resolver instance"); + _error ("UserAgent: Error: Creating the DNS resolver instance"); return status; } if (!get_dns_server_addresses (&dns_servers)) { - _debug ("Error while fetching DNS information"); + _error ("UserAgent: Error: while fetching DNS information"); return -1; } // Build the nameservers list needed by pjsip if ( (scount = dns_servers.size ()) <= 0) { - _debug ("No server detected while fetching DNS information, stop dns resolution"); + _warn ("UserAgent: No server detected while fetching DNS information, stop dns resolution"); return 0; } pj_str_t nameservers[scount]; - for (i = 0; i<scount; i++) { - nameservers[i] = pj_str ( (char*) dns_servers[i].c_str()); + _debug("UserAgent: Server: %s", (char *)dns_servers[i].c_str()); + nameservers[i] = pj_str ( (char *) dns_servers[i].c_str()); } // Update the name servers for the DNS resolver status = pj_dns_resolver_set_ns (resv, scount, nameservers, NULL); - if (status != PJ_SUCCESS) { - _debug ("Error updating the name servers for the DNS resolver"); + _debug ("UserAgent: Error updating the name servers for the DNS resolver"); return status; } // Set the DNS resolver instance of the SIP resolver engine status = pjsip_endpt_set_resolver (endpt, resv); - if (status != PJ_SUCCESS) { - _debug ("Error setting the DNS resolver instance of the SIP resolver engine"); + _debug ("UserAgent: Error setting the DNS resolver instance of the SIP resolver engine"); return status; }