|
reSIProcate/rutil
9694
|
#include <AresDns.hxx>


Public Member Functions | |
| AresDns () | |
| virtual | ~AresDns () |
| virtual int | init (const std::vector< GenericIPAddress > &additionalNameservers, AfterSocketCreationFuncPtr socketfunc, int timeout=0, int tries=0, unsigned int features=0) |
| int | internalInit (const std::vector< GenericIPAddress > &additionalNameservers, AfterSocketCreationFuncPtr socketfunc, unsigned int features=0, ares_channeldata **channel=0, int timeout=0, int tries=0) |
| virtual bool | checkDnsChange () |
| virtual unsigned int | getTimeTillNextProcessMS () |
| virtual void | process (FdSet &fdset) |
| Called once select() returns; this allows this object to inspect which of its FDs are ready, and perform any necessary IO with them. | |
| virtual void | buildFdSet (FdSet &fdset) |
| Add any FDs that we are interested in watching to an fdset, with the understanding that a select() call will be made immediately after. | |
| virtual void | buildFdSet (fd_set &read, fd_set &write, int &size) |
| virtual void | process (fd_set &read, fd_set &write) |
| virtual void | setPollGrp (FdPollGrp *pollGrp) |
| virtual void | processTimers () |
| virtual void | freeResult (ExternalDnsRawResult) |
| virtual void | freeResult (ExternalDnsHostResult) |
| virtual char * | errorMessage (long errorCode) |
| void | lookup (const char *target, unsigned short type, ExternalDnsHandler *handler, void *userData) |
| virtual bool | hostFileLookup (const char *target, in_addr &addr) |
| virtual bool | hostFileLookupLookupOnlyMode () |
| friend | void::resip_AresDns_aresCallback (void *arg, int status, unsigned char *abuf, int alen) |
| friend | void::resip_AresDns_caresCallback (void *arg, int status, int timeouts, unsigned char *abuf, int alen) |
Static Public Member Functions | |
| static void | enableHostFileLookupOnlyMode (bool enable) |
Private Types | |
| typedef std::pair < ExternalDnsHandler *, void * > | Payload |
Static Private Member Functions | |
| static ExternalDnsRawResult | makeRawResult (void *arg, int status, unsigned char *abuf, int alen) |
| static ExternalDnsHandler * | getHandler (void *arg) |
Private Attributes | |
| struct ares_channeldata * | mChannel |
| std::vector< GenericIPAddress > | mAdditionalNameservers |
| unsigned int | mFeatures |
| FdPollGrp * | mPollGrp |
| std::vector< AresDnsPollItem * > | mPollItems |
Static Private Attributes | |
| static volatile bool | mHostFileLookupOnlyMode = false |
Friends | |
| class | AresDnsPollItem |
Definition at line 25 of file AresDns.hxx.
typedef std::pair<ExternalDnsHandler*, void*> resip::AresDns::Payload [private] |
Definition at line 70 of file AresDns.hxx.
| resip::AresDns::AresDns | ( | ) | [inline] |
| AresDns::~AresDns | ( | ) | [virtual] |
Definition at line 515 of file AresDns.cxx.
References mChannel.
| void AresDns::buildFdSet | ( | FdSet & | fdset | ) | [virtual] |
Add any FDs that we are interested in watching to an fdset, with the understanding that a select() call will be made immediately after.
| fdset | The FdSet to be augmented |
Implements resip::FdSetIOObserver.
Definition at line 620 of file AresDns.cxx.
References resip::FdSet::read, resip::FdSet::size, and resip::FdSet::write.
{
buildFdSet(fdset.read, fdset.write, fdset.size);
}
| void AresDns::buildFdSet | ( | fd_set & | read, |
| fd_set & | write, | ||
| int & | size | ||
| ) | [virtual] |
Implements resip::ExternalDns.
Definition at line 591 of file AresDns.cxx.
References mChannel.
{
int newsize = ares_fds(mChannel, &read, &write);
if ( newsize > size )
{
size = newsize;
}
}
| bool AresDns::checkDnsChange | ( | ) | [virtual] |
Implements resip::ExternalDns.
Definition at line 416 of file AresDns.cxx.
References InfoLog, internalInit(), mAdditionalNameservers, mChannel, mFeatures, and resip::ExternalDns::Success.
{
// We must return 'true' if there are changes in the list of DNS servers
struct ares_channeldata* channel = 0;
bool bRet = false;
int result = internalInit(mAdditionalNameservers, 0, mFeatures, &channel);
if(result != Success || channel == 0)
{
// It has changed because it failed, I suppose
InfoLog(<< " DNS server list changed");
return true;
}
#if defined(USE_ARES)
{
// Compare the two lists. Are they different sizes?
if(mChannel->nservers != channel->nservers)
{
// Yes, so they're different
bRet = true;
}
else
{
// Compare them one-by-one
for (int i = 0; i < mChannel->nservers; ++i)
{
if (mChannel->servers[i].addr.s_addr
!= channel->servers[i].addr.s_addr)
{
bRet = true;
break;
}
}
}
// Destroy the secondary configuration we read
ares_destroy_suppress_callbacks(channel);
}
#elif defined(USE_CARES)
{
// Get the options, including the server list, from the old and the
// current (i.e. just read) configuration.
struct ares_options old;
struct ares_options updated;
std::memset(&old, 0, sizeof(old));
std::memset(&updated, 0, sizeof(updated));
int ignored;
// Can we get the configuration?
if(ares_save_options(mChannel, &old, &ignored) != ARES_SUCCESS
|| ares_save_options(channel, &updated, &ignored) != ARES_SUCCESS)
{
// It failed, so call it different
bRet = true;
}
else
{
// Compare the two lists. Are they different sizes?
if(old.nservers != updated.nservers)
{
// Yes, so they're different
bRet = true;
}
else
{
// Compare them one-by-one
for (int i = 0; i < old.nservers; ++i)
{
if (old.servers[i].s_addr != updated.servers[i].s_addr)
{
bRet = true;
break;
}
}
}
// Free any ares_options contents we have created.
ares_destroy_options(&old);
ares_destroy_options(&updated);
}
// Destroy the secondary configuration we read
ares_destroy(channel);
}
#endif
// Report on the results
if(!bRet)
{
InfoLog(<< " No changes in DNS server list");
}
else
{
InfoLog(<< " DNS server list changed");
}
return bRet;
}

| static void resip::AresDns::enableHostFileLookupOnlyMode | ( | bool | enable | ) | [inline, static] |
Definition at line 60 of file AresDns.hxx.
References mHostFileLookupOnlyMode.
{ mHostFileLookupOnlyMode = enable; }
| char * AresDns::errorMessage | ( | long | errorCode | ) | [virtual] |
Implements resip::ExternalDns.
Definition at line 632 of file AresDns.cxx.
{
const char* aresMsg = ares_strerror(errorCode);
size_t len = strlen(aresMsg);
char* errorString = new char[len+1];
strncpy(errorString, aresMsg, len);
errorString[len] = '\0';
return errorString;
}
| virtual void resip::AresDns::freeResult | ( | ExternalDnsRawResult | ) | [inline, virtual] |
| virtual void resip::AresDns::freeResult | ( | ExternalDnsHostResult | ) | [inline, virtual] |
| ExternalDnsHandler * AresDns::getHandler | ( | void * | arg | ) | [static, private] |
Definition at line 559 of file AresDns.cxx.
Referenced by resip_AresDns_aresCallback().
{
Payload* p = reinterpret_cast<Payload*>(arg);
ExternalDnsHandler *thisp = reinterpret_cast<ExternalDnsHandler*>(p->first);
return thisp;
}
| unsigned int AresDns::getTimeTillNextProcessMS | ( | ) | [virtual] |
Implements resip::ExternalDns.
Definition at line 583 of file AresDns.cxx.
References mChannel.
{
struct timeval tv;
ares_timeout(mChannel, NULL, &tv);
return tv.tv_sec*1000 + tv.tv_usec / 1000;
}
| bool AresDns::hostFileLookup | ( | const char * | target, |
| in_addr & | addr | ||
| ) | [virtual] |
Implements resip::ExternalDns.
Definition at line 524 of file AresDns.cxx.
References DebugLog, and mChannel.
{
assert(target);
hostent *hostdata = 0;
// Look this up
int status =
#if defined(USE_ARES)
hostfile_lookup(target, &hostdata)
#elif defined(USE_CARES)
ares_gethostbyname_file(mChannel, target, AF_INET, &hostdata)
#endif
;
if (status != ARES_SUCCESS)
{
DebugLog(<< "hostFileLookup failed for " << target);
return false;
}
sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr)); /* Initialize sockaddr fields. */
saddr.sin_family = AF_INET;
memcpy((char *)&(saddr.sin_addr.s_addr),(char *)hostdata->h_addr_list[0], (size_t)hostdata->h_length);
addr = saddr.sin_addr;
#if defined(USE_ARES)
// for resip-ares, the hostdata (and its contents) is dynamically allocated
ares_free_hostent(hostdata);
#endif
DebugLog(<< "hostFileLookup succeeded for " << target);
return true;
}
| virtual bool resip::AresDns::hostFileLookupLookupOnlyMode | ( | ) | [inline, virtual] |
Implements resip::ExternalDns.
Definition at line 59 of file AresDns.hxx.
References mHostFileLookupOnlyMode.
{ return mHostFileLookupOnlyMode; }
| int AresDns::init | ( | const std::vector< GenericIPAddress > & | additionalNameservers, |
| AfterSocketCreationFuncPtr | socketfunc, | ||
| int | timeout = 0, |
||
| int | tries = 0, |
||
| unsigned int | features = 0 |
||
| ) | [virtual] |
Implements resip::ExternalDns.
Definition at line 170 of file AresDns.cxx.
References internalInit(), mAdditionalNameservers, mChannel, mFeatures, mHostFileLookupOnlyMode, and resip::ExternalDns::Success.
{
mAdditionalNameservers = additionalNameservers;
mFeatures = features;
int ret = internalInit(additionalNameservers,
socketfunc,
features,
&mChannel,
timeout,
tries);
if (ret != Success)
return ret;
#ifdef WIN32
// For windows OSs it is uncommon to run a local DNS server. Therefor if there
// are no defined DNS servers in windows networking and ARES just returned the
// loopback address (ie. default localhost server / named)
// then put resip DNS resolution into hostfile lookup only mode
if(mChannel->nservers == 1 &&
mChannel->servers[0].default_localhost_server)
{
// enable hostfile only lookup mode
mHostFileLookupOnlyMode = true;
}
else
{
// disable hostfile only lookup mode
mHostFileLookupOnlyMode = false;
}
#endif
return Success;
}

| int AresDns::internalInit | ( | const std::vector< GenericIPAddress > & | additionalNameservers, |
| AfterSocketCreationFuncPtr | socketfunc, | ||
| unsigned int | features = 0, |
||
| ares_channeldata ** | channel = 0, |
||
| int | timeout = 0, |
||
| int | tries = 0 |
||
| ) |
Definition at line 211 of file AresDns.cxx.
References resip::ExternalDns::BuildMismatch, ErrLog, resip::DnsUtil::inet_ntop(), InfoLog, mChannel, mPollGrp, mPollItems, resip::AresDnsPollItem::socket_poll_cb(), resip::ExternalDns::Success, resip::ExternalDns::TryServersOfNextNetworkUponRcode3, and WarningLog.
Referenced by checkDnsChange(), and init().
{
if(*channel)
{
#if defined(USE_ARES)
ares_destroy_suppress_callbacks(*channel);
#elif defined(USE_CARES)
// Callbacks will be supressed by looking for the ARES_EDESTRUCTION
// sentinel status
ares_destroy(*channel);
#endif
*channel = 0;
}
#if defined(USE_ARES)
#ifdef USE_IPV6
int requiredCap = ARES_CAP_IPV6;
#else
int requiredCap = 0;
#endif
// Only the contrib/ares has this function
int cap = ares_capabilities(requiredCap);
if (cap != requiredCap)
{
ErrLog (<< "Build mismatch (ipv4/ipv6) problem in ares library"); // !dcm!
return BuildMismatch;
}
#endif
int status;
ares_options opt;
int optmask = 0;
memset(&opt, '\0', sizeof(opt));
#if defined(USE_ARES)
// TODO: What is this and how does it map to c-ares?
if ((features & ExternalDns::TryServersOfNextNetworkUponRcode3))
{
optmask |= ARES_OPT_FLAGS;
opt.flags |= ARES_FLAG_TRY_NEXT_SERVER_ON_RCODE3;
}
#endif
#if defined(USE_CARES)
// In c-ares, we can actually set the timeout and retries via the API
if (timeout > 0)
{
opt.timeout = timeout;
optmask |= ARES_OPT_TIMEOUT;
}
if (tries > 0)
{
opt.tries = tries;
optmask |= ARES_OPT_TRIES;
}
#endif
if (additionalNameservers.empty())
{
#if defined(USE_ARES)
status = ares_init_options_with_socket_function(channel, &opt, optmask, socketfunc);
#elif defined(USE_CARES)
// TODO: Does the socket function matter?
status = ares_init_options(channel, &opt, optmask);
#endif
}
else
{
optmask |= ARES_OPT_SERVERS;
opt.nservers = (int)additionalNameservers.size();
#if defined(USE_IPV6) && defined(USE_ARES)
// With contrib/ares, you can configure IPv6 addresses for the
// nameservers themselves.
opt.servers = new multiFamilyAddr[additionalNameservers.size()];
for (size_t i =0; i < additionalNameservers.size(); i++)
{
if (additionalNameservers[i].isVersion4())
{
opt.servers[i].family = AF_INET;
opt.servers[i].addr = additionalNameservers[i].v4Address.sin_addr;
}
else
{
opt.servers[i].family = AF_INET6;
opt.servers[i].addr6 = additionalNameservers[i].v6Address.sin6_addr;
}
}
#else
// If we're only supporting IPv4 or we are using c-ares, we can't
// support additional nameservers that are IPv6 right now.
opt.servers = new in_addr[additionalNameservers.size()];
for (size_t i =0; i < additionalNameservers.size(); i++)
{
if(additionalNameservers[i].isVersion4())
{
opt.servers[i] = additionalNameservers[i].v4Address.sin_addr;
}
else
{
#if defined(USE_CARES)
WarningLog (<< "Ignoring non-IPv4 additional name server (not yet supported with c-ares)");
#elif defined(USE_ARES)
WarningLog (<< "Ignoring non-IPv4 additional name server (IPv6 support was not enabled)");
#endif
}
}
#endif
#if defined(USE_ARES)
status = ares_init_options_with_socket_function(channel, &opt, optmask, socketfunc);
#elif defined(USE_CARES)
// TODO: Does the socket function matter?
status = ares_init_options(channel, &opt, optmask);
#endif
delete [] opt.servers;
opt.servers = 0;
}
if (status != ARES_SUCCESS)
{
ErrLog (<< "Failed to initialize DNS library (status=" << status << ")");
return status;
}
else
{
#if defined(USE_ARES)
InfoLog(<< "DNS initialization: found " << (*channel)->nservers << " name servers");
for (int i = 0; i < (*channel)->nservers; ++i)
{
#ifdef USE_IPV6
if((*channel)->servers[i].family == AF_INET6)
{
InfoLog(<< " name server: " << DnsUtil::inet_ntop((*channel)->servers[i].addr6));
}
else
#endif
{
InfoLog(<< " name server: " << DnsUtil::inet_ntop((*channel)->servers[i].addr));
}
}
// In ares, we must manipulate these directly
if (timeout > 0)
{
mChannel->timeout = timeout;
}
if (tries > 0)
{
mChannel->tries = tries;
}
#ifndef USE_CARES
if ( mPollGrp )
{
// expand vector to hold {nservers} and init to NULL
mPollItems.insert( mPollItems.end(), (*channel)->nservers, (AresDnsPollItem*)0);
// tell ares to let us know when things change
ares_process_set_poll_cb(mChannel, AresDnsPollItem::socket_poll_cb, this);
}
#endif
#elif defined(USE_CARES)
{
// Log which version of c-ares we're using
InfoLog(<< "DNS initialization: using c-ares v"
<< ::ares_version(NULL));
// Ask for the current configuration so we can print the servers found
struct ares_options options;
std::memset(&options, 0, sizeof(options));
int ignored;
if(ares_save_options(*channel, &options, &ignored) == ARES_SUCCESS)
{
InfoLog(<< "DNS initialization: found "
<< options.nservers << " name servers");
// Log them all
for (int i = 0; i < options.nservers; ++i)
{
InfoLog(<< " name server: "
<< DnsUtil::inet_ntop(options.servers[i]));
}
ares_destroy_options(&options);
}
}
#endif
return Success;
}
}

| void AresDns::lookup | ( | const char * | target, |
| unsigned short | type, | ||
| ExternalDnsHandler * | handler, | ||
| void * | userData | ||
| ) | [virtual] |
Implements resip::ExternalDns.
Definition at line 645 of file AresDns.cxx.
References mChannel, resip_AresDns_aresCallback(), and resip_AresDns_caresCallback().
{
ares_query(mChannel, target, C_IN, type,
#if defined(USE_ARES)
resip_AresDns_aresCallback,
#elif defined(USE_CARES)
resip_AresDns_caresCallback,
#endif
new Payload(handler, userData));
}

| ExternalDnsRawResult AresDns::makeRawResult | ( | void * | arg, |
| int | status, | ||
| unsigned char * | abuf, | ||
| int | alen | ||
| ) | [static, private] |
Definition at line 567 of file AresDns.cxx.
Referenced by resip_AresDns_aresCallback().
{
Payload* p = reinterpret_cast<Payload*>(arg);
void* userArg = reinterpret_cast<void*>(p->second);
if (status != ARES_SUCCESS)
{
return ExternalDnsRawResult(status, abuf, alen, userArg);
}
else
{
return ExternalDnsRawResult(abuf, alen, userArg);
}
}
| void AresDns::process | ( | FdSet & | fdset | ) | [virtual] |
Called once select() returns; this allows this object to inspect which of its FDs are ready, and perform any necessary IO with them.
| fdset | The FdSet after the call to select(). |
Implements resip::FdSetIOObserver.
Definition at line 614 of file AresDns.cxx.
References resip::FdSet::read, and resip::FdSet::write.
| void AresDns::process | ( | fd_set & | read, |
| fd_set & | write | ||
| ) | [virtual] |
Implements resip::ExternalDns.
Definition at line 626 of file AresDns.cxx.
References mChannel.
{
ares_process(mChannel, &read, &write);
}
| void AresDns::processTimers | ( | ) | [virtual] |
Implements resip::ExternalDns.
Definition at line 601 of file AresDns.cxx.
| void AresDns::setPollGrp | ( | FdPollGrp * | pollGrp | ) | [virtual] |
Implements resip::ExternalDns.
Definition at line 144 of file AresDns.cxx.
References mPollGrp, mPollItems, resip::FdPollGrp::registerFdSetIOObserver(), and resip::FdPollGrp::unregisterFdSetIOObserver().
{
#ifdef USE_CARES
if(mPollGrp)
{
mPollGrp->unregisterFdSetIOObserver(*this);
}
mPollGrp=grp;
if(mPollGrp)
{
mPollGrp->registerFdSetIOObserver(*this);
}
#else
for(std::vector<AresDnsPollItem*>::iterator i=mPollItems.begin();
i!=mPollItems.end(); ++i)
{
if(*i)
{
(*i)->resetPollGrp(grp);
}
}
mPollGrp = grp;
#endif
}

| resip::AresDns::void::resip_AresDns_aresCallback | ( | void * | arg, |
| int | status, | ||
| unsigned char * | abuf, | ||
| int | alen | ||
| ) |
| resip::AresDns::void::resip_AresDns_caresCallback | ( | void * | arg, |
| int | status, | ||
| int | timeouts, | ||
| unsigned char * | abuf, | ||
| int | alen | ||
| ) |
friend class AresDnsPollItem [friend] |
Definition at line 27 of file AresDns.hxx.
std::vector<GenericIPAddress> resip::AresDns::mAdditionalNameservers [private] |
Definition at line 74 of file AresDns.hxx.
Referenced by checkDnsChange(), and init().
struct ares_channeldata* resip::AresDns::mChannel [private] |
Definition at line 73 of file AresDns.hxx.
Referenced by AresDns(), buildFdSet(), checkDnsChange(), getTimeTillNextProcessMS(), hostFileLookup(), init(), internalInit(), lookup(), process(), processTimers(), and ~AresDns().
unsigned int resip::AresDns::mFeatures [private] |
Definition at line 75 of file AresDns.hxx.
Referenced by AresDns(), checkDnsChange(), and init().
volatile bool AresDns::mHostFileLookupOnlyMode = false [static, private] |
Definition at line 76 of file AresDns.hxx.
Referenced by enableHostFileLookupOnlyMode(), hostFileLookupLookupOnlyMode(), and init().
FdPollGrp* resip::AresDns::mPollGrp [private] |
Definition at line 78 of file AresDns.hxx.
Referenced by AresDns(), internalInit(), processTimers(), setPollGrp(), and resip::AresDnsPollItem::socket_poll_cb().
std::vector<AresDnsPollItem*> resip::AresDns::mPollItems [private] |
Definition at line 79 of file AresDns.hxx.
Referenced by internalInit(), setPollGrp(), and resip::AresDnsPollItem::socket_poll_cb().
1.7.5.1