From 99f79a4e5c3abbe91a03216824e7659051872054 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Tue, 24 Sep 2013 20:40:20 +0200 Subject: Split IOHook into IOHook and IOHookProvider Create one IOHook instance for each hooked socket which contains all the hook specific data and read/write/close functions, removing the need for the "issl_session" array in SSL modules. Register instances of the IOHookProvider class in the core and use them to create specialized IOHook instances (OnConnect/OnAccept). Remove the OnHookIO hook, add a dynamic reference to ListenSocket that points to the hook provider (if any) to use for incoming connections on that socket. For outgoing connections modules still have to find the IOHookProvider they want to use themselves but instead of calling AddIOHook(hookprov), now they have to call IOHookProvider::OnConnect() after the connection has been established. --- include/iohook.h | 34 ++++++++++++++++++++++------------ include/modules.h | 8 +------- include/modules/ssl.h | 30 ++++++++++++++++++------------ include/socket.h | 13 +++++++++++++ 4 files changed, 54 insertions(+), 31 deletions(-) (limited to 'include') diff --git a/include/iohook.h b/include/iohook.h index 7c3a0faee..ce7ca2a1b 100644 --- a/include/iohook.h +++ b/include/iohook.h @@ -21,7 +21,7 @@ class StreamSocket; -class IOHook : public ServiceProvider +class IOHookProvider : public ServiceProvider { public: enum Type @@ -32,19 +32,35 @@ class IOHook : public ServiceProvider const Type type; - IOHook(Module* mod, const std::string& Name, Type hooktype = IOH_UNKNOWN) + IOHookProvider(Module* mod, const std::string& Name, Type hooktype = IOH_UNKNOWN) : ServiceProvider(mod, Name, SERVICE_IOHOOK), type(hooktype) { } - /** Called immediately after any connection is accepted. This is intended for raw socket + /** Called immediately after a 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. - * There are no return values from this call as all modules get an opportunity if required to - * process the connection. * @param sock The socket in question * @param client The client IP address and port * @param server The server IP address and port */ - virtual void OnStreamSocketAccept(StreamSocket* sock, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) = 0; + virtual void OnAccept(StreamSocket* sock, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) = 0; + + /** Called immediately upon connection of an outbound BufferedSocket which has been hooked + * by a module. + * @param sock The socket in question + */ + virtual void OnConnect(StreamSocket* sock) = 0; +}; + +class IOHook : public classbase +{ + public: + /** The IOHookProvider for this hook, contains information about the hook, + * such as the module providing it and the hook type. + */ + IOHookProvider* const prov; + + IOHook(IOHookProvider* provider) + : prov(provider) { } /** * Called when a hooked stream has data to write, or when the socket @@ -62,12 +78,6 @@ class IOHook : public ServiceProvider */ virtual void OnStreamSocketClose(StreamSocket* sock) = 0; - /** Called immediately upon connection of an outbound BufferedSocket which has been hooked - * by a module. - * @param sock The socket in question - */ - virtual void OnStreamSocketConnect(StreamSocket* sock) = 0; - /** * Called when the stream socket has data to read * @param sock The socket that is ready diff --git a/include/modules.h b/include/modules.h index 0be1ea294..7223f6b9d 100644 --- a/include/modules.h +++ b/include/modules.h @@ -264,7 +264,7 @@ enum Implementation I_OnChangeLocalUserGECOS, I_OnUserRegister, I_OnChannelPreDelete, I_OnChannelDelete, I_OnPostOper, I_OnSyncNetwork, I_OnSetAway, I_OnPostCommand, I_OnPostJoin, I_OnWhoisLine, I_OnBuildNeighborList, I_OnGarbageCollect, I_OnSetConnectClass, - I_OnText, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem, I_OnNumeric, I_OnHookIO, + I_OnText, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem, I_OnNumeric, I_OnPreRehash, I_OnModuleRehash, I_OnSendWhoLine, I_OnChangeIdent, I_OnSetUserIP, I_END }; @@ -989,12 +989,6 @@ class CoreExport Module : public classbase, public usecountbase */ virtual void OnPostConnect(User* user); - /** Called to install an I/O hook on an event handler - * @param user The socket to possibly install the I/O hook on - * @param via The port that the user connected on - */ - virtual void OnHookIO(StreamSocket* user, ListenSocket* via); - /** Called when a port accepts a connection * Return MOD_RES_ACCEPT if you have used the file descriptor. * @param fd The file descriptor returned from accept() diff --git a/include/modules/ssl.h b/include/modules/ssl.h index 25076215a..0f58e0b7b 100644 --- a/include/modules/ssl.h +++ b/include/modules/ssl.h @@ -133,28 +133,34 @@ class ssl_cert : public refcountbase class SSLIOHook : public IOHook { + protected: + /** Peer SSL certificate, set by the SSL module + */ + reference certificate; + public: - SSLIOHook(Module* mod, const std::string& Name) - : IOHook(mod, Name, IOHook::IOH_SSL) + SSLIOHook(IOHookProvider* hookprov) + : IOHook(hookprov) { } /** - * Get the client certificate from a socket - * @param sock The socket to get the certificate from, must be using this IOHook - * @return The SSL client certificate information + * Get the certificate sent by this peer + * @return The SSL certificate sent by the peer, NULL if no cert was sent */ - virtual ssl_cert* GetCertificate(StreamSocket* sock) = 0; + ssl_cert* GetCertificate() const + { + return certificate; + } /** - * Get the fingerprint of a client certificate from a socket - * @param sock The socket to get the certificate fingerprint from, must be using this IOHook + * Get the fingerprint of the peer's certificate * @return The fingerprint of the SSL client certificate sent by the peer, * empty if no cert was sent */ - std::string GetFingerprint(StreamSocket* sock) + std::string GetFingerprint() const { - ssl_cert* cert = GetCertificate(sock); + ssl_cert* cert = GetCertificate(); if (cert) return cert->GetFingerprint(); return ""; @@ -175,11 +181,11 @@ class SSLClientCert static ssl_cert* GetCertificate(StreamSocket* sock) { IOHook* iohook = sock->GetIOHook(); - if ((!iohook) || (iohook->type != IOHook::IOH_SSL)) + if ((!iohook) || (iohook->prov->type != IOHookProvider::IOH_SSL)) return NULL; SSLIOHook* ssliohook = static_cast(iohook); - return ssliohook->GetCertificate(sock); + return ssliohook->GetCertificate(); } /** diff --git a/include/socket.h b/include/socket.h index c54517a76..c292b7010 100644 --- a/include/socket.h +++ b/include/socket.h @@ -127,6 +127,7 @@ namespace irc } } +#include "iohook.h" #include "socketengine.h" /** This class handles incoming connections on client ports. * It will create a new User for every valid connection @@ -140,6 +141,12 @@ class CoreExport ListenSocket : public EventHandler int bind_port; /** Human-readable bind description */ std::string bind_desc; + + /** The IOHook provider which handles connections on this socket, + * NULL if there is none. + */ + dynamic_reference_nocheck iohookprov; + /** Create a new listening socket */ ListenSocket(ConfigTag* tag, const irc::sockets::sockaddrs& bind_to); @@ -153,4 +160,10 @@ class CoreExport ListenSocket : public EventHandler /** Handles sockets internals crap of a connection, convenience wrapper really */ void AcceptInternal(); + + /** Inspects the bind block belonging to this socket to set the name of the IO hook + * provider which this socket will use for incoming connections. + * @return True if the IO hook provider was found or none was given, false otherwise. + */ + bool ResetIOHookProvider(); }; -- cgit v1.2.3