From ef1639e7e069e7f60b4ac4b741bb85309aee0e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= Date: Fri, 30 May 2014 00:26:25 +0200 Subject: [PATCH 1/4] Join channels immediately after spoof if set This patch makes the client start joining its channels as soon as its spoof if set, if the user uses JoinAfterCloaked. --- modules/q.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/q.cpp b/modules/q.cpp index 9b6a6acf..a4e70956 100644 --- a/modules/q.cpp +++ b/modules/q.cpp @@ -257,6 +257,11 @@ public: if (sLine.Token(1) == "396" && sLine.Token(3).find("users.quakenet.org") != CString::npos) { m_bCloaked = true; PutModule("Cloak successful: Your hostname is now cloaked."); + + // Join channels immediately after our spoof is set. + if (m_bJoinAfterCloaked) { + m_pNetwork->JoinChans(); + } } return CONTINUE; } From 299f3aa637f3d069fdbd1886ff4de55b6c854adc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= Date: Fri, 30 May 2014 01:06:14 +0200 Subject: [PATCH 2/4] Split CUserTimer into CIRCNetworkPingTimer and CIRCNetworkJoinTimer This patch splits CUserTimer into two other timers: CIRCNetworkPingTimer: This timer sends PING messages to connected client's and IRC servers. CIRCNetworkJoinTimer: This timer enforces the MaxJoin setting by only allowing a specified amount of channels to join at the same time. JoinChans() is modified to reset the ping timer once we hit the MaxJoin. This allows us to call it from any function without breaking the timing logic. --- include/znc/IRCNetwork.h | 5 +++ src/IRCNetwork.cpp | 67 +++++++++++++++++++++++++++++++++++++++- src/User.cpp | 24 -------------- 3 files changed, 71 insertions(+), 25 deletions(-) diff --git a/include/znc/IRCNetwork.h b/include/znc/IRCNetwork.h index 6af760ec..728bd86e 100644 --- a/include/znc/IRCNetwork.h +++ b/include/znc/IRCNetwork.h @@ -32,6 +32,8 @@ class CConfig; class CChan; class CServer; class CIRCSock; +class CIRCNetworkPingTimer; +class CIRCNetworkJoinTimer; class CIRCNetwork { public: @@ -196,6 +198,9 @@ protected: CBuffer m_RawBuffer; CBuffer m_MotdBuffer; CBuffer m_QueryBuffer; + + CIRCNetworkPingTimer* m_pPingTimer; + CIRCNetworkJoinTimer* m_pJoinTimer; }; #endif // !_IRCNETWORK_H diff --git a/src/IRCNetwork.cpp b/src/IRCNetwork.cpp index fc1bc60d..2d179cf6 100644 --- a/src/IRCNetwork.cpp +++ b/src/IRCNetwork.cpp @@ -25,6 +25,59 @@ using std::vector; using std::set; +class CIRCNetworkPingTimer : public CCron { +public: + CIRCNetworkPingTimer(CIRCNetwork *pNetwork) : CCron() { + m_pNetwork = pNetwork; + SetName("CIRCNetworkPingTimer::" + m_pNetwork->GetUser()->GetUserName() + "::" + m_pNetwork->GetName()); + Start(30); + } + + virtual ~CIRCNetworkPingTimer() {} + +protected: + virtual void RunJob() { + CIRCSock* pIRCSock = m_pNetwork->GetIRCSock(); + + if (pIRCSock && pIRCSock->GetTimeSinceLastDataTransaction() >= 270) { + pIRCSock->PutIRC("PING :ZNC"); + } + + vector& vClients = m_pNetwork->GetClients(); + for (size_t b = 0; b < vClients.size(); b++) { + CClient* pClient = vClients[b]; + + if (pClient->GetTimeSinceLastDataTransaction() >= 270) { + pClient->PutClient("PING :ZNC"); + } + } + } + +private: + CIRCNetwork* m_pNetwork; +}; + +class CIRCNetworkJoinTimer : public CCron { +public: + CIRCNetworkJoinTimer(CIRCNetwork *pNetwork) : CCron() { + m_pNetwork = pNetwork; + SetName("CIRCNetworkJoinTimer::" + m_pNetwork->GetUser()->GetUserName() + "::" + m_pNetwork->GetName()); + Start(30); + } + + virtual ~CIRCNetworkJoinTimer() {} + +protected: + virtual void RunJob() { + if (m_pNetwork->IsIRCConnected()) { + m_pNetwork->JoinChans(); + } + } + +private: + CIRCNetwork* m_pNetwork; +}; + bool CIRCNetwork::IsValidNetwork(const CString& sNetwork) { // ^[-\w]+$ @@ -65,6 +118,12 @@ CIRCNetwork::CIRCNetwork(CUser *pUser, const CString& sName) { m_MotdBuffer.SetLineCount(200, true); // This should be more than enough motd lines m_QueryBuffer.SetLineCount(250, true); + m_pPingTimer = new CIRCNetworkPingTimer(this); + CZNC::Get().GetManager().AddCron(m_pPingTimer); + + m_pJoinTimer = new CIRCNetworkJoinTimer(this); + CZNC::Get().GetManager().AddCron(m_pJoinTimer); + SetIRCConnectEnabled(true); } @@ -226,6 +285,9 @@ CIRCNetwork::~CIRCNetwork() { // Make sure we are not in the connection queue CZNC::Get().GetConnectionQueue().remove(this); + + CZNC::Get().GetManager().DelCronByAddr(m_pPingTimer); + CZNC::Get().GetManager().DelCronByAddr(m_pJoinTimer); } void CIRCNetwork::DelServers() { @@ -718,8 +780,11 @@ void CIRCNetwork::JoinChans() { sChans.insert(pChan); // Limit the number of joins - if (uJoins != 0 && --uJoins == 0) + if (uJoins != 0 && --uJoins == 0) { + // Reset the timer. + m_pJoinTimer->Reset(); break; + } } } diff --git a/src/User.cpp b/src/User.cpp index cf664f1b..48cc871a 100644 --- a/src/User.cpp +++ b/src/User.cpp @@ -36,30 +36,6 @@ public: private: protected: virtual void RunJob() { - vector vNetworks = m_pUser->GetNetworks(); - - for (size_t a = 0; a < vNetworks.size(); a++) { - CIRCNetwork* pNetwork = vNetworks[a]; - CIRCSock* pIRCSock = pNetwork->GetIRCSock(); - - if (pIRCSock && pIRCSock->GetTimeSinceLastDataTransaction() >= 270) { - pIRCSock->PutIRC("PING :ZNC"); - } - - if (pNetwork->IsIRCConnected()) { - pNetwork->JoinChans(); - } - - vector& vClients = pNetwork->GetClients(); - for (size_t b = 0; b < vClients.size(); b++) { - CClient* pClient = vClients[b]; - - if (pClient->GetTimeSinceLastDataTransaction() >= 270) { - pClient->PutClient("PING :ZNC"); - } - } - } - vector& vUserClients = m_pUser->GetUserClients(); for (size_t c = 0; c < vUserClients.size(); ++c) { CClient* pUserClient = vUserClients[c]; From 1e9e029227b5b993c9f4f17b297313a43f1081d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= Date: Fri, 30 May 2014 01:11:11 +0200 Subject: [PATCH 3/4] Start joining channels as soon as we are connected --- src/IRCSock.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/IRCSock.cpp b/src/IRCSock.cpp index 2ef12f64..1e0c7931 100644 --- a/src/IRCSock.cpp +++ b/src/IRCSock.cpp @@ -199,6 +199,10 @@ void CIRCSock::ReadLine(const CString& sData) { m_pNetwork->ClearRawBuffer(); m_pNetwork->AddRawBuffer(":" + _NAMEDFMT(sServer) + " " + sCmd + " {target} " + _NAMEDFMT(sRest)); + // Join the first set of channels as soon as we are connected + // and let the CIRCNetworkJoinTimer join the rest. + m_pNetwork->JoinChans(); + break; } case 5: From 2521d64a1c4ea967c5fe5284b9a348f9010aa1b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= Date: Fri, 30 May 2014 12:57:39 +0200 Subject: [PATCH 4/4] Add PING_TIMEOUT constant to CIRCNetwork --- include/znc/IRCNetwork.h | 4 ++++ src/IRCNetwork.cpp | 4 ++-- src/User.cpp | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/znc/IRCNetwork.h b/include/znc/IRCNetwork.h index 728bd86e..289451ec 100644 --- a/include/znc/IRCNetwork.h +++ b/include/znc/IRCNetwork.h @@ -43,6 +43,10 @@ public: CIRCNetwork(CUser *pUser, const CIRCNetwork& Network); ~CIRCNetwork(); + enum { + PING_TIMEOUT = 270 + }; + void Clone(const CIRCNetwork& Network, bool bCloneName = true); CString GetNetworkPath(); diff --git a/src/IRCNetwork.cpp b/src/IRCNetwork.cpp index 2d179cf6..00c5787a 100644 --- a/src/IRCNetwork.cpp +++ b/src/IRCNetwork.cpp @@ -39,7 +39,7 @@ protected: virtual void RunJob() { CIRCSock* pIRCSock = m_pNetwork->GetIRCSock(); - if (pIRCSock && pIRCSock->GetTimeSinceLastDataTransaction() >= 270) { + if (pIRCSock && pIRCSock->GetTimeSinceLastDataTransaction() >= CIRCNetwork::PING_TIMEOUT) { pIRCSock->PutIRC("PING :ZNC"); } @@ -47,7 +47,7 @@ protected: for (size_t b = 0; b < vClients.size(); b++) { CClient* pClient = vClients[b]; - if (pClient->GetTimeSinceLastDataTransaction() >= 270) { + if (pClient->GetTimeSinceLastDataTransaction() >= CIRCNetwork::PING_TIMEOUT) { pClient->PutClient("PING :ZNC"); } } diff --git a/src/User.cpp b/src/User.cpp index 48cc871a..ee672b09 100644 --- a/src/User.cpp +++ b/src/User.cpp @@ -40,7 +40,7 @@ protected: for (size_t c = 0; c < vUserClients.size(); ++c) { CClient* pUserClient = vUserClients[c]; - if (pUserClient->GetTimeSinceLastDataTransaction() >= 270) { + if (pUserClient->GetTimeSinceLastDataTransaction() >= CIRCNetwork::PING_TIMEOUT) { pUserClient->PutClient("PING :ZNC"); } }