mirror of
https://github.com/znc/znc.git
synced 2026-08-07 17:33:34 +02:00
@@ -48,18 +48,6 @@ class CIRCNetwork {
|
||||
CIRCNetwork(const CIRCNetwork&) = delete;
|
||||
CIRCNetwork& operator=(const CIRCNetwork&) = delete;
|
||||
|
||||
enum {
|
||||
JOIN_FREQUENCY = 30,
|
||||
/** How long must an IRC connection be idle before ZNC sends a ping */
|
||||
PING_FREQUENCY = 120,
|
||||
/** Time between checks if PINGs need to be sent */
|
||||
PING_SLACK = 30,
|
||||
/** Timeout after which IRC connections are closed. Must
|
||||
* obviously be greater than PING_FREQUENCY + PING_SLACK.
|
||||
*/
|
||||
NO_TRAFFIC_TIMEOUT = 180
|
||||
};
|
||||
|
||||
void Clone(const CIRCNetwork& Network, bool bCloneName = true);
|
||||
|
||||
CString GetNetworkPath() const;
|
||||
@@ -157,7 +145,8 @@ class CIRCNetwork {
|
||||
void SetIRCAway(bool b) { m_bIRCAway = b; }
|
||||
|
||||
bool Connect();
|
||||
/** This method will return whether the user is connected and authenticated to an IRC server.
|
||||
/** This method will return whether the user is connected and authenticated
|
||||
* to an IRC server.
|
||||
*/
|
||||
bool IsIRCConnected() const;
|
||||
void SetIRCSocket(CIRCSock* pIRCSock);
|
||||
@@ -266,7 +255,9 @@ class CIRCNetwork {
|
||||
m_uJoinDelay = uJoinDelay;
|
||||
}
|
||||
|
||||
void SetTrustAllCerts(const bool bTrustAll = false) { m_bTrustAllCerts = bTrustAll; }
|
||||
void SetTrustAllCerts(const bool bTrustAll = false) {
|
||||
m_bTrustAllCerts = bTrustAll;
|
||||
}
|
||||
bool GetTrustAllCerts() const { return m_bTrustAllCerts; }
|
||||
|
||||
void SetTrustPKI(const bool bTrustPKI = true) { m_bTrustPKI = bTrustPKI; }
|
||||
|
||||
@@ -155,6 +155,7 @@ class CUser {
|
||||
void SetSkinName(const CString& s) { m_sSkinName = s; }
|
||||
void SetMaxNetworks(unsigned int i) { m_uMaxNetworks = i; }
|
||||
void SetMaxQueryBuffers(unsigned int i) { m_uMaxQueryBuffers = i; }
|
||||
void SetNoTrafficTimeout(unsigned int i) { m_uNoTrafficTimeout = i; }
|
||||
// !Setters
|
||||
|
||||
// Getters
|
||||
@@ -185,6 +186,14 @@ class CUser {
|
||||
bool MultiClients() const;
|
||||
const CString& GetStatusPrefix() const;
|
||||
const CString& GetDefaultChanModes() const;
|
||||
/** How long must an IRC connection be idle before ZNC sends a ping */
|
||||
unsigned int GetPingFrequency() const { return m_uNoTrafficTimeout / 2; }
|
||||
/** Time between checks if PINGs need to be sent */
|
||||
unsigned int GetPingSlack() const { return m_uNoTrafficTimeout / 6; }
|
||||
/** Timeout after which IRC connections are closed. Must
|
||||
* obviously be greater than GetPingFrequency() + GetPingSlack().
|
||||
*/
|
||||
unsigned int GetNoTrafficTimeout() const { return m_uNoTrafficTimeout; }
|
||||
|
||||
CString GetQuitMsg() const;
|
||||
const MCString& GetCTCPReplies() const;
|
||||
@@ -254,6 +263,7 @@ class CUser {
|
||||
unsigned int m_uMaxNetworks;
|
||||
unsigned int m_uMaxQueryBuffers;
|
||||
unsigned int m_uMaxJoins;
|
||||
unsigned int m_uNoTrafficTimeout;
|
||||
CString m_sSkinName;
|
||||
CString m_sLanguage;
|
||||
|
||||
|
||||
@@ -249,6 +249,9 @@ class CAdminMod : public CModule {
|
||||
CString(pUser->AutoClearQueryBuffer()));
|
||||
else if (sVar == "maxjoins")
|
||||
PutModule("MaxJoins = " + CString(pUser->MaxJoins()));
|
||||
else if (sVar == "notraffictimeout")
|
||||
PutModule("NoTrafficTimeout = " +
|
||||
CString(pUser->GetNoTrafficTimeout()));
|
||||
else if (sVar == "maxnetworks")
|
||||
PutModule("MaxNetworks = " + CString(pUser->MaxNetworks()));
|
||||
else if (sVar == "maxquerybuffers")
|
||||
@@ -386,6 +389,15 @@ class CAdminMod : public CModule {
|
||||
unsigned int i = sValue.ToUInt();
|
||||
pUser->SetMaxJoins(i);
|
||||
PutModule("MaxJoins = " + CString(pUser->MaxJoins()));
|
||||
} else if (sVar == "notraffictimeout") {
|
||||
unsigned int i = sValue.ToUInt();
|
||||
if (i < 30) {
|
||||
PutModule("Timeout can't be less than 30 seconds!");
|
||||
} else {
|
||||
pUser->SetNoTrafficTimeout(i);
|
||||
PutModule("NoTrafficTimeout = " +
|
||||
CString(pUser->GetNoTrafficTimeout()));
|
||||
}
|
||||
} else if (sVar == "maxnetworks") {
|
||||
if (GetUser()->IsAdmin()) {
|
||||
unsigned int i = sValue.ToUInt();
|
||||
|
||||
@@ -312,6 +312,11 @@
|
||||
<input id="maxjoins" type="number" name="maxjoins" value="<? VAR MaxJoins ?>" class="third" min="0"
|
||||
title="<? FORMAT "How many channels are joined in one JOIN command. 0 is unlimited (default). Set to small positive value if you get disconnected with “Max SendQ Exceeded”" ?>"/>
|
||||
</div>
|
||||
<div class="subsection">
|
||||
<div class="inputlabel"><label for="notraffictimeout"><? FORMAT "Timeout before reconnect:" ?></label></div>
|
||||
<input id="notraffictimeout" type="number" name="notraffictimeout" value="<? VAR NoTrafficTimeout ?>" class="third" min="30"
|
||||
title="<? FORMAT "How much time ZNC waits (in seconds) until it receives something from network or declares the connection timeout. This happens after attempts to ping the peer." ?>"/>
|
||||
</div>
|
||||
<div class="subsection">
|
||||
<div class="inputlabel"><label for="maxnetworks"><? FORMAT "Max IRC Networks Number:" ?></label></div>
|
||||
<input type="number" name="maxnetworks" value="<? VAR MaxNetworks ?>" class="third" min="0"
|
||||
|
||||
@@ -306,6 +306,14 @@ class CWebAdminMod : public CModule {
|
||||
WebSock.GetParam("autoclearquerybuffer").ToBool());
|
||||
pNewUser->SetMaxQueryBuffers(
|
||||
WebSock.GetParam("maxquerybuffers").ToUInt());
|
||||
unsigned int uNoTrafficTimeout =
|
||||
WebSock.GetParam("notraffictimeout").ToUInt();
|
||||
if (uNoTrafficTimeout < 30) {
|
||||
uNoTrafficTimeout = 30;
|
||||
WebSock.GetSession()->AddError(
|
||||
t_s("Timeout can't be less than 30 seconds!"));
|
||||
}
|
||||
pNewUser->SetNoTrafficTimeout(uNoTrafficTimeout);
|
||||
|
||||
#ifdef HAVE_I18N
|
||||
pNewUser->SetLanguage(WebSock.GetParam("language"));
|
||||
@@ -1319,6 +1327,8 @@ class CWebAdminMod : public CModule {
|
||||
Tmpl["TimestampFormat"] = pUser->GetTimestampFormat();
|
||||
Tmpl["Timezone"] = pUser->GetTimezone();
|
||||
Tmpl["JoinTries"] = CString(pUser->JoinTries());
|
||||
Tmpl["NoTrafficTimeout"] =
|
||||
CString(pUser->GetNoTrafficTimeout());
|
||||
Tmpl["MaxNetworks"] = CString(pUser->MaxNetworks());
|
||||
Tmpl["MaxJoins"] = CString(pUser->MaxJoins());
|
||||
Tmpl["MaxQueryBuffers"] = CString(pUser->MaxQueryBuffers());
|
||||
|
||||
+1
-1
@@ -388,7 +388,7 @@ void CClient::AcceptLogin(CUser& User) {
|
||||
|
||||
// Set our proper timeout and set back our proper timeout mode
|
||||
// (constructor set a different timeout and mode)
|
||||
SetTimeout(CIRCNetwork::NO_TRAFFIC_TIMEOUT, TMO_READ);
|
||||
SetTimeout(User.GetNoTrafficTimeout(), TMO_READ);
|
||||
|
||||
SetSockName("USR::" + m_pUser->GetUserName());
|
||||
SetEncoding(m_pUser->GetClientEncoding());
|
||||
|
||||
+12
-7
@@ -36,7 +36,7 @@ class CIRCNetworkPingTimer : public CCron {
|
||||
SetName("CIRCNetworkPingTimer::" +
|
||||
m_pNetwork->GetUser()->GetUserName() + "::" +
|
||||
m_pNetwork->GetName());
|
||||
Start(CIRCNetwork::PING_SLACK);
|
||||
Start(m_pNetwork->GetUser()->GetPingSlack());
|
||||
}
|
||||
|
||||
~CIRCNetworkPingTimer() override {}
|
||||
@@ -47,20 +47,23 @@ class CIRCNetworkPingTimer : public CCron {
|
||||
protected:
|
||||
void RunJob() override {
|
||||
CIRCSock* pIRCSock = m_pNetwork->GetIRCSock();
|
||||
auto uFrequency = m_pNetwork->GetUser()->GetPingFrequency();
|
||||
|
||||
if (pIRCSock &&
|
||||
pIRCSock->GetTimeSinceLastDataTransaction() >=
|
||||
CIRCNetwork::PING_FREQUENCY) {
|
||||
pIRCSock->GetTimeSinceLastDataTransaction() >= uFrequency) {
|
||||
pIRCSock->PutIRC("PING :ZNC");
|
||||
}
|
||||
|
||||
const vector<CClient*>& vClients = m_pNetwork->GetClients();
|
||||
for (CClient* pClient : vClients) {
|
||||
if (pClient->GetTimeSinceLastDataTransaction() >=
|
||||
CIRCNetwork::PING_FREQUENCY) {
|
||||
if (pClient->GetTimeSinceLastDataTransaction() >= uFrequency) {
|
||||
pClient->PutClient("PING :ZNC");
|
||||
}
|
||||
}
|
||||
|
||||
// Restart timer for the case if the period had changed. Usually this is
|
||||
// noop
|
||||
Start(m_pNetwork->GetUser()->GetPingSlack());
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -68,13 +71,15 @@ class CIRCNetworkPingTimer : public CCron {
|
||||
};
|
||||
|
||||
class CIRCNetworkJoinTimer : public CCron {
|
||||
constexpr static int JOIN_FREQUENCY = 30 /* seconds */;
|
||||
|
||||
public:
|
||||
CIRCNetworkJoinTimer(CIRCNetwork* pNetwork)
|
||||
: CCron(), m_bDelayed(false), m_pNetwork(pNetwork) {
|
||||
SetName("CIRCNetworkJoinTimer::" +
|
||||
m_pNetwork->GetUser()->GetUserName() + "::" +
|
||||
m_pNetwork->GetName());
|
||||
Start(CIRCNetwork::JOIN_FREQUENCY);
|
||||
Start(JOIN_FREQUENCY);
|
||||
}
|
||||
|
||||
~CIRCNetworkJoinTimer() override {}
|
||||
@@ -91,7 +96,7 @@ class CIRCNetworkJoinTimer : public CCron {
|
||||
void RunJob() override {
|
||||
if (m_bDelayed) {
|
||||
m_bDelayed = false;
|
||||
Start(CIRCNetwork::JOIN_FREQUENCY);
|
||||
Start(JOIN_FREQUENCY);
|
||||
}
|
||||
if (m_pNetwork->IsIRCConnected()) {
|
||||
m_pNetwork->JoinChans();
|
||||
|
||||
+1
-1
@@ -686,7 +686,7 @@ bool CIRCSock::OnNumericMessage(CNumericMessage& Message) {
|
||||
|
||||
m_pNetwork->SetIRCServer(sServer);
|
||||
// Now that we are connected, let nature take its course
|
||||
SetTimeout(CIRCNetwork::NO_TRAFFIC_TIMEOUT, TMO_READ);
|
||||
SetTimeout(m_pNetwork->GetUser()->GetNoTrafficTimeout(), TMO_READ);
|
||||
PutIRC("WHO " + sNick);
|
||||
|
||||
m_bAuthed = true;
|
||||
|
||||
+11
-3
@@ -32,7 +32,7 @@ class CUserTimer : public CCron {
|
||||
public:
|
||||
CUserTimer(CUser* pUser) : CCron(), m_pUser(pUser) {
|
||||
SetName("CUserTimer::" + m_pUser->GetUserName());
|
||||
Start(CIRCNetwork::PING_SLACK);
|
||||
Start(m_pUser->GetPingSlack());
|
||||
}
|
||||
~CUserTimer() override {}
|
||||
|
||||
@@ -46,10 +46,14 @@ class CUserTimer : public CCron {
|
||||
|
||||
for (CClient* pUserClient : vUserClients) {
|
||||
if (pUserClient->GetTimeSinceLastDataTransaction() >=
|
||||
CIRCNetwork::PING_FREQUENCY) {
|
||||
m_pUser->GetPingFrequency()) {
|
||||
pUserClient->PutClient("PING :ZNC");
|
||||
}
|
||||
}
|
||||
|
||||
// Restart timer for the case if the period had changed. Usually this is
|
||||
// noop
|
||||
Start(m_pUser->GetPingSlack());
|
||||
}
|
||||
|
||||
CUser* m_pUser;
|
||||
@@ -96,6 +100,7 @@ CUser::CUser(const CString& sUserName)
|
||||
m_uMaxNetworks(1),
|
||||
m_uMaxQueryBuffers(50),
|
||||
m_uMaxJoins(0),
|
||||
m_uNoTrafficTimeout(180),
|
||||
m_sSkinName(""),
|
||||
m_pModules(new CModules) {
|
||||
m_pUserTimer = new CUserTimer(this);
|
||||
@@ -151,6 +156,7 @@ bool CUser::ParseConfig(CConfig* pConfig, CString& sError) {
|
||||
{"maxnetworks", &CUser::SetMaxNetworks},
|
||||
{"maxquerybuffers", &CUser::SetMaxQueryBuffers},
|
||||
{"maxjoins", &CUser::SetMaxJoins},
|
||||
{"notraffictimeout", &CUser::SetNoTrafficTimeout},
|
||||
};
|
||||
TOption<bool> BoolOptions[] = {
|
||||
{"keepbuffer",
|
||||
@@ -752,6 +758,7 @@ bool CUser::Clone(const CUser& User, CString& sErrorRet, bool bCloneNetworks) {
|
||||
SetMaxNetworks(User.MaxNetworks());
|
||||
SetMaxQueryBuffers(User.MaxQueryBuffers());
|
||||
SetMaxJoins(User.MaxJoins());
|
||||
SetNoTrafficTimeout(User.GetNoTrafficTimeout());
|
||||
SetClientEncoding(User.GetClientEncoding());
|
||||
SetLanguage(User.GetLanguage());
|
||||
|
||||
@@ -962,7 +969,8 @@ CConfig CUser::ToConfig() const {
|
||||
config.AddKeyValuePair("MaxQueryBuffers", CString(m_uMaxQueryBuffers));
|
||||
config.AddKeyValuePair("MaxJoins", CString(m_uMaxJoins));
|
||||
config.AddKeyValuePair("ClientEncoding", GetClientEncoding());
|
||||
config.AddKeyValuePair("Language", GetLanguage());
|
||||
config.AddKeyValuePair("Language", GetLanguage());
|
||||
config.AddKeyValuePair("NoTrafficTimeout", CString(GetNoTrafficTimeout()));
|
||||
|
||||
// Allow Hosts
|
||||
if (!m_ssAllowedHosts.empty()) {
|
||||
|
||||
Reference in New Issue
Block a user