diff --git a/Csocket.cpp b/Csocket.cpp index 52a62b37..a4a1243c 100644 --- a/Csocket.cpp +++ b/Csocket.cpp @@ -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; } diff --git a/Csocket.h b/Csocket.h index a065df28..f4fd3e00 100644 --- a/Csocket.h +++ b/Csocket.h @@ -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 diff --git a/configure b/configure index 0ed92f88..9417bd6d 100755 --- a/configure +++ b/configure @@ -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" diff --git a/configure.in b/configure.in index 0b7ac81f..50526831 100644 --- a/configure.in +++ b/configure.in @@ -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,)