reverse the order of dns lookup on bind vs dns lookup on remote host. this also does a check on each ip returned by getaddrinfo to be sure its able to connect to that host

git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@994 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
imaginos
2008-03-28 05:09:48 +00:00
parent f9d12fb872
commit 1fb0039732
2 changed files with 56 additions and 34 deletions
+38 -18
View File
@@ -28,7 +28,7 @@
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* $Revision: 1.68 $
* $Revision: 1.70 $
*/
#include "Csocket.h"
@@ -186,6 +186,7 @@ int GetAddrInfo( const CS_STRING & sHostname, Csock *pSock, CSSockAddr & csSockA
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
int iRet = getaddrinfo( sHostname.c_str(), NULL, &hints, &res );
if( iRet == EAI_AGAIN )
return( EAGAIN );
@@ -203,9 +204,24 @@ int GetAddrInfo( const CS_STRING & sHostname, Csock *pSock, CSSockAddr & csSockA
if( ( pRes->ai_socktype != SOCK_STREAM ) || ( pRes->ai_protocol != IPPROTO_TCP ) )
#endif /* __sun work around broken impl of getaddrinfo */
continue;
if( ( csSockAddr.GetAFRequire() != CSSockAddr::RAF_ANY ) && ( pRes->ai_family != csSockAddr.GetAFRequire() ) )
continue; // they requested a special type, so be certain we woop past anything unwanted
if( csSockAddr.GetAFRequire() == CSSockAddr::RAF_ANY )
{
// this is a quick check to see if we can connect to this type of outside port (ipv6 or ipv4)
// this doesn't do an actual connection (man connect), but its a great way to validate a possible connection canidate
bool bContinue = false;
int iTestFD = socket( pRes->ai_family, SOCK_DGRAM, IPPROTO_IP );
if( iTestFD >= 0 )
{
if( connect( iTestFD, pRes->ai_addr, pRes->ai_addrlen ) != 0 )
bContinue = true; // skip this one, we can't use it
}
close( iTestFD );
if( bContinue )
continue;
}
if( pRes->ai_family == AF_INET )
{
@@ -267,7 +283,9 @@ int GetAddrInfo( const CS_STRING & sHostname, Csock *pSock, CSSockAddr & csSockA
}
freeaddrinfo( res );
if( pUseAddr ) // the data pointed to here is invalid now, but the pointer itself is a good test
{
return( 0 );
}
}
#endif /* ! HAVE_IPV6 */
return( ETIMEDOUT );
@@ -651,7 +669,6 @@ void Csock::Copy( const Csock & cCopy )
m_sCipherType = cCopy.m_sCipherType;
m_sParentName = cCopy.m_sParentName;
m_sSend = cCopy.m_sSend;
m_sSSLBuffer = cCopy.m_sSSLBuffer;
m_sPemPass = cCopy.m_sPemPass;
m_sLocalIP = cCopy.m_sLocalIP;
m_sRemoteIP = cCopy.m_sRemoteIP;
@@ -672,6 +689,8 @@ void Csock::Copy( const Csock & cCopy )
m_bIsIPv6 = cCopy.m_bIsIPv6;
#ifdef HAVE_LIBSSL
m_sSSLBuffer = cCopy.m_sSSLBuffer;
FREE_SSL();
FREE_CTX(); // be sure to remove anything that was already here
m_ssl = cCopy.m_ssl;
@@ -772,18 +791,6 @@ bool Csock::Connect( const CS_STRING & sBindHost, bool bSkipSetup )
m_sBindHost = sBindHost;
if ( !bSkipSetup )
{
int iDNSRet = ETIMEDOUT;
while( true )
{
iDNSRet = DNSLookup( DNS_VHOST );
if ( iDNSRet == EAGAIN )
continue;
break;
}
if ( iDNSRet != 0 )
return( false );
if ( !sBindHost.empty() )
{
// try to bind 3 times, otherwise exit failure
@@ -805,6 +812,19 @@ bool Csock::Connect( const CS_STRING & sBindHost, bool bSkipSetup )
return( false );
}
}
int iDNSRet = ETIMEDOUT;
while( true )
{
iDNSRet = DNSLookup( DNS_VHOST );
if ( iDNSRet == EAGAIN )
continue;
break;
}
if ( iDNSRet != 0 )
return( false );
}
// set it none blocking
@@ -2040,7 +2060,7 @@ int Csock::DNSLookup( EDNSLType eDNSLType )
if ( m_sBindHost.empty() )
{
if ( m_eConState != CST_OK )
m_eConState = CST_BINDVHOST;
m_eConState = CST_VHOSTDNS;
return( 0 );
}
@@ -2095,7 +2115,7 @@ int Csock::DNSLookup( EDNSLType eDNSLType )
}
if ( m_eConState != CST_OK )
m_eConState = ( ( eDNSLType == DNS_VHOST ) ? CST_BINDVHOST : CST_VHOSTDNS );
m_eConState = ( ( eDNSLType == DNS_VHOST ) ? CST_VHOSTDNS : CST_CONNECT );
if( !CreateSocksFD() )
return( ETIMEDOUT );
@@ -2134,7 +2154,7 @@ int Csock::DNSLookup( EDNSLType eDNSLType )
if ( iRet == 0 )
{
if ( m_eConState != CST_OK )
m_eConState = ( ( eDNSLType == DNS_VHOST ) ? CST_BINDVHOST : CST_VHOSTDNS );
m_eConState = ( ( eDNSLType == DNS_VHOST ) ? CST_VHOSTDNS : CST_CONNECT );
m_iDNSTryCount = 0;
return( 0 );
}