From a26502ff51141c3cd74c078876d3322b49a3833c Mon Sep 17 00:00:00 2001 From: danieldg Date: Fri, 6 Nov 2009 22:37:36 +0000 Subject: Move StreamSocket inheritance off of User git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@12047 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/users.h | 36 ++++++++++++++-------- src/modules/extra/m_ssl_gnutls.cpp | 10 +++--- src/modules/extra/m_ssl_openssl.cpp | 3 +- src/modules/m_cgiirc.cpp | 4 +-- src/modules/m_dnsbl.cpp | 2 +- src/stats.cpp | 4 +-- src/user_resolver.cpp | 6 ++-- src/usermanager.cpp | 20 ++++++------ src/userprocess.cpp | 2 +- src/users.cpp | 61 ++++++++++++++++++------------------- 10 files changed, 78 insertions(+), 70 deletions(-) diff --git a/include/users.h b/include/users.h index ed649f1b9..5cf7669af 100644 --- a/include/users.h +++ b/include/users.h @@ -140,7 +140,7 @@ struct CoreExport ConnectClass : public refcountbase /** Create a new connect class with inherited settings. */ ConnectClass(ConfigTag* tag, char type, const std::string& mask, const ConnectClass& parent); - + /** Update the settings in this block to match the given block */ void Update(const ConnectClass* newSettings); @@ -149,7 +149,7 @@ struct CoreExport ConnectClass : public refcountbase const std::string& GetPass() { return pass; } const std::string& GetHost() { return host; } const int GetPort() { return port; } - + /** Returns the registration timeout */ time_t GetRegTimeout() @@ -213,7 +213,7 @@ struct CoreExport ConnectClass : public refcountbase * connection is stored here primarily, from the user's socket ID (file descriptor) through to the * user's nickname and hostname. */ -class CoreExport User : public StreamSocket +class CoreExport User : public Extensible { private: /** Cached nick!ident@dhost value using the displayed hostname @@ -706,14 +706,28 @@ class CoreExport User : public StreamSocket */ void ShowRULES(); - virtual void OnDataReady(); - virtual void OnError(BufferedSocketError error); /** Default destructor */ virtual ~User(); virtual CullResult cull(); }; +class CoreExport UserIOHandler : public StreamSocket +{ + public: + LocalUser* const user; + UserIOHandler(LocalUser* me) : user(me) {} + void OnDataReady(); + void OnError(BufferedSocketError error); + + /** Adds to the user's write buffer. + * You may add any amount of text up to this users sendq value, if you exceed the + * sendq value, the user will be removed, and further buffer adds will be dropped. + * @param data The data to add to the write buffer + */ + void AddWriteBuf(const std::string &data); +}; + class CoreExport LocalUser : public User { /** A list of channels the user has a pending invite to. @@ -726,6 +740,8 @@ class CoreExport LocalUser : public User LocalUser(int fd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server); CullResult cull(); + UserIOHandler eh; + /** Stats counter for bytes inbound */ int bytes_in; @@ -797,18 +813,10 @@ class CoreExport LocalUser : public User */ void SetClass(const std::string &explicit_name = ""); - void OnDataReady(); void SendText(const std::string& line); void Write(const std::string& text); void Write(const char*, ...) CUSTOM_PRINTF(2, 3); - /** Adds to the user's write buffer. - * You may add any amount of text up to this users sendq value, if you exceed the - * sendq value, the user will be removed, and further buffer adds will be dropped. - * @param data The data to add to the write buffer - */ - void AddWriteBuf(const std::string &data); - /** Returns the list of channels this user has been invited to but has not yet joined. * @return A list of channels the user is invited to */ @@ -859,6 +867,8 @@ class CoreExport LocalUser : public User * @return True if the user can set or unset this mode. */ bool HasModePermission(unsigned char mode, ModeType type); + + inline int GetFd() { return eh.GetFd(); } }; class CoreExport RemoteUser : public User diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index d4422a3de..bd22404b3 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -106,11 +106,11 @@ class CommandStartTLS : public SplitCommand } else { - if (!user->GetIOHook()) + if (!user->eh.GetIOHook()) { user->WriteNumeric(670, "%s :STARTTLS successful, go ahead with TLS handshake", user->nick.c_str()); - user->AddIOHook(creator); - creator->OnStreamSocketAccept(user, NULL, NULL); + user->eh.AddIOHook(creator); + creator->OnStreamSocketAccept(&user->eh, NULL, NULL); } else user->WriteNumeric(691, "%s :STARTTLS failure", user->nick.c_str()); @@ -129,6 +129,7 @@ class ModuleSSLGnuTLS : public Module std::string keyfile; std::string certfile; + std::string cafile; std::string crlfile; std::string sslports; @@ -298,12 +299,11 @@ class ModuleSSLGnuTLS : public Module { LocalUser* user = IS_LOCAL(static_cast(item)); - if (user && user->GetIOHook() == this) + if (user && user->eh.GetIOHook() == this) { // User is using SSL, they're a local user, and they're using one of *our* SSL ports. // Potentially there could be multiple SSL modules loaded at once on different ports. ServerInstance->Users->QuitUser(user, "SSL module unloading"); - user->DelIOHook(); } } } diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 61b54eceb..5eac93af6 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -250,12 +250,11 @@ class ModuleSSLOpenSSL : public Module { LocalUser* user = IS_LOCAL((User*)item); - if (user && user->GetIOHook() == this) + if (user && user->eh.GetIOHook() == this) { // User is using SSL, they're a local user, and they're using one of *our* SSL ports. // Potentially there could be multiple SSL modules loaded at once on different ports. ServerInstance->Users->QuitUser(user, "SSL module unloading"); - user->DelIOHook(); } } } diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp index cc1e34368..07cf3c376 100644 --- a/src/modules/m_cgiirc.cpp +++ b/src/modules/m_cgiirc.cpp @@ -112,7 +112,7 @@ class CGIResolver : public Resolver virtual void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached) { /* Check the user still exists */ - if ((them) && (them == ServerInstance->SE->GetRef(theirfd))) + if ((them) && (&them->eh == ServerInstance->SE->GetRef(theirfd))) { if (notify) ServerInstance->SNO->WriteGlobalSno('a', "Connecting user %s detected as using CGI:IRC (%s), changing real host to %s from %s", them->nick.c_str(), them->host.c_str(), result.c_str(), typ.c_str()); @@ -129,7 +129,7 @@ class CGIResolver : public Resolver virtual void OnError(ResolverError e, const std::string &errormessage) { - if ((them) && (them == ServerInstance->SE->GetRef(theirfd))) + if ((them) && (&them->eh == ServerInstance->SE->GetRef(theirfd))) { if (notify) ServerInstance->SNO->WriteToSnoMask('a', "Connecting user %s detected as using CGI:IRC (%s), but their host can't be resolved from their %s!", them->nick.c_str(), them->host.c_str(), typ.c_str()); diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp index 486a816da..d6622dc77 100644 --- a/src/modules/m_dnsbl.cpp +++ b/src/modules/m_dnsbl.cpp @@ -63,7 +63,7 @@ class DNSBLResolver : public Resolver virtual void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached) { /* Check the user still exists */ - if ((them) && (them == ServerInstance->SE->GetRef(theirfd))) + if ((them) && (&them->eh == ServerInstance->SE->GetRef(theirfd))) { // Now we calculate the bitmask: 256*(256*(256*a+b)+c)+d if(result.length()) diff --git a/src/stats.cpp b/src/stats.cpp index fa11758f9..e8173e655 100644 --- a/src/stats.cpp +++ b/src/stats.cpp @@ -250,7 +250,7 @@ void InspIRCd::DoStats(char statschar, User* user, string_list &results) for (std::vector::iterator n = this->Users->local_users.begin(); n != this->Users->local_users.end(); n++) { LocalUser* i = *n; - results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age)); + results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age)); } break; @@ -260,7 +260,7 @@ void InspIRCd::DoStats(char statschar, User* user, string_list &results) for (std::vector::iterator n = this->Users->local_users.begin(); n != this->Users->local_users.end(); n++) { LocalUser* i = *n; - results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age)); + results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age)); } break; diff --git a/src/user_resolver.cpp b/src/user_resolver.cpp index 8a2bc71ea..b7c17a85a 100644 --- a/src/user_resolver.cpp +++ b/src/user_resolver.cpp @@ -23,7 +23,7 @@ void UserResolver::OnLookupComplete(const std::string &result, unsigned int ttl, { UserResolver *res_forward; // for forward-resolution - if ((!this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == this->bound_user)) + if ((!this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == &bound_user->eh)) { this->bound_user->stored_host = result; try @@ -50,7 +50,7 @@ void UserResolver::OnLookupComplete(const std::string &result, unsigned int ttl, ServerInstance->Logs->Log("RESOLVER", DEBUG,"Error in resolver: %s",e.GetReason()); } } - else if ((this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == this->bound_user)) + else if ((this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == &bound_user->eh)) { /* Both lookups completed */ @@ -118,7 +118,7 @@ void UserResolver::OnLookupComplete(const std::string &result, unsigned int ttl, void UserResolver::OnError(ResolverError e, const std::string &errormessage) { - if (ServerInstance->SE->GetRef(this->bound_fd) == this->bound_user) + if (ServerInstance->SE->GetRef(this->bound_fd) == &bound_user->eh) { this->bound_user->WriteServ("NOTICE Auth :*** Could not resolve your hostname: %s; using your IP address (%s) instead.", errormessage.c_str(), this->bound_user->GetIPString()); this->bound_user->dns_done = true; diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 6315f059d..1e3e9fa72 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -32,15 +32,16 @@ void UserManager::AddUser(int socket, ListenSocket* via, irc::sockets::sockaddrs ServerInstance->SNO->WriteToSnoMask('a', "WARNING *** Duplicate UUID allocated!"); return; } + UserIOHandler* eh = &New->eh; /* Give each of the modules an attempt to hook the user for I/O */ - FOREACH_MOD(I_OnHookIO, OnHookIO(New, via)); + FOREACH_MOD(I_OnHookIO, OnHookIO(eh, via)); - if (New->GetIOHook()) + if (eh->GetIOHook()) { try { - New->GetIOHook()->OnStreamSocketAccept(New, client, server); + eh->GetIOHook()->OnStreamSocketAccept(eh, client, server); } catch (CoreException& modexcept) { @@ -127,7 +128,7 @@ void UserManager::AddUser(int socket, ListenSocket* via, irc::sockets::sockaddrs } } - if (!ServerInstance->SE->AddFd(New, FD_WANT_FAST_READ | FD_WANT_EDGE_WRITE)) + if (!ServerInstance->SE->AddFd(eh, FD_WANT_FAST_READ | FD_WANT_EDGE_WRITE)) { ServerInstance->Logs->Log("USERS", DEBUG,"Internal error on new connection"); this->QuitUser(New, "Internal error handling connection"); @@ -192,12 +193,13 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char { LocalUser* lu = IS_LOCAL(user); FOREACH_MOD(I_OnUserDisconnect,OnUserDisconnect(lu)); - lu->DoWrite(); - if (lu->GetIOHook()) + UserIOHandler* eh = &lu->eh; + eh->DoWrite(); + if (eh->GetIOHook()) { try { - lu->GetIOHook()->OnStreamSocketClose(lu); + eh->GetIOHook()->OnStreamSocketClose(eh); } catch (CoreException& modexcept) { @@ -205,8 +207,8 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char } } - ServerInstance->SE->DelFd(lu); - lu->Close(); + ServerInstance->SE->DelFd(eh); + eh->Close(); } /* diff --git a/src/userprocess.cpp b/src/userprocess.cpp index 4cc3f0a88..8aa76a1fd 100644 --- a/src/userprocess.cpp +++ b/src/userprocess.cpp @@ -58,7 +58,7 @@ void InspIRCd::DoBackgroundUserStuff() if (curr->Penalty) { curr->Penalty--; - curr->OnDataReady(); + curr->eh.OnDataReady(); } switch (curr->registered) diff --git a/src/users.cpp b/src/users.cpp index 14edf649f..ec6fd0571 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -240,13 +240,13 @@ User::User(const std::string &uid, const std::string& sid, int type) } LocalUser::LocalUser(int myfd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* servaddr) - : User(ServerInstance->GetUID(), ServerInstance->Config->ServerName, USERTYPE_LOCAL) + : User(ServerInstance->GetUID(), ServerInstance->Config->ServerName, USERTYPE_LOCAL), eh(this) { bytes_in = bytes_out = cmds_in = cmds_out = 0; server_sa.sa.sa_family = AF_UNSPEC; Penalty = 0; lastping = nping = 0; - SetFd(myfd); + eh.SetFd(myfd); memcpy(&client_sa, client, sizeof(irc::sockets::sockaddrs)); memcpy(&server_sa, servaddr, sizeof(irc::sockets::sockaddrs)); } @@ -495,29 +495,25 @@ bool LocalUser::HasPrivPermission(const std::string &privstr, bool noisy) return false; } -void User::OnDataReady() +void UserIOHandler::OnDataReady() { -} - -void LocalUser::OnDataReady() -{ - if (quitting) + if (user->quitting) return; - if (recvq.length() > MyClass->GetRecvqMax() && !HasPrivPermission("users/flood/increased-buffers")) + if (recvq.length() > user->MyClass->GetRecvqMax() && !user->HasPrivPermission("users/flood/increased-buffers")) { - ServerInstance->Users->QuitUser(this, "RecvQ exceeded"); + ServerInstance->Users->QuitUser(user, "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()); + user->nick.c_str(), (unsigned long)recvq.length(), user->MyClass->GetRecvqMax()); } unsigned long sendqmax = ULONG_MAX; - if (!HasPrivPermission("users/flood/increased-buffers")) - sendqmax = MyClass->GetSendqSoftMax(); - int penaltymax = MyClass->GetPenaltyThreshold(); - if (penaltymax == 0 || HasPrivPermission("users/flood/no-fakelag")) + if (!user->HasPrivPermission("users/flood/increased-buffers")) + sendqmax = user->MyClass->GetSendqSoftMax(); + int penaltymax = user->MyClass->GetPenaltyThreshold(); + if (penaltymax == 0 || user->HasPrivPermission("users/flood/no-fakelag")) penaltymax = INT_MAX; - while (Penalty < penaltymax && getSendQSize() < sendqmax) + while (user->Penalty < penaltymax && getSendQSize() < sendqmax) { std::string line; line.reserve(MAXBUF); @@ -546,29 +542,30 @@ eol_found: // TODO should this be moved to when it was inserted in recvq? ServerInstance->stats->statsRecv += qpos; - this->bytes_in += qpos; - this->cmds_in++; + user->bytes_in += qpos; + user->cmds_in++; - ServerInstance->Parser->ProcessBuffer(line, this); - if (quitting) + ServerInstance->Parser->ProcessBuffer(line, user); + if (user->quitting) return; } // Add pseudo-penalty so that we continue processing after sendq recedes - if (Penalty == 0 && getSendQSize() >= sendqmax) - Penalty++; + if (user->Penalty == 0 && getSendQSize() >= sendqmax) + user->Penalty++; } -void LocalUser::AddWriteBuf(const std::string &data) +void UserIOHandler::AddWriteBuf(const std::string &data) { - if (!quitting && getSendQSize() + data.length() > MyClass->GetSendqHardMax() && !HasPrivPermission("users/flood/increased-buffers")) + if (!user->quitting && getSendQSize() + data.length() > user->MyClass->GetSendqHardMax() && + !user->HasPrivPermission("users/flood/increased-buffers")) { /* * Quit the user FIRST, because otherwise we could recurse * here and hit the same limit. */ - ServerInstance->Users->QuitUser(this, "SendQ exceeded"); + ServerInstance->Users->QuitUser(user, "SendQ exceeded"); ServerInstance->SNO->WriteToSnoMask('a', "User %s SendQ exceeds connect class maximum of %lu", - nick.c_str(), MyClass->GetSendqHardMax()); + user->nick.c_str(), user->MyClass->GetSendqHardMax()); return; } @@ -578,9 +575,9 @@ void LocalUser::AddWriteBuf(const std::string &data) WriteData(data); } -void User::OnError(BufferedSocketError) +void UserIOHandler::OnError(BufferedSocketError) { - ServerInstance->Users->QuitUser(this, getError()); + ServerInstance->Users->QuitUser(user, getError()); } CullResult User::cull() @@ -607,7 +604,7 @@ CullResult LocalUser::cull() else ServerInstance->Logs->Log("USERS", DEBUG, "Failed to remove user from vector"); - Close(); + eh.cull(); return User::cull(); } @@ -1001,7 +998,7 @@ void User::Write(const char *text, ...) void LocalUser::Write(const std::string& text) { - if (!ServerInstance->SE->BoundsCheckFd(this)) + if (!ServerInstance->SE->BoundsCheckFd(&eh)) return; if (text.length() > MAXBUF - 2) @@ -1014,8 +1011,8 @@ void LocalUser::Write(const std::string& text) ServerInstance->Logs->Log("USEROUTPUT", DEBUG,"C[%s] O %s", uuid.c_str(), text.c_str()); - this->AddWriteBuf(text); - this->AddWriteBuf(wide_newline); + eh.AddWriteBuf(text); + eh.AddWriteBuf(wide_newline); ServerInstance->stats->statsSent += text.length() + 2; this->bytes_out += text.length() + 2; -- cgit v1.2.3