]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/inspsocket.h
Fix some of the include guard names (requested by SaberUK)
[user/henk/code/inspircd.git] / include / inspsocket.h
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2010 InspIRCd Development Team
6  * See: http://wiki.inspircd.org/Credits
7  *
8  * This program is free but copyrighted software; see
9  *          the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #ifndef INSPSOCKET_H
15 #define INSPSOCKET_H
16
17 #include "timer.h"
18
19 /**
20  * States which a socket may be in
21  */
22 enum BufferedSocketState
23 {
24         /** Socket disconnected */
25         I_DISCONNECTED,
26         /** Socket connecting */
27         I_CONNECTING,
28         /** Socket fully connected */
29         I_CONNECTED,
30         /** Socket has an error */
31         I_ERROR
32 };
33
34 /**
35  * Error types which a socket may exhibit
36  */
37 enum BufferedSocketError
38 {
39         /** No error */
40         I_ERR_NONE,
41         /** Socket was closed by peer */
42         I_ERR_DISCONNECT,
43         /** Socket connect timed out */
44         I_ERR_TIMEOUT,
45         /** Socket could not be created */
46         I_ERR_SOCKET,
47         /** Socket could not connect (refused) */
48         I_ERR_CONNECT,
49         /** Socket could not bind to local port/ip */
50         I_ERR_BIND,
51         /** Socket could not write data */
52         I_ERR_WRITE,
53         /** No more file descriptors left to create socket! */
54         I_ERR_NOMOREFDS,
55         /** Some other error */
56         I_ERR_OTHER
57 };
58
59 /* Required forward declarations */
60 class BufferedSocket;
61
62 /** Used to time out socket connections
63  */
64 class CoreExport SocketTimeout : public Timer
65 {
66  private:
67         /** BufferedSocket the class is attached to
68          */
69         BufferedSocket* sock;
70
71         /** File descriptor of class this is attached to
72          */
73         int sfd;
74
75  public:
76         /** Create a socket timeout class
77          * @param fd File descriptor of BufferedSocket
78          * @pram Instance server instance to attach to
79          * @param thesock BufferedSocket to attach to
80          * @param secs_from_now Seconds from now to time out
81          * @param now The current time
82          */
83         SocketTimeout(int fd, BufferedSocket* thesock, long secs_from_now, time_t now) : Timer(secs_from_now, now), sock(thesock), sfd(fd) { }
84
85         /** Handle tick event
86          */
87         virtual void Tick(time_t now);
88 };
89
90 /**
91  * StreamSocket is a class that wraps a TCP socket and handles send
92  * and receive queues, including passing them to IO hooks
93  */
94 class CoreExport StreamSocket : public EventHandler
95 {
96         /** Module that handles raw I/O for this socket, or NULL */
97         reference<Module> IOHook;
98         /** Private send queue. Note that individual strings may be shared
99          */
100         std::deque<std::string> sendq;
101         /** Length, in bytes, of the sendq */
102         size_t sendq_len;
103         /** Error - if nonempty, the socket is dead, and this is the reason. */
104         std::string error;
105  protected:
106         std::string recvq;
107  public:
108         StreamSocket() : sendq_len(0) {}
109         inline Module* GetIOHook();
110         inline void AddIOHook(Module* m);
111         inline void DelIOHook();
112         /** Handle event from socket engine.
113          * This will call OnDataReady if there is *new* data in recvq
114          */
115         virtual void HandleEvent(EventType et, int errornum = 0);
116         /** Dispatched from HandleEvent */
117         virtual void DoRead();
118         /** Dispatched from HandleEvent */
119         virtual void DoWrite();
120
121         /** Sets the error message for this socket. Once set, the socket is dead. */
122         void SetError(const std::string& err) { if (error.empty()) error = err; }
123
124         /** Gets the error message for this socket. */
125         const std::string& getError() const { return error; }
126
127         /** Called when new data is present in recvq */
128         virtual void OnDataReady() = 0;
129         /** Called when the socket gets an error from socket engine or IO hook */
130         virtual void OnError(BufferedSocketError e) = 0;
131
132         /** Send the given data out the socket, either now or when writes unblock
133          */
134         void WriteData(const std::string& data);
135         /** Convenience function: read a line from the socket
136          * @param line The line read
137          * @param delim The line delimiter
138          * @return true if a line was read
139          */
140         bool GetNextLine(std::string& line, char delim = '\n');
141         /** Useful for implementing sendq exceeded */
142         inline const size_t getSendQSize() const { return sendq_len; }
143
144         /**
145          * Close the socket, remove from socket engine, etc
146          */
147         virtual void Close();
148         /** This ensures that close is called prior to destructor */
149         virtual CullResult cull();
150 };
151 /**
152  * BufferedSocket is an extendable socket class which modules
153  * can use for TCP socket support. It is fully integrated
154  * into InspIRCds socket loop and attaches its sockets to
155  * the core's instance of the SocketEngine class, meaning
156  * that all use is fully asynchronous.
157  *
158  * To use BufferedSocket, you must inherit a class from it.
159  */
160 class CoreExport BufferedSocket : public StreamSocket
161 {
162  public:
163         /** Timeout object or NULL
164          */
165         SocketTimeout* Timeout;
166
167         /**
168          * The state for this socket, either
169          * listening, connecting, connected
170          * or error.
171          */
172         BufferedSocketState state;
173
174         BufferedSocket();
175         /**
176          * This constructor is used to associate
177          * an existing connecting with an BufferedSocket
178          * class. The given file descriptor must be
179          * valid, and when initialized, the BufferedSocket
180          * will be placed in CONNECTED state.
181          */
182         BufferedSocket(int newfd);
183
184         /** Begin connection to the given address
185          * This will create a socket, register with socket engine, and start the asynchronous
186          * connection process. If an error is detected at this point (such as out of file descriptors),
187          * OnError will be called; otherwise, the state will become CONNECTING.
188          * @param dest Address to connect to
189          * @param bind Address to bind to (if NULL, no bind will be done)
190          * @param timeout Time to wait for connection
191          */
192         void DoConnect(const std::string &ipaddr, int aport, unsigned long maxtime, const std::string &connectbindip);
193
194         /** This method is called when an outbound connection on your socket is
195          * completed.
196          */
197         virtual void OnConnected();
198
199         /** When there is data waiting to be read on a socket, the OnDataReady()
200          * method is called.
201          */
202         virtual void OnDataReady() = 0;
203
204         /**
205          * When an outbound connection fails, and the attempt times out, you
206          * will receive this event.  The method will trigger once maxtime
207          * seconds are reached (as given in the constructor) just before the
208          * socket's descriptor is closed.  A failed DNS lookup may cause this
209          * event if the DNS server is not responding, as well as a failed
210          * connect() call, because DNS lookups are nonblocking as implemented by
211          * this class.
212          */
213         virtual void OnTimeout();
214
215         virtual ~BufferedSocket();
216  protected:
217         virtual void DoWrite();
218         BufferedSocketError BeginConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned long timeout);
219         BufferedSocketError BeginConnect(const std::string &ipaddr, int aport, unsigned long maxtime, const std::string &connectbindip);
220 };
221
222 #include "modules.h"
223
224 inline Module* StreamSocket::GetIOHook() { return IOHook; }
225 inline void StreamSocket::AddIOHook(Module* m) { IOHook = m; }
226 inline void StreamSocket::DelIOHook() { IOHook = NULL; }
227 #endif