]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/iohook.h
Fix RPL_ADMINME not having the correct parameters.
[user/henk/code/inspircd.git] / include / iohook.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2013 Attila Molnar <attilamolnar@hush.com>
5  *
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.
9  *
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
13  * details.
14  *
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/>.
17  */
18
19
20 #pragma once
21
22 class StreamSocket;
23
24 class IOHookProvider : public refcountbase, public ServiceProvider
25 {
26         const bool middlehook;
27
28  public:
29         enum Type
30         {
31                 IOH_UNKNOWN,
32                 IOH_SSL
33         };
34
35         const Type type;
36
37         /** Constructor
38          * @param mod Module that owns the IOHookProvider
39          * @param Name Name of the provider
40          * @param hooktype One of IOHookProvider::Type
41          * @param middle True if the IOHook instances created by this hook are subclasses of IOHookMiddle, false otherwise
42          */
43         IOHookProvider(Module* mod, const std::string& Name, Type hooktype = IOH_UNKNOWN, bool middle = false)
44                 : ServiceProvider(mod, Name, SERVICE_IOHOOK), middlehook(middle), type(hooktype) { }
45
46         /** Check if the IOHook provided can appear in the non-last position of a hook chain.
47          * That is the case if and only if the IOHook instances created are subclasses of IOHookMiddle.
48          * @return True if the IOHooks provided are subclasses of IOHookMiddle
49          */
50         bool IsMiddle() const { return middlehook; }
51
52         /** Called when the provider should hook an incoming connection and act as being on the server side of the connection.
53          * This occurs when a bind block has a hook configured and the listener accepts a connection.
54          * @param sock Socket to hook
55          * @param client Client IP address and port
56          * @param server Server IP address and port
57          */
58         virtual void OnAccept(StreamSocket* sock, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) = 0;
59
60         /** Called when the provider should hook an outgoing connection and act as being on the client side of the connection.
61          * @param sock Socket to hook
62          */
63         virtual void OnConnect(StreamSocket* sock) = 0;
64 };
65
66 class IOHook : public classbase
67 {
68  public:
69         /** The IOHookProvider for this hook, contains information about the hook,
70          * such as the module providing it and the hook type.
71          */
72         reference<IOHookProvider> prov;
73
74         /** Constructor
75          * @param provider IOHookProvider that creates this object
76          */
77         IOHook(IOHookProvider* provider)
78                 : prov(provider) { }
79
80         /**
81          * Called when the hooked socket has data to write, or when the socket engine returns it as writable
82          * @param sock Hooked socket
83          * @param sendq Send queue to send data from
84          * @return 1 if the sendq has been completely emptied, 0 if there is
85          *  still data to send, and -1 if there was an error
86          */
87         virtual int OnStreamSocketWrite(StreamSocket* sock, StreamSocket::SendQueue& sendq) = 0;
88
89         /** Called immediately before the hooked socket is closed. When this event is called, shutdown()
90          * has not yet been called on the socket.
91          * @param sock Hooked socket
92          */
93         virtual void OnStreamSocketClose(StreamSocket* sock) = 0;
94
95         /**
96          * Called when the hooked socket has data to read
97          * @param sock Hooked socket
98          * @param recvq The receive queue that new data should be appended to
99          * @return 1 if new data has been read, 0 if no new data is ready (but the
100          *  socket is still connected), -1 if there was an error or close
101          */
102         virtual int OnStreamSocketRead(StreamSocket* sock, std::string& recvq) = 0;
103 };
104
105 class IOHookMiddle : public IOHook
106 {
107         /** Data already processed by the IOHook waiting to go down the chain
108          */
109         StreamSocket::SendQueue sendq;
110
111         /** Data waiting to go up the chain
112          */
113         std::string precvq;
114
115         /** Next IOHook in the chain
116          */
117         IOHook* nexthook;
118
119  protected:
120         /** Get all queued up data which has not yet been passed up the hook chain
121          * @return RecvQ containing the data
122          */
123         std::string& GetRecvQ() { return precvq; }
124
125         /** Get all queued up data which is ready to go down the hook chain
126          * @return SendQueue containing all data waiting to go down the hook chain
127          */
128         StreamSocket::SendQueue& GetSendQ() { return sendq; }
129
130  public:
131         /** Constructor
132          * @param provider IOHookProvider that creates this object
133          */
134         IOHookMiddle(IOHookProvider* provider)
135                 : IOHook(provider)
136                 , nexthook(NULL)
137         {
138         }
139
140         /** Get all queued up data which is ready to go down the hook chain
141          * @return SendQueue containing all data waiting to go down the hook chain
142          */
143         const StreamSocket::SendQueue& GetSendQ() const { return sendq; }
144
145         /** Get the next IOHook in the chain
146          * @return Next hook in the chain or NULL if this is the last hook
147          */
148         IOHook* GetNextHook() const { return nexthook; }
149
150         /** Set the next hook in the chain
151          * @param hook Hook to set as the next hook in the chain
152          */
153         void SetNextHook(IOHook* hook) { nexthook = hook; }
154
155         /** 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.
156          * @param hook IOHook to check
157          * @return IOHookMiddle referring to the same hook or NULL
158          */
159         static IOHookMiddle* ToMiddleHook(IOHook* hook)
160         {
161                 if (hook->prov->IsMiddle())
162                         return static_cast<IOHookMiddle*>(hook);
163                 return NULL;
164         }
165
166         friend class StreamSocket;
167 };