From 9736711c03bd52a2d1747d3d5155a5e3b1f4f097 Mon Sep 17 00:00:00 2001 From: psychon Date: Tue, 7 Aug 2007 22:58:23 +0000 Subject: [PATCH] Update to latest CSocket version. git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@823 726aef4b-f618-498e-8847-2d620e286838 --- Csocket.cpp | 142 +++++++++++++++++++++++++++++++++++++++++++++------- Csocket.h | 67 ++++++++++++++++++++++--- 2 files changed, 186 insertions(+), 23 deletions(-) diff --git a/Csocket.cpp b/Csocket.cpp index cac39fa5..bd1f19c0 100644 --- a/Csocket.cpp +++ b/Csocket.cpp @@ -365,6 +365,9 @@ Csock::Csock( int itimeout ) #ifdef HAVE_LIBSSL m_pCerVerifyCB = NULL; #endif /* HAVE_LIBSSL */ +#ifdef ___DO_THREADS + m_pResolver = NULL; +#endif /* ___DO_THREADS */ Init( "", 0, itimeout ); } @@ -373,6 +376,9 @@ Csock::Csock( const CS_STRING & sHostname, u_short iport, int itimeout ) #ifdef HAVE_LIBSSL m_pCerVerifyCB = NULL; #endif /* HAVE_LIBSSL */ +#ifdef ___DO_THREADS + m_pResolver = NULL; +#endif /* ___DO_THREADS */ Init( sHostname, iport, itimeout ); } @@ -391,18 +397,24 @@ Csock *Csock::GetSockObj( const CS_STRING & sHostname, u_short iPort ) Csock::~Csock() { #ifdef ___DO_THREADS - m_cResolver.lock(); - CDNSResolver::EStatus eStatus = m_cResolver.Status(); - m_cResolver.unlock(); - if ( eStatus == CDNSResolver::RUNNING ) - m_cResolver.cancel(); + if( m_pResolver ) + { + m_pResolver->lock(); + CDNSResolver::EStatus eStatus = m_pResolver->Status(); + m_pResolver->unlock(); + if ( eStatus == CDNSResolver::RUNNING ) + m_pResolver->cancel(); + Zzap( m_pResolver ); + } #endif /* __DO_THREADS_ */ if ( m_iReadSock != m_iWriteSock ) { - CS_CLOSE( m_iReadSock ); - CS_CLOSE( m_iWriteSock ); - } else + if( m_iReadSock >= 0 ) + CS_CLOSE( m_iReadSock ); + if( m_iWriteSock >= 0 ) + CS_CLOSE( m_iWriteSock ); + } else if( m_iReadSock >= 0 ) CS_CLOSE( m_iReadSock ); m_iReadSock = -1; @@ -418,6 +430,99 @@ Csock::~Csock() CS_Delete( m_vcCrons[i] ); } +void Csock::Dereference() +{ +#ifdef ___DO_THREADS + m_pResolver = NULL; +#endif /* __DO_THREADS_ */ + m_iWriteSock = m_iReadSock = -1; + +#ifdef HAVE_LIBSSL + m_ssl = NULL; + m_ssl_ctx = NULL; +#endif /* HAVE_LIBSSL */ + + m_vcCrons.clear(); +} + +void Csock::Copy( const Csock & cCopy ) +{ + m_iport = cCopy.m_iport; + m_iRemotePort = cCopy.m_iRemotePort; + m_iLocalPort = cCopy.m_iLocalPort; + m_iReadSock = cCopy.m_iReadSock; + m_iWriteSock = cCopy.m_iWriteSock; + m_itimeout = cCopy.m_iWriteSock; + m_iConnType = cCopy.m_iTcount; + m_iMethod = cCopy.m_iMethod; + m_bssl = cCopy.m_bssl; + m_bIsConnected = cCopy.m_bIsConnected; + m_bBLOCK = cCopy.m_bBLOCK; + m_bFullsslAccept = cCopy.m_bFullsslAccept; + m_bsslEstablished = cCopy.m_bsslEstablished; + m_bEnableReadLine = cCopy.m_bEnableReadLine; + m_bRequireClientCert = cCopy.m_bRequireClientCert; + m_bPauseRead = cCopy.m_bPauseRead; + m_shostname = cCopy.m_shostname; + m_sbuffer = cCopy.m_sbuffer; + m_sSockName = cCopy.m_sSockName; + m_sPemFile = cCopy.m_sPemFile; + 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; + m_eCloseType = cCopy.m_eCloseType; + + m_iMaxMilliSeconds = cCopy.m_iMaxMilliSeconds; + m_iLastSendTime = cCopy.m_iLastSendTime; + m_iBytesRead = cCopy.m_iBytesRead; + m_iBytesWritten = cCopy.m_iBytesWritten; + m_iStartTime = cCopy.m_iStartTime; + m_iMaxBytes = cCopy.m_iMaxBytes; + m_iLastSend = cCopy.m_iLastSend; + m_iMaxStoredBufferLength = cCopy.m_iMaxStoredBufferLength; + m_iTimeoutType = cCopy.m_iTimeoutType; + + m_address = cCopy.m_address; + m_bindhost = cCopy.m_bindhost; + m_bIsIPv6 = cCopy.m_bIsIPv6; + +#ifdef HAVE_LIBSSL + FREE_SSL(); + FREE_CTX(); // be sure to remove anything that was already here + m_ssl = cCopy.m_ssl; + m_ssl_ctx = cCopy.m_ssl_ctx; + m_ssl_method = cCopy.m_ssl_method; + + m_pCerVerifyCB = cCopy.m_pCerVerifyCB; + +#endif /* HAVE_LIBSSL */ + + if( m_vcCrons.size() ) + { + for( u_long a = 0; a < m_vcCrons.size(); a++ ) + { + CS_Delete( m_vcCrons[a] ); + } + m_vcCrons.clear(); + } + m_vcCrons = cCopy.m_vcCrons; + + m_eConState = cCopy.m_eConState; + m_sBindHost = cCopy.m_sBindHost; + m_iCurBindCount = cCopy.m_iCurBindCount; + m_iDNSTryCount = cCopy.m_iDNSTryCount; + +#ifdef ___DO_THREADS + if( m_pResolver ) + CS_Delete( m_pResolver ); + m_pResolver = cCopy.m_pResolver; +#endif /* ___DO_THREADS */ +} + Csock & Csock::operator<<( const CS_STRING & s ) { Write( s ); @@ -1758,44 +1863,47 @@ int Csock::DNSLookup( EDNSLType eDNSLType ) } #ifdef ___DO_THREADS + if( !m_pResolver ) + m_pResolver = new CDNSResolver; + if ( m_iDNSTryCount == 0 ) { - m_cResolver.Lookup( ( eDNSLType == DNS_VHOST ) ? m_sBindHost : m_shostname ); + m_pResolverLookup( ( eDNSLType == DNS_VHOST ) ? m_sBindHost : m_shostname ); m_iDNSTryCount++; } - if ( m_cResolver.IsCompleted() ) + if ( m_pResolverIsCompleted() ) { m_iDNSTryCount = 0; - if ( m_cResolver.Suceeded() ) + if ( m_pResolverSuceeded() ) { if ( eDNSLType == DNS_VHOST ) { - if( !m_cResolver.GetSockAddr()->GetIPv6() ) + if( !m_pResolverGetSockAddr()->GetIPv6() ) { SetIPv6( false ); - memcpy( m_bindhost.GetAddr(), m_cResolver.GetSockAddr()->GetAddr(), sizeof( *(m_bindhost.GetAddr()) ) ); + memcpy( m_bindhost.GetAddr(), m_pResolverGetSockAddr()->GetAddr(), sizeof( *(m_bindhost.GetAddr()) ) ); } #ifdef HAVE_IPV6 else { SetIPv6( true ); - memcpy( m_bindhost.GetAddr6(), m_cResolver.GetSockAddr()->GetAddr6(), sizeof( *(m_bindhost.GetAddr6()) ) ); + memcpy( m_bindhost.GetAddr6(), m_pResolverGetSockAddr()->GetAddr6(), sizeof( *(m_bindhost.GetAddr6()) ) ); } #endif /* HAVE_IPV6 */ } else { - if( m_cResolver.GetSockAddr()->GetIPv6() ) + if( m_pResolverGetSockAddr()->GetIPv6() ) { SetIPv6( false ); - memcpy( m_address.GetAddr(), m_cResolver.GetSockAddr()->GetAddr(), sizeof( *(m_address.GetAddr()) ) ); + memcpy( m_address.GetAddr(), m_pResolverGetSockAddr()->GetAddr(), sizeof( *(m_address.GetAddr()) ) ); } #ifdef HAVE_IPV6 else { SetIPv6( true ); - memcpy( m_address.GetAddr6(), m_cResolver.GetSockAddr()->GetAddr6(), sizeof( *(m_address.GetAddr6()) ) ); + memcpy( m_address.GetAddr6(), m_pResolverGetSockAddr()->GetAddr6(), sizeof( *(m_address.GetAddr6()) ) ); } #endif /* HAVE_IPV6 */ } diff --git a/Csocket.h b/Csocket.h index 3494fad0..8fce8ba1 100644 --- a/Csocket.h +++ b/Csocket.h @@ -396,6 +396,9 @@ public: const CS_STRING & GetName() const; void SetName( const CS_STRING & sName ); + //! returns the timestamp of the next estimated run time. Note that it may not run at this EXACT time, but it will run at least at this time or after + time_t GetNextRun() const { return( m_iTime ); } + public: //! this is the method you should override @@ -441,6 +444,16 @@ public: virtual ~Csock(); + /** + * @brief in the event you pass this class to Copy(), you MUST call this function or + * on the original Csock other wise bad side effects will happen (double deletes, weird sock closures, etc) + * if you call this function and have not handled the internal pointers, other bad things can happend (memory leaks, fd leaks, etc) + * the whole point of this function is to allow this class to go away without shutting down + */ + virtual void Dereference(); + //! use this to copy a sock from one to the other, override it if you have special needs in the event of a copy + virtual void Copy( const Csock & cCopy ); + enum ETConn { OUTBOUND = 0, //!< outbound connection @@ -945,6 +958,10 @@ public: bool AllowWrite( unsigned long long & iNOW ) const; private: + //! making private for safety + Csock( const Csock & cCopy ) {} + + // NOTE! if you add any new members, be sure to add them to Copy() u_short m_iport, m_iRemotePort, m_iLocalPort; int m_iReadSock, m_iWriteSock, m_itimeout, m_iConnType, m_iTcount, m_iMethod; bool m_bssl, m_bIsConnected, m_bBLOCK, m_bFullsslAccept; @@ -966,16 +983,16 @@ private: FPCertVerifyCB m_pCerVerifyCB; - virtual void FREE_SSL(); - virtual void FREE_CTX(); + void FREE_SSL(); + void FREE_CTX(); #endif /* HAVE_LIBSSL */ std::vector m_vcCrons; //! Create the socket - virtual int SOCKET( bool bListen = false ); - virtual void Init( const CS_STRING & sHostname, u_short iport, int itimeout = 60 ); + int SOCKET( bool bListen = false ); + void Init( const CS_STRING & sHostname, u_short iport, int itimeout = 60 ); // Connection State Info @@ -984,7 +1001,7 @@ private: u_int m_iCurBindCount, m_iDNSTryCount; #ifdef ___DO_THREADS - CDNSResolver m_cResolver; + CDNSResolver m_pResolver; #endif /* ___DO_THREADS */ }; @@ -1680,7 +1697,7 @@ public: return; } - Csock * pSock = (*this)[iPos]; + T * pSock = (*this)[iPos]; if ( pSock->IsConnected() ) pSock->Disconnected(); // only call disconnected event if connected event was called (IE IsConnected was set) @@ -1692,6 +1709,44 @@ public: this->erase( this->begin() + iPos ); } + /** + * @brief swaps out a sock with a copy of the original sock + * @param pNewSock the new sock to change out with. (this should be constructed by you with the default ctor) + * @param iOrginalSockIdx the position in this sockmanager of the original sock + * @return true on success + */ + virtual bool SwapSockByIdx( Csock *pNewSock, u_long iOrginalSockIdx ) + { + if( iOrginalSockIdx >= this->size() ) + { + CS_DEBUG( "Invalid Sock Position Requested! [" << iOrginalSockIdx << "]" ); + return( false ); + } + + Csock *pSock = (*this)[iOrginalSockIdx]; + pNewSock->Copy( *pSock ); + pSock->Dereference(); + CS_Delete( pSock ); + (*this)[iOrginalSockIdx] = (T *)pNewSock; + return( true ); + } + + /** + * @brief swaps out a sock with a copy of the original sock + * @param pNewSock the new sock to change out with. (this should be constructed by you with the default ctor) + * @param pOrigSock the address of the original socket + * @return true on success + */ + virtual bool SwapSockByAddr( Csock *pNewSock, Csock *pOrigSock ) + { + for( u_long a = 0; a < this->size(); a++ ) + { + if( (*this)[a] == pOrigSock ) + return( SwapSockByIdx( pNewSock, a ) ); + } + return( false ); + } + //! Get the bytes read from all sockets current and past unsigned long long GetBytesRead() const {