Update to latest Csocket

git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1683 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
psychon
2009-12-19 16:29:26 +00:00
parent 195a06bc2e
commit 6ce29e77f2
2 changed files with 151 additions and 33 deletions
+104 -4
View File
@@ -28,7 +28,7 @@
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* $Revision: 1.105 $
* $Revision: 1.108 $
*/
#include "Csocket.h"
@@ -36,7 +36,6 @@
#include <sys/param.h>
#endif /* __NetBSD__ */
#include <list>
#define CS_SRANDBUFFER 128
@@ -197,6 +196,49 @@ static int __GetHostByName( const CS_STRING & sHostName, struct in_addr *paddr,
}
#endif /* !HAVE_IPV6 */
#ifdef HAVE_C_ARES
void Csock::FreeAres()
{
if( m_pARESChannel )
{
ares_destroy( m_pARESChannel );
m_pARESChannel = NULL;
}
}
#endif /* HAVE_C_ARES */
#ifdef HAVE_C_ARES
void AresHostCallback( void *pArg, int status, int timeouts, struct hostent *hent )
{
Csock *pSock = (Csock *)pArg;
if( status == ARES_SUCCESS && hent )
{
CSSockAddr *pSockAddr = pSock->GetCurrentAddr();
if( hent->h_addrtype == AF_INET )
{
pSock->SetIPv6( false );
memcpy( pSockAddr->GetAddr(), hent->h_addr_list[0], sizeof( *(pSockAddr->GetAddr()) ) );
}
#ifdef HAVE_IPV6
else if( hent->h_addrtype == AF_INET6 )
{
pSock->SetIPv6( true );
memcpy( pSockAddr->GetAddr6(), hent->h_addr_list[0], sizeof( *(pSockAddr->GetAddr6()) ) );
}
#endif /* HAVE_IPV6 */
else
{
status = ARES_ENOTFOUND;
}
}
else
{
CS_DEBUG( ares_strerror( status ) );
}
pSock->SetAresFinished( status );
}
#endif /* HAVE_C_ARES */
int GetAddrInfo( const CS_STRING & sHostname, Csock *pSock, CSSockAddr & csSockAddr )
{
#ifndef HAVE_IPV6
@@ -530,6 +572,12 @@ Csock *Csock::GetSockObj( const CS_STRING & sHostname, u_short iPort )
Csock::~Csock()
{
#ifdef HAVE_C_ARES
if( m_pARESChannel )
ares_cancel( m_pARESChannel );
FreeAres();
#endif /* HAVE_C_ARES */
#ifdef HAVE_LIBSSL
FREE_SSL();
FREE_CTX();
@@ -610,6 +658,11 @@ void Csock::Copy( const Csock & cCopy )
m_bindhost = cCopy.m_bindhost;
m_bIsIPv6 = cCopy.m_bIsIPv6;
m_bSkipConnect = cCopy.m_bSkipConnect;
#ifdef HAVE_C_ARES
FreeAres(); // Not copying this state, but making sure its nulled out
m_iARESStatus = -1; // set it to unitialized
m_pCurrAddr = NULL;
#endif /* HAVE_C_ARES */
#ifdef HAVE_LIBSSL
m_iRequireClientCertFlags = cCopy.m_iRequireClientCertFlags;
@@ -2006,6 +2059,48 @@ int Csock::GetPending()
int Csock::GetAddrInfo( const CS_STRING & sHostname, CSSockAddr & csSockAddr )
{
#ifdef HAVE_IPV6
if( csSockAddr.GetAFRequire() != AF_INET && inet_pton( AF_INET6, sHostname.c_str(), csSockAddr.GetAddr6() ) > 0 )
{
SetIPv6( true );
return( 0 );
}
#endif /* HAVE_IPV6 */
if( inet_pton( AF_INET, sHostname.c_str(), csSockAddr.GetAddr() ) > 0 )
{
#ifdef HAVE_IPV6
SetIPv6( false );
#endif /* HAVE_IPV6 */
return( 0 );
}
#ifdef HAVE_C_ARES
if( GetType() != LISTENER )
{ // right now the current function in Listen() is it blocks, the easy way around this at the moment is to use ip
if( !m_pARESChannel )
{
if( ares_init( &m_pARESChannel ) != ARES_SUCCESS )
{ // TODO throw some debug?
FreeAres();
return( ETIMEDOUT );
}
m_pCurrAddr = &csSockAddr; // flag its starting
int iFamily = AF_INET;
#ifdef HAVE_IPV6
iFamily = csSockAddr.GetAFRequire() == CSSockAddr::RAF_ANY ? AF_INET6 : csSockAddr.GetAFRequire();
#endif /* HAVE_IPV6 */
ares_gethostbyname( m_pARESChannel, sHostname.c_str(), iFamily, AresHostCallback, this );
}
if( !m_pCurrAddr )
{ // this means its finished
FreeAres();
return( m_iARESStatus == ARES_SUCCESS ? 0 : ETIMEDOUT );
}
return( EAGAIN );
}
#endif /* HAVE_C_ARES */
return( ::GetAddrInfo( sHostname, this, csSockAddr ) );
}
@@ -2147,7 +2242,7 @@ int Csock::SOCKET( bool bListen )
return( iRet );
}
void Csock::Init( const CS_STRING & sHostname, u_short iport, int itimeout )
void Csock::Init( const CS_STRING & sHostname, u_short uPort, int itimeout )
{
#ifdef HAVE_LIBSSL
m_ssl = NULL;
@@ -2160,7 +2255,7 @@ void Csock::Init( const CS_STRING & sHostname, u_short iport, int itimeout )
m_itimeout = itimeout;
m_bssl = false;
m_bIsConnected = false;
m_iport = iport;
m_iport = uPort;
m_shostname = sHostname;
m_sbuffer.clear();
m_eCloseType = CLT_DONT;
@@ -2189,5 +2284,10 @@ void Csock::Init( const CS_STRING & sHostname, u_short iport, int itimeout )
m_bIsIPv6 = false;
m_bSkipConnect = false;
m_iLastCheckTimeoutTime = 0;
#ifdef HAVE_C_ARES
m_pARESChannel = NULL;
m_pCurrAddr = NULL;
m_iARESStatus = -1;
#endif /* HAVE_C_ARES */
}
+47 -29
View File
@@ -28,7 +28,7 @@
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* $Revision: 1.211 $
* $Revision: 1.213 $
*/
// note to compile with win32 need to link to winsock2, using gcc its -lws2_32
@@ -61,6 +61,10 @@
#endif /* _WIN32 */
#ifdef HAVE_C_ARES
#include <ares.h>
#endif /* HAVE_C_ARES */
#include <stdlib.h>
#include <errno.h>
#include <string.h>
@@ -923,12 +927,12 @@ public:
enum EDNSLType
{
DNS_VHOST,
DNS_DEST
DNS_VHOST, //!< this lookup is for the vhost bind
DNS_DEST //!< this lookup is for the destination address
};
/**
* nonblocking dns lookup (when -pthread is set to compile)
* dns lookup @see EDNSLType
* @return 0 for success, EAGAIN to check back again (same arguments as before), ETIMEDOUT on failure
*/
int DNSLookup( EDNSLType eDNSLType );
@@ -966,6 +970,12 @@ public:
*/
virtual int GetAddrInfo( const CS_STRING & sHostname, CSSockAddr & csSockAddr );
#ifdef HAVE_C_ARES
CSSockAddr * GetCurrentAddr() const { return( m_pCurrAddr ); }
void SetAresFinished( int status ) { m_pCurrAddr = NULL; m_iARESStatus = status; }
ares_channel GetAresChannel() { return( m_pARESChannel ); }
#endif /* HAVE_C_ARES */
private:
//! making private for safety
Csock( const Csock & cCopy ) {}
@@ -1010,6 +1020,12 @@ private:
ECONState m_eConState;
CS_STRING m_sBindHost;
u_int m_iCurBindCount, m_iDNSTryCount;
#ifdef HAVE_C_ARES
void FreeAres();
ares_channel m_pARESChannel;
CSSockAddr *m_pCurrAddr;
int m_iARESStatus;
#endif /* HAVE_C_ARES */
};
@@ -1369,7 +1385,6 @@ public:
if ( ( pcSock->GetType() != T::OUTBOUND ) || ( pcSock->GetConState() == T::CST_OK ) )
continue;
if ( pcSock->GetConState() == T::CST_DNS )
{
if ( pcSock->DNSLookup( T::DNS_VHOST ) == ETIMEDOUT )
@@ -1847,24 +1862,32 @@ protected:
TFD_ZERO( &rfds );
TFD_ZERO( &wfds );
// before we go any further, Process work needing to be done on the job
for( unsigned int i = 0; i < this->size(); i++ )
{
Csock::ECloseType eCloseType = (*this)[i]->GetCloseType();
if( eCloseType == T::CLT_NOW || eCloseType == T::CLT_DEREFERENCE || ( eCloseType == T::CLT_AFTERWRITE && (*this)[i]->GetWriteBuffer().empty() ) )
DelSock( i-- ); // close any socks that have requested it
else
(*this)[i]->Cron(); // call the Cron handler here
}
bool bHasWriteable = false;
bool bHasAvailSocks = false;
unsigned long long iNOW = 0;
for( unsigned int i = 0; i < this->size(); i++ )
{
T *pcSock = (*this)[i];
Csock::ECloseType eCloseType = pcSock->GetCloseType();
if( eCloseType == T::CLT_NOW || eCloseType == T::CLT_DEREFERENCE || ( eCloseType == T::CLT_AFTERWRITE && pcSock->GetWriteBuffer().empty() ) )
{
DelSock( i-- ); // close any socks that have requested it
continue;
}
else
pcSock->Cron(); // call the Cron handler here
#ifdef HAVE_C_ARES
ares_channel pChannel = pcSock->GetAresChannel();
if( pChannel )
{
ares_fds( pChannel, &rfds, &wfds );
bHasWriteable = true;
}
#endif /* HAVE_C_ARES */
if ( pcSock->GetConState() != T::CST_OK )
continue;
@@ -1929,18 +1952,8 @@ protected:
} else
TFD_SET( iRSock, &rfds );
}
// first check to see if any ssl sockets are ready for immediate read
// a mini select() type deal for ssl
for( unsigned int i = 0; i < this->size(); i++ )
{
T *pcSock = (*this)[i];
if ( pcSock->GetConState() != T::CST_OK )
continue;
if ( ( pcSock->GetSSL() ) && ( pcSock->GetType() != Csock::LISTENER ) )
if( pcSock->GetSSL() && pcSock->GetType() != Csock::LISTENER )
{
if ( ( pcSock->GetPending() > 0 ) && ( !pcSock->IsReadPaused() ) )
SelectSock( mpeSocks, SUCCESS, pcSock );
@@ -1961,7 +1974,6 @@ protected:
tv.tv_sec = 0;
}
if ( bHasWriteable )
iSel = Select(FD_SETSIZE, &rfds, &wfds, NULL, &tv);
else
@@ -2002,6 +2014,12 @@ protected:
{
T *pcSock = (*this)[i];
#ifdef HAVE_C_ARES
ares_channel pChannel = pcSock->GetAresChannel();
if( pChannel )
ares_process( pChannel, &rfds, &wfds );
#endif /* HAVE_C_ARES */
if ( pcSock->GetConState() != T::CST_OK )
continue;