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-2020 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 
186  inline bool HasFd() const { return fd >= 0; }
187 
188  inline int GetEventMask() const { return event_mask; }
189 
195  void SetFd(int FD);
196 
199  EventHandler();
200 
203  virtual ~EventHandler() {}
204 
207  virtual void OnEventHandlerRead() = 0;
208 
212  virtual void OnEventHandlerWrite();
213 
218  virtual void OnEventHandlerError(int errornum);
219 
220  friend class SocketEngine;
221 };
222 
231 class CoreExport SocketEngine
232 {
233  public:
237  {
238  mutable size_t indata;
239  mutable size_t outdata;
240  mutable time_t lastempty;
241 
244  void CheckFlush() const;
245 
246  public:
250  Statistics() : lastempty(0), TotalEvents(0), ReadEvents(0), WriteEvents(0), ErrorEvents(0) { }
251 
257  void UpdateReadCounters(int len_in);
258 
264  void UpdateWriteCounters(int len_out);
265 
271  void CoreExport GetBandwidth(float& kbitpersec_in, float& kbitpersec_out, float& kbitpersec_total) const;
272 
273  unsigned long TotalEvents;
274  unsigned long ReadEvents;
275  unsigned long WriteEvents;
276  unsigned long ErrorEvents;
277  };
278 
279  private:
282  static std::vector<EventHandler*> ref;
283 
285  static size_t CurrentSetSize;
286 
288  static size_t MaxSetSize;
289 
292  static std::set<int> trials;
293 
296  static Statistics stats;
297 
299  static void LookupMaxFds();
300 
302  static void InitError();
303 
304  static void OnSetEvent(EventHandler* eh, int old_mask, int new_mask);
305 
308  static bool AddFdRef(EventHandler* eh);
309 
310  static void DelFdRef(EventHandler* eh);
311 
312  template <typename T>
313  static void ResizeDouble(std::vector<T>& vect)
314  {
315  if (SocketEngine::CurrentSetSize > vect.size())
316  vect.resize(SocketEngine::CurrentSetSize * 2);
317  }
318 
319 public:
320 #ifndef _WIN32
321  typedef iovec IOVector;
322 #else
323  typedef WindowsIOVec IOVector;
324 #endif
325 
336  static void Init();
337 
342  static void Deinit();
343 
351  static bool AddFd(EventHandler* eh, int event_mask);
352 
364  static void ChangeEventMask(EventHandler* eh, int event_mask);
365 
371  static size_t GetMaxFds() { return MaxSetSize; }
372 
376  static size_t GetUsedFds() { return CurrentSetSize; }
377 
386  static void DelFd(EventHandler* eh);
387 
393  static bool HasFd(int fd);
394 
400  static EventHandler* GetRef(int fd);
401 
409  static int DispatchEvents();
410 
414  static void DispatchTrialWrites();
415 
419  static bool BoundsCheckFd(EventHandler* eh);
420 
428  static int Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen);
429 
434  static int Close(EventHandler* eh);
435 
441  static int Close(int fd);
442 
451  static int Send(EventHandler* fd, const void *buf, size_t len, int flags);
452 
461  static int WriteV(EventHandler* fd, const IOVector* iov, int count);
462 
463 #ifdef _WIN32
464 
471  static int WriteV(EventHandler* fd, const iovec* iov, int count);
472 #endif
473 
482  static int Recv(EventHandler* fd, void *buf, size_t len, int flags);
483 
494  static int RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen);
495 
505  static int SendTo(EventHandler* fd, const void* buf, size_t len, int flags, const irc::sockets::sockaddrs& address);
506 
513  static int Connect(EventHandler* fd, const irc::sockets::sockaddrs& address);
514 
519  static int Blocking(int fd);
520 
525  static int NonBlocking(int fd);
526 
533  static int Shutdown(EventHandler* fd, int how);
534 
539  static int Shutdown(int fd, int how);
540 
545  static int Bind(int fd, const irc::sockets::sockaddrs& addr);
546 
551  static int Listen(int sockfd, int backlog);
552 
555  static void SetReuse(int sockfd);
556 
566  static void RecoverFromFork();
567 
570  static const Statistics& GetStats() { return stats; }
571 
575  static bool IgnoreError();
576 
579  static std::string LastError();
580 
583  static std::string GetError(int errnum);
584 };
585 
587 {
588  if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
589  return true;
590 
591 #ifdef _WIN32
592  if (WSAGetLastError() == WSAEWOULDBLOCK)
593  return true;
594 #endif
595 
596  return false;
597 }
EventHandler
Definition: socketengine.h:157
irc::sockets::sockaddrs
Definition: socket.h:62
classbase
Definition: base.h:47
iovec
Definition: inspircd_win32wrapper.h:162
SocketEngine::IgnoreError
static bool IgnoreError()
Definition: socketengine.h:586
SocketEngine::GetMaxFds
static size_t GetMaxFds()
Definition: socketengine.h:371
EventHandler::GetFd
int GetFd() const
Definition: socketengine.h:183
EventHandler::HasFd
bool HasFd() const
Definition: socketengine.h:186
SocketEngine::GetUsedFds
static size_t GetUsedFds()
Definition: socketengine.h:376
SocketEngine::Statistics
Definition: socketengine.h:236
SocketEngine::GetStats
static const Statistics & GetStats()
Definition: socketengine.h:570
SocketEngine
Definition: socketengine.h:231
WindowsIOVec
Definition: inspircd_win32wrapper.h:169
EventHandler::~EventHandler
virtual ~EventHandler()
Definition: socketengine.h:203
SocketEngine::Statistics::Statistics
Statistics()
Definition: socketengine.h:250
EventHandler::fd
int fd
Definition: socketengine.h:172