]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/users.cpp
Flexible SendQ
[user/henk/code/inspircd.git] / src / users.cpp
index 5d6b1a01a748f928f5d57dc80d1d0c64565fc6ea..1f38dfada92901a81a73fa54ac7d6345e966bfab 100644 (file)
@@ -109,7 +109,7 @@ void User::StartDNSLookup()
                UserResolver *res_reverse;
 
                QueryType resolvtype = this->client_sa.sa.sa_family == AF_INET6 ? DNS_QUERY_PTR6 : DNS_QUERY_PTR4;
-               res_reverse = new UserResolver(ServerInstance, this, sip, resolvtype, cached);
+               res_reverse = new UserResolver(this, sip, resolvtype, cached);
 
                ServerInstance->AddResolver(res_reverse, cached);
        }
@@ -205,9 +205,9 @@ void User::DecrementModes()
        }
 }
 
-User::User(InspIRCd* Instance, const std::string &uid)
+User::User(const std::string &uid)
 {
-       server = Instance->FindServerNamePtr(Instance->Config->ServerName);
+       server = ServerInstance->FindServerNamePtr(ServerInstance->Config->ServerName);
        age = ServerInstance->Time();
        Penalty = 0;
        lastping = signon = idle_lastmsg = nping = registered = 0;
@@ -220,21 +220,22 @@ User::User(InspIRCd* Instance, const std::string &uid)
        AllowedPrivs = AllowedOperCommands = NULL;
 
        if (uid.empty())
-               uuid.assign(Instance->GetUID(), 0, UUID_LENGTH - 1);
+               uuid.assign(ServerInstance->GetUID(), 0, UUID_LENGTH - 1);
        else
                uuid.assign(uid, 0, UUID_LENGTH - 1);
 
        ServerInstance->Logs->Log("USERS", DEBUG,"New UUID for user: %s (%s)", uuid.c_str(), uid.empty() ? "allocated new" : "used remote");
 
-       user_hash::iterator finduuid = Instance->Users->uuidlist->find(uuid);
-       if (finduuid == Instance->Users->uuidlist->end())
-               (*Instance->Users->uuidlist)[uuid] = this;
+       user_hash::iterator finduuid = ServerInstance->Users->uuidlist->find(uuid);
+       if (finduuid == ServerInstance->Users->uuidlist->end())
+               (*ServerInstance->Users->uuidlist)[uuid] = this;
        else
                throw CoreException("Duplicate UUID "+std::string(uuid)+" in User constructor");
 }
 
 User::~User()
 {
+       ServerInstance->Logs->Log("USERS", DEBUG, "User destructor for %s", uuid.c_str());
        /* NULL for remote users :) */
        if (this->MyClass)
        {
@@ -517,14 +518,17 @@ void User::OnDataReady()
        if (quitting)
                return;
 
-       if (MyClass && !HasPrivPermission("users/flood/increased-buffers") && recvq.length() > MyClass->GetRecvqMax())
+       if (MyClass && recvq.length() > MyClass->GetRecvqMax() && !HasPrivPermission("users/flood/increased-buffers"))
        {
                ServerInstance->Users->QuitUser(this, "RecvQ exceeded");
                ServerInstance->SNO->WriteToSnoMask('a', "User %s RecvQ of %lu exceeds connect class maximum of %lu",
                        nick.c_str(), (unsigned long)recvq.length(), MyClass->GetRecvqMax());
        }
+       unsigned long sendqmax = ULONG_MAX;
+       if (MyClass && !HasPrivPermission("users/flood/increased-buffers"))
+               sendqmax = MyClass->GetSendqSoftMax();
 
-       while (this->Penalty < 10)
+       while (Penalty < 10 && getSendQSize() < sendqmax)
        {
                std::string line;
                line.reserve(MAXBUF);
@@ -558,6 +562,9 @@ eol_found:
 
                ServerInstance->Parser->ProcessBuffer(line, this);
        }
+       // Add pseudo-penalty so that we continue processing after sendq recedes
+       if (Penalty == 0 && getSendQSize() >= sendqmax)
+               Penalty++;
 }
 
 void User::AddWriteBuf(const std::string &data)
@@ -565,7 +572,7 @@ void User::AddWriteBuf(const std::string &data)
        // Don't bother sending text to remote users!
        if (IS_REMOTE(this))
                return;
-       if (!quitting && MyClass && getSendQSize() + data.length() > MyClass->GetSendqMax() && !HasPrivPermission("users/flood/increased-buffers"))
+       if (!quitting && MyClass && getSendQSize() + data.length() > MyClass->GetSendqHardMax() && !HasPrivPermission("users/flood/increased-buffers"))
        {
                /*
                 * Fix by brain - Set the error text BEFORE calling, because
@@ -574,7 +581,7 @@ void User::AddWriteBuf(const std::string &data)
                 */
                ServerInstance->Users->QuitUser(this, "SendQ exceeded");
                ServerInstance->SNO->WriteToSnoMask('a', "User %s SendQ of %lu exceeds connect class maximum of %lu",
-                       nick.c_str(), (unsigned long)getSendQSize() + data.length(), MyClass->GetSendqMax());
+                       nick.c_str(), (unsigned long)getSendQSize() + data.length(), MyClass->GetSendqHardMax());
                return;
        }
 
@@ -852,7 +859,7 @@ void User::FullConnect()
        ModResult MOD_RESULT;
        std::string command("LUSERS");
        std::vector<std::string> parameters;
-       FIRST_MOD_RESULT(ServerInstance, OnPreCommand, MOD_RESULT, (command, parameters, this, true, "LUSERS"));
+       FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, parameters, this, true, "LUSERS"));
        if (!MOD_RESULT)
                ServerInstance->CallCommandHandler(command, parameters, this);
 
@@ -909,7 +916,7 @@ bool User::ForceNickChange(const char* newnick)
        this->InvalidateCache();
 
        NICKForced.set(this, 1);
-       FIRST_MOD_RESULT(ServerInstance, OnUserPreNick, MOD_RESULT, (this, newnick));
+       FIRST_MOD_RESULT(OnUserPreNick, MOD_RESULT, (this, newnick));
        NICKForced.set(this, 0);
 
        if (MOD_RESULT == MOD_RES_DENY)
@@ -1147,7 +1154,7 @@ void User::WriteNumeric(unsigned int numeric, const std::string &text)
        char textbuffer[MAXBUF];
        ModResult MOD_RESULT;
 
-       FIRST_MOD_RESULT(ServerInstance, OnNumeric, MOD_RESULT, (this, numeric, text));
+       FIRST_MOD_RESULT(OnNumeric, MOD_RESULT, (this, numeric, text));
 
        if (MOD_RESULT == MOD_RES_DENY)
                return;
@@ -1408,7 +1415,7 @@ bool User::ChangeName(const char* gecos)
        if (IS_LOCAL(this))
        {
                ModResult MOD_RESULT;
-               FIRST_MOD_RESULT(ServerInstance, OnChangeLocalUserGECOS, MOD_RESULT, (this,gecos));
+               FIRST_MOD_RESULT(OnChangeLocalUserGECOS, MOD_RESULT, (this,gecos));
                if (MOD_RESULT == MOD_RES_DENY)
                        return false;
                FOREACH_MOD(I_OnChangeName,OnChangeName(this,gecos));
@@ -1423,7 +1430,7 @@ void User::DoHostCycle(const std::string &quitline)
        char buffer[MAXBUF];
 
        ModResult result = MOD_RES_PASSTHRU;
-       FIRST_MOD_RESULT(ServerInstance, OnHostCycle, result, (this));
+       FIRST_MOD_RESULT(OnHostCycle, result, (this));
 
        if (result == MOD_RES_DENY)
                return;
@@ -1474,7 +1481,7 @@ bool User::ChangeDisplayedHost(const char* shost)
        if (IS_LOCAL(this))
        {
                ModResult MOD_RESULT;
-               FIRST_MOD_RESULT(ServerInstance, OnChangeLocalUserHost, MOD_RESULT, (this,shost));
+               FIRST_MOD_RESULT(OnChangeLocalUserHost, MOD_RESULT, (this,shost));
                if (MOD_RESULT == MOD_RES_DENY)
                        return false;
        }
@@ -1733,7 +1740,7 @@ void User::PurgeEmptyChannels()
                if (i2 != ServerInstance->chanlist->end())
                {
                        ModResult MOD_RESULT;
-                       FIRST_MOD_RESULT(ServerInstance, OnChannelPreDelete, MOD_RESULT, (i2->second));
+                       FIRST_MOD_RESULT(OnChannelPreDelete, MOD_RESULT, (i2->second));
                        if (MOD_RESULT == MOD_RES_DENY)
                                continue; // delete halted by module
                        FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(i2->second));
@@ -1808,12 +1815,21 @@ const std::string FakeUser::GetFullRealHost()
 }
 
 ConnectClass::ConnectClass(char t, const std::string& mask)
-       : type(t), name("unnamed"), registration_timeout(0), host(mask), pingtime(0), pass(""), hash(""), sendqmax(0), recvqmax(0), maxlocal(0), maxglobal(0), maxchans(0), port(0), limit(0), RefCount(1)
+       : type(t), name("unnamed"), registration_timeout(0), host(mask),
+       pingtime(0), pass(""), hash(""), softsendqmax(0), hardsendqmax(0),
+       recvqmax(0), maxlocal(0), maxglobal(0), maxchans(0), port(0), limit(0),
+       RefCount(1)
 {
 }
 
 ConnectClass::ConnectClass(char t, const std::string& mask, const ConnectClass& parent)
-       : type(t), name("unnamed"), registration_timeout(parent.registration_timeout), host(mask), pingtime(parent.pingtime), pass(parent.pass), hash(parent.hash), sendqmax(parent.sendqmax), recvqmax(parent.recvqmax), maxlocal(parent.maxlocal), maxglobal(parent.maxglobal), maxchans(parent.maxchans), port(parent.port), limit(parent.limit), RefCount(1)
+       : type(t), name("unnamed"),
+       registration_timeout(parent.registration_timeout), host(mask),
+       pingtime(parent.pingtime), pass(parent.pass), hash(parent.hash),
+       softsendqmax(parent.softsendqmax), hardsendqmax(parent.hardsendqmax),
+       recvqmax(parent.recvqmax), maxlocal(parent.maxlocal),
+       maxglobal(parent.maxglobal), maxchans(parent.maxchans),
+       port(parent.port), limit(parent.limit), RefCount(1)
 {
 }
 
@@ -1825,7 +1841,8 @@ void ConnectClass::Update(const ConnectClass* src)
        pingtime = src->pingtime;
        pass = src->pass;
        hash = src->hash;
-       sendqmax = src->sendqmax;
+       softsendqmax = src->softsendqmax;
+       hardsendqmax = src->hardsendqmax;
        recvqmax = src->recvqmax;
        maxlocal = src->maxlocal;
        maxglobal = src->maxglobal;