mirror of
https://github.com/znc/znc.git
synced 2026-08-07 17:33:34 +02:00
Split CTCPListener from CListener
This splits up CListener into a TCP-specific class and a general class. The intention is to later add another class inheriting from CListener that listens on unix sockets. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
+33
-15
@@ -29,27 +29,19 @@ class CListener {
|
||||
public:
|
||||
typedef enum { ACCEPT_IRC, ACCEPT_HTTP, ACCEPT_ALL } EAcceptType;
|
||||
|
||||
CListener(unsigned short uPort, const CString& sBindHost,
|
||||
const CString& sURIPrefix, bool bSSL, EAddrType eAddr,
|
||||
EAcceptType eAccept)
|
||||
CListener(const CString& sURIPrefix, bool bSSL, EAcceptType eAccept)
|
||||
: m_bSSL(bSSL),
|
||||
m_eAddr(eAddr),
|
||||
m_uPort(uPort),
|
||||
m_sBindHost(sBindHost),
|
||||
m_sURIPrefix(sURIPrefix),
|
||||
m_pListener(nullptr),
|
||||
m_eAcceptType(eAccept) {}
|
||||
|
||||
~CListener();
|
||||
virtual ~CListener();
|
||||
|
||||
CListener(const CListener&) = delete;
|
||||
CListener& operator=(const CListener&) = delete;
|
||||
|
||||
// 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; }
|
||||
const CString& GetURIPrefix() const { return m_sURIPrefix; }
|
||||
EAcceptType GetAcceptType() const { return m_eAcceptType; }
|
||||
@@ -59,21 +51,47 @@ class CListener {
|
||||
// except this one, so don't add other setters!
|
||||
void SetAcceptType(EAcceptType eType) { m_eAcceptType = eType; }
|
||||
|
||||
bool Listen();
|
||||
virtual bool Listen() = 0;
|
||||
void ResetRealListener();
|
||||
CConfig ToConfig() const;
|
||||
virtual CConfig ToConfig() const = 0;
|
||||
|
||||
private:
|
||||
protected:
|
||||
bool m_bSSL;
|
||||
EAddrType m_eAddr;
|
||||
unsigned short m_uPort;
|
||||
CString m_sBindHost;
|
||||
CString m_sURIPrefix;
|
||||
CRealListener* m_pListener;
|
||||
EAcceptType m_eAcceptType;
|
||||
};
|
||||
|
||||
class CTCPListener : public CListener {
|
||||
public:
|
||||
CTCPListener(unsigned short uPort, const CString& sBindHost,
|
||||
const CString& sURIPrefix, bool bSSL, EAddrType eAddr,
|
||||
EAcceptType eAccept)
|
||||
: CListener(sURIPrefix, bSSL, eAccept),
|
||||
m_eAddr(eAddr),
|
||||
m_uPort(uPort),
|
||||
m_sBindHost(sBindHost) {}
|
||||
~CTCPListener();
|
||||
|
||||
CTCPListener(const CTCPListener&) = delete;
|
||||
CTCPListener& operator=(const CTCPListener&) = delete;
|
||||
|
||||
// Getters
|
||||
EAddrType GetAddrType() const { return m_eAddr; }
|
||||
unsigned short GetPort() const { return m_uPort; }
|
||||
const CString& GetBindHost() const { return m_sBindHost; }
|
||||
// !Getters
|
||||
|
||||
bool Listen() override;
|
||||
CConfig ToConfig() const override;
|
||||
|
||||
protected:
|
||||
EAddrType m_eAddr;
|
||||
unsigned short m_uPort;
|
||||
CString m_sBindHost;
|
||||
};
|
||||
|
||||
class CRealListener : public CZNCSock {
|
||||
public:
|
||||
CRealListener(CListener& listener) : CZNCSock(), m_Listener(listener) {}
|
||||
|
||||
+29
-22
@@ -161,7 +161,7 @@ class CWebAdminMod : public CModule {
|
||||
}
|
||||
|
||||
// Now turn that into a listener instance
|
||||
CListener* pListener = new CListener(
|
||||
CListener* pListener = new CTCPListener(
|
||||
uPort, sListenHost, sURIPrefix, bSSL,
|
||||
(!bIPv6 ? ADDR_IPV4ONLY : ADDR_ALL), CListener::ACCEPT_HTTP);
|
||||
|
||||
@@ -1883,8 +1883,18 @@ class CWebAdminMod : public CModule {
|
||||
for (const CListener* pListener : vpListeners) {
|
||||
CTemplate& l = Tmpl.AddRow("ListenLoop");
|
||||
|
||||
l["Port"] = CString(pListener->GetPort());
|
||||
l["BindHost"] = pListener->GetBindHost();
|
||||
const CTCPListener* pTCPListener = dynamic_cast<const CTCPListener*>(pListener);
|
||||
if (pTCPListener != nullptr) {
|
||||
l["Port"] = CString(pTCPListener->GetPort());
|
||||
l["BindHost"] = pTCPListener->GetBindHost();
|
||||
|
||||
// simple protection for user from shooting his own foot
|
||||
// TODO check also for hosts/families
|
||||
// such check is only here, user still can forge HTTP request to
|
||||
// delete web port
|
||||
l["SuggestDeletion"] =
|
||||
CString(pTCPListener->GetPort() != WebSock.GetLocalPort());
|
||||
}
|
||||
|
||||
l["IsHTTP"] = CString(pListener->GetAcceptType() !=
|
||||
CListener::ACCEPT_IRC);
|
||||
@@ -1893,13 +1903,6 @@ class CWebAdminMod : public CModule {
|
||||
|
||||
l["URIPrefix"] = pListener->GetURIPrefix() + "/";
|
||||
|
||||
// simple protection for user from shooting his own foot
|
||||
// TODO check also for hosts/families
|
||||
// such check is only here, user still can forge HTTP request to
|
||||
// delete web port
|
||||
l["SuggestDeletion"] =
|
||||
CString(pListener->GetPort() != WebSock.GetLocalPort());
|
||||
|
||||
#ifdef HAVE_LIBSSL
|
||||
if (pListener->IsSSL()) {
|
||||
l["IsSSL"] = "true";
|
||||
@@ -1907,20 +1910,24 @@ class CWebAdminMod : public CModule {
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
switch (pListener->GetAddrType()) {
|
||||
case ADDR_IPV4ONLY:
|
||||
l["IsIPV4"] = "true";
|
||||
break;
|
||||
case ADDR_IPV6ONLY:
|
||||
l["IsIPV6"] = "true";
|
||||
break;
|
||||
case ADDR_ALL:
|
||||
l["IsIPV4"] = "true";
|
||||
l["IsIPV6"] = "true";
|
||||
break;
|
||||
if (pTCPListener != nullptr) {
|
||||
switch (pTCPListener->GetAddrType()) {
|
||||
case ADDR_IPV4ONLY:
|
||||
l["IsIPV4"] = "true";
|
||||
break;
|
||||
case ADDR_IPV6ONLY:
|
||||
l["IsIPV6"] = "true";
|
||||
break;
|
||||
case ADDR_ALL:
|
||||
l["IsIPV4"] = "true";
|
||||
l["IsIPV6"] = "true";
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
l["IsIPV4"] = "true";
|
||||
if (pTCPListener != nullptr) {
|
||||
l["IsIPV4"] = "true";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+19
-11
@@ -1543,17 +1543,25 @@ void CClient::UserPortCommand(CString& sLine) {
|
||||
|
||||
for (const CListener* pListener : vpListeners) {
|
||||
Table.AddRow();
|
||||
Table.SetCell("Port", CString(pListener->GetPort()));
|
||||
Table.SetCell("BindHost", (pListener->GetBindHost().empty()
|
||||
? CString("*")
|
||||
: pListener->GetBindHost()));
|
||||
Table.SetCell("SSL", CString(pListener->IsSSL()));
|
||||
|
||||
EAddrType eAddr = pListener->GetAddrType();
|
||||
Table.SetCell("Proto",
|
||||
(eAddr == ADDR_ALL
|
||||
? "All"
|
||||
: (eAddr == ADDR_IPV4ONLY ? "IPv4" : "IPv6")));
|
||||
const CTCPListener* pTCPListener = dynamic_cast<const CTCPListener*>(pListener);
|
||||
|
||||
if (pTCPListener != nullptr) {
|
||||
Table.SetCell("Port", CString(pTCPListener->GetPort()));
|
||||
Table.SetCell("BindHost", (pTCPListener->GetBindHost().empty()
|
||||
? CString("*")
|
||||
: pTCPListener->GetBindHost()));
|
||||
|
||||
EAddrType eAddr = pTCPListener->GetAddrType();
|
||||
Table.SetCell("Proto",
|
||||
(eAddr == ADDR_ALL
|
||||
? "All"
|
||||
: (eAddr == ADDR_IPV4ONLY ? "IPv4" : "IPv6")));
|
||||
} else {
|
||||
Table.SetCell("Port", "unknown");
|
||||
}
|
||||
|
||||
Table.SetCell("SSL", CString(pListener->IsSSL()));
|
||||
|
||||
CListener::EAcceptType eAccept = pListener->GetAcceptType();
|
||||
Table.SetCell(
|
||||
@@ -1608,7 +1616,7 @@ void CClient::UserPortCommand(CString& sLine) {
|
||||
const CString sBindHost = sLine.Token(4);
|
||||
const CString sURIPrefix = sLine.Token(5);
|
||||
|
||||
CListener* pListener = new CListener(uPort, sBindHost, sURIPrefix,
|
||||
CListener* pListener = new CTCPListener(uPort, sBindHost, sURIPrefix,
|
||||
bSSL, eAddr, eAccept);
|
||||
|
||||
if (!pListener->Listen()) {
|
||||
|
||||
+5
-2
@@ -22,7 +22,10 @@ CListener::~CListener() {
|
||||
if (m_pListener) CZNC::Get().GetManager().DelSockByAddr(m_pListener);
|
||||
}
|
||||
|
||||
bool CListener::Listen() {
|
||||
CTCPListener::~CTCPListener() {
|
||||
}
|
||||
|
||||
bool CTCPListener::Listen() {
|
||||
if (!m_uPort || m_pListener) {
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
@@ -49,7 +52,7 @@ bool CListener::Listen() {
|
||||
m_pListener, 0, m_eAddr);
|
||||
}
|
||||
|
||||
CConfig CListener::ToConfig() const {
|
||||
CConfig CTCPListener::ToConfig() const {
|
||||
CConfig listenerConfig;
|
||||
|
||||
listenerConfig.AddKeyValuePair("Host", GetBindHost());
|
||||
|
||||
+7
-5
@@ -669,7 +669,7 @@ bool CZNC::WriteNewConfig(const CString& sConfigFile) {
|
||||
// Don't ask for listen host, it may be configured later if needed.
|
||||
|
||||
CUtils::PrintAction("Verifying the listener");
|
||||
CListener* pListener = new CListener(
|
||||
CListener* pListener = new CTCPListener(
|
||||
(unsigned short int)uListenPort, sListenHost, sURIPrefix,
|
||||
bListenSSL, b6 ? ADDR_ALL : ADDR_IPV4ONLY, CListener::ACCEPT_ALL);
|
||||
if (!pListener->Listen()) {
|
||||
@@ -1568,9 +1568,11 @@ bool CZNC::AddUser(CUser* pUser, CString& sErrorRet, bool bStartup) {
|
||||
CListener* CZNC::FindListener(u_short uPort, const CString& sBindHost,
|
||||
EAddrType eAddr) {
|
||||
for (CListener* pListener : m_vpListeners) {
|
||||
if (pListener->GetPort() != uPort) continue;
|
||||
if (pListener->GetBindHost() != sBindHost) continue;
|
||||
if (pListener->GetAddrType() != eAddr) continue;
|
||||
CTCPListener* pTCPListener = dynamic_cast<CTCPListener*>(pListener);
|
||||
if (!pTCPListener) continue;
|
||||
if (pTCPListener->GetPort() != uPort) continue;
|
||||
if (pTCPListener->GetBindHost() != sBindHost) continue;
|
||||
if (pTCPListener->GetAddrType() != eAddr) continue;
|
||||
return pListener;
|
||||
}
|
||||
return nullptr;
|
||||
@@ -1700,7 +1702,7 @@ bool CZNC::AddListener(unsigned short uPort, const CString& sBindHost,
|
||||
}
|
||||
|
||||
CListener* pListener =
|
||||
new CListener(uPort, sBindHost, sURIPrefix, bSSL, eAddr, eAccept);
|
||||
new CTCPListener(uPort, sBindHost, sURIPrefix, bSSL, eAddr, eAccept);
|
||||
|
||||
if (!pListener->Listen()) {
|
||||
sError = FormatBindError();
|
||||
|
||||
Reference in New Issue
Block a user