2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2013 Attila Molnar <attilamolnar@hush.com>
6 * This file is part of InspIRCd. InspIRCd is free software: you can
7 * redistribute it and/or modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation, version 2.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 class IOHookProvider : public ServiceProvider
26 const bool middlehook;
37 IOHookProvider(Module* mod, const std::string& Name, Type hooktype = IOH_UNKNOWN, bool middle = false)
38 : ServiceProvider(mod, Name, SERVICE_IOHOOK), middlehook(middle), type(hooktype) { }
40 /** Check if the IOHook provided can appear in the non-last position of a hook chain.
41 * That is the case if and only if the IOHook instances created are subclasses of IOHookMiddle.
42 * @return True if the IOHooks provided are subclasses of IOHookMiddle
44 bool IsMiddle() const { return middlehook; }
46 /** Called immediately after a connection is accepted. This is intended for raw socket
47 * processing (e.g. modules which wrap the tcp connection within another library) and provides
48 * no information relating to a user record as the connection has not been assigned yet.
49 * @param sock The socket in question
50 * @param client The client IP address and port
51 * @param server The server IP address and port
53 virtual void OnAccept(StreamSocket* sock, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) = 0;
55 /** Called immediately upon connection of an outbound BufferedSocket which has been hooked
57 * @param sock The socket in question
59 virtual void OnConnect(StreamSocket* sock) = 0;
62 class IOHook : public classbase
65 /** The IOHookProvider for this hook, contains information about the hook,
66 * such as the module providing it and the hook type.
68 IOHookProvider* const prov;
70 IOHook(IOHookProvider* provider)
74 * Called when a hooked stream has data to write, or when the socket
75 * engine returns it as writable
76 * @param sock The socket in question
77 * @param sendq Send queue to send data from
78 * @return 1 if the sendq has been completely emptied, 0 if there is
79 * still data to send, and -1 if there was an error
81 virtual int OnStreamSocketWrite(StreamSocket* sock, StreamSocket::SendQueue& sendq) = 0;
83 /** Called immediately before any socket is closed. When this event is called, shutdown()
84 * has not yet been called on the socket.
85 * @param sock The socket in question
87 virtual void OnStreamSocketClose(StreamSocket* sock) = 0;
90 * Called when the stream socket has data to read
91 * @param sock The socket that is ready
92 * @param recvq The receive queue that new data should be appended to
93 * @return 1 if new data has been read, 0 if no new data is ready (but the
94 * socket is still connected), -1 if there was an error or close
96 virtual int OnStreamSocketRead(StreamSocket* sock, std::string& recvq) = 0;
99 class IOHookMiddle : public IOHook
101 /** Data already processed by the IOHook waiting to go down the chain
103 StreamSocket::SendQueue sendq;
105 /** Data waiting to go up the chain
109 /** Next IOHook in the chain
114 /** Get all queued up data which has not yet been passed up the hook chain
115 * @return RecvQ containing the data
117 std::string& GetRecvQ() { return precvq; }
119 /** Get all queued up data which is ready to go down the hook chain
120 * @return SendQueue containing all data waiting to go down the hook chain
122 StreamSocket::SendQueue& GetSendQ() { return sendq; }
126 * @param provider IOHookProvider that creates this object
128 IOHookMiddle(IOHookProvider* provider)
134 /** Get all queued up data which is ready to go down the hook chain
135 * @return SendQueue containing all data waiting to go down the hook chain
137 const StreamSocket::SendQueue& GetSendQ() const { return sendq; }
139 /** Get the next IOHook in the chain
140 * @return Next hook in the chain or NULL if this is the last hook
142 IOHook* GetNextHook() const { return nexthook; }
144 /** Set the next hook in the chain
145 * @param hook Hook to set as the next hook in the chain
147 void SetNextHook(IOHook* hook) { nexthook = hook; }
149 /** Check if a hook is capable of being the non-last hook in a hook chain and if so, cast it to an IOHookMiddle object.
150 * @param hook IOHook to check
151 * @return IOHookMiddle referring to the same hook or NULL
153 static IOHookMiddle* ToMiddleHook(IOHook* hook)
155 if (hook->prov->IsMiddle())
156 return static_cast<IOHookMiddle*>(hook);
160 friend class StreamSocket;