InspIRCd  3.0
inspsocket.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  * Copyright (C) 2020 Matt Schatz <[email protected]>
5  * Copyright (C) 2019 linuxdaemon <[email protected]>
6  * Copyright (C) 2013, 2015-2016 Attila Molnar <[email protected]>
7  * Copyright (C) 2012-2013, 2017-2019 Sadie Powell <[email protected]>
8  * Copyright (C) 2012 Robby <[email protected]>
9  * Copyright (C) 2009 Uli Schlachter <[email protected]>
10  * Copyright (C) 2009 Daniel De Graaf <[email protected]>
11  * Copyright (C) 2007-2009 Robin Burchell <[email protected]>
12  * Copyright (C) 2007 Dennis Friis <[email protected]>
13  * Copyright (C) 2006, 2010 Craig Edwards <[email protected]>
14  *
15  * This file is part of InspIRCd. InspIRCd is free software: you can
16  * redistribute it and/or modify it under the terms of the GNU General Public
17  * License as published by the Free Software Foundation, version 2.
18  *
19  * This program is distributed in the hope that it will be useful, but WITHOUT
20  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
22  * details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program. If not, see <http://www.gnu.org/licenses/>.
26  */
27 
28 
29 #pragma once
30 
31 #include "timer.h"
32 
33 class IOHook;
34 
38 enum BufferedSocketState
39 {
41  I_DISCONNECTED,
43  I_CONNECTING,
45  I_CONNECTED,
47  I_ERROR
48 };
49 
53 enum BufferedSocketError
54 {
56  I_ERR_NONE,
58  I_ERR_DISCONNECT,
60  I_ERR_TIMEOUT,
62  I_ERR_SOCKET,
64  I_ERR_CONNECT,
66  I_ERR_BIND,
68  I_ERR_WRITE,
70  I_ERR_NOMOREFDS,
72  I_ERR_OTHER
73 };
74 
75 /* Required forward declarations */
76 class BufferedSocket;
77 
80 class CoreExport SocketTimeout : public Timer
81 {
82  private:
85  BufferedSocket* sock;
86 
89  int sfd;
90 
91  public:
97  SocketTimeout(int fd, BufferedSocket* thesock, unsigned int secs_from_now)
98  : Timer(secs_from_now)
99  , sock(thesock)
100  , sfd(fd)
101  {
102  }
103 
106  bool Tick(time_t now) CXX11_OVERRIDE;
107 };
108 
113 class CoreExport StreamSocket : public EventHandler
114 {
115  public:
118  class SendQueue
119  {
120  public:
123  typedef std::string Element;
124 
127  typedef std::deque<Element> Container;
128 
131  typedef Container::const_iterator const_iterator;
132 
133  SendQueue() : nbytes(0) { }
134 
138  bool empty() const { return (nbytes == 0); }
139 
143  Container::size_type size() const { return data.size(); }
144 
148  size_t bytes() const { return nbytes; }
149 
153  const Element& front() const { return data.front(); }
154 
160  const_iterator begin() const { return data.begin(); }
161 
165  const_iterator end() const { return data.end(); }
166 
169  void pop_front()
170  {
171  nbytes -= data.front().length();
172  data.pop_front();
173  }
174 
178  void erase_front(Element::size_type n)
179  {
180  nbytes -= n;
181  data.front().erase(0, n);
182  }
183 
187  void push_front(const Element& newdata)
188  {
189  data.push_front(newdata);
190  nbytes += newdata.length();
191  }
192 
196  void push_back(const Element& newdata)
197  {
198  data.push_back(newdata);
199  nbytes += newdata.length();
200  }
201 
204  void clear()
205  {
206  data.clear();
207  nbytes = 0;
208  }
209 
210  void moveall(SendQueue& other)
211  {
212  nbytes += other.bytes();
213  data.insert(data.end(), other.data.begin(), other.data.end());
214  other.clear();
215  }
216 
217  private:
220  Container data;
221 
224  size_t nbytes;
225  };
226 
228  enum Type
229  {
230  SS_UNKNOWN,
231  SS_USER
232  };
233 
234  private:
236  bool closeonempty;
237 
239  bool closing;
240 
242  IOHook* iohook;
243 
246  SendQueue sendq;
247 
249  std::string error;
250 
254  void CheckError(BufferedSocketError err);
255 
258  void DoRead();
259 
264  void FlushSendQ(SendQueue& sq);
265 
270  int ReadToRecvQ(std::string& rq);
271 
280  int HookChainRead(IOHook* hook, std::string& rq);
281 
282  protected:
284  std::string recvq;
285 
289  void SwapInternals(StreamSocket& other);
290 
291  public:
292  const Type type;
293  StreamSocket(Type sstype = SS_UNKNOWN)
294  : closeonempty(false)
295  , closing(false)
296  , iohook(NULL)
297  , type(sstype)
298  {
299  }
300  IOHook* GetIOHook() const;
301  void AddIOHook(IOHook* hook);
302  void DelIOHook();
303 
306  void DoWrite();
307 
310  void OnEventHandlerRead() CXX11_OVERRIDE;
311 
314  void OnEventHandlerWrite() CXX11_OVERRIDE;
315 
319  void OnEventHandlerError(int errcode) CXX11_OVERRIDE;
320 
322  void SetError(const std::string& err) { if (error.empty()) error = err; }
323 
325  const std::string& getError() const { return error; }
326 
328  virtual void OnDataReady() = 0;
330  virtual void OnError(BufferedSocketError e) = 0;
331 
337  virtual bool OnSetEndPoint(const irc::sockets::sockaddrs& local, const irc::sockets::sockaddrs& remote);
338 
341  void WriteData(const std::string& data);
347  bool GetNextLine(std::string& line, char delim = '\n');
349  size_t getSendQSize() const;
350 
351  SendQueue& GetSendQ() { return sendq; }
352 
356  virtual void Close();
357 
359  void Close(bool writeblock);
360 
362  CullResult cull() CXX11_OVERRIDE;
363 
368  IOHook* GetModHook(Module* mod) const;
369 
373  IOHook* GetLastHook() const;
374 };
384 class CoreExport BufferedSocket : public StreamSocket
385 {
386  public:
390 
396  BufferedSocketState state;
397 
398  BufferedSocket();
406  BufferedSocket(int newfd);
407 
416  void DoConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned int maxtime);
417 
421  virtual void OnConnected();
422 
426  void OnDataReady() CXX11_OVERRIDE = 0;
427 
437  virtual void OnTimeout();
438 
439  virtual ~BufferedSocket();
440  protected:
441  void OnEventHandlerWrite() CXX11_OVERRIDE;
442  BufferedSocketError BeginConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned int timeout);
443 };
444 
445 inline IOHook* StreamSocket::GetIOHook() const { return iohook; }
446 inline void StreamSocket::DelIOHook() { iohook = NULL; }
StreamSocket::SendQueue::push_back
void push_back(const Element &newdata)
Definition: inspsocket.h:196
StreamSocket::SendQueue::const_iterator
Container::const_iterator const_iterator
Definition: inspsocket.h:131
SocketTimeout::SocketTimeout
SocketTimeout(int fd, BufferedSocket *thesock, unsigned int secs_from_now)
Definition: inspsocket.h:97
BufferedSocket::state
BufferedSocketState state
Definition: inspsocket.h:396
StreamSocket::SendQueue::clear
void clear()
Definition: inspsocket.h:204
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:325
StreamSocket::SendQueue::erase_front
void erase_front(Element::size_type n)
Definition: inspsocket.h:178
StreamSocket::Type
Type
Definition: inspsocket.h:228
StreamSocket
Definition: inspsocket.h:113
StreamSocket::SendQueue::bytes
size_t bytes() const
Definition: inspsocket.h:148
irc::sockets::sockaddrs
Definition: socket.h:62
StreamSocket::SendQueue::Container
std::deque< Element > Container
Definition: inspsocket.h:127
StreamSocket::recvq
std::string recvq
Definition: inspsocket.h:284
StreamSocket::SendQueue::push_front
void push_front(const Element &newdata)
Definition: inspsocket.h:187
StreamSocket::SendQueue::front
const Element & front() const
Definition: inspsocket.h:153
BufferedSocket
Definition: inspsocket.h:384
SocketTimeout
Definition: inspsocket.h:80
StreamSocket::SendQueue::size
Container::size_type size() const
Definition: inspsocket.h:143
StreamSocket::SendQueue::end
const_iterator end() const
Definition: inspsocket.h:165
Module
Definition: modules.h:316
CullResult
Definition: base.h:37
StreamSocket::SendQueue::pop_front
void pop_front()
Definition: inspsocket.h:169
StreamSocket::SendQueue::empty
bool empty() const
Definition: inspsocket.h:138
Timer
Definition: timer.h:41
BufferedSocket::Timeout
SocketTimeout * Timeout
Definition: inspsocket.h:389
StreamSocket::SendQueue::Element
std::string Element
Definition: inspsocket.h:123
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:160
StreamSocket::SendQueue
Definition: inspsocket.h:118