From 3d1551b7f2b933655da5ebd3bad668c0c25fed3a Mon Sep 17 00:00:00 2001 From: Alexey Sokolov Date: Sat, 10 May 2025 19:56:23 +0100 Subject: [PATCH] Don't forward client JOINs during registration ZNC remembers that it should join these channels, and will join them after registration. But if client automatically joins some channels, we don't want it to be added to send queue before parts of registration itself (CAP, AUTHENTICATE), because server will just disconnect with "Registration timeout". After registration is complete, using /join still joins the channel immediately. Only limiting this to joins, because server may request some input from user to finish registration, and joins are the ones which are prone to be sent automatically by client to cause issues. Fix #1949 --- src/Chan.cpp | 4 +++- src/Client.cpp | 10 +++++----- test/integration/tests/core.cpp | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/Chan.cpp b/src/Chan.cpp index 12c71fe3..88433a3e 100644 --- a/src/Chan.cpp +++ b/src/Chan.cpp @@ -143,7 +143,9 @@ void CChan::JoinUser(const CString& sKey) { if (!IsOn() && !sKey.empty()) { SetKey(sKey); } - m_pNetwork->PutIRC("JOIN " + GetName() + " " + GetKey()); + if (m_pNetwork->IsIRCConnected()) { + m_pNetwork->PutIRC("JOIN " + GetName() + " " + GetKey()); + } } void CChan::AttachUser(CClient* pClient) { diff --git a/src/Client.cpp b/src/Client.cpp index fcc7fe2e..b3753e28 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -1477,13 +1477,13 @@ bool CClient::OnJoinMessage(CJoinMessage& Message) { pChan->SetKey(sKey); } } - } - if (!sChannel.empty()) { - sChans += (sChans.empty()) ? sChannel : CString("," + sChannel); + if (!sChannel.empty() && m_pNetwork->IsIRCConnected()) { + sChans += (sChans.empty()) ? sChannel : CString("," + sChannel); - if (!vsKeys.empty()) { - sKeys += (sKeys.empty()) ? sKey : CString("," + sKey); + if (!vsKeys.empty()) { + sKeys += (sKeys.empty()) ? sKey : CString("," + sKey); + } } } } diff --git a/test/integration/tests/core.cpp b/test/integration/tests/core.cpp index 4d000dcb..0aa6c373 100644 --- a/test/integration/tests/core.cpp +++ b/test/integration/tests/core.cpp @@ -1172,5 +1172,19 @@ TEST_F(ZNCTest, ManyCapsInReq) { EXPECT_TRUE(caps.split(' ').contains(caps3)); } +TEST_F(ZNCTest, JoinWhileRegistration) { + auto znc = Run(); + auto ircd = ConnectIRCd(); + auto client = LoginClient(); + // First JOIN just adds channel to the list, second one updates the key and + // sends JOIN from CChan::JoinUser. Both should be delayed until + // registration ends. + client.Write("JOIN #foo"); + client.Write("JOIN #foo"); + EXPECT_THAT(ircd.ReadRemainder().toStdString(), Not(HasSubstr("JOIN"))); + ircd.Write(":server 001 nick :Hello"); + ircd.ReadUntil("JOIN #foo"); +} + } // namespace } // namespace znc_inttest