mirror of
https://github.com/znc/znc.git
synced 2026-07-03 08:21:57 +02:00
Pulled in Csocket changes for ipv6 support
git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@626 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
+274
-88
@@ -40,6 +40,89 @@ namespace Csocket
|
||||
{
|
||||
#endif /* _NO_CSOCKET_NS */
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
int GetHostByName6( const CS_STRING & sHostName, in6_addr * paddr, u_int iNumRetries )
|
||||
{
|
||||
int iReturn = HOST_NOT_FOUND;
|
||||
struct hostent *hent = NULL;
|
||||
if( ( sHostName.find( ":" ) != CS_STRING::npos ) && ( inet_pton( AF_INET6, sHostName.c_str(), paddr ) > 0 ) )
|
||||
return( 0 );
|
||||
|
||||
#ifdef __linux__
|
||||
char hbuff[2048];
|
||||
struct hostent hentbuff;
|
||||
|
||||
int err;
|
||||
for( u_int a = 0; a < iNumRetries; a++ )
|
||||
{
|
||||
memset( (char *)hbuff, '\0', 2048 );
|
||||
iReturn = gethostbyname_r( sHostName.c_str(), &hentbuff, hbuff, 2048, &hent, &err );
|
||||
|
||||
if ( iReturn == 0 )
|
||||
break;
|
||||
|
||||
if ( iReturn != TRY_AGAIN )
|
||||
break;
|
||||
|
||||
PERROR( "gethostbyname_r" );
|
||||
}
|
||||
if ( ( !hent ) && ( iReturn == 0 ) )
|
||||
iReturn = HOST_NOT_FOUND;
|
||||
#else
|
||||
hent = gethostbyname( sHostName.c_str() );
|
||||
PERROR( "gethostbyname" );
|
||||
|
||||
if ( hent )
|
||||
iReturn = 0;
|
||||
|
||||
#endif /* __linux__ */
|
||||
|
||||
if ( iReturn == 0 )
|
||||
memcpy( &paddr->s6_addr, hent->h_addr_list[0], sizeof( paddr->s6_addr ) );
|
||||
|
||||
return( iReturn );
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
int GetHostByName( const CS_STRING & sHostName, in_addr * paddr, u_int iNumRetries )
|
||||
{
|
||||
int iReturn = HOST_NOT_FOUND;
|
||||
struct hostent *hent = NULL;
|
||||
|
||||
#ifdef __linux__
|
||||
char hbuff[2048];
|
||||
struct hostent hentbuff;
|
||||
|
||||
int err;
|
||||
for( u_int a = 0; a < iNumRetries; a++ )
|
||||
{
|
||||
memset( (char *)hbuff, '\0', 2048 );
|
||||
iReturn = gethostbyname_r( sHostName.c_str(), &hentbuff, hbuff, 2048, &hent, &err );
|
||||
|
||||
if ( iReturn == 0 )
|
||||
break;
|
||||
|
||||
if ( iReturn != TRY_AGAIN )
|
||||
break;
|
||||
|
||||
PERROR( "gethostbyname_r" );
|
||||
}
|
||||
if ( ( !hent ) && ( iReturn == 0 ) )
|
||||
iReturn = HOST_NOT_FOUND;
|
||||
#else
|
||||
hent = gethostbyname( sHostName.c_str() );
|
||||
PERROR( "gethostbyname" );
|
||||
|
||||
if ( hent )
|
||||
iReturn = 0;
|
||||
|
||||
#endif /* __linux__ */
|
||||
|
||||
if ( iReturn == 0 )
|
||||
memcpy( &paddr->s_addr, hent->h_addr_list[0], sizeof( paddr->s_addr ) );
|
||||
|
||||
return( iReturn );
|
||||
}
|
||||
#ifdef ___DO_THREADS
|
||||
CSMutex::CSMutex()
|
||||
{
|
||||
@@ -119,22 +202,33 @@ void *CSThread::start_thread( void *args )
|
||||
pthread_exit( NULL );
|
||||
}
|
||||
|
||||
void CDNSResolver::Lookup( const CS_STRING & sHostname )
|
||||
void CDNSResolver::Lookup( const CS_STRING & sHostname, bool bIsIPv6 )
|
||||
{
|
||||
m_bSuccess = false;
|
||||
m_sHostname = sHostname;
|
||||
memset( (struct in_addr *)&m_inAddr, '\0', sizeof( m_inAddr ) );
|
||||
#ifdef HAVE_IPV6
|
||||
m_bIsIPv6 = bIsIPv6;
|
||||
memset( (struct in6_addr *)&m_inAddr6, '\0', sizeof( m_inAddr6 ) );
|
||||
#endif /* HAVE_IPV6 */
|
||||
start();
|
||||
}
|
||||
|
||||
void CDNSResolver::run()
|
||||
{
|
||||
if ( GetHostByName( m_sHostname, &m_inAddr ) != 0 )
|
||||
m_bSuccess = false;
|
||||
m_bSuccess = false;
|
||||
if( !m_bIsIPv6 )
|
||||
{
|
||||
if ( GetHostByName( m_sHostname, &m_inAddr ) == 0 )
|
||||
m_bSuccess = true;
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
m_bSuccess = true;
|
||||
if ( GetHostByName6( m_sHostname, &m_inAddr6 ) == 0 )
|
||||
m_bSuccess = true;
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
}
|
||||
|
||||
bool CDNSResolver::IsCompleted()
|
||||
@@ -242,45 +336,6 @@ unsigned long long millitime()
|
||||
return( iTime );
|
||||
}
|
||||
|
||||
int GetHostByName( const CS_STRING & sHostName, struct in_addr *paddr, u_int iNumRetries )
|
||||
{
|
||||
int iReturn = HOST_NOT_FOUND;
|
||||
struct hostent *hent = NULL;
|
||||
#ifdef __linux__
|
||||
char hbuff[2048];
|
||||
struct hostent hentbuff;
|
||||
|
||||
int err;
|
||||
for( u_int a = 0; a < iNumRetries; a++ )
|
||||
{
|
||||
memset( (char *)hbuff, '\0', 2048 );
|
||||
iReturn = gethostbyname_r( sHostName.c_str(), &hentbuff, hbuff, 2048, &hent, &err );
|
||||
|
||||
if ( iReturn == 0 )
|
||||
break;
|
||||
|
||||
if ( iReturn != TRY_AGAIN )
|
||||
break;
|
||||
|
||||
PERROR( "gethostbyname_r" );
|
||||
}
|
||||
if ( ( !hent ) && ( iReturn == 0 ) )
|
||||
iReturn = HOST_NOT_FOUND;
|
||||
#else
|
||||
hent = gethostbyname( sHostName.c_str() );
|
||||
PERROR( "gethostbyname" );
|
||||
|
||||
if ( hent )
|
||||
iReturn = 0;
|
||||
|
||||
#endif /* __linux__ */
|
||||
|
||||
if ( iReturn == 0 )
|
||||
memcpy( &paddr->s_addr, hent->h_addr_list[0], sizeof( paddr->s_addr ) );
|
||||
|
||||
return( iReturn );
|
||||
}
|
||||
|
||||
#ifndef _NO_CSOCKET_NS // some people may not want to use a namespace
|
||||
}
|
||||
using namespace Csocket;
|
||||
@@ -529,8 +584,13 @@ bool Csock::Connect( const CS_STRING & sBindHost, bool bSkipSetup )
|
||||
|
||||
m_iConnType = OUTBOUND;
|
||||
|
||||
// connect
|
||||
int ret = connect( m_iReadSock, (struct sockaddr *)&m_address, sizeof( m_address ) );
|
||||
int ret = -1;
|
||||
if( !GetIPv6() )
|
||||
ret = connect( m_iReadSock, (struct sockaddr *)m_address.GetSockAddr(), m_address.GetSockAddrLen() );
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
ret = connect( m_iReadSock, (struct sockaddr *)m_address.GetSockAddr6(), m_address.GetSockAddrLen6() );
|
||||
#endif /* HAVE_IPV6 */
|
||||
#ifndef _WIN32
|
||||
if ( ( ret == -1 ) && ( GetSockError() != EINPROGRESS ) )
|
||||
#else
|
||||
@@ -631,20 +691,39 @@ bool Csock::Listen( u_short iPort, int iMaxConns, const CS_STRING & sBindHost, u
|
||||
return( false );
|
||||
|
||||
m_sBindHost = sBindHost;
|
||||
|
||||
m_address.sin_family = PF_INET;
|
||||
if ( sBindHost.empty() )
|
||||
m_address.sin_addr.s_addr = htonl( INADDR_ANY );
|
||||
else
|
||||
m_address.SinFamily();
|
||||
if ( !sBindHost.empty() )
|
||||
{
|
||||
if ( GetHostByName( sBindHost, &(m_address.sin_addr) ) != 0 )
|
||||
#ifdef HAVE_IPV6
|
||||
if( GetIPv6() )
|
||||
{
|
||||
if ( GetHostByName6( sBindHost, m_address.GetAddr6() ) != 0 )
|
||||
return( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( GetHostByName( sBindHost, m_address.GetAddr() ) != 0 )
|
||||
return( false );
|
||||
}
|
||||
#else
|
||||
if ( GetHostByName( sBindHost, m_address.GetAddr() ) != 0 )
|
||||
return( false );
|
||||
#endif /* HAVE_IPV6 */
|
||||
}
|
||||
m_address.SinPort( iPort );
|
||||
|
||||
if( !GetIPv6() )
|
||||
{
|
||||
if ( bind( m_iReadSock, (struct sockaddr *) m_address.GetSockAddr(), m_address.GetSockAddrLen() ) == -1 )
|
||||
return( false );
|
||||
}
|
||||
m_address.sin_port = htons( iPort );
|
||||
memset( &(m_address.sin_zero), '\0', sizeof( m_address.sin_zero ) );
|
||||
|
||||
if ( bind( m_iReadSock, (struct sockaddr *) &m_address, sizeof( m_address ) ) == -1 )
|
||||
return( false );
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
if ( bind( m_iReadSock, (struct sockaddr *) m_address.GetSockAddr6(), m_address.GetSockAddrLen6() ) == -1 )
|
||||
return( false );
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
if ( listen( m_iReadSock, iMaxConns ) == -1 )
|
||||
return( false );
|
||||
@@ -666,10 +745,33 @@ bool Csock::Listen( u_short iPort, int iMaxConns, const CS_STRING & sBindHost, u
|
||||
|
||||
int Csock::Accept( CS_STRING & sHost, u_short & iRPort )
|
||||
{
|
||||
struct sockaddr_in client;
|
||||
socklen_t clen = sizeof(struct sockaddr);
|
||||
int iSock = -1;
|
||||
if( !GetIPv6() )
|
||||
{
|
||||
struct sockaddr_in client;
|
||||
socklen_t clen = sizeof( client );
|
||||
iSock = accept( m_iReadSock, (struct sockaddr *) &client, &clen );
|
||||
getpeername( iSock, (struct sockaddr *) &client, &clen );
|
||||
sHost = inet_ntoa( client.sin_addr );
|
||||
iRPort = ntohs( client.sin_port );
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
char straddr[INET6_ADDRSTRLEN];
|
||||
struct sockaddr_in6 client;
|
||||
socklen_t clen = sizeof( client );
|
||||
iSock = accept( m_iReadSock, (struct sockaddr *) &client, &clen );
|
||||
getpeername( iSock, (struct sockaddr *) &client, &clen );
|
||||
if( inet_ntop( AF_INET6, &client.sin6_addr, straddr, sizeof(straddr) ) > 0 )
|
||||
{
|
||||
sHost = straddr;
|
||||
iRPort = ntohs( client.sin6_port );
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
int iSock = accept( m_iReadSock , (struct sockaddr *) &client, &clen );
|
||||
|
||||
if ( iSock != -1 )
|
||||
{
|
||||
if ( !m_bBLOCK )
|
||||
@@ -684,11 +786,6 @@ int Csock::Accept( CS_STRING & sHost, u_short & iRPort )
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
getpeername( iSock, (struct sockaddr *) &client, &clen );
|
||||
|
||||
sHost = inet_ntoa( client.sin_addr );
|
||||
iRPort = ntohs( client.sin_port );
|
||||
|
||||
if ( !ConnectionFrom( sHost, iRPort ) )
|
||||
{
|
||||
close( iSock );
|
||||
@@ -1176,10 +1273,26 @@ CS_STRING Csock::GetLocalIP()
|
||||
if ( iSock < 0 )
|
||||
return( "" );
|
||||
|
||||
struct sockaddr_in mLocalAddr;
|
||||
socklen_t mLocalLen = sizeof(struct sockaddr);
|
||||
if ( getsockname( iSock, (struct sockaddr *) &mLocalAddr, &mLocalLen ) == 0 )
|
||||
m_sLocalIP = inet_ntoa( mLocalAddr.sin_addr );
|
||||
if( !GetIPv6() )
|
||||
{
|
||||
struct sockaddr_in mLocalAddr;
|
||||
socklen_t mLocalLen = sizeof( mLocalAddr );
|
||||
if ( getsockname( iSock, (struct sockaddr *) &mLocalAddr, &mLocalLen ) == 0 )
|
||||
m_sLocalIP = inet_ntoa( mLocalAddr.sin_addr );
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
char straddr[INET6_ADDRSTRLEN];
|
||||
struct sockaddr_in6 mLocalAddr;
|
||||
socklen_t mLocalLen = sizeof( mLocalAddr );
|
||||
if ( ( getsockname( iSock, (struct sockaddr *) &mLocalAddr, &mLocalLen ) == 0 )
|
||||
&& ( inet_ntop( AF_INET6, &mLocalAddr.sin6_addr, straddr, sizeof(straddr) ) ) )
|
||||
{
|
||||
m_sLocalIP = straddr;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
return( m_sLocalIP );
|
||||
}
|
||||
@@ -1197,10 +1310,26 @@ CS_STRING Csock::GetRemoteIP()
|
||||
return( "" );
|
||||
}
|
||||
|
||||
struct sockaddr_in mRemoteAddr;
|
||||
socklen_t mRemoteLen = sizeof(struct sockaddr);
|
||||
if ( getpeername( iSock, (struct sockaddr *) &mRemoteAddr, &mRemoteLen ) == 0 )
|
||||
m_sRemoteIP = inet_ntoa( mRemoteAddr.sin_addr );
|
||||
if( !GetIPv6() )
|
||||
{
|
||||
struct sockaddr_in mRemoteAddr;
|
||||
socklen_t mRemoteLen = sizeof( mRemoteAddr );
|
||||
if ( getpeername( iSock, (struct sockaddr *) &mRemoteAddr, &mRemoteLen ) == 0 )
|
||||
m_sRemoteIP = inet_ntoa( mRemoteAddr.sin_addr );
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
char straddr[INET6_ADDRSTRLEN];
|
||||
struct sockaddr_in6 mRemoteAddr;
|
||||
socklen_t mRemoteLen = sizeof( mRemoteAddr );
|
||||
if ( ( getpeername( iSock, (struct sockaddr *) &mRemoteAddr, &mRemoteLen ) == 0 )
|
||||
&& ( inet_ntop( AF_INET6, &mRemoteAddr.sin6_addr, straddr, sizeof(straddr) ) ) )
|
||||
{
|
||||
m_sRemoteIP = straddr;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
return( m_sRemoteIP );
|
||||
}
|
||||
@@ -1328,10 +1457,22 @@ u_short Csock::GetRemotePort()
|
||||
|
||||
if ( iSock >= 0 )
|
||||
{
|
||||
struct sockaddr_in mAddr;
|
||||
socklen_t mLen = sizeof(struct sockaddr);
|
||||
if ( getpeername( iSock, (struct sockaddr *) &mAddr, &mLen ) == 0 )
|
||||
m_iRemotePort = ntohs( mAddr.sin_port );
|
||||
if( !GetIPv6() )
|
||||
{
|
||||
struct sockaddr_in mAddr;
|
||||
socklen_t mLen = sizeof( mAddr );
|
||||
if ( getpeername( iSock, (struct sockaddr *) &mAddr, &mLen ) == 0 )
|
||||
m_iRemotePort = ntohs( mAddr.sin_port );
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
struct sockaddr_in6 mAddr;
|
||||
socklen_t mLen = sizeof( mAddr );
|
||||
if ( getpeername( iSock, (struct sockaddr *) &mAddr, &mLen ) == 0 )
|
||||
m_iRemotePort = ntohs( mAddr.sin6_port );
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
}
|
||||
|
||||
return( m_iRemotePort );
|
||||
@@ -1346,10 +1487,22 @@ u_short Csock::GetLocalPort()
|
||||
|
||||
if ( iSock >= 0 )
|
||||
{
|
||||
struct sockaddr_in mLocalAddr;
|
||||
socklen_t mLocalLen = sizeof(struct sockaddr);
|
||||
if ( getsockname( iSock, (struct sockaddr *) &mLocalAddr, &mLocalLen ) == 0 )
|
||||
m_iLocalPort = ntohs( mLocalAddr.sin_port );
|
||||
if( !GetIPv6() )
|
||||
{
|
||||
struct sockaddr_in mLocalAddr;
|
||||
socklen_t mLocalLen = sizeof( mLocalLen );
|
||||
if ( getsockname( iSock, (struct sockaddr *) &mLocalAddr, &mLocalLen ) == 0 )
|
||||
m_iLocalPort = ntohs( mLocalAddr.sin_port );
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
struct sockaddr_in6 mLocalAddr;
|
||||
socklen_t mLocalLen = sizeof( mLocalLen );
|
||||
if ( getsockname( iSock, (struct sockaddr *) &mLocalAddr, &mLocalLen ) == 0 )
|
||||
m_iLocalPort = ntohs( mLocalAddr.sin6_port );
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
}
|
||||
|
||||
return( m_iLocalPort );
|
||||
@@ -1650,14 +1803,14 @@ int Csock::DNSLookup( EDNSLType eDNSLType )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
m_bindhost.sin_family = PF_INET;
|
||||
m_bindhost.sin_port = htons( 0 );
|
||||
m_bindhost.SinFamily();
|
||||
m_bindhost.SinPort( 0 );
|
||||
}
|
||||
|
||||
#ifdef ___DO_THREADS
|
||||
if ( m_iDNSTryCount == 0 )
|
||||
{
|
||||
m_cResolver.Lookup( ( eDNSLType == DNS_VHOST ) ? m_sBindHost : m_shostname );
|
||||
m_cResolver.Lookup( ( eDNSLType == DNS_VHOST ) ? m_sBindHost : m_shostname, GetIPv6() );
|
||||
m_iDNSTryCount++;
|
||||
}
|
||||
|
||||
@@ -1667,9 +1820,23 @@ int Csock::DNSLookup( EDNSLType eDNSLType )
|
||||
if ( m_cResolver.Suceeded() )
|
||||
{
|
||||
if ( eDNSLType == DNS_VHOST )
|
||||
memcpy( &(m_bindhost.sin_addr), m_cResolver.GetAddr(), sizeof( m_bindhost.sin_addr ) );
|
||||
{
|
||||
if( !GetIPv6() )
|
||||
memcpy( m_bindhost.GetAddr(), m_cResolver.GetAddr(), sizeof( *(m_bindhost.GetAddr()) ) );
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
memcpy( m_bindhost.GetAddr6(), m_cResolver.GetAddr6(), sizeof( *(m_bindhost.GetAddr6()) ) );
|
||||
#endif /* HAVE_IPV6 */
|
||||
}
|
||||
else
|
||||
memcpy( &(m_address.sin_addr), m_cResolver.GetAddr(), sizeof( m_address.sin_addr ) );
|
||||
{
|
||||
if( !GetIPv6() )
|
||||
memcpy( m_address.GetAddr(), m_cResolver.GetAddr(), sizeof( *(m_address.GetAddr()) ) );
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
memcpy( m_address.GetAddr6(), m_cResolver.GetAddr6(), sizeof( *(m_address.GetAddr6()) ) );
|
||||
#endif /* HAVE_IPV6 */
|
||||
}
|
||||
|
||||
if ( m_eConState != CST_OK )
|
||||
m_eConState = ( ( eDNSLType == DNS_VHOST ) ? CST_BINDVHOST : CST_VHOSTDNS );
|
||||
@@ -1684,9 +1851,27 @@ int Csock::DNSLookup( EDNSLType eDNSLType )
|
||||
#else
|
||||
int iRet;
|
||||
if ( eDNSLType == DNS_VHOST )
|
||||
iRet = GetHostByName( m_sBindHost, &(m_bindhost.sin_addr), 1 );
|
||||
{
|
||||
if( !GetIPv6() )
|
||||
iRet = GetHostByName( m_sBindHost, m_bindhost.GetAddr(), 1 );
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
iRet = GetHostByName6( m_sBindHost, m_bindhost.GetAddr6(), 1 );
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
}
|
||||
else
|
||||
iRet = GetHostByName( m_shostname, &(m_address.sin_addr), 1 );
|
||||
{
|
||||
if( !GetIPv6() )
|
||||
iRet = GetHostByName( m_shostname, m_address.GetAddr(), 1 );
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
iRet = GetHostByName6( m_shostname, m_bindhost.GetAddr6(), 1 );
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
}
|
||||
|
||||
if ( iRet == 0 )
|
||||
{
|
||||
@@ -1758,7 +1943,7 @@ void Csock::FREE_CTX()
|
||||
//! Create the socket
|
||||
int Csock::SOCKET( bool bListen )
|
||||
{
|
||||
int iRet = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
|
||||
int iRet = socket( ( GetIPv6() ? PF_INET6 : PF_INET ), SOCK_STREAM, IPPROTO_TCP );
|
||||
|
||||
if ( ( iRet > -1 ) && ( bListen ) )
|
||||
{
|
||||
@@ -1812,5 +1997,6 @@ void Csock::Init( const CS_STRING & sHostname, u_short iport, int itimeout )
|
||||
m_eConState = CST_OK; // default should be ok
|
||||
m_iDNSTryCount = 0;
|
||||
m_iCurBindCount = 0;
|
||||
m_bIsIPv6 = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,70 @@ namespace Csocket
|
||||
{
|
||||
#endif /* _NO_CSOCKET_NS */
|
||||
|
||||
int GetHostByName( const CS_STRING & sHostName, struct in_addr *paddr, u_int iNumRetries = 20 );
|
||||
#ifdef HAVE_IPV6
|
||||
int GetHostByName6( const CS_STRING & sHostName, in6_addr * paddr, u_int iNumRetries = 20 );
|
||||
#endif /* HAVE_IPV6 */
|
||||
int GetHostByName( const CS_STRING & sHostName, in_addr * paddr, u_int iNumRetries = 20 );
|
||||
|
||||
class CSSockAddr
|
||||
{
|
||||
public:
|
||||
CSSockAddr()
|
||||
{
|
||||
m_bIsIPv6 = false;
|
||||
memset( (struct sockaddr_in *)&m_saddr, '\0', sizeof( m_saddr ) );
|
||||
#ifdef HAVE_IPV6
|
||||
memset( (struct sockaddr_in6 *)&m_saddr, '\0', sizeof( m_saddr6 ) );
|
||||
#endif /* HAVE_IPV6 */
|
||||
}
|
||||
virtual ~CSSockAddr() {}
|
||||
|
||||
|
||||
void SinFamily()
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
if( m_bIsIPv6 )
|
||||
{
|
||||
m_saddr6.sin6_family = PF_INET6;
|
||||
return;
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
m_saddr.sin_family = PF_INET;
|
||||
}
|
||||
void SinPort( u_short iPort )
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
if( m_bIsIPv6 )
|
||||
{
|
||||
m_saddr6.sin6_port = htons( iPort );
|
||||
return;
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
m_saddr.sin_port = htons( iPort );
|
||||
}
|
||||
|
||||
void SetIPv6( bool b ) { m_bIsIPv6 = b; }
|
||||
bool GetIPv6() const { return( m_bIsIPv6 ); }
|
||||
|
||||
|
||||
|
||||
socklen_t GetSockAddrLen() { return( sizeof( m_saddr ) ); }
|
||||
sockaddr_in * GetSockAddr() { return( &m_saddr ); }
|
||||
in_addr * GetAddr() { return( &(m_saddr.sin_addr) ); }
|
||||
#ifdef HAVE_IPV6
|
||||
socklen_t GetSockAddrLen6() { return( sizeof( m_saddr6 ) ); }
|
||||
sockaddr_in6 * GetSockAddr6() { return( &m_saddr6 ); }
|
||||
in6_addr * GetAddr6() { return( &(m_saddr6.sin6_addr) ); }
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
private:
|
||||
bool m_bIsIPv6;
|
||||
sockaddr_in m_saddr;
|
||||
#ifdef HAVE_IPV6
|
||||
sockaddr_in6 m_saddr6;
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
};
|
||||
|
||||
#if defined( _REENTRANT ) && defined( _USE_THREADED_DNS )
|
||||
#define ___DO_THREADS
|
||||
@@ -168,15 +231,19 @@ private:
|
||||
class CDNSResolver : public CSThread
|
||||
{
|
||||
public:
|
||||
CDNSResolver() : CSThread() { m_bSuccess = false; }
|
||||
CDNSResolver() : CSThread() { m_bSuccess = false; m_bIsIPv6 = false; }
|
||||
virtual ~CDNSResolver() {}
|
||||
//! returns imediatly, from here out check if IsCompleted() returns true before looking at ANY of the data
|
||||
void Lookup( const CS_STRING & sHostname );
|
||||
void Lookup( const CS_STRING & sHostname, bool bIsIPv6 = false );
|
||||
|
||||
virtual void run();
|
||||
|
||||
//! returns the underlying in_addr structure containing the resolved hostname
|
||||
const struct in_addr * GetAddr() const { return( &m_inAddr ); }
|
||||
#ifdef HAVE_IPV6
|
||||
const struct in6_addr * GetAddr6() const { return( &m_inAddr6 ); }
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
//! true if dns entry was successfuly found
|
||||
bool Suceeded() const { return( m_bSuccess ); }
|
||||
|
||||
@@ -187,9 +254,13 @@ public:
|
||||
static CS_STRING CreateIP( const struct in_addr *pAddr );
|
||||
|
||||
private:
|
||||
bool m_bSuccess;
|
||||
bool m_bSuccess, m_bIsIPv6;
|
||||
CS_STRING m_sHostname;
|
||||
struct in_addr m_inAddr;
|
||||
#ifdef HAVE_IPV6
|
||||
struct in6_addr m_inAddr6;
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -798,8 +869,8 @@ public:
|
||||
if ( m_iReadSock == -1 )
|
||||
return( false );
|
||||
|
||||
m_address.sin_family = PF_INET;
|
||||
m_address.sin_port = htons( m_iport );
|
||||
m_address.SinFamily();
|
||||
m_address.SinPort( m_iport );
|
||||
|
||||
return( true );
|
||||
}
|
||||
@@ -823,7 +894,13 @@ public:
|
||||
//! this is only used on outbound connections, listeners bind in a different spot
|
||||
bool SetupVHost();
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
bool GetIPv6() const { return( m_bIsIPv6 ); }
|
||||
void SetIPv6( bool b )
|
||||
{
|
||||
m_bIsIPv6 = b;
|
||||
m_address.SetIPv6( b );
|
||||
m_bindhost.SetIPv6( b );
|
||||
}
|
||||
|
||||
private:
|
||||
u_short m_iport, m_iRemotePort, m_iLocalPort;
|
||||
@@ -837,7 +914,8 @@ private:
|
||||
unsigned long long m_iMaxMilliSeconds, m_iLastSendTime, m_iBytesRead, m_iBytesWritten, m_iStartTime;
|
||||
unsigned int m_iMaxBytes, m_iLastSend, m_iMaxStoredBufferLength, m_iTimeoutType;
|
||||
|
||||
struct sockaddr_in m_address, m_bindhost;
|
||||
CSSockAddr m_address, m_bindhost;
|
||||
bool m_bIsIPv6;
|
||||
|
||||
#ifdef HAVE_LIBSSL
|
||||
SSL *m_ssl;
|
||||
@@ -940,9 +1018,10 @@ public:
|
||||
* \param iTimeout the amount of time to try to connect
|
||||
* \param isSSL does the connection require a SSL layer
|
||||
* \param sBindHost the host to bind too
|
||||
* \param bIsIPv6 set to true to connect to an ipv6 host, requires HAVE_IPV6 at compile time to work
|
||||
* \return true on success
|
||||
*/
|
||||
virtual bool Connect( const CS_STRING & sHostname, u_short iPort , const CS_STRING & sSockName, int iTimeout = 60, bool isSSL = false, const CS_STRING & sBindHost = "", T *pcSock = NULL )
|
||||
virtual bool Connect( const CS_STRING & sHostname, u_short iPort , const CS_STRING & sSockName, int iTimeout = 60, bool isSSL = false, const CS_STRING & sBindHost = "", T *pcSock = NULL, bool bIsIPv6 = false )
|
||||
{
|
||||
// create the new object
|
||||
if ( !pcSock )
|
||||
@@ -953,6 +1032,7 @@ public:
|
||||
pcSock->SetPort( iPort );
|
||||
pcSock->SetTimeout( iTimeout );
|
||||
}
|
||||
pcSock->SetIPv6( bIsIPv6 );
|
||||
|
||||
// make it NON-Blocking IO
|
||||
pcSock->BlockIO( false );
|
||||
@@ -973,6 +1053,12 @@ public:
|
||||
AddSock( pcSock, sSockName );
|
||||
return( true );
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
virtual bool Connect6( const CS_STRING & sHostname, u_short iPort , const CS_STRING & sSockName, int iTimeout = 60, bool isSSL = false, const CS_STRING & sBindHost = "", T *pcSock = NULL )
|
||||
{
|
||||
return( Connect( sHostname, iPort, sSockName, iTimeout, isSSL, sBindHost, pcSock, true ) );
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
/**
|
||||
* @brief Create a listening socket
|
||||
@@ -985,14 +1071,16 @@ public:
|
||||
* @param sSockName the name of the socket
|
||||
* @param isSSL if the sockets created require an ssl layer
|
||||
* @param iMaxConns the maximum amount of connections to accept
|
||||
* @param bIsIPv6 set to true to listen on an ipv6 host, requires HAVE_IPV6 at compile time to work
|
||||
* @return pointer to sock, NULL if not successfull
|
||||
*/
|
||||
virtual T * ListenHost( u_short iPort, const CS_STRING & sSockName, const CS_STRING & sBindHost, int isSSL = false, int iMaxConns = SOMAXCONN, T *pcSock = NULL, u_int iTimeout = 0 )
|
||||
virtual T * ListenHost( u_short iPort, const CS_STRING & sSockName, const CS_STRING & sBindHost, int isSSL = false, int iMaxConns = SOMAXCONN, T *pcSock = NULL, u_int iTimeout = 0, bool bIsIPv6 = false )
|
||||
{
|
||||
if ( !pcSock )
|
||||
pcSock = new T();
|
||||
|
||||
pcSock->BlockIO( false );
|
||||
pcSock->SetIPv6( bIsIPv6 );
|
||||
|
||||
pcSock->SetSSL( isSSL );
|
||||
|
||||
@@ -1005,18 +1093,18 @@ public:
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
virtual bool ListenAll( u_short iPort, const CS_STRING & sSockName, int isSSL = false, int iMaxConns = SOMAXCONN, T *pcSock = NULL, u_int iTimeout = 0 )
|
||||
virtual bool ListenAll( u_short iPort, const CS_STRING & sSockName, int isSSL = false, int iMaxConns = SOMAXCONN, T *pcSock = NULL, u_int iTimeout = 0, bool bIsIPv6 = false )
|
||||
{
|
||||
return( ListenHost( iPort, sSockName, "", isSSL, iMaxConns, pcSock, iTimeout ) );
|
||||
return( ListenHost( iPort, sSockName, "", isSSL, iMaxConns, pcSock, iTimeout, bIsIPv6 ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* @return the port number being listened on
|
||||
*/
|
||||
virtual u_short ListenRand( const CS_STRING & sSockName, const CS_STRING & sBindHost, int isSSL = false, int iMaxConns = SOMAXCONN, T *pcSock = NULL, u_int iTimeout = 0 )
|
||||
virtual u_short ListenRand( const CS_STRING & sSockName, const CS_STRING & sBindHost, int isSSL = false, int iMaxConns = SOMAXCONN, T *pcSock = NULL, u_int iTimeout = 0, bool bIsIPv6 = false )
|
||||
{
|
||||
u_short iPort = 0;
|
||||
T *pNewSock = ListenHost( 0, sSockName, sBindHost, isSSL, iMaxConns, pcSock, iTimeout );
|
||||
T *pNewSock = ListenHost( 0, sSockName, sBindHost, isSSL, iMaxConns, pcSock, iTimeout, bIsIPv6 );
|
||||
if ( pNewSock )
|
||||
{
|
||||
int iSock = pNewSock->GetSock();
|
||||
@@ -1037,9 +1125,9 @@ public:
|
||||
|
||||
return( iPort );
|
||||
}
|
||||
virtual u_short ListenAllRand( const CS_STRING & sSockName, int isSSL = false, int iMaxConns = SOMAXCONN, T *pcSock = NULL, u_int iTimeout = 0 )
|
||||
virtual u_short ListenAllRand( const CS_STRING & sSockName, int isSSL = false, int iMaxConns = SOMAXCONN, T *pcSock = NULL, u_int iTimeout = 0, bool bIsIPv6 = false )
|
||||
{
|
||||
return( ListenRand( sSockName, "", isSSL, iMaxConns, pcSock, iTimeout ) );
|
||||
return( ListenRand( sSockName, "", isSSL, iMaxConns, pcSock, iTimeout, bIsIPv6 ) );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1624,6 +1712,7 @@ private:
|
||||
NewpcSock->SetType( T::INBOUND );
|
||||
NewpcSock->SetRSock( inSock );
|
||||
NewpcSock->SetWSock( inSock );
|
||||
NewpcSock->SetIPv6( pcSock->GetIPv6() );
|
||||
|
||||
bool bAddSock = true;
|
||||
#ifdef HAVE_LIBSSL
|
||||
|
||||
@@ -811,6 +811,7 @@ Optional Features:
|
||||
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
|
||||
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
||||
--enable-debug enable debuging
|
||||
--enable-ipv6 enable ipv6 support
|
||||
--disable-modules disable modules
|
||||
--disable-openssl disable openssl
|
||||
--disable-perl disable perl
|
||||
@@ -1948,6 +1949,11 @@ if test "${with_openssl+set}" = set; then
|
||||
withval="$with_openssl"
|
||||
OPENSSL=$withval
|
||||
fi;
|
||||
# Check whether --enable-ipv6 or --disable-ipv6 was given.
|
||||
if test "${enable_ipv6+set}" = set; then
|
||||
enableval="$enable_ipv6"
|
||||
appendCXX -DHAVE_IPV6
|
||||
fi;
|
||||
# Check whether --enable-debug or --disable-debug was given.
|
||||
if test "${enable_debug+set}" = set; then
|
||||
enableval="$enable_debug"
|
||||
|
||||
@@ -41,6 +41,7 @@ if test "$host_cpu" = "x86_64"; then
|
||||
fi
|
||||
|
||||
AC_ARG_WITH( openssl, [ --with-openssl=/path/to/openssl], OPENSSL=$withval,)
|
||||
AC_ARG_ENABLE( ipv6, [ --enable-ipv6 enable ipv6 support], -DWITH_IPV6,)
|
||||
AC_ARG_ENABLE( debug, [ --enable-debug enable debuging], appendCXX -Wall -ggdb -D_DEBUG, appendCXX -Wall -s -O2 -fomit-frame-pointer )
|
||||
AC_ARG_ENABLE( modules, [ --disable-modules disable modules], MODULES="no", MODULES="yes")
|
||||
AC_ARG_ENABLE( openssl, [ --disable-openssl disable openssl], NOSSL=1,)
|
||||
|
||||
Reference in New Issue
Block a user