user->nick.c_str(), (unsigned long)recvq.length(), user->MyClass->GetRecvqMax());
return;
}
+
unsigned long sendqmax = ULONG_MAX;
if (!user->HasPrivPermission("users/flood/increased-buffers"))
sendqmax = user->MyClass->GetSendqSoftMax();
+
unsigned long penaltymax = ULONG_MAX;
if (!user->HasPrivPermission("users/flood/no-fakelag"))
penaltymax = user->MyClass->GetPenaltyThreshold() * 1000;
+ // The maximum size of an IRC message minus the terminating CR+LF.
+ const size_t maxmessage = ServerInstance->Config->Limits.MaxLine - 2;
+ std::string line;
+ line.reserve(maxmessage);
+
+ bool eol_found;
+ std::string::size_type qpos;
+
while (user->CommandFloodPenalty < penaltymax && getSendQSize() < sendqmax)
{
- std::string line;
- line.reserve(ServerInstance->Config->Limits.MaxLine);
- std::string::size_type qpos = 0;
- while (qpos < recvq.length())
+ qpos = 0;
+ eol_found = false;
+
+ const size_t qlen = recvq.length();
+ while (qpos < qlen)
{
char c = recvq[qpos++];
switch (c)
{
- case '\0':
- c = ' ';
- break;
- case '\r':
- continue;
- case '\n':
- goto eol_found;
+ case '\0':
+ c = ' ';
+ break;
+ case '\r':
+ continue;
+ case '\n':
+ eol_found = true;
+ break;
}
- if (line.length() < ServerInstance->Config->Limits.MaxLine - 2)
+
+ if (eol_found)
+ break;
+
+ if (line.length() < maxmessage)
line.push_back(c);
}
- // if we got here, the recvq ran out before we found a newline
- return;
-eol_found:
+
+ // if we return here, we haven't found a newline and make no modifications to recvq
+ // so we can wait for more data
+ if (!eol_found)
+ return;
+
// just found a newline. Terminate the string, and pull it out of recvq
recvq.erase(0, qpos);
ServerInstance->Parser.ProcessBuffer(line, user);
if (user->quitting)
return;
+
+ // clear() does not reclaim memory associated with the string, so our .reserve() call is safe
+ line.clear();
}
+
if (user->CommandFloodPenalty >= penaltymax && !user->MyClass->fakelag)
ServerInstance->Users->QuitUser(user, "Excess Flood");
}
ModeHandler* opermh = ServerInstance->Modes->FindMode('o', MODETYPE_USER);
this->SetMode(opermh, false);
+ FOREACH_MOD(OnPostDeoper, (this));
}
/*
}
if (this->registered == REG_ALL)
- this->WriteCommon("NICK %s",newnick.c_str());
- std::string oldnick = nick;
+ this->WriteCommon("NICK %s", newnick.c_str());
+ const std::string oldnick = nick;
nick = newnick;
InvalidateCache();
int LocalUser::GetServerPort()
{
- switch (this->server_sa.sa.sa_family)
- {
- case AF_INET6:
- return htons(this->server_sa.in6.sin6_port);
- case AF_INET:
- return htons(this->server_sa.in4.sin_port);
- }
- return 0;
+ return this->server_sa.port();
}
const std::string& User::GetIPString()
if (!SocketEngine::BoundsCheckFd(&eh))
return;
- if (text.length() > ServerInstance->Config->Limits.MaxLine - 2)
+ // The maximum size of an IRC message minus the terminating CR+LF.
+ const size_t maxmessage = ServerInstance->Config->Limits.MaxLine - 2;
+ if (text.length() > maxmessage)
{
- // this should happen rarely or never. Crop the string at 512 and try again.
- std::string try_again(text, 0, ServerInstance->Config->Limits.MaxLine - 2);
+ // This should happen rarely or never. Crop the string at MaxLine and try again.
+ std::string try_again(text, 0, maxmessage);
Write(try_again);
return;
}
eh.AddWriteBuf(text);
eh.AddWriteBuf(wide_newline);
- ServerInstance->stats.Sent += text.length() + 2;
- this->bytes_out += text.length() + 2;
+ const size_t bytessent = text.length() + 2;
+ ServerInstance->stats.Sent += bytessent;
+ this->bytes_out += bytessent;
this->cmds_out++;
}