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 
269  protected:
272  static size_t CurrentSetSize;
275  static std::set<int> trials;
276 
277  static int MAX_DESCRIPTORS;
278 
282 
283  static void OnSetEvent(EventHandler* eh, int old_mask, int new_mask);
284 
287  static bool AddFdRef(EventHandler* eh);
288 
289  static void DelFdRef(EventHandler* eh);
290 
291  template <typename T>
292  static void ResizeDouble(std::vector<T>& vect)
293  {
294  if (SocketEngine::CurrentSetSize > vect.size())
295  vect.resize(vect.size() * 2);
296  }
297 
298 public:
299 #ifndef _WIN32
300  typedef iovec IOVector;
301 #else
302  typedef WindowsIOVec IOVector;
303 #endif
304 
315  static void Init();
316 
321  static void Deinit();
322 
330  static bool AddFd(EventHandler* eh, int event_mask);
331 
343  static void ChangeEventMask(EventHandler* eh, int event_mask);
344 
350  static int GetMaxFds() { return MAX_DESCRIPTORS; }
351 
355  static size_t GetUsedFds() { return CurrentSetSize; }
356 
365  static void DelFd(EventHandler* eh);
366 
372  static bool HasFd(int fd);
373 
379  static EventHandler* GetRef(int fd);
380 
388  static int DispatchEvents();
389 
393  static void DispatchTrialWrites();
394 
398  static bool BoundsCheckFd(EventHandler* eh);
399 
407  static int Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen);
408 
413  static int Close(EventHandler* eh);
414 
420  static int Close(int fd);
421 
430  static int Send(EventHandler* fd, const void *buf, size_t len, int flags);
431 
440  static int WriteV(EventHandler* fd, const IOVector* iov, int count);
441 
442 #ifdef _WIN32
443 
450  static int WriteV(EventHandler* fd, const iovec* iov, int count);
451 #endif
452 
461  static int Recv(EventHandler* fd, void *buf, size_t len, int flags);
462 
473  static int RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen);
474 
485  static int SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen);
486 
494  static int Connect(EventHandler* fd, const sockaddr *serv_addr, socklen_t addrlen);
495 
500  static int Blocking(int fd);
501 
506  static int NonBlocking(int fd);
507 
514  static int Shutdown(EventHandler* fd, int how);
515 
520  static int Shutdown(int fd, int how);
521 
526  static int Bind(int fd, const irc::sockets::sockaddrs& addr);
527 
532  static int Listen(int sockfd, int backlog);
533 
536  static void SetReuse(int sockfd);
537 
547  static void RecoverFromFork();
548 
551  static const Statistics& GetStats() { return stats; }
552 
556  static bool IgnoreError();
557 
560  static std::string LastError();
561 
564  static std::string GetError(int errnum);
565 };
566 
568 {
569  if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
570  return true;
571 
572 #ifdef _WIN32
573  if (WSAGetLastError() == WSAEWOULDBLOCK)
574  return true;
575 #endif
576 
577  return false;
578 }
static size_t GetUsedFds()
Definition: socketengine.h:355
static int GetMaxFds()
Definition: socketengine.h:350
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
static size_t CurrentSetSize
Definition: socketengine.h:272
Definition: inspircd_win32wrapper.h:179
Definition: socketengine.h:151
static bool IgnoreError()
Definition: socketengine.h:567
static Statistics stats
Definition: socketengine.h:281
int fd
Definition: socketengine.h:166
static std::set< int > trials
Definition: socketengine.h:275
Statistics()
Definition: socketengine.h:235
static const Statistics & GetStats()
Definition: socketengine.h:551