diff --git a/ClientCommand.cpp b/ClientCommand.cpp index a96050db..db4264cc 100644 --- a/ClientCommand.cpp +++ b/ClientCommand.cpp @@ -14,6 +14,7 @@ #include "Server.h" #include "User.h" #include "znc.h" +#include "Listener.h" void CClient::UserCommand(CString& sLine) { if (!m_pUser) { diff --git a/Listener.cpp b/Listener.cpp new file mode 100644 index 00000000..4b36d3d8 --- /dev/null +++ b/Listener.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2004-2010 See the AUTHORS file for details. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include "Listener.h" + +bool CListener::Listen() { + if (!m_uPort || m_pListener) { + return false; + } + + m_pListener = new CRealListener(this); + + bool bSSL = false; +#ifdef HAVE_LIBSSL + if (IsSSL()) { + bSSL = true; + m_pListener->SetPemLocation(CZNC::Get().GetPemLocation()); + } +#endif + + return CZNC::Get().GetManager().ListenHost(m_uPort, "_LISTENER", m_sBindHost, bSSL, SOMAXCONN, + m_pListener, 0, m_eAddr); +} + +CRealListener::~CRealListener() { + m_pParent->SetRealListener(NULL); +} + +bool CRealListener::ConnectionFrom(const CString& sHost, unsigned short uPort) { + bool bHostAllowed = CZNC::Get().IsHostAllowed(sHost); + DEBUG(GetSockName() << " == ConnectionFrom(" << sHost << ", " << uPort << ") [" << (bHostAllowed ? "Allowed" : "Not allowed") << "]"); + return bHostAllowed; +} + +Csock* CRealListener::GetSockObj(const CString& sHost, unsigned short uPort) { + CClient *pClient = new CClient(sHost, uPort); + if (CZNC::Get().AllowConnectionFrom(sHost)) { + CZNC::Get().GetModules().OnClientConnect(pClient, sHost, uPort); + } else { + pClient->RefuseLogin("Too many anonymous connections from your IP"); + CZNC::Get().GetModules().OnFailedLogin("", sHost); + } + return pClient; +} + +void CRealListener::SockError(int iErrno) { + DEBUG(GetSockName() << " == SockError(" << strerror(iErrno) << ")"); + if (iErrno == EMFILE) { + // We have too many open fds, let's close this listening port to be able to continue + // to work, next rehash will (try to) reopen it. + Close(); + } +} diff --git a/Listener.h b/Listener.h new file mode 100644 index 00000000..0ead18d2 --- /dev/null +++ b/Listener.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2004-2010 See the AUTHORS file for details. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef _LISTENER_H +#define _LISTENER_H + +#include "znc.h" + +class CRealListener : public CZNCSock { +public: + CRealListener(CListener *pParent) : CZNCSock(), m_pParent(pParent) {} + virtual ~CRealListener(); + + virtual bool ConnectionFrom(const CString& sHost, unsigned short uPort); + virtual Csock* GetSockObj(const CString& sHost, unsigned short uPort); + virtual void SockError(int iErrno); + +private: + CListener* m_pParent; +}; + +class CListener { +public: + CListener(unsigned short uPort, const CString& sBindHost, bool bSSL, EAddrType eAddr) { + m_uPort = uPort; + m_sBindHost = sBindHost; + m_bSSL = bSSL; + m_eAddr = eAddr; + m_pListener = NULL; + } + + ~CListener() { + if (m_pListener) + CZNC::Get().GetManager().DelSockByAddr(m_pListener); + } + + // Setters + void SetSSL(bool b) { m_bSSL = b; } + void SetAddrType(EAddrType eAddr) { m_eAddr = eAddr; } + void SetPort(unsigned short u) { m_uPort = u; } + void SetBindHost(const CString& s) { m_sBindHost = s; } + void SetRealListener(CRealListener* p) { m_pListener = p; } + // !Setters + + // Getters + bool IsSSL() const { return m_bSSL; } + EAddrType GetAddrType() const { return m_eAddr; } + unsigned short GetPort() const { return m_uPort; } + const CString& GetBindHost() const { return m_sBindHost; } + CRealListener* GetRealListener() const { return m_pListener; } + // !Getters + + bool Listen(); + +private: +protected: + bool m_bSSL; + EAddrType m_eAddr; + unsigned short m_uPort; + CString m_sBindHost; + CRealListener* m_pListener; +}; + +#endif // !_LISTENER_H diff --git a/Makefile.in b/Makefile.in index 66d6de89..95ed1911 100644 --- a/Makefile.in +++ b/Makefile.in @@ -23,7 +23,8 @@ PKGCONFIGDIR := $(libdir)/pkgconfig LIB_SRCS := ZNCString.cpp Csocket.cpp znc.cpp User.cpp IRCSock.cpp Client.cpp DCCBounce.cpp \ DCCSock.cpp Chan.cpp Nick.cpp Server.cpp Modules.cpp MD5.cpp Buffer.cpp Utils.cpp \ - FileUtils.cpp HTTPSock.cpp Template.cpp ClientCommand.cpp Socket.cpp SHA256.cpp WebModules.cpp + FileUtils.cpp HTTPSock.cpp Template.cpp ClientCommand.cpp Socket.cpp SHA256.cpp \ + WebModules.cpp Listener.cpp BIN_SRCS := main.cpp LIB_OBJS := $(patsubst %cpp,%o,$(LIB_SRCS)) BIN_OBJS := $(patsubst %cpp,%o,$(BIN_SRCS)) diff --git a/modules/webadmin.cpp b/modules/webadmin.cpp index d0ec72fe..9ce11ec1 100644 --- a/modules/webadmin.cpp +++ b/modules/webadmin.cpp @@ -14,6 +14,7 @@ #include "znc.h" #include "WebModules.h" #include "ZNCString.h" +#include "Listener.h" #include #include diff --git a/znc.cpp b/znc.cpp index 9a1a7506..1d22d1bc 100644 --- a/znc.cpp +++ b/znc.cpp @@ -11,6 +11,7 @@ #include "IRCSock.h" #include "Server.h" #include "User.h" +#include "Listener.h" #include #include @@ -2035,7 +2036,3 @@ void CZNC::LeakConnectUser(CConnectUserTimer *pTimer) { if (m_pConnectUserTimer == pTimer) m_pConnectUserTimer = NULL; } - -CRealListener::~CRealListener() { - m_pParent->SetRealListener(NULL); -} diff --git a/znc.h b/znc.h index f7dd47b9..b8511079 100644 --- a/znc.h +++ b/znc.h @@ -178,97 +178,4 @@ protected: TCacheMap m_sConnectThrottle; }; -class CRealListener : public CZNCSock { -public: - CRealListener(CListener *pParent) : CZNCSock(), m_pParent(pParent) {} - virtual ~CRealListener(); - - virtual bool ConnectionFrom(const CString& sHost, unsigned short uPort) { - bool bHostAllowed = CZNC::Get().IsHostAllowed(sHost); - DEBUG(GetSockName() << " == ConnectionFrom(" << sHost << ", " << uPort << ") [" << (bHostAllowed ? "Allowed" : "Not allowed") << "]"); - return bHostAllowed; - } - - virtual Csock* GetSockObj(const CString& sHost, unsigned short uPort) { - CClient *pClient = new CClient(sHost, uPort); - if (CZNC::Get().AllowConnectionFrom(sHost)) { - CZNC::Get().GetModules().OnClientConnect(pClient, sHost, uPort); - } else { - pClient->RefuseLogin("Too many anonymous connections from your IP"); - CZNC::Get().GetModules().OnFailedLogin("", sHost); - } - return pClient; - } - - virtual void SockError(int iErrno) { - DEBUG(GetSockName() << " == SockError(" << strerror(iErrno) << ")"); - if (iErrno == EMFILE) { - // We have too many open fds, let's close this listening port to be able to continue - // to work, next rehash will (try to) reopen it. - Close(); - } - } - -private: - CListener* m_pParent; -}; - -class CListener { -public: - CListener(unsigned short uPort, const CString& sBindHost, bool bSSL, EAddrType eAddr) { - m_uPort = uPort; - m_sBindHost = sBindHost; - m_bSSL = bSSL; - m_eAddr = eAddr; - m_pListener = NULL; - } - - ~CListener() { - if (m_pListener) - CZNC::Get().GetManager().DelSockByAddr(m_pListener); - } - - // Setters - void SetSSL(bool b) { m_bSSL = b; } - void SetAddrType(EAddrType eAddr) { m_eAddr = eAddr; } - void SetPort(unsigned short u) { m_uPort = u; } - void SetBindHost(const CString& s) { m_sBindHost = s; } - void SetRealListener(CRealListener* p) { m_pListener = p; } - // !Setters - - // Getters - bool IsSSL() const { return m_bSSL; } - EAddrType GetAddrType() const { return m_eAddr; } - unsigned short GetPort() const { return m_uPort; } - const CString& GetBindHost() const { return m_sBindHost; } - CRealListener* GetRealListener() const { return m_pListener; } - // !Getters - - bool Listen() { - if (!m_uPort || m_pListener) { - return false; - } - - m_pListener = new CRealListener(this); - - bool bSSL = false; -#ifdef HAVE_LIBSSL - if (IsSSL()) { - bSSL = true; - m_pListener->SetPemLocation(CZNC::Get().GetPemLocation()); - } -#endif - - return CZNC::Get().GetManager().ListenHost(m_uPort, "_LISTENER", m_sBindHost, bSSL, SOMAXCONN, - m_pListener, 0, m_eAddr); - } -private: -protected: - bool m_bSSL; - EAddrType m_eAddr; - unsigned short m_uPort; - CString m_sBindHost; - CRealListener* m_pListener; -}; - #endif // !_ZNC_H