diff --git a/Client.cpp b/Client.cpp index cb945b88..3846c728 100644 --- a/Client.cpp +++ b/Client.cpp @@ -696,6 +696,14 @@ void CClient::Disconnected() { 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; } diff --git a/Client.h b/Client.h index 20813233..4729ef85 100644 --- a/Client.h +++ b/Client.h @@ -75,6 +75,9 @@ public: 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 @@ public: virtual void Connected(); virtual void Disconnected(); virtual void ConnectionRefused(); + virtual void ReachedMaxBuffer(); void SetNick(const CString& s); CUser* GetUser() const { return m_pUser; } diff --git a/DCCBounce.cpp b/DCCBounce.cpp index 76fd897d..a0803592 100644 --- a/DCCBounce.cpp +++ b/DCCBounce.cpp @@ -38,6 +38,15 @@ void CDCCBounce::ReadLine(const CString& sData) { 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; diff --git a/DCCBounce.h b/DCCBounce.h index 773aa795..e7f6bf3f 100644 --- a/DCCBounce.h +++ b/DCCBounce.h @@ -43,6 +43,7 @@ public: m_sRemoteIP = sRemoteIP; m_bIsRemote = false; + SetMaxBufferThreshold(10240); if (bIsChat) { EnableReadLine(); } @@ -56,6 +57,7 @@ public: virtual void ReadPaused(); virtual void Timeout(); virtual void ConnectionRefused(); + virtual void ReachedMaxBuffer(); virtual void SockError(int iErrno); virtual void Connected(); virtual void Disconnected(); diff --git a/HTTPSock.cpp b/HTTPSock.cpp index 91bfdcb3..337f5da3 100644 --- a/HTTPSock.cpp +++ b/HTTPSock.cpp @@ -19,6 +19,7 @@ CHTTPSock::CHTTPSock() : Csock() { 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 @@ CHTTPSock::CHTTPSock(const CString& sHostname, unsigned short uPort, int iTimeou m_bDone = false; m_uPostLen = 0; EnableReadLine(); + SetMaxBufferThreshold(10240); } CHTTPSock::~CHTTPSock() {} @@ -384,6 +386,11 @@ void CHTTPSock::Connected() { 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"); diff --git a/HTTPSock.h b/HTTPSock.h index 691ada76..768087e7 100644 --- a/HTTPSock.h +++ b/HTTPSock.h @@ -23,6 +23,7 @@ public: // 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(); diff --git a/IRCSock.cpp b/IRCSock.cpp index 6fa08142..1983aeb6 100644 --- a/IRCSock.cpp +++ b/IRCSock.cpp @@ -36,6 +36,9 @@ CIRCSock::CIRCSock(CUser* pUser) : Csock() { 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 @@ void CIRCSock::ConnectionRefused() { 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++); diff --git a/IRCSock.h b/IRCSock.h index 50dddf27..982b3120 100644 --- a/IRCSock.h +++ b/IRCSock.h @@ -46,6 +46,7 @@ public: virtual void ConnectionRefused(); virtual void SockError(int iErrno); virtual void Timeout(); + virtual void ReachedMaxBuffer(); void PutIRC(const CString& sLine); void ResetChans(); diff --git a/Modules.cpp b/Modules.cpp index e1b3d70f..bab4c8d8 100644 --- a/Modules.cpp +++ b/Modules.cpp @@ -103,18 +103,26 @@ CSocket::CSocket(CModule* pModule) : Csock() { 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(); diff --git a/Modules.h b/Modules.h index ffa4e987..bd224b9f 100644 --- a/Modules.h +++ b/Modules.h @@ -139,6 +139,9 @@ public: 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);