InspIRCd  3.0
inspsocket.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) 2007 Dennis Friis <[email protected]>
7  * Copyright (C) 2006-2007 Craig Edwards <[email protected]>
8  * Copyright (C) 2006 Oliver Lupton <[email protected]>
9  *
10  * This file is part of InspIRCd. InspIRCd is free software: you can
11  * redistribute it and/or modify it under the terms of the GNU General Public
12  * License as published by the Free Software Foundation, version 2.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 
24 #pragma once
25 
26 #include "timer.h"
27 
28 class IOHook;
29 
33 enum BufferedSocketState
34 {
36  I_DISCONNECTED,
38  I_CONNECTING,
40  I_CONNECTED,
42  I_ERROR
43 };
44 
48 enum BufferedSocketError
49 {
51  I_ERR_NONE,
53  I_ERR_DISCONNECT,
55  I_ERR_TIMEOUT,
57  I_ERR_SOCKET,
59  I_ERR_CONNECT,
61  I_ERR_BIND,
63  I_ERR_WRITE,
65  I_ERR_NOMOREFDS,
67  I_ERR_OTHER
68 };
69 
70 /* Required forward declarations */
71 class BufferedSocket;
72 
75 class CoreExport SocketTimeout : public Timer
76 {
77  private:
80  BufferedSocket* sock;
81 
84  int sfd;
85 
86  public:
92  SocketTimeout(int fd, BufferedSocket* thesock, unsigned int secs_from_now)
93  : Timer(secs_from_now)
94  , sock(thesock)
95  , sfd(fd)
96  {
97  }
98 
101  bool Tick(time_t now) CXX11_OVERRIDE;
102 };
103 
108 class CoreExport StreamSocket : public EventHandler
109 {
110  public:
113  class SendQueue
114  {
115  public:
118  typedef std::string Element;
119 
122  typedef std::deque<Element> Container;
123 
126  typedef Container::const_iterator const_iterator;
127 
128  SendQueue() : nbytes(0) { }
129 
133  bool empty() const { return (nbytes == 0); }
134 
138  Container::size_type size() const { return data.size(); }
139 
143  size_t bytes() const { return nbytes; }
144 
148  const Element& front() const { return data.front(); }
149 
155  const_iterator begin() const { return data.begin(); }
156 
160  const_iterator end() const { return data.end(); }
161 
164  void pop_front()
165  {
166  nbytes -= data.front().length();
167  data.pop_front();
168  }
169 
173  void erase_front(Element::size_type n)
174  {
175  nbytes -= n;
176  data.front().erase(0, n);
177  }
178 
182  void push_front(const Element& newdata)
183  {
184  data.push_front(newdata);
185  nbytes += newdata.length();
186  }
187 
191  void push_back(const Element& newdata)
192  {
193  data.push_back(newdata);
194  nbytes += newdata.length();
195  }
196 
199  void clear()
200  {
201  data.clear();
202  nbytes = 0;
203  }
204 
205  void moveall(SendQueue& other)
206  {
207  nbytes += other.bytes();
208  data.insert(data.end(), other.data.begin(), other.data.end());
209  other.clear();
210  }
211 
212  private:
215  Container data;
216 
219  size_t nbytes;
220  };
221 
223  enum Type
224  {
225  SS_UNKNOWN,
226  SS_USER
227  };
228 
229  private:
231  IOHook* iohook;
232 
235  SendQueue sendq;
236 
238  std::string error;
239 
243  void CheckError(BufferedSocketError err);
244 
247  void DoRead();
248 
253  void FlushSendQ(SendQueue& sq);
254 
259  int ReadToRecvQ(std::string& rq);
260 
269  int HookChainRead(IOHook* hook, std::string& rq);
270 
271  protected:
272  std::string recvq;
273  public:
274  const Type type;
275  StreamSocket(Type sstype = SS_UNKNOWN)
276  : iohook(NULL)
277  , type(sstype)
278  {
279  }
280  IOHook* GetIOHook() const;
281  void AddIOHook(IOHook* hook);
282  void DelIOHook();
283 
286  void DoWrite();
287 
290  void OnEventHandlerRead() CXX11_OVERRIDE;
291 
294  void OnEventHandlerWrite() CXX11_OVERRIDE;
295 
299  void OnEventHandlerError(int errcode) CXX11_OVERRIDE;
300 
302  void SetError(const std::string& err) { if (error.empty()) error = err; }
303 
305  const std::string& getError() const { return error; }
306 
308  virtual void OnDataReady() = 0;
310  virtual void OnError(BufferedSocketError e) = 0;
311 
317  virtual bool OnSetEndPoint(const irc::sockets::sockaddrs& local, const irc::sockets::sockaddrs& remote);
318 
321  void WriteData(const std::string& data);
327  bool GetNextLine(std::string& line, char delim = '\n');
329  size_t getSendQSize() const;
330 
331  SendQueue& GetSendQ() { return sendq; }
332 
336  virtual void Close();
338  CullResult cull() CXX11_OVERRIDE;
339 
344  IOHook* GetModHook(Module* mod) const;
345 };
355 class CoreExport BufferedSocket : public StreamSocket
356 {
357  public:
361 
367  BufferedSocketState state;
368 
369  BufferedSocket();
377  BufferedSocket(int newfd);
378 
387  void DoConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned int maxtime);
388 
392  virtual void OnConnected();
393 
397  void OnDataReady() CXX11_OVERRIDE = 0;
398 
408  virtual void OnTimeout();
409 
410  virtual ~BufferedSocket();
411  protected:
412  void OnEventHandlerWrite() CXX11_OVERRIDE;
413  BufferedSocketError BeginConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned int timeout);
414 };
415 
416 inline IOHook* StreamSocket::GetIOHook() const { return iohook; }
417 inline void StreamSocket::DelIOHook() { iohook = NULL; }
SocketTimeout(int fd, BufferedSocket *thesock, unsigned int secs_from_now)
Definition: inspsocket.h:92
const_iterator begin() const
Definition: inspsocket.h:155
virtual CullResult cull()
Definition: base.cpp:36
Definition: timer.h:36
Definition: iohook.h:66
virtual void OnEventHandlerRead()=0
Definition: hashcomp.h:69
void clear()
Definition: inspsocket.h:199
void push_back(const Element &newdata)
Definition: inspsocket.h:191
Container::const_iterator const_iterator
Definition: inspsocket.h:126
Definition: socket.h:58
void push_front(const Element &newdata)
Definition: inspsocket.h:182
Definition: inspsocket.h:108
size_t bytes() const
Definition: inspsocket.h:143
BufferedSocketState state
Definition: inspsocket.h:367
Definition: inspsocket.h:113
void erase_front(Element::size_type n)
Definition: inspsocket.h:173
std::deque< Element > Container
Definition: inspsocket.h:122
Type
Definition: inspsocket.h:223
SocketTimeout * Timeout
Definition: inspsocket.h:360
Definition: modules.h:240
const Element & front() const
Definition: inspsocket.h:148
const std::string & getError() const
Definition: inspsocket.h:305
void pop_front()
Definition: inspsocket.h:164
virtual bool Tick(time_t TIME)=0
Definition: inspsocket.h:75
Definition: socketengine.h:151
const_iterator end() const
Definition: inspsocket.h:160
Container::size_type size() const
Definition: inspsocket.h:138
Definition: inspsocket.h:355
Definition: base.h:31
std::string Element
Definition: inspsocket.h:118
bool empty() const
Definition: inspsocket.h:133