From baeb2a666e5321765ec8c7d155f42d630078cdca Mon Sep 17 00:00:00 2001 From: imaginos Date: Fri, 15 Jan 2010 19:45:58 +0000 Subject: [PATCH] added workaround for a canonical name that points to ipv6 and ipv4 ip's, the ipv6 ip is tried first, followed up by a final try on ipv4 in the event the ipv6 connect results in a network unreachable. I wonder what this will break ... git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1712 726aef4b-f618-498e-8847-2d620e286838 --- Csocket.cpp | 20 ++++++++++++++++++++ Csocket.h | 1 + 2 files changed, 21 insertions(+) diff --git a/Csocket.cpp b/Csocket.cpp index ebc7196c..43ee295f 100644 --- a/Csocket.cpp +++ b/Csocket.cpp @@ -2154,6 +2154,26 @@ int Csock::GetAddrInfo( const CS_STRING & sHostname, CSSockAddr & csSockAddr ) { // this means its finished FreeAres(); #ifdef HAVE_IPV6 + if( m_iARESStatus == ARES_SUCCESS && csSockAddr.GetAFRequire() == CSSockAddr::RAF_ANY && GetIPv6() ) + { + // this means that ares_host returned an ipv6 host, so try a connect right away + if( CreateSocksFD() && Connect( GetBindHost(), true ) ) + { + SetSkipConnect( true ); + } + else if( GetSockError() == ENETUNREACH ) + { + // the Connect() failed, so throw a retry back in with ipv4, and let it process normally + CS_DEBUG( "Failed ipv6 connection with PF_UNSPEC, falling back to ipv4" ); + m_iARESStatus = -1; + if( m_iReadSock != m_iWriteSock ) + CS_CLOSE( m_iWriteSock ); + CS_CLOSE( m_iReadSock ); + m_iReadSock = m_iWriteSock = CS_INVALID_SOCK; + SetAFRequire( CSSockAddr::RAF_INET ); + return( GetAddrInfo( sHostname, csSockAddr ) ); + } + } #if ARES_VERSION < CREATE_ARES_VER( 1, 5, 3 ) if( m_iARESStatus != ARES_SUCCESS && csSockAddr.GetAFRequire() == CSSockAddr::RAF_ANY ) { // this is a workaround for ares < 1.5.3 where the builtin retry on failed AF_INET6 isn't there yet diff --git a/Csocket.h b/Csocket.h index 6847cba2..71273452 100644 --- a/Csocket.h +++ b/Csocket.h @@ -58,6 +58,7 @@ #define ETIMEDOUT WSAETIMEDOUT #define EADDRNOTAVAIL WSAEADDRNOTAVAIL #define ECONNABORTED WSAECONNABORTED +#define ENETUNREACH WSAENETUNREACH #endif /* _WIN32 */