summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2008-03-24 15:13:17 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2008-03-24 15:13:17 +0000
commit343f12b9b2d4e519b09877f76a00f6a0714509f2 (patch)
treeb51aee0ca78a19fd356cdc2788cab4530c7928c1
parent638381c529a2f19c699718234d689e54ad459c97 (diff)
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
-rw-r--r--include/modules.h4
-rw-r--r--include/users.h4
-rw-r--r--src/cull_list.cpp4
-rw-r--r--src/modules.cpp1
-rw-r--r--src/modules/extra/m_ssl_gnutls.cpp27
-rw-r--r--src/modules/extra/m_ssl_openssl.cpp15
-rw-r--r--src/socket.cpp11
-rw-r--r--src/usermanager.cpp30
-rw-r--r--src/userprocess.cpp4
-rw-r--r--src/users.cpp5
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 &param)
@@ -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)
{