InspIRCd  3.0
socketengine.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  * Copyright (C) 2009 Daniel De Graaf <[email protected]>
5  * Copyright (C) 2007-2008 Robin Burchell <[email protected]>
6  * Copyright (C) 2005-2007 Craig Edwards <[email protected]>
7  * Copyright (C) 2007 Dennis Friis <[email protected]>
8  *
9  * This file is part of InspIRCd. InspIRCd is free software: you can
10  * redistribute it and/or modify it under the terms of the GNU General Public
11  * License as published by the Free Software Foundation, version 2.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 
23 #pragma once
24 
25 #include <vector>
26 #include <string>
27 #include <map>
28 #include "config.h"
29 #include "socket.h"
30 #include "base.h"
31 
32 #ifndef _WIN32
33 #include <sys/uio.h>
34 #endif
35 
36 #ifndef IOV_MAX
37 #define IOV_MAX 1024
38 #endif
39 
43 enum EventMask
44 {
47  FD_WANT_NO_READ = 0x1,
50  FD_WANT_POLL_READ = 0x2,
57  FD_WANT_FAST_READ = 0x4,
64  FD_WANT_EDGE_READ = 0x8,
65 
67  FD_WANT_READ_MASK = 0x0F,
68 
71  FD_WANT_NO_WRITE = 0x10,
79  FD_WANT_POLL_WRITE = 0x20,
93  FD_WANT_FAST_WRITE = 0x40,
99  FD_WANT_EDGE_WRITE = 0x80,
103  FD_WANT_SINGLE_WRITE = 0x100,
104 
106  FD_WANT_WRITE_MASK = 0x1F0,
107 
112  FD_ADD_TRIAL_READ = 0x1000,
116  FD_READ_WILL_BLOCK = 0x2000,
117 
126  FD_ADD_TRIAL_WRITE = 0x4000,
130  FD_WRITE_WILL_BLOCK = 0x8000,
131 
133  FD_TRIAL_NOTE_MASK = 0x5000
134 };
135 
151 class CoreExport EventHandler : public classbase
152 {
153  private:
155  int event_mask;
156 
157  void SetEventMask(int mask) { event_mask = mask; }
158 
159  protected:
166  int fd;
167  public:
171  inline int GetFd() const { return fd; }
172 
173  inline int GetEventMask() const { return event_mask; }
174 
180  void SetFd(int FD);
181 
184  EventHandler();
185 
188  virtual ~EventHandler() {}
189 
192  virtual void OnEventHandlerRead() = 0;
193 
197  virtual void OnEventHandlerWrite();
198 
203  virtual void OnEventHandlerError(int errornum);
204 
205  friend class SocketEngine;
206 };
207 
216 class CoreExport SocketEngine
217 {
218  public:
222  {
223  mutable size_t indata;
224  mutable size_t outdata;
225  mutable time_t lastempty;
226 
229  void CheckFlush() const;
230 
231  public:
235  Statistics() : lastempty(0), TotalEvents(0), ReadEvents(0), WriteEvents(0), ErrorEvents(0) { }
236 
242  void UpdateReadCounters(int len_in);
243 
249  void UpdateWriteCounters(int len_out);
250 
256  void CoreExport GetBandwidth(float& kbitpersec_in, float& kbitpersec_out, float& kbitpersec_total) const;
257 
258  unsigned long TotalEvents;
259  unsigned long ReadEvents;
260  unsigned long WriteEvents;
261  unsigned long ErrorEvents;
262  };
263 
264  private:
267  static std::vector<EventHandler*> ref;
268 
270  static size_t CurrentSetSize;
271 
273  static size_t MaxSetSize;
274 
277  static std::set<int> trials;
278 
281  static Statistics stats;
282 
284  static void LookupMaxFds();
285 
287  static void InitError();
288 
289  static void OnSetEvent(EventHandler* eh, int old_mask, int new_mask);
290 
293  static bool AddFdRef(EventHandler* eh);
294 
295  static void DelFdRef(EventHandler* eh);
296 
297  template <typename T>
298  static void ResizeDouble(std::vector<T>& vect)
299  {
300  if (SocketEngine::CurrentSetSize > vect.size())
301  vect.resize(vect.size() * 2);
302  }
303 
304 public:
305 #ifndef _WIN32
306  typedef iovec IOVector;
307 #else
308  typedef WindowsIOVec IOVector;
309 #endif
310 
321  static void Init();
322 
327  static void Deinit();
328 
336  static bool AddFd(EventHandler* eh, int event_mask);
337 
349  static void ChangeEventMask(EventHandler* eh, int event_mask);
350 
356  static size_t GetMaxFds() { return MaxSetSize; }
357 
361  static size_t GetUsedFds() { return CurrentSetSize; }
362 
371  static void DelFd(EventHandler* eh);
372 
378  static bool HasFd(int fd);
379 
385  static EventHandler* GetRef(int fd);
386 
394  static int DispatchEvents();
395 
399  static void DispatchTrialWrites();
400 
404  static bool BoundsCheckFd(EventHandler* eh);
405 
413  static int Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen);
414 
419  static int Close(EventHandler* eh);
420 
426  static int Close(int fd);
427 
436  static int Send(EventHandler* fd, const void *buf, size_t len, int flags);
437 
446  static int WriteV(EventHandler* fd, const IOVector* iov, int count);
447 
448 #ifdef _WIN32
449 
456  static int WriteV(EventHandler* fd, const iovec* iov, int count);
457 #endif
458 
467  static int Recv(EventHandler* fd, void *buf, size_t len, int flags);
468 
479  static int RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen);
480 
491  static int SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen);
492 
500  static int Connect(EventHandler* fd, const sockaddr *serv_addr, socklen_t addrlen);
501 
506  static int Blocking(int fd);
507 
512  static int NonBlocking(int fd);
513 
520  static int Shutdown(EventHandler* fd, int how);
521 
526  static int Shutdown(int fd, int how);
527 
532  static int Bind(int fd, const irc::sockets::sockaddrs& addr);
533 
538  static int Listen(int sockfd, int backlog);
539 
542  static void SetReuse(int sockfd);
543 
553  static void RecoverFromFork();
554 
557  static const Statistics& GetStats() { return stats; }
558 
562  static bool IgnoreError();
563 
566  static std::string LastError();
567 
570  static std::string GetError(int errnum);
571 };
572 
574 {
575  if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
576  return true;
577 
578 #ifdef _WIN32
579  if (WSAGetLastError() == WSAEWOULDBLOCK)
580  return true;
581 #endif
582 
583  return false;
584 }
static size_t GetUsedFds()
Definition: socketengine.h:361
int GetFd() const
Definition: socketengine.h:171
Definition: socket.h:57
Definition: base.h:41
virtual ~EventHandler()
Definition: socketengine.h:188
Definition: inspircd_win32wrapper.h:186
Definition: socketengine.h:221
Definition: socketengine.h:216
Definition: inspircd_win32wrapper.h:179
static size_t GetMaxFds()
Definition: socketengine.h:356
Definition: socketengine.h:151
static bool IgnoreError()
Definition: socketengine.h:573
int fd
Definition: socketengine.h:166
Statistics()
Definition: socketengine.h:235
static const Statistics & GetStats()
Definition: socketengine.h:557