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  bool closeonempty;
232 
234  bool closing;
235 
237  IOHook* iohook;
238 
241  SendQueue sendq;
242 
244  std::string error;
245 
249  void CheckError(BufferedSocketError err);
250 
253  void DoRead();
254 
259  void FlushSendQ(SendQueue& sq);
260 
265  int ReadToRecvQ(std::string& rq);
266 
275  int HookChainRead(IOHook* hook, std::string& rq);
276 
277  protected:
278  std::string recvq;
279  public:
280  const Type type;
281  StreamSocket(Type sstype = SS_UNKNOWN)
282  : closeonempty(false)
283  , closing(false)
284  , iohook(NULL)
285  , type(sstype)
286  {
287  }
288  IOHook* GetIOHook() const;
289  void AddIOHook(IOHook* hook);
290  void DelIOHook();
291 
294  void DoWrite();
295 
298  void OnEventHandlerRead() CXX11_OVERRIDE;
299 
302  void OnEventHandlerWrite() CXX11_OVERRIDE;
303 
307  void OnEventHandlerError(int errcode) CXX11_OVERRIDE;
308 
310  void SetError(const std::string& err) { if (error.empty()) error = err; }
311 
313  const std::string& getError() const { return error; }
314 
316  virtual void OnDataReady() = 0;
318  virtual void OnError(BufferedSocketError e) = 0;
319 
325  virtual bool OnSetEndPoint(const irc::sockets::sockaddrs& local, const irc::sockets::sockaddrs& remote);
326 
329  void WriteData(const std::string& data);
335  bool GetNextLine(std::string& line, char delim = '\n');
337  size_t getSendQSize() const;
338 
339  SendQueue& GetSendQ() { return sendq; }
340 
344  virtual void Close();
345 
347  void Close(bool writeblock);
348 
350  CullResult cull() CXX11_OVERRIDE;
351 
356  IOHook* GetModHook(Module* mod) const;
357 };
367 class CoreExport BufferedSocket : public StreamSocket
368 {
369  public:
373 
379  BufferedSocketState state;
380 
381  BufferedSocket();
389  BufferedSocket(int newfd);
390 
399  void DoConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned int maxtime);
400 
404  virtual void OnConnected();
405 
409  void OnDataReady() CXX11_OVERRIDE = 0;
410 
420  virtual void OnTimeout();
421 
422  virtual ~BufferedSocket();
423  protected:
424  void OnEventHandlerWrite() CXX11_OVERRIDE;
425  BufferedSocketError BeginConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned int timeout);
426 };
427 
428 inline IOHook* StreamSocket::GetIOHook() const { return iohook; }
429 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:379
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:372
Definition: modules.h:242
const Element & front() const
Definition: inspsocket.h:148
const std::string & getError() const
Definition: inspsocket.h:313
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:367
Definition: base.h:31
std::string Element
Definition: inspsocket.h:118
bool empty() const
Definition: inspsocket.h:133