InspIRCd  3.0
inspsocket.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  * Copyright (C) 2019 linuxdaemon <[email protected]>
5  * Copyright (C) 2013, 2015-2016 Attila Molnar <[email protected]>
6  * Copyright (C) 2012-2013, 2017-2019 Sadie Powell <[email protected]>
7  * Copyright (C) 2012 Robby <[email protected]>
8  * Copyright (C) 2009 Uli Schlachter <[email protected]>
9  * Copyright (C) 2009 Daniel De Graaf <[email protected]>
10  * Copyright (C) 2007-2009 Robin Burchell <[email protected]>
11  * Copyright (C) 2007 Dennis Friis <[email protected]>
12  * Copyright (C) 2006, 2010 Craig Edwards <[email protected]>
13  *
14  * This file is part of InspIRCd. InspIRCd is free software: you can
15  * redistribute it and/or modify it under the terms of the GNU General Public
16  * License as published by the Free Software Foundation, version 2.
17  *
18  * This program is distributed in the hope that it will be useful, but WITHOUT
19  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
21  * details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program. If not, see <http://www.gnu.org/licenses/>.
25  */
26 
27 
28 #pragma once
29 
30 #include "timer.h"
31 
32 class IOHook;
33 
37 enum BufferedSocketState
38 {
40  I_DISCONNECTED,
42  I_CONNECTING,
44  I_CONNECTED,
46  I_ERROR
47 };
48 
52 enum BufferedSocketError
53 {
55  I_ERR_NONE,
57  I_ERR_DISCONNECT,
59  I_ERR_TIMEOUT,
61  I_ERR_SOCKET,
63  I_ERR_CONNECT,
65  I_ERR_BIND,
67  I_ERR_WRITE,
69  I_ERR_NOMOREFDS,
71  I_ERR_OTHER
72 };
73 
74 /* Required forward declarations */
75 class BufferedSocket;
76 
79 class CoreExport SocketTimeout : public Timer
80 {
81  private:
84  BufferedSocket* sock;
85 
88  int sfd;
89 
90  public:
96  SocketTimeout(int fd, BufferedSocket* thesock, unsigned int secs_from_now)
97  : Timer(secs_from_now)
98  , sock(thesock)
99  , sfd(fd)
100  {
101  }
102 
105  bool Tick(time_t now) CXX11_OVERRIDE;
106 };
107 
112 class CoreExport StreamSocket : public EventHandler
113 {
114  public:
117  class SendQueue
118  {
119  public:
122  typedef std::string Element;
123 
126  typedef std::deque<Element> Container;
127 
130  typedef Container::const_iterator const_iterator;
131 
132  SendQueue() : nbytes(0) { }
133 
137  bool empty() const { return (nbytes == 0); }
138 
142  Container::size_type size() const { return data.size(); }
143 
147  size_t bytes() const { return nbytes; }
148 
152  const Element& front() const { return data.front(); }
153 
159  const_iterator begin() const { return data.begin(); }
160 
164  const_iterator end() const { return data.end(); }
165 
168  void pop_front()
169  {
170  nbytes -= data.front().length();
171  data.pop_front();
172  }
173 
177  void erase_front(Element::size_type n)
178  {
179  nbytes -= n;
180  data.front().erase(0, n);
181  }
182 
186  void push_front(const Element& newdata)
187  {
188  data.push_front(newdata);
189  nbytes += newdata.length();
190  }
191 
195  void push_back(const Element& newdata)
196  {
197  data.push_back(newdata);
198  nbytes += newdata.length();
199  }
200 
203  void clear()
204  {
205  data.clear();
206  nbytes = 0;
207  }
208 
209  void moveall(SendQueue& other)
210  {
211  nbytes += other.bytes();
212  data.insert(data.end(), other.data.begin(), other.data.end());
213  other.clear();
214  }
215 
216  private:
219  Container data;
220 
223  size_t nbytes;
224  };
225 
227  enum Type
228  {
229  SS_UNKNOWN,
230  SS_USER
231  };
232 
233  private:
235  bool closeonempty;
236 
238  bool closing;
239 
241  IOHook* iohook;
242 
245  SendQueue sendq;
246 
248  std::string error;
249 
253  void CheckError(BufferedSocketError err);
254 
257  void DoRead();
258 
263  void FlushSendQ(SendQueue& sq);
264 
269  int ReadToRecvQ(std::string& rq);
270 
279  int HookChainRead(IOHook* hook, std::string& rq);
280 
281  protected:
283  std::string recvq;
284 
288  void SwapInternals(StreamSocket& other);
289 
290  public:
291  const Type type;
292  StreamSocket(Type sstype = SS_UNKNOWN)
293  : closeonempty(false)
294  , closing(false)
295  , iohook(NULL)
296  , type(sstype)
297  {
298  }
299  IOHook* GetIOHook() const;
300  void AddIOHook(IOHook* hook);
301  void DelIOHook();
302 
305  void DoWrite();
306 
309  void OnEventHandlerRead() CXX11_OVERRIDE;
310 
313  void OnEventHandlerWrite() CXX11_OVERRIDE;
314 
318  void OnEventHandlerError(int errcode) CXX11_OVERRIDE;
319 
321  void SetError(const std::string& err) { if (error.empty()) error = err; }
322 
324  const std::string& getError() const { return error; }
325 
327  virtual void OnDataReady() = 0;
329  virtual void OnError(BufferedSocketError e) = 0;
330 
336  virtual bool OnSetEndPoint(const irc::sockets::sockaddrs& local, const irc::sockets::sockaddrs& remote);
337 
340  void WriteData(const std::string& data);
346  bool GetNextLine(std::string& line, char delim = '\n');
348  size_t getSendQSize() const;
349 
350  SendQueue& GetSendQ() { return sendq; }
351 
355  virtual void Close();
356 
358  void Close(bool writeblock);
359 
361  CullResult cull() CXX11_OVERRIDE;
362 
367  IOHook* GetModHook(Module* mod) const;
368 };
378 class CoreExport BufferedSocket : public StreamSocket
379 {
380  public:
384 
390  BufferedSocketState state;
391 
392  BufferedSocket();
400  BufferedSocket(int newfd);
401 
410  void DoConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned int maxtime);
411 
415  virtual void OnConnected();
416 
420  void OnDataReady() CXX11_OVERRIDE = 0;
421 
431  virtual void OnTimeout();
432 
433  virtual ~BufferedSocket();
434  protected:
435  void OnEventHandlerWrite() CXX11_OVERRIDE;
436  BufferedSocketError BeginConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned int timeout);
437 };
438 
439 inline IOHook* StreamSocket::GetIOHook() const { return iohook; }
440 inline void StreamSocket::DelIOHook() { iohook = NULL; }
StreamSocket::SendQueue::push_back
void push_back(const Element &newdata)
Definition: inspsocket.h:195
StreamSocket::SendQueue::const_iterator
Container::const_iterator const_iterator
Definition: inspsocket.h:130
SocketTimeout::SocketTimeout
SocketTimeout(int fd, BufferedSocket *thesock, unsigned int secs_from_now)
Definition: inspsocket.h:96
BufferedSocket::state
BufferedSocketState state
Definition: inspsocket.h:390
StreamSocket::SendQueue::clear
void clear()
Definition: inspsocket.h:203
Timer::Tick
virtual bool Tick(time_t TIME)=0
IOHook
Definition: iohook.h:67
classbase::cull
virtual CullResult cull()
Definition: base.cpp:41
EventHandler
Definition: socketengine.h:157
StreamSocket::getError
const std::string & getError() const
Definition: inspsocket.h:324
StreamSocket::SendQueue::erase_front
void erase_front(Element::size_type n)
Definition: inspsocket.h:177
StreamSocket::Type
Type
Definition: inspsocket.h:227
StreamSocket
Definition: inspsocket.h:112
StreamSocket::SendQueue::bytes
size_t bytes() const
Definition: inspsocket.h:147
irc::sockets::sockaddrs
Definition: socket.h:62
StreamSocket::SendQueue::Container
std::deque< Element > Container
Definition: inspsocket.h:126
StreamSocket::recvq
std::string recvq
Definition: inspsocket.h:283
StreamSocket::SendQueue::push_front
void push_front(const Element &newdata)
Definition: inspsocket.h:186
StreamSocket::SendQueue::front
const Element & front() const
Definition: inspsocket.h:152
BufferedSocket
Definition: inspsocket.h:378
SocketTimeout
Definition: inspsocket.h:79
StreamSocket::SendQueue::size
Container::size_type size() const
Definition: inspsocket.h:142
StreamSocket::SendQueue::end
const_iterator end() const
Definition: inspsocket.h:164
Module
Definition: modules.h:247
CullResult
Definition: base.h:36
StreamSocket::SendQueue::pop_front
void pop_front()
Definition: inspsocket.h:168
StreamSocket::SendQueue::empty
bool empty() const
Definition: inspsocket.h:137
Timer
Definition: timer.h:41
BufferedSocket::Timeout
SocketTimeout * Timeout
Definition: inspsocket.h:383
StreamSocket::SendQueue::Element
std::string Element
Definition: inspsocket.h:122
irc
Definition: hashcomp.h:75
EventHandler::SwapInternals
void SwapInternals(EventHandler &other)
Definition: socketengine.cpp:58
EventHandler::OnEventHandlerRead
virtual void OnEventHandlerRead()=0
StreamSocket::SendQueue::begin
const_iterator begin() const
Definition: inspsocket.h:159
StreamSocket::SendQueue
Definition: inspsocket.h:117