From: <ps...@us...> - 2008-09-30 14:44:14
|
Revision: 1233 http://znc.svn.sourceforge.net/znc/?rev=1233&view=rev Author: psychon Date: 2008-09-30 14:43:51 +0000 (Tue, 30 Sep 2008) Log Message: ----------- Limit the maximal read buffer space that is used for every socket CSocket caches the data read from a socket and then looks for lines in there. If there is no line end, this buffer can grow quite large. This patch now closes sockets if they get a huge read buffer. Modified Paths: -------------- trunk/Client.cpp trunk/Client.h trunk/DCCBounce.cpp trunk/DCCBounce.h trunk/HTTPSock.cpp trunk/HTTPSock.h trunk/IRCSock.cpp trunk/IRCSock.h trunk/Modules.cpp trunk/Modules.h Modified: trunk/Client.cpp =================================================================== --- trunk/Client.cpp 2008-09-30 12:58:34 UTC (rev 1232) +++ trunk/Client.cpp 2008-09-30 14:43:51 UTC (rev 1233) @@ -696,6 +696,14 @@ MODULECALL(OnUserDetached(), m_pUser, this, ); } +void CClient::ReachedMaxBuffer() { + DEBUG_ONLY(cout << GetSockName() << " == ReachedMaxBuffer()" << endl); + if (IsAttached()) { + PutClient("ERROR :Closing link [Too long raw line]"); + } + Close(); +} + void CClient::IRCConnected(CIRCSock* pIRCSock) { m_pIRCSock = pIRCSock; } Modified: trunk/Client.h =================================================================== --- trunk/Client.h 2008-09-30 12:58:34 UTC (rev 1232) +++ trunk/Client.h 2008-09-30 14:43:51 UTC (rev 1233) @@ -75,6 +75,9 @@ m_bNamesx = false; m_bUHNames = false; EnableReadLine(); + // RFC says a line can have 512 chars max, but we are + // a little more gentle ;) + SetMaxBufferThreshold(1024); StartLoginTimeout(); } @@ -113,6 +116,7 @@ virtual void Connected(); virtual void Disconnected(); virtual void ConnectionRefused(); + virtual void ReachedMaxBuffer(); void SetNick(const CString& s); CUser* GetUser() const { return m_pUser; } Modified: trunk/DCCBounce.cpp =================================================================== --- trunk/DCCBounce.cpp 2008-09-30 12:58:34 UTC (rev 1232) +++ trunk/DCCBounce.cpp 2008-09-30 14:43:51 UTC (rev 1233) @@ -38,6 +38,15 @@ PutPeer(sLine); } +void CDCCBounce::ReachedMaxBuffer() { + DEBUG_ONLY(cout << GetSockName() << " == ReachedMaxBuffer()" << endl); + + CString sType = (m_bIsChat) ? "Chat" : "Xfer"; + + m_pUser->PutStatus("DCC " + sType + " Bounce (" + m_sRemoteNick + "): Too long line received"); + Close(); +} + void CDCCBounce::ReadData(const char* data, int len) { size_t BufLen; Modified: trunk/DCCBounce.h =================================================================== --- trunk/DCCBounce.h 2008-09-30 12:58:34 UTC (rev 1232) +++ trunk/DCCBounce.h 2008-09-30 14:43:51 UTC (rev 1233) @@ -43,6 +43,7 @@ m_sRemoteIP = sRemoteIP; m_bIsRemote = false; + SetMaxBufferThreshold(10240); if (bIsChat) { EnableReadLine(); } @@ -56,6 +57,7 @@ virtual void ReadPaused(); virtual void Timeout(); virtual void ConnectionRefused(); + virtual void ReachedMaxBuffer(); virtual void SockError(int iErrno); virtual void Connected(); virtual void Disconnected(); Modified: trunk/HTTPSock.cpp =================================================================== --- trunk/HTTPSock.cpp 2008-09-30 12:58:34 UTC (rev 1232) +++ trunk/HTTPSock.cpp 2008-09-30 14:43:51 UTC (rev 1233) @@ -19,6 +19,7 @@ m_bDone = false; m_uPostLen = 0; EnableReadLine(); + SetMaxBufferThreshold(10240); } CHTTPSock::CHTTPSock(const CString& sHostname, unsigned short uPort, int iTimeout) : Csock(sHostname, uPort, iTimeout) { @@ -29,6 +30,7 @@ m_bDone = false; m_uPostLen = 0; EnableReadLine(); + SetMaxBufferThreshold(10240); } CHTTPSock::~CHTTPSock() {} @@ -384,6 +386,11 @@ void CHTTPSock::Disconnected() { } +void CHTTPSock::ReachedMaxBuffer() { + DEBUG_ONLY(cout << GetSockName() << " == ReachedMaxBuffer()" << endl); + Close(); +} + Csock* CHTTPSock::GetSockObj(const CString& sHost, unsigned short uPort) { CHTTPSock* pSock = new CHTTPSock; pSock->SetSockName("HTTP::CLIENT"); Modified: trunk/HTTPSock.h =================================================================== --- trunk/HTTPSock.h 2008-09-30 12:58:34 UTC (rev 1232) +++ trunk/HTTPSock.h 2008-09-30 14:43:51 UTC (rev 1233) @@ -23,6 +23,7 @@ // Csocket derived members virtual void ReadData(const char* data, int len); virtual void ReadLine(const CString& sData); + virtual void ReachedMaxBuffer(); virtual void SockError(int iErrno); virtual void Timeout(); virtual void Connected(); Modified: trunk/IRCSock.cpp =================================================================== --- trunk/IRCSock.cpp 2008-09-30 12:58:34 UTC (rev 1232) +++ trunk/IRCSock.cpp 2008-09-30 14:43:51 UTC (rev 1233) @@ -36,6 +36,9 @@ m_mueChanModes['t'] = NoArg; m_mueChanModes['i'] = NoArg; m_mueChanModes['n'] = NoArg; + + // RFC says a line can have 512 chars max, but we don't care ;) + SetMaxBufferThreshold(1024); } CIRCSock::~CIRCSock() { @@ -878,6 +881,12 @@ m_pUser->ClearMotdBuffer(); } +void CIRCSock::ReachedMaxBuffer() { + DEBUG_ONLY(cout << GetSockName() << " == ReachedMaxBuffer()" << endl); + m_pUser->PutStatus("Received a too long line from the IRC server!"); + Quit(); +} + void CIRCSock::ParseISupport(const CString& sLine) { unsigned int i = 0; CString sArg = sLine.Token(i++); Modified: trunk/IRCSock.h =================================================================== --- trunk/IRCSock.h 2008-09-30 12:58:34 UTC (rev 1232) +++ trunk/IRCSock.h 2008-09-30 14:43:51 UTC (rev 1233) @@ -46,6 +46,7 @@ virtual void ConnectionRefused(); virtual void SockError(int iErrno); virtual void Timeout(); + virtual void ReachedMaxBuffer(); void PutIRC(const CString& sLine); void ResetChans(); Modified: trunk/Modules.cpp =================================================================== --- trunk/Modules.cpp 2008-09-30 12:58:34 UTC (rev 1232) +++ trunk/Modules.cpp 2008-09-30 14:43:51 UTC (rev 1233) @@ -103,18 +103,26 @@ m_pModule = pModule; m_pModule->AddSocket(this); EnableReadLine(); + SetMaxBufferThreshold(10240); } CSocket::CSocket(CModule* pModule, const CString& sHostname, unsigned short uPort, int iTimeout) : Csock(sHostname, uPort, iTimeout) { m_pModule = pModule; m_pModule->AddSocket(this); EnableReadLine(); + SetMaxBufferThreshold(10240); } CSocket::~CSocket() { m_pModule->UnlinkSocket(this); } +void CSocket::ReachedMaxBuffer() { + DEBUG_ONLY(cout << GetSockName() << " == ReachedMaxBuffer()" << endl); + PutModule("Some socket reached its max buffer limit and was closed!"); + Close(); +} + bool CSocket::Connect(const CString& sHostname, unsigned short uPort, bool bSSL, unsigned int uTimeout) { CUser* pUser = m_pModule->GetUser(); CString sSockName = "MOD::C::" + m_pModule->GetModName(); Modified: trunk/Modules.h =================================================================== --- trunk/Modules.h 2008-09-30 12:58:34 UTC (rev 1232) +++ trunk/Modules.h 2008-09-30 14:43:51 UTC (rev 1233) @@ -139,6 +139,9 @@ using Csock::Connect; using Csock::Listen; + // This defaults to closing the socket, feel free to override + virtual void ReachedMaxBuffer(); + bool Connect(const CString& sHostname, unsigned short uPort, bool bSSL = false, unsigned int uTimeout = 60); bool Listen(unsigned short uPort, bool bSSL = false, unsigned int uTimeout = 0); virtual bool PutIRC(const CString& sLine); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |