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, long secs_from_now) : Timer(secs_from_now), sock(thesock), sfd(fd) { }
93 
96  virtual bool Tick(time_t now);
97 };
98 
103 class CoreExport StreamSocket : public EventHandler
104 {
105  public:
108  class SendQueue
109  {
110  public:
113  typedef std::string Element;
114 
117  typedef std::deque<Element> Container;
118 
121  typedef Container::const_iterator const_iterator;
122 
123  SendQueue() : nbytes(0) { }
124 
128  bool empty() const { return (nbytes == 0); }
129 
133  Container::size_type size() const { return data.size(); }
134 
138  size_t bytes() const { return nbytes; }
139 
143  const Element& front() const { return data.front(); }
144 
150  const_iterator begin() const { return data.begin(); }
151 
155  const_iterator end() const { return data.end(); }
156 
159  void pop_front()
160  {
161  nbytes -= data.front().length();
162  data.pop_front();
163  }
164 
168  void erase_front(Element::size_type n)
169  {
170  nbytes -= n;
171  data.front().erase(0, n);
172  }
173 
177  void push_front(const Element& newdata)
178  {
179  data.push_front(newdata);
180  nbytes += newdata.length();
181  }
182 
186  void push_back(const Element& newdata)
187  {
188  data.push_back(newdata);
189  nbytes += newdata.length();
190  }
191 
194  void clear()
195  {
196  data.clear();
197  nbytes = 0;
198  }
199 
200  void moveall(SendQueue& other)
201  {
202  nbytes += other.bytes();
203  data.insert(data.end(), other.data.begin(), other.data.end());
204  other.clear();
205  }
206 
207  private:
210  Container data;
211 
214  size_t nbytes;
215  };
216 
217  private:
219  IOHook* iohook;
220 
223  SendQueue sendq;
224 
226  std::string error;
227 
231  void CheckError(BufferedSocketError err);
232 
235  void DoRead();
236 
241  void FlushSendQ(SendQueue& sq);
242 
247  int ReadToRecvQ(std::string& rq);
248 
257  int HookChainRead(IOHook* hook, std::string& rq);
258 
259  protected:
260  std::string recvq;
261  public:
262  StreamSocket() : iohook(NULL) { }
263  IOHook* GetIOHook() const;
264  void AddIOHook(IOHook* hook);
265  void DelIOHook();
266 
269  void DoWrite();
270 
273  void OnEventHandlerRead() CXX11_OVERRIDE;
274 
277  void OnEventHandlerWrite() CXX11_OVERRIDE;
278 
282  void OnEventHandlerError(int errcode) CXX11_OVERRIDE;
283 
285  void SetError(const std::string& err) { if (error.empty()) error = err; }
286 
288  const std::string& getError() const { return error; }
289 
291  virtual void OnDataReady() = 0;
293  virtual void OnError(BufferedSocketError e) = 0;
294 
297  void WriteData(const std::string& data);
303  bool GetNextLine(std::string& line, char delim = '\n');
305  size_t getSendQSize() const;
306 
307  SendQueue& GetSendQ() { return sendq; }
308 
312  virtual void Close();
314  virtual CullResult cull() CXX11_OVERRIDE;
315 
320  IOHook* GetModHook(Module* mod) const;
321 };
331 class CoreExport BufferedSocket : public StreamSocket
332 {
333  public:
337 
343  BufferedSocketState state;
344 
345  BufferedSocket();
353  BufferedSocket(int newfd);
354 
364  void DoConnect(const std::string &ipaddr, int aport, unsigned long maxtime, const std::string &connectbindip);
365 
369  virtual void OnConnected();
370 
374  virtual void OnDataReady() CXX11_OVERRIDE = 0;
375 
385  virtual void OnTimeout();
386 
387  virtual ~BufferedSocket();
388  protected:
389  void OnEventHandlerWrite() CXX11_OVERRIDE;
390  BufferedSocketError BeginConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned long timeout);
391  BufferedSocketError BeginConnect(const std::string &ipaddr, int aport, unsigned long maxtime, const std::string &connectbindip);
392 };
393 
394 inline IOHook* StreamSocket::GetIOHook() const { return iohook; }
395 inline void StreamSocket::DelIOHook() { iohook = NULL; }
const_iterator begin() const
Definition: inspsocket.h:150
Definition: timer.h:36
Definition: iohook.h:66
Definition: hashcomp.h:69
void clear()
Definition: inspsocket.h:194
void push_back(const Element &newdata)
Definition: inspsocket.h:186
SocketTimeout(int fd, BufferedSocket *thesock, long secs_from_now)
Definition: inspsocket.h:92
Container::const_iterator const_iterator
Definition: inspsocket.h:121
STL namespace.
void push_front(const Element &newdata)
Definition: inspsocket.h:177
void SetError(const std::string &err)
Definition: inspsocket.h:285
Definition: inspsocket.h:103
size_t bytes() const
Definition: inspsocket.h:138
BufferedSocketState state
Definition: inspsocket.h:343
Definition: inspsocket.h:108
void erase_front(Element::size_type n)
Definition: inspsocket.h:168
std::deque< Element > Container
Definition: inspsocket.h:117
SocketTimeout * Timeout
Definition: inspsocket.h:336
Definition: modules.h:245
const Element & front() const
Definition: inspsocket.h:143
const std::string & getError() const
Definition: inspsocket.h:288
void pop_front()
Definition: inspsocket.h:159
virtual bool Tick(time_t TIME)=0
Definition: inspsocket.h:75
Definition: socketengine.h:151
const_iterator end() const
Definition: inspsocket.h:155
Container::size_type size() const
Definition: inspsocket.h:133
Definition: inspsocket.h:331
Definition: base.h:31
std::string Element
Definition: inspsocket.h:113
bool empty() const
Definition: inspsocket.h:128