InspIRCd  3.0
socketengine.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  * Copyright (C) 2013-2016 Attila Molnar <[email protected]>
5  * Copyright (C) 2013-2014 Adam <[email protected]>
6  * Copyright (C) 2012-2013, 2017-2019 Sadie Powell <[email protected]>
7  * Copyright (C) 2012 Robby <[email protected]>
8  * Copyright (C) 2009 Uli Schlachter <[email protected]>
9  * Copyright (C) 2009 Daniel De Graaf <[email protected]>
10  * Copyright (C) 2007-2008, 2017 Robin Burchell <[email protected]>
11  * Copyright (C) 2007-2008, 2010 Craig Edwards <[email protected]>
12  * Copyright (C) 2007 burlex <[email protected]>
13  * Copyright (C) 2007 Dennis Friis <[email protected]>
14  *
15  * This file is part of InspIRCd. InspIRCd is free software: you can
16  * redistribute it and/or modify it under the terms of the GNU General Public
17  * License as published by the Free Software Foundation, version 2.
18  *
19  * This program is distributed in the hope that it will be useful, but WITHOUT
20  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
22  * details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program. If not, see <http://www.gnu.org/licenses/>.
26  */
27 
28 
29 #pragma once
30 
31 #include <vector>
32 #include <string>
33 #include <map>
34 #include "config.h"
35 #include "socket.h"
36 #include "base.h"
37 
38 #ifndef _WIN32
39 #include <sys/uio.h>
40 #endif
41 
42 #ifndef IOV_MAX
43 #define IOV_MAX 1024
44 #endif
45 
49 enum EventMask
50 {
53  FD_WANT_NO_READ = 0x1,
56  FD_WANT_POLL_READ = 0x2,
63  FD_WANT_FAST_READ = 0x4,
70  FD_WANT_EDGE_READ = 0x8,
71 
73  FD_WANT_READ_MASK = 0x0F,
74 
77  FD_WANT_NO_WRITE = 0x10,
85  FD_WANT_POLL_WRITE = 0x20,
99  FD_WANT_FAST_WRITE = 0x40,
105  FD_WANT_EDGE_WRITE = 0x80,
109  FD_WANT_SINGLE_WRITE = 0x100,
110 
112  FD_WANT_WRITE_MASK = 0x1F0,
113 
118  FD_ADD_TRIAL_READ = 0x1000,
122  FD_READ_WILL_BLOCK = 0x2000,
123 
132  FD_ADD_TRIAL_WRITE = 0x4000,
136  FD_WRITE_WILL_BLOCK = 0x8000,
137 
139  FD_TRIAL_NOTE_MASK = 0x5000
140 };
141 
157 class CoreExport EventHandler : public classbase
158 {
159  private:
161  int event_mask;
162 
163  void SetEventMask(int mask) { event_mask = mask; }
164 
165  protected:
172  int fd;
173 
177  void SwapInternals(EventHandler& other);
178 
179  public:
183  inline int GetFd() const { return fd; }
184 
185  inline int GetEventMask() const { return event_mask; }
186 
192  void SetFd(int FD);
193 
196  EventHandler();
197 
200  virtual ~EventHandler() {}
201 
204  virtual void OnEventHandlerRead() = 0;
205 
209  virtual void OnEventHandlerWrite();
210 
215  virtual void OnEventHandlerError(int errornum);
216 
217  friend class SocketEngine;
218 };
219 
228 class CoreExport SocketEngine
229 {
230  public:
234  {
235  mutable size_t indata;
236  mutable size_t outdata;
237  mutable time_t lastempty;
238 
241  void CheckFlush() const;
242 
243  public:
247  Statistics() : lastempty(0), TotalEvents(0), ReadEvents(0), WriteEvents(0), ErrorEvents(0) { }
248 
254  void UpdateReadCounters(int len_in);
255 
261  void UpdateWriteCounters(int len_out);
262 
268  void CoreExport GetBandwidth(float& kbitpersec_in, float& kbitpersec_out, float& kbitpersec_total) const;
269 
270  unsigned long TotalEvents;
271  unsigned long ReadEvents;
272  unsigned long WriteEvents;
273  unsigned long ErrorEvents;
274  };
275 
276  private:
279  static std::vector<EventHandler*> ref;
280 
282  static size_t CurrentSetSize;
283 
285  static size_t MaxSetSize;
286 
289  static std::set<int> trials;
290 
293  static Statistics stats;
294 
296  static void LookupMaxFds();
297 
299  static void InitError();
300 
301  static void OnSetEvent(EventHandler* eh, int old_mask, int new_mask);
302 
305  static bool AddFdRef(EventHandler* eh);
306 
307  static void DelFdRef(EventHandler* eh);
308 
309  template <typename T>
310  static void ResizeDouble(std::vector<T>& vect)
311  {
312  if (SocketEngine::CurrentSetSize > vect.size())
313  vect.resize(SocketEngine::CurrentSetSize * 2);
314  }
315 
316 public:
317 #ifndef _WIN32
318  typedef iovec IOVector;
319 #else
320  typedef WindowsIOVec IOVector;
321 #endif
322 
333  static void Init();
334 
339  static void Deinit();
340 
348  static bool AddFd(EventHandler* eh, int event_mask);
349 
361  static void ChangeEventMask(EventHandler* eh, int event_mask);
362 
368  static size_t GetMaxFds() { return MaxSetSize; }
369 
373  static size_t GetUsedFds() { return CurrentSetSize; }
374 
383  static void DelFd(EventHandler* eh);
384 
390  static bool HasFd(int fd);
391 
397  static EventHandler* GetRef(int fd);
398 
406  static int DispatchEvents();
407 
411  static void DispatchTrialWrites();
412 
416  static bool BoundsCheckFd(EventHandler* eh);
417 
425  static int Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen);
426 
431  static int Close(EventHandler* eh);
432 
438  static int Close(int fd);
439 
448  static int Send(EventHandler* fd, const void *buf, size_t len, int flags);
449 
458  static int WriteV(EventHandler* fd, const IOVector* iov, int count);
459 
460 #ifdef _WIN32
461 
468  static int WriteV(EventHandler* fd, const iovec* iov, int count);
469 #endif
470 
479  static int Recv(EventHandler* fd, void *buf, size_t len, int flags);
480 
491  static int RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen);
492 
502  static int SendTo(EventHandler* fd, const void* buf, size_t len, int flags, const irc::sockets::sockaddrs& address);
503 
510  static int Connect(EventHandler* fd, const irc::sockets::sockaddrs& address);
511 
516  static int Blocking(int fd);
517 
522  static int NonBlocking(int fd);
523 
530  static int Shutdown(EventHandler* fd, int how);
531 
536  static int Shutdown(int fd, int how);
537 
542  static int Bind(int fd, const irc::sockets::sockaddrs& addr);
543 
548  static int Listen(int sockfd, int backlog);
549 
552  static void SetReuse(int sockfd);
553 
563  static void RecoverFromFork();
564 
567  static const Statistics& GetStats() { return stats; }
568 
572  static bool IgnoreError();
573 
576  static std::string LastError();
577 
580  static std::string GetError(int errnum);
581 };
582 
584 {
585  if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
586  return true;
587 
588 #ifdef _WIN32
589  if (WSAGetLastError() == WSAEWOULDBLOCK)
590  return true;
591 #endif
592 
593  return false;
594 }
EventHandler
Definition: socketengine.h:157
irc::sockets::sockaddrs
Definition: socket.h:62
classbase
Definition: base.h:46
iovec
Definition: inspircd_win32wrapper.h:158
SocketEngine::IgnoreError
static bool IgnoreError()
Definition: socketengine.h:583
SocketEngine::GetMaxFds
static size_t GetMaxFds()
Definition: socketengine.h:368
EventHandler::GetFd
int GetFd() const
Definition: socketengine.h:183
SocketEngine::GetUsedFds
static size_t GetUsedFds()
Definition: socketengine.h:373
SocketEngine::Statistics
Definition: socketengine.h:233
SocketEngine::GetStats
static const Statistics & GetStats()
Definition: socketengine.h:567
SocketEngine
Definition: socketengine.h:228
WindowsIOVec
Definition: inspircd_win32wrapper.h:165
EventHandler::~EventHandler
virtual ~EventHandler()
Definition: socketengine.h:200
SocketEngine::Statistics::Statistics
Statistics()
Definition: socketengine.h:247
EventHandler::fd
int fd
Definition: socketengine.h:172