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