From fc77edef0813e44e9b51ba5b5073f9830cb508f0 Mon Sep 17 00:00:00 2001 From: psychon Date: Sun, 10 Jan 2010 13:20:20 +0000 Subject: [PATCH] Switch to Csocket's c-ares code This removes all of znc's c-ares code and instead enables Csocket's built-in version. That code is newer than ZNC's, but should hopefully work just as good. Let's wait for the bug reports.... git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1704 726aef4b-f618-498e-8847-2d620e286838 --- Csocket.cpp | 2 +- Socket.cpp | 192 --------------------------------------------------- Socket.h | 37 ++-------- configure | 2 +- configure.in | 2 +- 5 files changed, 8 insertions(+), 227 deletions(-) diff --git a/Csocket.cpp b/Csocket.cpp index d6b785c7..93e30f26 100644 --- a/Csocket.cpp +++ b/Csocket.cpp @@ -208,7 +208,7 @@ void Csock::FreeAres() #endif /* HAVE_C_ARES */ #ifdef HAVE_C_ARES -void AresHostCallback( void *pArg, int status, int timeouts, struct hostent *hent ) +static void AresHostCallback( void *pArg, int status, int timeouts, struct hostent *hent ) { Csock *pSock = (Csock *)pArg; if( status == ARES_SUCCESS && hent ) diff --git a/Socket.cpp b/Socket.cpp index 3871763b..9e9b4225 100644 --- a/Socket.cpp +++ b/Socket.cpp @@ -7,198 +7,6 @@ */ #include "Socket.h" -#ifdef HAVE_ARES -#include -#endif - -#ifdef HAVE_ARES -struct DNSLookup { - bool bSocketDead; - bool bLookupDone; - // When both of the above are true, this struct can be freed - - // Query - CString sHost; - CSSockAddr::EAFRequire family; - - // Result - int ares_status; - CSSockAddr addr; -}; - -static ares_channel& GetAres() { - static ares_channel m_ares; - return m_ares; -} -#endif - -CZNCSock::~CZNCSock() { -#ifdef HAVE_ARES - if (m_dns_lookup) { - m_dns_lookup->bSocketDead = true; - if (m_dns_lookup->bLookupDone) - delete m_dns_lookup; - m_dns_lookup = NULL; - } -#endif -} - -CSockManager::CSockManager() : TSocketManager() { -#ifdef HAVE_ARES - int i = ares_init(&GetAres()); - if (i != ARES_SUCCESS) { - CUtils::PrintError("Could not initialize c-ares: " + CString(ares_strerror(i))); - exit(-1); - } - DEBUG("Successfully initialized c-ares"); -#endif -} - -CSockManager::~CSockManager() { -#ifdef HAVE_ARES - ares_destroy(GetAres()); -#endif -} - -#ifdef HAVE_ARES -int CSockManager::Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) -{ - int ret; - fd_set tmp; - - // Csocket sometimes can use NULL for writefds and c-ares doesn't like NULLs here - if (writefds == NULL) - { - writefds = &tmp; - FD_ZERO(writefds); - } - - // We assume that nfds is already the max. number of sockets allowed by - // the OS, so we don't need to update it here. - ares_fds(GetAres(), readfds, writefds); - ares_timeout(GetAres(), timeout, timeout); - - ret = ::select(nfds, readfds, writefds, exceptfds, timeout); - - ares_process(GetAres(), readfds, writefds); - - return ret; -} - -void CZNCSock::ares_callback(void *lookup, int status, int timeout, struct hostent *h) { - struct DNSLookup *p = (struct DNSLookup *) lookup; - p->bLookupDone = true; - - DEBUG("DNS lookup done for " << p->sHost); - if (p->bSocketDead) { - delete p; - return; - } - - p->ares_status = status; - if (!h) { -#ifdef HAVE_IPV6 - if (p->family == CSSockAddr::RAF_ANY) { - // Try an AAAA lookup - p->family = CSSockAddr::RAF_INET6; - DEBUG("Retrying with AAAA"); - p->bLookupDone = false; - ares_gethostbyname(GetAres(), p->sHost.c_str(), p->family, - ares_callback, p); - return; - } -#endif - if (status == ARES_SUCCESS) - p->ares_status = ARES_ENOTIMP; - return; - } - - if (h->h_addrtype == AF_INET && h->h_length == sizeof(in_addr)) { - memcpy(p->addr.GetAddr(), h->h_addr_list[0], sizeof(in_addr)); - p->addr.SetIPv6(false); - } -#ifdef HAVE_IPV6 - else if (h->h_addrtype == AF_INET6 && h->h_length == sizeof(in6_addr)) { - memcpy(p->addr.GetAddr6(), h->h_addr_list[0], sizeof(in6_addr)); - p->addr.SetIPv6(true); - } -#endif - else - DEBUG(__PRETTY_FUNCTION__ << ": Got unknown address with length " << h->h_length); -} - -int CZNCSock::GetAddrInfo(const CS_STRING &sHostname, CSSockAddr &csSockAddr) { - // If this is an ip address, no lookup is necessary -#ifdef HAVE_IPV6 - if (inet_pton(AF_INET6, sHostname.c_str(), csSockAddr.GetAddr6()) > 0) { - csSockAddr.SetIPv6(true); - SetIPv6(true); - return 0; - } -#endif - if (inet_pton(AF_INET, sHostname.c_str(), csSockAddr.GetAddr()) > 0) { - csSockAddr.SetIPv6(false); - SetIPv6(false); - return 0; - } - - if (!m_dns_lookup) { - DEBUG("New dns lookup for " << sHostname); - - m_dns_lookup = new struct DNSLookup; - m_dns_lookup->bSocketDead = false; - m_dns_lookup->bLookupDone = false; - m_dns_lookup->sHost = sHostname; - m_dns_lookup->ares_status = 0; - m_dns_lookup->family = csSockAddr.GetAFRequire(); - - CSSockAddr::EAFRequire family = csSockAddr.GetAFRequire(); - if (family == CSSockAddr::RAF_ANY) { - // post-1.6.0 c-ares (=current CVS versions) support - // lookups with AF_UNSPEC which means it first tries an - // AAAA lookup and then fails back to an A lookup. - // Older versions (= any version out there) just - // generate an "address family not supported" error - // message if you feed them, so we can't use this nice - // feature for now. - family = CSSockAddr::RAF_INET; - } - ares_gethostbyname(GetAres(), sHostname.c_str(), family, - ares_callback, m_dns_lookup); - } - - if (m_dns_lookup->sHost != sHostname) - // This *cannot* happen - DEBUG(__PRETTY_FUNCTION__ << ": Query target for an active DNS query changed!"); - - if (!m_dns_lookup->bLookupDone) { - DEBUG("waiting for dns on [" << sHostname << "] to finish..."); - return EAGAIN; - } - - if (m_dns_lookup->ares_status != ARES_SUCCESS) { - DEBUG("Error while looking up [" << sHostname << "]: " - << ares_strerror(m_dns_lookup->ares_status)); - delete m_dns_lookup; - m_dns_lookup = NULL; - return ETIMEDOUT; - } - -#ifdef HAVE_IPV6 - memcpy(csSockAddr.GetAddr6(), m_dns_lookup->addr.GetAddr6(), sizeof(in6_addr)); -#endif - memcpy(csSockAddr.GetAddr(), m_dns_lookup->addr.GetAddr(), sizeof(in_addr)); - csSockAddr.SetIPv6(m_dns_lookup->addr.GetIPv6()); - SetIPv6(csSockAddr.GetIPv6()); - - DEBUG("GetAddrInfo() done for " << sHostname.c_str()); - - delete m_dns_lookup; - m_dns_lookup = NULL; - - return 0; -} -#endif unsigned int CSockManager::GetAnonConnectionCount(const CString &sIP) const { const_iterator it; diff --git a/Socket.h b/Socket.h index 6cf8f72d..46c393a2 100644 --- a/Socket.h +++ b/Socket.h @@ -11,38 +11,17 @@ #include "Csocket.h" -#ifdef HAVE_ARES -struct DNSLookup; -#endif - class CZNCSock : public Csock { public: - CZNCSock(int timeout = 60) : Csock(timeout) { -#ifdef HAVE_ARES - m_dns_lookup = NULL; -#endif - } - CZNCSock(const CString& sHost, u_short port, int timeout = 60) : Csock(sHost, port, timeout) { -#ifdef HAVE_ARES - m_dns_lookup = NULL; -#endif - } - - ~CZNCSock(); - -#ifdef HAVE_ARES - static void ares_callback(void *lookup, int status, int timeout, struct hostent *h); - virtual int GetAddrInfo(const CS_STRING & sHostname, CSSockAddr & csSockAddr); - -private: - struct DNSLookup *m_dns_lookup; -#endif + CZNCSock(int timeout = 60) : Csock(timeout) {} + CZNCSock(const CString& sHost, u_short port, int timeout = 60) : Csock(sHost, port, timeout) {} + ~CZNCSock() {} }; class CSockManager : public TSocketManager { public: - CSockManager(); - virtual ~CSockManager(); + CSockManager() {} + virtual ~CSockManager() {} bool ListenHost(u_short iPort, const CString& sSockName, const CString& sBindHost, bool bSSL = false, int iMaxConns = SOMAXCONN, CZNCSock *pcSock = NULL, u_int iTimeout = 0, bool bIsIPv6 = false) { CSListener L(iPort, sBindHost); @@ -102,12 +81,6 @@ public: unsigned int GetAnonConnectionCount(const CString &sIP) const; private: protected: -#ifdef HAVE_ARES - int Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); - -private: - using TSocketManager::Select; -#endif /* HAVE_ARES */ }; #endif /* SOCKET_H */ diff --git a/configure b/configure index 99e47317..a5ee40ee 100755 --- a/configure +++ b/configure @@ -3091,7 +3091,7 @@ Disabling c-ares may result in a slight performance decrease but will not have a $as_echo "$as_me: WARNING: \"c-ares was not found and thus disabled\"" >&2;} fi else - appendCXX $c_ares_CFLAGS -DHAVE_ARES + appendCXX $c_ares_CFLAGS -DHAVE_C_ARES appendLib $c_ares_LIBS ARES=yes fi diff --git a/configure.in b/configure.in index b2727a22..17ffe9e9 100644 --- a/configure.in +++ b/configure.in @@ -141,7 +141,7 @@ Disabling c-ares may result in a slight performance decrease but will not have a AC_MSG_WARN(["c-ares was not found and thus disabled"]) fi else - appendCXX $c_ares_CFLAGS -DHAVE_ARES + appendCXX $c_ares_CFLAGS -DHAVE_C_ARES appendLib $c_ares_LIBS ARES=yes fi