X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fusers.cpp;h=4050337c7a2e7ed6ab9b02564136d508ff044c14;hb=168ee804903e5ee10edc04e870e36a1256885e34;hp=f11a7a38079e43d3fba28c9fc914f1ce0fcc3deb;hpb=51891f10f2a05e16e45651a669db6680a433bf9b;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/users.cpp b/src/users.cpp index f11a7a380..4050337c7 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -97,7 +97,7 @@ LocalUser::LocalUser(int myfd, irc::sockets::sockaddrs* client, irc::sockets::so , quitting_sendq(false) , lastping(true) , exempt(false) - , nping(0) + , nextping(0) , idle_lastmsg(0) , CommandFloodPenalty(0) , already_sent(0) @@ -239,23 +239,30 @@ void UserIOHandler::OnDataReady() 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; + // The cleaned message sent by the user or empty if not found yet. std::string line; - line.reserve(maxmessage); - bool eol_found; + // The position of the most \n character or npos if not found yet. + std::string::size_type eolpos; + + // The position within the recvq of the current character. std::string::size_type qpos; while (user->CommandFloodPenalty < penaltymax && getSendQSize() < sendqmax) { - qpos = 0; - eol_found = false; + // Check the newly received data for an EOL. + eolpos = recvq.find('\n', checked_until); + if (eolpos == std::string::npos) + { + checked_until = recvq.length(); + return; + } - const size_t qlen = recvq.length(); - while (qpos < qlen) + // We've found a line! Clean it up and move it to the line buffer. + line.reserve(eolpos); + for (qpos = 0; qpos < eolpos; ++qpos) { - char c = recvq[qpos++]; + char c = recvq[qpos]; switch (c) { case '\0': @@ -263,25 +270,14 @@ void UserIOHandler::OnDataReady() break; case '\r': continue; - case '\n': - eol_found = true; - break; } - if (eol_found) - break; - - if (line.length() < maxmessage) - line.push_back(c); + line.push_back(c); } - // 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); + recvq.erase(0, eolpos + 1); + checked_until = 0; // TODO should this be moved to when it was inserted in recvq? ServerInstance->stats.Recv += qpos; @@ -318,10 +314,11 @@ void UserIOHandler::AddWriteBuf(const std::string &data) WriteData(data); } -void UserIOHandler::OnSetEndPoint(const irc::sockets::sockaddrs& server, const irc::sockets::sockaddrs& client) +bool UserIOHandler::OnSetEndPoint(const irc::sockets::sockaddrs& server, const irc::sockets::sockaddrs& client) { memcpy(&user->server_sa, &server, sizeof(irc::sockets::sockaddrs)); user->SetClientIP(client); + return !user->quitting; } void UserIOHandler::OnError(BufferedSocketError) @@ -380,17 +377,6 @@ void User::Oper(OperInfo* info) if (info->oper_block) opername = info->oper_block->getString("name"); - if (IS_LOCAL(this)) - { - LocalUser* l = IS_LOCAL(this); - std::string vhost = oper->getConfig("vhost"); - if (!vhost.empty()) - l->ChangeDisplayedHost(vhost); - std::string opClass = oper->getConfig("class"); - if (!opClass.empty()) - l->SetClass(opClass); - } - ServerInstance->SNO->WriteToSnoMask('o',"%s (%s@%s) is now an IRC operator of type %s (using oper '%s')", nick.c_str(), ident.c_str(), GetRealHost().c_str(), oper->name.c_str(), opername.c_str()); this->WriteNumeric(RPL_YOUAREOPER, InspIRCd::Format("You are now %s %s", strchr("aeiouAEIOU", oper->name[0]) ? "an" : "a", oper->name.c_str())); @@ -517,7 +503,7 @@ void LocalUser::CheckClass(bool clone_count) } } - this->nping = ServerInstance->Time() + a->GetPingTime(); + this->nextping = ServerInstance->Time() + a->GetPingTime(); } bool LocalUser::CheckLines(bool doZline) @@ -723,17 +709,17 @@ irc::sockets::cidr_mask User::GetCIDRMask() return irc::sockets::cidr_mask(client_sa, range); } -bool User::SetClientIP(const std::string& address, bool recheck_eline) +bool User::SetClientIP(const std::string& address) { irc::sockets::sockaddrs sa; if (!irc::sockets::aptosa(address, client_sa.port(), sa)) return false; - User::SetClientIP(sa, recheck_eline); + User::SetClientIP(sa); return true; } -void User::SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_eline) +void User::SetClientIP(const irc::sockets::sockaddrs& sa) { const std::string oldip(GetIPString()); memcpy(&client_sa, &sa, sizeof(irc::sockets::sockaddrs)); @@ -746,26 +732,33 @@ void User::SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_eline) ChangeDisplayedHost(GetIPString()); } -bool LocalUser::SetClientIP(const std::string& address, bool recheck_eline) +bool LocalUser::SetClientIP(const std::string& address) { irc::sockets::sockaddrs sa; if (!irc::sockets::aptosa(address, client_sa.port(), sa)) return false; - LocalUser::SetClientIP(sa, recheck_eline); + LocalUser::SetClientIP(sa); return true; } -void LocalUser::SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_eline) +void LocalUser::SetClientIP(const irc::sockets::sockaddrs& sa) { - if (sa != client_sa) - { - User::SetClientIP(sa); - if (recheck_eline) - this->exempt = (ServerInstance->XLines->MatchesLine("E", this) != NULL); + if (sa == client_sa) + return; - FOREACH_MOD(OnSetUserIP, (this)); - } + ServerInstance->Users->RemoveCloneCounts(this); + + User::SetClientIP(sa); + + FOREACH_MOD(OnSetUserIP, (this)); + + ServerInstance->Users->AddClone(this); + + // Recheck the connect class. + this->MyClass = NULL; + this->SetClass(); + this->CheckClass(); } void LocalUser::Write(const ClientProtocol::SerializedMessage& text) @@ -796,7 +789,11 @@ void LocalUser::Write(const ClientProtocol::SerializedMessage& text) void LocalUser::Send(ClientProtocol::Event& protoev) { if (!serializer) + { + ServerInstance->Logs->Log("USERS", LOG_DEBUG, "BUG: LocalUser::Send() called on %s who does not have a serializer!", + GetFullRealHost().c_str()); return; + } // In the most common case a static LocalUser field, sendmsglist, is passed to the event to be // populated. The list is cleared before returning. @@ -1005,7 +1002,7 @@ bool User::ChangeDisplayedHost(const std::string& shost) this->InvalidateCache(); - if (IS_LOCAL(this)) + if (IS_LOCAL(this) && this->registered != REG_NONE) this->WriteNumeric(RPL_YOURDISPLAYEDHOST, this->GetDisplayedHost(), "is now your displayed host"); return true; @@ -1018,7 +1015,7 @@ void User::ChangeRealHost(const std::string& host, bool resetdisplay) const bool changehost = (realhost != host); if (!changehost && !resetdisplay) return; - + // If the displayhost is not set and we are not resetting it then // we need to copy it to the displayhost field. if (displayhost.empty() && !resetdisplay)