]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/socketengine.h
Update copyright headers.
[user/henk/code/inspircd.git] / include / socketengine.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2013-2016 Attila Molnar <attilamolnar@hush.com>
5  *   Copyright (C) 2013-2014 Adam <Adam@anope.org>
6  *   Copyright (C) 2012-2013, 2017-2020 Sadie Powell <sadie@witchery.services>
7  *   Copyright (C) 2012 Robby <robby@chatbelgie.be>
8  *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
9  *   Copyright (C) 2009 Uli Schlachter <psychon@inspircd.org>
10  *   Copyright (C) 2007-2008, 2017 Robin Burchell <robin+git@viroteck.net>
11  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
12  *   Copyright (C) 2005-2008 Craig Edwards <brain@inspircd.org>
13  *
14  * This file is part of InspIRCd.  InspIRCd is free software: you can
15  * redistribute it and/or modify it under the terms of the GNU General Public
16  * License as published by the Free Software Foundation, version 2.
17  *
18  * This program is distributed in the hope that it will be useful, but WITHOUT
19  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
21  * details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
25  */
26
27
28 #pragma once
29
30 #include <vector>
31 #include <string>
32 #include <map>
33 #include "config.h"
34 #include "socket.h"
35 #include "base.h"
36
37 #ifndef _WIN32
38 #include <sys/uio.h>
39 #endif
40
41 #ifndef IOV_MAX
42 #define IOV_MAX 1024
43 #endif
44
45 /**
46  * Event mask for SocketEngine events
47  */
48 enum EventMask
49 {
50         /** Do not test this socket for readability
51          */
52         FD_WANT_NO_READ = 0x1,
53         /** Give a read event at all times when reads will not block.
54          */
55         FD_WANT_POLL_READ = 0x2,
56         /** Give a read event when there is new data to read.
57          *
58          * An event MUST be sent if there is new data to be read, and the most
59          * recent read/recv() on this FD returned EAGAIN. An event MAY be sent
60          * at any time there is data to be read on the socket.
61          */
62         FD_WANT_FAST_READ = 0x4,
63         /** Give an optional read event when reads begin to unblock
64          *
65          * This state is useful if you want to leave data in the OS receive
66          * queue but not get continuous event notifications about it, because
67          * it may not require a system call to transition from FD_WANT_FAST_READ
68          */
69         FD_WANT_EDGE_READ = 0x8,
70
71         /** Mask for all read events */
72         FD_WANT_READ_MASK = 0x0F,
73
74         /** Do not test this socket for writeability
75          */
76         FD_WANT_NO_WRITE = 0x10,
77         /** Give a write event at all times when writes will not block.
78          *
79          * You probably shouldn't use this state; if it's likely that the write
80          * will not block, try it first, then use FD_WANT_FAST_WRITE if it
81          * fails. If it's likely to block (or you are using polling-style reads)
82          * then use FD_WANT_SINGLE_WRITE.
83          */
84         FD_WANT_POLL_WRITE = 0x20,
85         /** Give a write event when writes don't block any more
86          *
87          * An event MUST be sent if writes will not block, and the most recent
88          * write/send() on this FD returned EAGAIN, or connect() returned
89          * EINPROGRESS. An event MAY be sent at any time that writes will not
90          * block.
91          *
92          * Before calling OnEventHandler*(), a socket engine MAY change the state of
93          * the FD back to FD_WANT_EDGE_WRITE if it is simpler (for example, if a
94          * one-shot notification was registered). If further writes are needed,
95          * it is the responsibility of the event handler to change the state to
96          * one that will generate the required notifications
97          */
98         FD_WANT_FAST_WRITE = 0x40,
99         /** Give an optional write event on edge-triggered write unblock.
100          *
101          * This state is useful to avoid system calls when moving to/from
102          * FD_WANT_FAST_WRITE when writing data to a mostly-unblocked socket.
103          */
104         FD_WANT_EDGE_WRITE = 0x80,
105         /** Request a one-shot poll-style write notification. The socket will
106          * return to the FD_WANT_NO_WRITE state before OnEventHandler*() is called.
107          */
108         FD_WANT_SINGLE_WRITE = 0x100,
109
110         /** Mask for all write events */
111         FD_WANT_WRITE_MASK = 0x1F0,
112
113         /** Add a trial read. During the next DispatchEvents invocation, this
114          * will call OnEventHandlerRead() unless reads are known to be
115          * blocking.
116          */
117         FD_ADD_TRIAL_READ  = 0x1000,
118         /** Assert that reads are known to block. This cancels FD_ADD_TRIAL_READ.
119          * Reset by SE before running OnEventHandlerRead().
120          */
121         FD_READ_WILL_BLOCK = 0x2000,
122
123         /** Add a trial write. During the next DispatchEvents invocation, this
124          * will call OnEventHandlerWrite() unless writes are known to be
125          * blocking.
126          *
127          * This could be used to group several writes together into a single
128          * send() syscall, or to ensure that writes are blocking when attempting
129          * to use FD_WANT_FAST_WRITE.
130          */
131         FD_ADD_TRIAL_WRITE = 0x4000,
132         /** Assert that writes are known to block. This cancels FD_ADD_TRIAL_WRITE.
133          * Reset by SE before running OnEventHandlerWrite().
134          */
135         FD_WRITE_WILL_BLOCK = 0x8000,
136
137         /** Mask for trial read/trial write */
138         FD_TRIAL_NOTE_MASK = 0x5000
139 };
140
141 /** This class is a basic I/O handler class.
142  * Any object which wishes to receive basic I/O events
143  * from the socketengine must derive from this class and
144  * implement the OnEventHandler*() methods. The derived class
145  * must then be added to SocketEngine using the method
146  * SocketEngine::AddFd(), after which point the derived
147  * class will receive events to its OnEventHandler*() methods.
148  * The event mask passed to SocketEngine::AddFd() determines
149  * what events the EventHandler gets notified about and with
150  * what semantics. SocketEngine::ChangeEventMask() can be
151  * called to update the event mask later. The only
152  * requirement beyond this for an event handler is that it
153  * must have a file descriptor. What this file descriptor
154  * is actually attached to is completely up to you.
155  */
156 class CoreExport EventHandler : public classbase
157 {
158  private:
159         /** Private state maintained by socket engine */
160         int event_mask;
161
162         void SetEventMask(int mask) { event_mask = mask; }
163
164  protected:
165         /** File descriptor.
166          * All events which can be handled must have a file descriptor.  This
167          * allows you to add events for sockets, fifo's, pipes, and various
168          * other forms of IPC.  Do not change this while the object is
169          * registered with the SocketEngine
170          */
171         int fd;
172
173         /** Swaps the internals of this EventHandler with another one.
174          * @param other A EventHandler to swap internals with.
175          */
176         void SwapInternals(EventHandler& other);
177
178  public:
179         /** Get the current file descriptor
180          * @return The file descriptor of this handler
181          */
182         inline int GetFd() const { return fd; }
183
184         /** Checks if this event handler has a fd associated with it. */
185         inline bool HasFd() const { return fd >= 0; }
186
187         inline int GetEventMask() const { return event_mask; }
188
189         /** Set a new file descriptor
190          * @param FD The new file descriptor. Do not call this method without
191          * first deleting the object from the SocketEngine if you have
192          * added it to a SocketEngine instance.
193          */
194         void SetFd(int FD);
195
196         /** Constructor
197          */
198         EventHandler();
199
200         /** Destructor
201          */
202         virtual ~EventHandler() {}
203
204         /** Called by the socket engine in case of a read event
205          */
206         virtual void OnEventHandlerRead() = 0;
207
208         /** Called by the socket engine in case of a write event.
209          * The default implementation does nothing.
210          */
211         virtual void OnEventHandlerWrite();
212
213         /** Called by the socket engine in case of an error event.
214          * The default implementation does nothing.
215          * @param errornum Error code
216          */
217         virtual void OnEventHandlerError(int errornum);
218
219         friend class SocketEngine;
220 };
221
222 /** Provides basic file-descriptor-based I/O support.
223  * The actual socketengine class presents the
224  * same interface on all operating systems, but
225  * its private members and internal behaviour
226  * should be treated as blackboxed, and vary
227  * from system to system and upon the config
228  * settings chosen by the server admin.
229  */
230 class CoreExport SocketEngine
231 {
232  public:
233         /** Socket engine statistics: count of various events, bandwidth usage
234          */
235         class Statistics
236         {
237                 mutable size_t indata;
238                 mutable size_t outdata;
239                 mutable time_t lastempty;
240
241                 /** Reset the byte counters and lastempty if there wasn't a reset in this second.
242                  */
243                 void CheckFlush() const;
244
245          public:
246                 /** Constructor, initializes member vars except indata and outdata because those are set to 0
247                  * in CheckFlush() the first time Update() or GetBandwidth() is called.
248                  */
249                 Statistics() : lastempty(0), TotalEvents(0), ReadEvents(0), WriteEvents(0), ErrorEvents(0) { }
250
251                 /** Update counters for network data received.
252                  * This should be called after every read-type syscall.
253                  * @param len_in Number of bytes received, or -1 for error, as typically
254                  * returned by a read-style syscall.
255                  */
256                 void UpdateReadCounters(int len_in);
257
258                 /** Update counters for network data sent.
259                  * This should be called after every write-type syscall.
260                  * @param len_out Number of bytes sent, or -1 for error, as typically
261                  * returned by a read-style syscall.
262                  */
263                 void UpdateWriteCounters(int len_out);
264
265                 /** Get data transfer statistics.
266                  * @param kbitpersec_in Filled with incoming traffic in this second in kbit/s.
267                  * @param kbitpersec_out Filled with outgoing traffic in this second in kbit/s.
268                  * @param kbitpersec_total Filled with total traffic in this second in kbit/s.
269                  */
270                 void CoreExport GetBandwidth(float& kbitpersec_in, float& kbitpersec_out, float& kbitpersec_total) const;
271
272                 unsigned long TotalEvents;
273                 unsigned long ReadEvents;
274                 unsigned long WriteEvents;
275                 unsigned long ErrorEvents;
276         };
277
278  private:
279         /** Reference table, contains all current handlers
280          **/
281         static std::vector<EventHandler*> ref;
282
283         /** Current number of descriptors in the engine. */
284         static size_t CurrentSetSize;
285
286         /** The maximum number of descriptors in the engine. */
287         static size_t MaxSetSize;
288
289         /** List of handlers that want a trial read/write
290          */
291         static std::set<int> trials;
292
293         /** Socket engine statistics: count of various events, bandwidth usage
294          */
295         static Statistics stats;
296
297         /** Look up the fd limit using rlimit. */
298         static void LookupMaxFds();
299
300         /** Terminates the program when the socket engine fails to initialize. */
301         static void InitError();
302
303         static void OnSetEvent(EventHandler* eh, int old_mask, int new_mask);
304
305         /** Add an event handler to the base socket engine. AddFd(EventHandler*, int) should call this.
306          */
307         static bool AddFdRef(EventHandler* eh);
308
309         static void DelFdRef(EventHandler* eh);
310
311         template <typename T>
312         static void ResizeDouble(std::vector<T>& vect)
313         {
314                 if (SocketEngine::CurrentSetSize > vect.size())
315                         vect.resize(SocketEngine::CurrentSetSize * 2);
316         }
317
318 public:
319 #ifndef _WIN32
320         typedef iovec IOVector;
321 #else
322         typedef WindowsIOVec IOVector;
323 #endif
324
325         /** Constructor.
326          * The constructor transparently initializes
327          * the socket engine which the ircd is using.
328          * Please note that if there is a catastrophic
329          * failure (for example, you try and enable
330          * epoll on a 2.4 linux kernel) then this
331          * function may bail back to the shell.
332          * @return void, but it is acceptable for this function to bail back to
333          * the shell or operating system on fatal error.
334          */
335         static void Init();
336
337         /** Destructor.
338          * The destructor transparently tidies up
339          * any resources used by the socket engine.
340          */
341         static void Deinit();
342
343         /** Add an EventHandler object to the engine.  Use AddFd to add a file
344          * descriptor to the engine and have the socket engine monitor it. You
345          * must provide an object derived from EventHandler which implements
346          * the required OnEventHandler*() methods.
347          * @param eh An event handling object to add
348          * @param event_mask The initial event mask for the object
349          */
350         static bool AddFd(EventHandler* eh, int event_mask);
351
352         /** If you call this function and pass it an
353          * event handler, that event handler will
354          * receive the next available write event,
355          * even if the socket is a readable socket only.
356          * Developers should avoid constantly keeping
357          * an eventhandler in the writeable state,
358          * as this will consume large amounts of
359          * CPU time.
360          * @param eh The event handler to change
361          * @param event_mask The changes to make to the wait state
362          */
363         static void ChangeEventMask(EventHandler* eh, int event_mask);
364
365         /** Returns the number of file descriptors reported by the system this program may use
366          * when it was started.
367          * @return If non-zero the number of file descriptors that the system reported that we
368          * may use.
369          */
370         static size_t GetMaxFds() { return MaxSetSize; }
371
372         /** Returns the number of file descriptors being queried
373          * @return The set size
374          */
375         static size_t GetUsedFds() { return CurrentSetSize; }
376
377         /** Delete an event handler from the engine.
378          * This function call deletes an EventHandler
379          * from the engine, returning true if it succeeded
380          * and false if it failed. This does not free the
381          * EventHandler pointer using delete, if this is
382          * required you must do this yourself.
383          * @param eh The event handler object to remove
384          */
385         static void DelFd(EventHandler* eh);
386
387         /** Returns true if a file descriptor exists in
388          * the socket engine's list.
389          * @param fd The event handler to look for
390          * @return True if this fd has an event handler
391          */
392         static bool HasFd(int fd);
393
394         /** Returns the EventHandler attached to a specific fd.
395          * If the fd isn't in the socketengine, returns NULL.
396          * @param fd The event handler to look for
397          * @return A pointer to the event handler, or NULL
398          */
399         static EventHandler* GetRef(int fd);
400
401         /** Waits for events and dispatches them to handlers.  Please note that
402          * this doesn't wait long, only a couple of milliseconds. It returns the
403          * number of events which occurred during this call.  This method will
404          * dispatch events to their handlers by calling their
405          * EventHandler::OnEventHandler*() methods.
406          * @return The number of events which have occurred.
407          */
408         static int DispatchEvents();
409
410         /** Dispatch trial reads and writes. This causes the actual socket I/O
411          * to happen when writes have been pre-buffered.
412          */
413         static void DispatchTrialWrites();
414
415         /** Returns true if the file descriptors in the given event handler are
416          * within sensible ranges which can be handled by the socket engine.
417          */
418         static bool BoundsCheckFd(EventHandler* eh);
419
420         /** Abstraction for BSD sockets accept(2).
421          * This function should emulate its namesake system call exactly.
422          * @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
423          * @param addr The client IP address and port
424          * @param addrlen The size of the sockaddr parameter.
425          * @return This method should return exactly the same values as the system call it emulates.
426          */
427         static int Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen);
428
429         /** Close the underlying fd of an event handler, remove it from the socket engine and set the fd to -1.
430          * @param eh The EventHandler to close.
431          * @return 0 on success, a negative value on error
432          */
433         static int Close(EventHandler* eh);
434
435         /** Abstraction for BSD sockets close(2).
436          * This function should emulate its namesake system call exactly.
437          * This function should emulate its namesake system call exactly.
438          * @return This method should return exactly the same values as the system call it emulates.
439          */
440         static int Close(int fd);
441
442         /** Abstraction for BSD sockets send(2).
443          * This function should emulate its namesake system call exactly.
444          * @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
445          * @param buf The buffer in which the data that is sent is stored.
446          * @param len The size of the buffer.
447          * @param flags A flag value that controls the sending of the data.
448          * @return This method should return exactly the same values as the system call it emulates.
449          */
450         static int Send(EventHandler* fd, const void *buf, size_t len, int flags);
451
452         /** Abstraction for vector write function writev().
453          * This function should emulate its namesake system call exactly.
454          * @param fd EventHandler to send data with
455          * @param iov Array of IOVectors containing the buffers to send and their lengths in the platform's
456          * native format.
457          * @param count Number of elements in iov.
458          * @return This method should return exactly the same values as the system call it emulates.
459          */
460         static int WriteV(EventHandler* fd, const IOVector* iov, int count);
461
462 #ifdef _WIN32
463         /** Abstraction for vector write function writev() that accepts a POSIX format iovec.
464          * This function should emulate its namesake system call exactly.
465          * @param fd EventHandler to send data with
466          * @param iov Array of iovecs containing the buffers to send and their lengths in POSIX format.
467          * @param count Number of elements in iov.
468          * @return This method should return exactly the same values as the system call it emulates.
469          */
470         static int WriteV(EventHandler* fd, const iovec* iov, int count);
471 #endif
472
473         /** Abstraction for BSD sockets recv(2).
474          * This function should emulate its namesake system call exactly.
475          * @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
476          * @param buf The buffer in which the data that is read is stored.
477          * @param len The size of the buffer.
478          * @param flags A flag value that controls the reception of the data.
479          * @return This method should return exactly the same values as the system call it emulates.
480          */
481         static int Recv(EventHandler* fd, void *buf, size_t len, int flags);
482
483         /** Abstraction for BSD sockets recvfrom(2).
484          * This function should emulate its namesake system call exactly.
485          * @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
486          * @param buf The buffer in which the data that is read is stored.
487          * @param len The size of the buffer.
488          * @param flags A flag value that controls the reception of the data.
489          * @param from The remote IP address and port.
490          * @param fromlen The size of the from parameter.
491          * @return This method should return exactly the same values as the system call it emulates.
492          */
493         static int RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen);
494
495         /** Abstraction for BSD sockets sendto(2).
496          * This function should emulate its namesake system call exactly.
497          * @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
498          * @param buf The buffer in which the data that is sent is stored.
499          * @param len The size of the buffer.
500          * @param flags A flag value that controls the sending of the data.
501          * @param address The remote IP address and port.
502          * @return This method should return exactly the same values as the system call it emulates.
503          */
504         static int SendTo(EventHandler* fd, const void* buf, size_t len, int flags, const irc::sockets::sockaddrs& address);
505
506         /** Abstraction for BSD sockets connect(2).
507          * This function should emulate its namesake system call exactly.
508          * @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
509          * @param address The server IP address and port.
510          * @return This method should return exactly the same values as the system call it emulates.
511          */
512         static int Connect(EventHandler* fd, const irc::sockets::sockaddrs& address);
513
514         /** Make a file descriptor blocking.
515          * @param fd a file descriptor to set to blocking mode
516          * @return 0 on success, -1 on failure, errno is set appropriately.
517          */
518         static int Blocking(int fd);
519
520         /** Make a file descriptor nonblocking.
521          * @param fd A file descriptor to set to nonblocking mode
522          * @return 0 on success, -1 on failure, errno is set appropriately.
523          */
524         static int NonBlocking(int fd);
525
526         /** Abstraction for BSD sockets shutdown(2).
527          * This function should emulate its namesake system call exactly.
528          * @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
529          * @param how What part of the socket to shut down
530          * @return This method should return exactly the same values as the system call it emulates.
531          */
532         static int Shutdown(EventHandler* fd, int how);
533
534         /** Abstraction for BSD sockets shutdown(2).
535          * This function should emulate its namesake system call exactly.
536          * @return This method should return exactly the same values as the system call it emulates.
537          */
538         static int Shutdown(int fd, int how);
539
540         /** Abstraction for BSD sockets bind(2).
541          * This function should emulate its namesake system call exactly.
542          * @return This method should return exactly the same values as the system call it emulates.
543          */
544         static int Bind(int fd, const irc::sockets::sockaddrs& addr);
545
546         /** Abstraction for BSD sockets listen(2).
547          * This function should emulate its namesake system call exactly.
548          * @return This method should return exactly the same values as the system call it emulates.
549          */
550         static int Listen(int sockfd, int backlog);
551
552         /** Set SO_REUSEADDR and SO_LINGER on this file descriptor
553          */
554         static void SetReuse(int sockfd);
555
556         /** This function is called immediately after fork().
557          * Some socket engines (notably kqueue) cannot have their
558          * handles inherited by forked processes. This method
559          * allows for the socket engine to re-create its handle
560          * after the daemon forks as the socket engine is created
561          * long BEFORE the daemon forks.
562          * @return void, but it is acceptable for this function to bail back to
563          * the shell or operating system on fatal error.
564          */
565         static void RecoverFromFork();
566
567         /** Get data transfer and event statistics
568          */
569         static const Statistics& GetStats() { return stats; }
570
571         /** Should we ignore the error in errno?
572          * Checks EAGAIN and WSAEWOULDBLOCK
573          */
574         static bool IgnoreError();
575
576         /** Return the last socket related error. strrerror(errno) on *nix
577          */
578         static std::string LastError();
579
580         /** Returns the error for the given error num, strerror(errnum) on *nix
581          */
582         static std::string GetError(int errnum);
583 };
584
585 inline bool SocketEngine::IgnoreError()
586 {
587         if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
588                 return true;
589
590 #ifdef _WIN32
591         if (WSAGetLastError() == WSAEWOULDBLOCK)
592                 return true;
593 #endif
594
595         return false;
596 }