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 
222  private:
224  IOHook* iohook;
225 
228  SendQueue sendq;
229 
231  std::string error;
232 
236  void CheckError(BufferedSocketError err);
237 
240  void DoRead();
241 
246  void FlushSendQ(SendQueue& sq);
247 
252  int ReadToRecvQ(std::string& rq);
253 
262  int HookChainRead(IOHook* hook, std::string& rq);
263 
264  protected:
265  std::string recvq;
266  public:
267  StreamSocket() : iohook(NULL) { }
268  IOHook* GetIOHook() const;
269  void AddIOHook(IOHook* hook);
270  void DelIOHook();
271 
274  void DoWrite();
275 
278  void OnEventHandlerRead() CXX11_OVERRIDE;
279 
282  void OnEventHandlerWrite() CXX11_OVERRIDE;
283 
287  void OnEventHandlerError(int errcode) CXX11_OVERRIDE;
288 
290  void SetError(const std::string& err) { if (error.empty()) error = err; }
291 
293  const std::string& getError() const { return error; }
294 
296  virtual void OnDataReady() = 0;
298  virtual void OnError(BufferedSocketError e) = 0;
299 
302  void WriteData(const std::string& data);
308  bool GetNextLine(std::string& line, char delim = '\n');
310  size_t getSendQSize() const;
311 
312  SendQueue& GetSendQ() { return sendq; }
313 
317  virtual void Close();
319  CullResult cull() CXX11_OVERRIDE;
320 
325  IOHook* GetModHook(Module* mod) const;
326 };
336 class CoreExport BufferedSocket : public StreamSocket
337 {
338  public:
342 
348  BufferedSocketState state;
349 
350  BufferedSocket();
358  BufferedSocket(int newfd);
359 
369  void DoConnect(const std::string& ipaddr, int aport, unsigned int maxtime, const std::string& connectbindip);
370 
374  virtual void OnConnected();
375 
379  void OnDataReady() CXX11_OVERRIDE = 0;
380 
390  virtual void OnTimeout();
391 
392  virtual ~BufferedSocket();
393  protected:
394  void OnEventHandlerWrite() CXX11_OVERRIDE;
395  BufferedSocketError BeginConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned int timeout);
396  BufferedSocketError BeginConnect(const std::string& ipaddr, int aport, unsigned int maxtime, const std::string& connectbindip);
397 };
398 
399 inline IOHook* StreamSocket::GetIOHook() const { return iohook; }
400 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
STL namespace.
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:348
Definition: inspsocket.h:113
void erase_front(Element::size_type n)
Definition: inspsocket.h:173
std::deque< Element > Container
Definition: inspsocket.h:122
SocketTimeout * Timeout
Definition: inspsocket.h:341
Definition: modules.h:239
const Element & front() const
Definition: inspsocket.h:148
const std::string & getError() const
Definition: inspsocket.h:293
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:336
Definition: base.h:31
std::string Element
Definition: inspsocket.h:118
bool empty() const
Definition: inspsocket.h:133