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