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 
171  void SwapInternals(EventHandler& other);
172 
173  public:
177  inline int GetFd() const { return fd; }
178 
179  inline int GetEventMask() const { return event_mask; }
180 
186  void SetFd(int FD);
187 
190  EventHandler();
191 
194  virtual ~EventHandler() {}
195 
198  virtual void OnEventHandlerRead() = 0;
199 
203  virtual void OnEventHandlerWrite();
204 
209  virtual void OnEventHandlerError(int errornum);
210 
211  friend class SocketEngine;
212 };
213 
222 class CoreExport SocketEngine
223 {
224  public:
228  {
229  mutable size_t indata;
230  mutable size_t outdata;
231  mutable time_t lastempty;
232 
235  void CheckFlush() const;
236 
237  public:
241  Statistics() : lastempty(0), TotalEvents(0), ReadEvents(0), WriteEvents(0), ErrorEvents(0) { }
242 
248  void UpdateReadCounters(int len_in);
249 
255  void UpdateWriteCounters(int len_out);
256 
262  void CoreExport GetBandwidth(float& kbitpersec_in, float& kbitpersec_out, float& kbitpersec_total) const;
263 
264  unsigned long TotalEvents;
265  unsigned long ReadEvents;
266  unsigned long WriteEvents;
267  unsigned long ErrorEvents;
268  };
269 
270  private:
273  static std::vector<EventHandler*> ref;
274 
276  static size_t CurrentSetSize;
277 
279  static size_t MaxSetSize;
280 
283  static std::set<int> trials;
284 
287  static Statistics stats;
288 
290  static void LookupMaxFds();
291 
293  static void InitError();
294 
295  static void OnSetEvent(EventHandler* eh, int old_mask, int new_mask);
296 
299  static bool AddFdRef(EventHandler* eh);
300 
301  static void DelFdRef(EventHandler* eh);
302 
303  template <typename T>
304  static void ResizeDouble(std::vector<T>& vect)
305  {
306  if (SocketEngine::CurrentSetSize > vect.size())
307  vect.resize(SocketEngine::CurrentSetSize * 2);
308  }
309 
310 public:
311 #ifndef _WIN32
312  typedef iovec IOVector;
313 #else
314  typedef WindowsIOVec IOVector;
315 #endif
316 
327  static void Init();
328 
333  static void Deinit();
334 
342  static bool AddFd(EventHandler* eh, int event_mask);
343 
355  static void ChangeEventMask(EventHandler* eh, int event_mask);
356 
362  static size_t GetMaxFds() { return MaxSetSize; }
363 
367  static size_t GetUsedFds() { return CurrentSetSize; }
368 
377  static void DelFd(EventHandler* eh);
378 
384  static bool HasFd(int fd);
385 
391  static EventHandler* GetRef(int fd);
392 
400  static int DispatchEvents();
401 
405  static void DispatchTrialWrites();
406 
410  static bool BoundsCheckFd(EventHandler* eh);
411 
419  static int Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen);
420 
425  static int Close(EventHandler* eh);
426 
432  static int Close(int fd);
433 
442  static int Send(EventHandler* fd, const void *buf, size_t len, int flags);
443 
452  static int WriteV(EventHandler* fd, const IOVector* iov, int count);
453 
454 #ifdef _WIN32
455 
462  static int WriteV(EventHandler* fd, const iovec* iov, int count);
463 #endif
464 
473  static int Recv(EventHandler* fd, void *buf, size_t len, int flags);
474 
485  static int RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen);
486 
496  static int SendTo(EventHandler* fd, const void* buf, size_t len, int flags, const irc::sockets::sockaddrs& address);
497 
504  static int Connect(EventHandler* fd, const irc::sockets::sockaddrs& address);
505 
510  static int Blocking(int fd);
511 
516  static int NonBlocking(int fd);
517 
524  static int Shutdown(EventHandler* fd, int how);
525 
530  static int Shutdown(int fd, int how);
531 
536  static int Bind(int fd, const irc::sockets::sockaddrs& addr);
537 
542  static int Listen(int sockfd, int backlog);
543 
546  static void SetReuse(int sockfd);
547 
557  static void RecoverFromFork();
558 
561  static const Statistics& GetStats() { return stats; }
562 
566  static bool IgnoreError();
567 
570  static std::string LastError();
571 
574  static std::string GetError(int errnum);
575 };
576 
578 {
579  if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
580  return true;
581 
582 #ifdef _WIN32
583  if (WSAGetLastError() == WSAEWOULDBLOCK)
584  return true;
585 #endif
586 
587  return false;
588 }
EventHandler
Definition: socketengine.h:151
irc::sockets::sockaddrs
Definition: socket.h:58
classbase
Definition: base.h:41
iovec
Definition: inspircd_win32wrapper.h:162
SocketEngine::IgnoreError
static bool IgnoreError()
Definition: socketengine.h:577
SocketEngine::GetMaxFds
static size_t GetMaxFds()
Definition: socketengine.h:362
EventHandler::GetFd
int GetFd() const
Definition: socketengine.h:177
SocketEngine::GetUsedFds
static size_t GetUsedFds()
Definition: socketengine.h:367
SocketEngine::Statistics
Definition: socketengine.h:227
SocketEngine::GetStats
static const Statistics & GetStats()
Definition: socketengine.h:561
SocketEngine
Definition: socketengine.h:222
WindowsIOVec
Definition: inspircd_win32wrapper.h:169
EventHandler::~EventHandler
virtual ~EventHandler()
Definition: socketengine.h:194
SocketEngine::Statistics::Statistics
Statistics()
Definition: socketengine.h:241
EventHandler::fd
int fd
Definition: socketengine.h:166