diff --git a/Modules.cpp b/Modules.cpp index b17c4f51..212b8774 100644 --- a/Modules.cpp +++ b/Modules.cpp @@ -102,108 +102,6 @@ CModule* CTimer::GetModule() const { return m_pModule; } const CString& CTimer::GetDescription() const { return m_sDescription; } /////////////////// !Timer /////////////////// -/////////////////// Socket /////////////////// -CSocket::CSocket(CModule* pModule) : CZNCSock() { - m_pModule = pModule; - m_pModule->AddSocket(this); - EnableReadLine(); - SetMaxBufferThreshold(10240); -} - -CSocket::CSocket(CModule* pModule, const CString& sHostname, unsigned short uPort, int iTimeout) : CZNCSock(sHostname, uPort, iTimeout) { - m_pModule = pModule; - m_pModule->AddSocket(this); - EnableReadLine(); - SetMaxBufferThreshold(10240); -} - -CSocket::~CSocket() { - CUser *pUser = m_pModule->GetUser(); - - m_pModule->UnlinkSocket(this); - - if (!m_pModule->IsGlobal() && pUser) { - pUser->AddBytesWritten(GetBytesWritten()); - pUser->AddBytesRead(GetBytesRead()); - } else { - CZNC::Get().AddBytesWritten(GetBytesWritten()); - CZNC::Get().AddBytesRead(GetBytesRead()); - } -} - -void CSocket::ReachedMaxBuffer() { - DEBUG(GetSockName() << " == ReachedMaxBuffer()"); - PutModule("Some socket reached its max buffer limit and was closed!"); - Close(); -} - -void CSocket::SockError(int iErrno) { - DEBUG(GetSockName() << " == SockError(" << strerror(iErrno) << ")"); - if (iErrno == EMFILE) { - // We have too many open fds, this can cause a busy loop. - Close(); - } -} - -bool CSocket::ConnectionFrom(const CString& sHost, unsigned short uPort) { - return CZNC::Get().AllowConnectionFrom(sHost); -} - -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(); - CString sVHost; - - if (pUser) { - sSockName += "::" + pUser->GetUserName(); - sVHost = m_pModule->GetUser()->GetVHost(); - } - - // Don't overwrite the socket name if one is already set - if (!GetSockName().empty()) { - sSockName = GetSockName(); - } - - return m_pModule->GetManager()->Connect(sHostname, uPort, sSockName, uTimeout, bSSL, sVHost, this); -} - -bool CSocket::Listen(unsigned short uPort, bool bSSL, unsigned int uTimeout) { - CUser* pUser = m_pModule->GetUser(); - CString sSockName = "MOD::L::" + m_pModule->GetModName(); - - if (pUser) { - sSockName += "::" + pUser->GetUserName(); - } - // Don't overwrite the socket name if one is already set - if (!GetSockName().empty()) { - sSockName = GetSockName(); - } - - return m_pModule->GetManager()->ListenAll(uPort, sSockName, bSSL, SOMAXCONN, this); -} - -bool CSocket::PutIRC(const CString& sLine) { - return (m_pModule) ? m_pModule->PutIRC(sLine) : false; -} - -bool CSocket::PutUser(const CString& sLine) { - return (m_pModule) ? m_pModule->PutUser(sLine) : false; -} - -bool CSocket::PutStatus(const CString& sLine) { - return (m_pModule) ? m_pModule->PutStatus(sLine) : false; -} - -bool CSocket::PutModule(const CString& sLine, const CString& sIdent, const CString& sHost) { - return (m_pModule) ? m_pModule->PutModule(sLine, sIdent, sHost) : false; -} -bool CSocket::PutModNotice(const CString& sLine, const CString& sIdent, const CString& sHost) { - return (m_pModule) ? m_pModule->PutModNotice(sLine, sIdent, sHost) : false; -} - -void CSocket::SetModule(CModule* p) { m_pModule = p; } -CModule* CSocket::GetModule() const { return m_pModule; } -/////////////////// !Socket /////////////////// CModule::CModule(ModHandle pDLL, CUser* pUser, const CString& sModName, const CString& sDataDir) { m_bFake = false; diff --git a/Modules.h b/Modules.h index 2cfc5b38..e7d27dab 100644 --- a/Modules.h +++ b/Modules.h @@ -163,42 +163,6 @@ private: FPTimer_t m_pFBCallback; }; -class CSocket : public CZNCSock { -public: - CSocket(CModule* pModule); - CSocket(CModule* pModule, const CString& sHostname, unsigned short uPort, int iTimeout = 60); - virtual ~CSocket(); - - using Csock::Connect; - using Csock::Listen; - - // This defaults to closing the socket, feel free to override - virtual void ReachedMaxBuffer(); - virtual void SockError(int iErrno); - // This limits the global connections from this IP to defeat DoS - // attacks, feel free to override - virtual bool ConnectionFrom(const CString& sHost, unsigned short uPort); - - 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); - virtual bool PutUser(const CString& sLine); - virtual bool PutStatus(const CString& sLine); - virtual bool PutModule(const CString& sLine, const CString& sIdent = "", const CString& sHost = "znc.in"); - virtual bool PutModNotice(const CString& sLine, const CString& sIdent = "", const CString& sHost = "znc.in"); - - // Setters - void SetModule(CModule* p); - // !Setters - - // Getters - CModule* GetModule() const; - // !Getters -private: -protected: - CModule* m_pModule; -}; - class CModInfo { public: CModInfo() {} diff --git a/Socket.cpp b/Socket.cpp index 9e9b4225..cb678bbc 100644 --- a/Socket.cpp +++ b/Socket.cpp @@ -7,6 +7,9 @@ */ #include "Socket.h" +#include "Modules.h" +#include "User.h" +#include "znc.h" unsigned int CSockManager::GetAnonConnectionCount(const CString &sIP) const { const_iterator it; @@ -24,3 +27,106 @@ unsigned int CSockManager::GetAnonConnectionCount(const CString &sIP) const { return ret; } + +/////////////////// CSocket /////////////////// +CSocket::CSocket(CModule* pModule) : CZNCSock() { + m_pModule = pModule; + m_pModule->AddSocket(this); + EnableReadLine(); + SetMaxBufferThreshold(10240); +} + +CSocket::CSocket(CModule* pModule, const CString& sHostname, unsigned short uPort, int iTimeout) : CZNCSock(sHostname, uPort, iTimeout) { + m_pModule = pModule; + m_pModule->AddSocket(this); + EnableReadLine(); + SetMaxBufferThreshold(10240); +} + +CSocket::~CSocket() { + CUser *pUser = m_pModule->GetUser(); + + m_pModule->UnlinkSocket(this); + + if (!m_pModule->IsGlobal() && pUser) { + pUser->AddBytesWritten(GetBytesWritten()); + pUser->AddBytesRead(GetBytesRead()); + } else { + CZNC::Get().AddBytesWritten(GetBytesWritten()); + CZNC::Get().AddBytesRead(GetBytesRead()); + } +} + +void CSocket::ReachedMaxBuffer() { + DEBUG(GetSockName() << " == ReachedMaxBuffer()"); + PutModule("Some socket reached its max buffer limit and was closed!"); + Close(); +} + +void CSocket::SockError(int iErrno) { + DEBUG(GetSockName() << " == SockError(" << strerror(iErrno) << ")"); + if (iErrno == EMFILE) { + // We have too many open fds, this can cause a busy loop. + Close(); + } +} + +bool CSocket::ConnectionFrom(const CString& sHost, unsigned short uPort) { + return CZNC::Get().AllowConnectionFrom(sHost); +} + +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(); + CString sVHost; + + if (pUser) { + sSockName += "::" + pUser->GetUserName(); + sVHost = m_pModule->GetUser()->GetVHost(); + } + + // Don't overwrite the socket name if one is already set + if (!GetSockName().empty()) { + sSockName = GetSockName(); + } + + return m_pModule->GetManager()->Connect(sHostname, uPort, sSockName, uTimeout, bSSL, sVHost, this); +} + +bool CSocket::Listen(unsigned short uPort, bool bSSL, unsigned int uTimeout) { + CUser* pUser = m_pModule->GetUser(); + CString sSockName = "MOD::L::" + m_pModule->GetModName(); + + if (pUser) { + sSockName += "::" + pUser->GetUserName(); + } + // Don't overwrite the socket name if one is already set + if (!GetSockName().empty()) { + sSockName = GetSockName(); + } + + return m_pModule->GetManager()->ListenAll(uPort, sSockName, bSSL, SOMAXCONN, this); +} + +bool CSocket::PutIRC(const CString& sLine) { + return (m_pModule) ? m_pModule->PutIRC(sLine) : false; +} + +bool CSocket::PutUser(const CString& sLine) { + return (m_pModule) ? m_pModule->PutUser(sLine) : false; +} + +bool CSocket::PutStatus(const CString& sLine) { + return (m_pModule) ? m_pModule->PutStatus(sLine) : false; +} + +bool CSocket::PutModule(const CString& sLine, const CString& sIdent, const CString& sHost) { + return (m_pModule) ? m_pModule->PutModule(sLine, sIdent, sHost) : false; +} +bool CSocket::PutModNotice(const CString& sLine, const CString& sIdent, const CString& sHost) { + return (m_pModule) ? m_pModule->PutModNotice(sLine, sIdent, sHost) : false; +} + +void CSocket::SetModule(CModule* p) { m_pModule = p; } +CModule* CSocket::GetModule() const { return m_pModule; } +/////////////////// !CSocket /////////////////// diff --git a/Socket.h b/Socket.h index 46c393a2..584e3c1f 100644 --- a/Socket.h +++ b/Socket.h @@ -11,6 +11,8 @@ #include "Csocket.h" +class CModule; + class CZNCSock : public Csock { public: CZNCSock(int timeout = 60) : Csock(timeout) {} @@ -83,4 +85,40 @@ private: protected: }; +class CSocket : public CZNCSock { +public: + CSocket(CModule* pModule); + CSocket(CModule* pModule, const CString& sHostname, unsigned short uPort, int iTimeout = 60); + virtual ~CSocket(); + + using Csock::Connect; + using Csock::Listen; + + // This defaults to closing the socket, feel free to override + virtual void ReachedMaxBuffer(); + virtual void SockError(int iErrno); + // This limits the global connections from this IP to defeat DoS + // attacks, feel free to override + virtual bool ConnectionFrom(const CString& sHost, unsigned short uPort); + + 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); + virtual bool PutUser(const CString& sLine); + virtual bool PutStatus(const CString& sLine); + virtual bool PutModule(const CString& sLine, const CString& sIdent = "", const CString& sHost = "znc.in"); + virtual bool PutModNotice(const CString& sLine, const CString& sIdent = "", const CString& sHost = "znc.in"); + + // Setters + void SetModule(CModule* p); + // !Setters + + // Getters + CModule* GetModule() const; + // !Getters +private: +protected: + CModule* m_pModule; +}; + #endif /* SOCKET_H */