From 343f12b9b2d4e519b09877f76a00f6a0714509f2 Mon Sep 17 00:00:00 2001 From: brain Date: Mon, 24 Mar 2008 15:13:17 +0000 Subject: Add stuff so that modules can hook users by altering a pointer in the User class. Note that ssl modules still bind by port, but the idea of doing this change is so we can remove that logic next git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@9187 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/modules.h | 4 +++- include/users.h | 4 ++++ src/cull_list.cpp | 4 ++-- src/modules.cpp | 1 + src/modules/extra/m_ssl_gnutls.cpp | 27 ++++++++++++++++----------- src/modules/extra/m_ssl_openssl.cpp | 15 +++++++++++++-- src/socket.cpp | 11 ----------- src/usermanager.cpp | 30 +++++++++++++++++++++++------- src/userprocess.cpp | 4 ++-- src/users.cpp | 5 +++-- 10 files changed, 67 insertions(+), 38 deletions(-) diff --git a/include/modules.h b/include/modules.h index 693fd41fb..de0e0d7fe 100644 --- a/include/modules.h +++ b/include/modules.h @@ -401,7 +401,7 @@ enum Implementation I_OnRawSocketAccept, I_OnRawSocketClose, I_OnRawSocketWrite, I_OnRawSocketRead, I_OnChangeLocalUserGECOS, I_OnUserRegister, I_OnChannelPreDelete, I_OnChannelDelete, I_OnPostOper, I_OnSyncOtherMetaData, I_OnSetAway, I_OnCancelAway, I_OnUserList, I_OnPostCommand, I_OnPostJoin, I_OnWhoisLine, I_OnBuildExemptList, I_OnRawSocketConnect, I_OnGarbageCollect, I_OnBufferFlushed, - I_OnText, I_OnReadConfig, I_OnDownloadFile, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem, I_OnNumeric, + I_OnText, I_OnReadConfig, I_OnDownloadFile, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem, I_OnNumeric, I_OnHookUserIO, I_END }; @@ -1245,6 +1245,8 @@ class CoreExport Module : public Extensible */ virtual int OnDelBan(User* source, Channel* channel,const std::string &banmask); + virtual void OnHookUserIO(User* user); + /** Called immediately after any connection is accepted. This is intended for raw socket * processing (e.g. modules which wrap the tcp connection within another library) and provides * no information relating to a user record as the connection has not been assigned yet. diff --git a/include/users.h b/include/users.h index 07843b7c0..74b55202d 100644 --- a/include/users.h +++ b/include/users.h @@ -464,6 +464,10 @@ class CoreExport User : public connection bool* AllowedChanModes; public: + /** Module responsible for raw i/o + */ + Module* io; + /** Contains a pointer to the connect class a user is on from - this will be NULL for remote connections. * The pointer is guarenteed to *always* be valid. :) */ diff --git a/src/cull_list.cpp b/src/cull_list.cpp index 224591b6f..f7f163298 100644 --- a/src/cull_list.cpp +++ b/src/cull_list.cpp @@ -80,11 +80,11 @@ int CullList::Apply() if (IS_LOCAL(u)) { - if (ServerInstance->Config->GetIOHook(u->GetPort())) + if (u->io) { try { - ServerInstance->Config->GetIOHook(u->GetPort())->OnRawSocketClose(u->GetFd()); + u->io->OnRawSocketClose(u->GetFd()); } catch (CoreException& modexcept) { diff --git a/src/modules.cpp b/src/modules.cpp index 6a870361b..82dbea185 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -195,6 +195,7 @@ void Module::OnText(User*, void*, int, const std::string&, char, CUList&) { } void Module::OnRunTestSuite() { } void Module::OnNamesListItem(User*, User*, Channel*, std::string&, std::string&) { } int Module::OnNumeric(User*, unsigned int, const std::string&) { return 0; } +void Module::OnHookUserIO(User*) { } ModuleManager::ModuleManager(InspIRCd* Ins) : ModCount(0), Instance(Ins) { diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 78d9c785a..f3af386ae 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -78,15 +78,9 @@ class CommandStartTLS : public Command if (!user->GetExt("tls")) return CMD_FAILURE; - for (size_t i = 0; i < ServerInstance->Config->ports.size(); i++) - { - if (ServerInstance->Config->ports[i]->GetDescription() == "ssl") - { - Caller->OnRawSocketAccept(user->GetFd(), user->GetIPString(), ServerInstance->Config->ports[i]->GetPort()); - user->SetSockAddr(user->GetProtocolFamily(), user->GetIPString(), ServerInstance->Config->ports[i]->GetPort()); - break; - } - } + user->io = Caller; + Caller->OnRawSocketAccept(user->GetFd(), user->GetIPString(), ServerInstance->Config->ports[i]->GetPort()); + return CMD_FAILURE; } }; @@ -142,8 +136,8 @@ class ModuleSSLGnuTLS : public Module // Void return, guess we assume success gnutls_certificate_set_dh_params(x509_cred, dh_params); Implementation eventlist[] = { I_On005Numeric, I_OnRawSocketConnect, I_OnRawSocketAccept, I_OnRawSocketClose, I_OnRawSocketRead, I_OnRawSocketWrite, I_OnCleanup, - I_OnBufferFlushed, I_OnRequest, I_OnSyncUserMetaData, I_OnDecodeMetaData, I_OnUnloadModule, I_OnRehash, I_OnWhois, I_OnPostConnect, I_OnEvent }; - ServerInstance->Modules->Attach(eventlist, this, 16); + I_OnBufferFlushed, I_OnRequest, I_OnSyncUserMetaData, I_OnDecodeMetaData, I_OnUnloadModule, I_OnRehash, I_OnWhois, I_OnPostConnect, I_OnEvent, I_OnHookUserIO }; + ServerInstance->Modules->Attach(eventlist, this, 17); starttls = new CommandStartTLS(ServerInstance, this); ServerInstance->AddCommand(starttls); @@ -303,6 +297,8 @@ class ModuleSSLGnuTLS : public Module delete tofree; user->Shrink("ssl_cert"); } + + user->io = NULL; } } @@ -331,6 +327,15 @@ class ModuleSSLGnuTLS : public Module output.append(" SSL=" + sslports); } + virtual void OnHookUserIO(User* user) + { + if (!user->io && isin(user->GetPort(), listenports)) + { + /* Hook the user with our module */ + user->io = this; + } + } + virtual const char* OnRequest(Request* request) { ISHRequest* ISR = (ISHRequest*)request; diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 610565002..ba32c4013 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -150,8 +150,17 @@ class ModuleSSLOpenSSL : public Module // Needs the flag as it ignores a plain /rehash OnRehash(NULL,"ssl"); Implementation eventlist[] = { I_OnRawSocketConnect, I_OnRawSocketAccept, I_OnRawSocketClose, I_OnRawSocketRead, I_OnRawSocketWrite, I_OnCleanup, I_On005Numeric, - I_OnBufferFlushed, I_OnRequest, I_OnSyncUserMetaData, I_OnDecodeMetaData, I_OnUnloadModule, I_OnRehash, I_OnWhois, I_OnPostConnect }; - ServerInstance->Modules->Attach(eventlist, this, 15); + I_OnBufferFlushed, I_OnRequest, I_OnSyncUserMetaData, I_OnDecodeMetaData, I_OnUnloadModule, I_OnRehash, I_OnWhois, I_OnPostConnect, I_OnHookUserIO }; + ServerInstance->Modules->Attach(eventlist, this, 16); + } + + virtual void OnHookUserIO(User* user) + { + if (!user->io && isin(user->GetPort(), listenports)) + { + /* Hook the user with our module */ + user->io = this; + } } virtual void OnRehash(User* user, const std::string ¶m) @@ -320,6 +329,8 @@ class ModuleSSLOpenSSL : public Module delete tofree; user->Shrink("ssl_cert"); } + + user->io = NULL; } } diff --git a/src/socket.cpp b/src/socket.cpp index e045df1f9..2089fffbd 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -116,17 +116,6 @@ void ListenSocket::HandleEvent(EventType, int) ServerInstance->SE->NonBlocking(incomingSockfd); - if (ServerInstance->Config->GetIOHook(in_port)) - { - try - { - ServerInstance->Config->GetIOHook(in_port)->OnRawSocketAccept(incomingSockfd, buf, in_port); - } - catch (CoreException& modexcept) - { - ServerInstance->Logs->Log("SOCKET", DEBUG,"%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason()); - } - } ServerInstance->stats->statsAccept++; ServerInstance->Users->AddClient(ServerInstance, incomingSockfd, in_port, false, this->family, client); } diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 6145c887b..b518685fa 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -35,19 +35,35 @@ void UserManager::AddClient(InspIRCd* Instance, int socket, int port, bool iscac return; } - Instance->Logs->Log("USERS", DEBUG,"New user fd: %d", socket); - - int j = 0; - - this->unregistered_count++; - char ipaddr[MAXBUF]; #ifdef IPV6 if (socketfamily == AF_INET6) inet_ntop(AF_INET6, &((const sockaddr_in6*)ip)->sin6_addr, ipaddr, sizeof(ipaddr)); else #endif - inet_ntop(AF_INET, &((const sockaddr_in*)ip)->sin_addr, ipaddr, sizeof(ipaddr)); + inet_ntop(AF_INET, &((const sockaddr_in*)ip)->sin_addr, ipaddr, sizeof(ipaddr)); + + + /* Give each of the modules an attempt to hook the user for I/O */ + FOREACH_MOD_I(Instance, I_OnHookUserIO, OnHookUserIO(New)); + + if (New->io) + { + try + { + New->io->OnRawSocketAccept(socket, ipaddr, port); + } + catch (CoreException& modexcept) + { + ServerInstance->Logs->Log("SOCKET", DEBUG,"%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason()); + } + } + + Instance->Logs->Log("USERS", DEBUG,"New user fd: %d", socket); + + int j = 0; + + this->unregistered_count++; (*(this->clientlist))[New->uuid] = New; diff --git a/src/userprocess.cpp b/src/userprocess.cpp index 62cd452cd..c2de4dc2b 100644 --- a/src/userprocess.cpp +++ b/src/userprocess.cpp @@ -46,14 +46,14 @@ void ProcessUserHandler::Call(User* cu) char* ReadBuffer = Server->GetReadBuffer(); - if (Server->Config->GetIOHook(cu->GetPort())) + if (cu->io) { int result2 = 0; int MOD_RESULT = 0; try { - MOD_RESULT = Server->Config->GetIOHook(cu->GetPort())->OnRawSocketRead(cu->GetFd(),ReadBuffer,Server->Config->NetBufferSize,result2); + MOD_RESULT = cu->io->OnRawSocketRead(cu->GetFd(),ReadBuffer,Server->Config->NetBufferSize,result2); } catch (CoreException& modexcept) { diff --git a/src/users.cpp b/src/users.cpp index 46665396f..f8a95af49 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -193,6 +193,7 @@ User::User(InspIRCd* Instance, const std::string &uid) : ServerInstance(Instance Visibility = NULL; ip = NULL; MyClass = NULL; + io = NULL; AllowedUserModes = NULL; AllowedChanModes = NULL; AllowedOperCommands = NULL; @@ -1165,14 +1166,14 @@ void User::Write(std::string text) return; } - if (ServerInstance->Config->GetIOHook(this->GetPort())) + if (this->io) { /* XXX: The lack of buffering here is NOT a bug, modules implementing this interface have to * implement their own buffering mechanisms */ try { - ServerInstance->Config->GetIOHook(this->GetPort())->OnRawSocketWrite(this->fd, text.data(), text.length()); + this->io->OnRawSocketWrite(this->fd, text.data(), text.length()); } catch (CoreException& modexcept) { -- cgit v1.2.3