Commit a36aa008 authored by Alexandre Savard's avatar Alexandre Savard
Browse files

[#3168] Reapply patch described in #1841

parent dfe439ad
......@@ -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;
......
......@@ -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;
......
......@@ -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,
......
......@@ -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;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment