mirror of
https://github.com/znc/znc.git
synced 2026-08-06 17:03:14 +02:00
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:
+38
-18
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* $Revision: 1.182 $
|
||||
* $Revision: 1.184 $
|
||||
*/
|
||||
|
||||
// note to compile with win32 need to link to winsock2, using gcc its -lws2_32
|
||||
@@ -83,7 +83,7 @@
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#include "main.h" // require this as a general rule, most projects have a defines.h or the like
|
||||
#include "main.h"
|
||||
|
||||
#ifndef CS_STRING
|
||||
# ifdef _HAS_CSTRING_
|
||||
@@ -520,8 +520,8 @@ public:
|
||||
{
|
||||
CST_START = 0,
|
||||
CST_DNS = CST_START,
|
||||
CST_VHOSTDNS = 1,
|
||||
CST_BINDVHOST = 2,
|
||||
CST_BINDVHOST = 1,
|
||||
CST_VHOSTDNS = 2,
|
||||
CST_CONNECT = 3,
|
||||
CST_OK = 4
|
||||
};
|
||||
@@ -1012,7 +1012,7 @@ private:
|
||||
bool m_bssl, m_bIsConnected, m_bBLOCK, m_bFullsslAccept;
|
||||
bool m_bsslEstablished, m_bEnableReadLine, m_bRequireClientCert, m_bPauseRead;
|
||||
CS_STRING m_shostname, m_sbuffer, m_sSockName, m_sPemFile, m_sCipherType, m_sParentName;
|
||||
CS_STRING m_sSend, m_sSSLBuffer, m_sPemPass, m_sLocalIP, m_sRemoteIP;
|
||||
CS_STRING m_sSend, m_sPemPass, m_sLocalIP, m_sRemoteIP;
|
||||
ECloseType m_eCloseType;
|
||||
|
||||
unsigned long long m_iMaxMilliSeconds, m_iLastSendTime, m_iBytesRead, m_iBytesWritten, m_iStartTime;
|
||||
@@ -1023,6 +1023,7 @@ private:
|
||||
time_t m_iLastCheckTimeoutTime;
|
||||
|
||||
#ifdef HAVE_LIBSSL
|
||||
CS_STRING m_sSSLBuffer;
|
||||
SSL *m_ssl;
|
||||
SSL_CTX *m_ssl_ctx;
|
||||
SSL_METHOD *m_ssl_method;
|
||||
@@ -1408,20 +1409,10 @@ public:
|
||||
continue;
|
||||
|
||||
if ( pcSock->GetConState() == T::CST_DNS )
|
||||
{
|
||||
if ( pcSock->DNSLookup( T::DNS_DEST ) == ETIMEDOUT )
|
||||
{
|
||||
pcSock->SockError( EDOM );
|
||||
DelSock( a-- );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pcSock->GetConState() == T::CST_VHOSTDNS )
|
||||
{
|
||||
if ( pcSock->DNSLookup( T::DNS_VHOST ) == ETIMEDOUT )
|
||||
{
|
||||
pcSock->SockError( EADDRNOTAVAIL );
|
||||
pcSock->SockError( EDOM );
|
||||
DelSock( a-- );
|
||||
continue;
|
||||
}
|
||||
@@ -1437,6 +1428,17 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if ( pcSock->GetConState() == T::CST_VHOSTDNS )
|
||||
{
|
||||
if ( pcSock->DNSLookup( T::DNS_DEST ) == ETIMEDOUT )
|
||||
{
|
||||
pcSock->SockError( EADDRNOTAVAIL );
|
||||
DelSock( a-- );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( pcSock->GetConState() == T::CST_CONNECT )
|
||||
{
|
||||
if ( !pcSock->Connect( pcSock->GetBindHost(), true ) )
|
||||
|
||||
Reference in New Issue
Block a user