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, 2021 Sadie Powell <[email protected]>
8  * Copyright (C) 2012 Robby <[email protected]elgie.be>
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  * Copyright (C) 2006 Oliver Lupton <[email protected]>
15  *
16  * This file is part of InspIRCd. InspIRCd is free software: you can
17  * redistribute it and/or modify it under the terms of the GNU General Public
18  * License as published by the Free Software Foundation, version 2.
19  *
20  * This program is distributed in the hope that it will be useful, but WITHOUT
21  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
23  * details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program. If not, see <http://www.gnu.org/licenses/>.
27  */
28 
29 
30 #pragma once
31 
32 #include "timer.h"
33 
34 class IOHook;
35 
39 enum BufferedSocketState
40 {
42  I_DISCONNECTED,
44  I_CONNECTING,
46  I_CONNECTED,
48  I_ERROR
49 };
50 
54 enum BufferedSocketError
55 {
57  I_ERR_NONE,
59  I_ERR_DISCONNECT,
61  I_ERR_TIMEOUT,
63  I_ERR_SOCKET,
65  I_ERR_CONNECT,
67  I_ERR_BIND,
69  I_ERR_WRITE,
71  I_ERR_NOMOREFDS,
73  I_ERR_OTHER
74 };
75 
76 /* Required forward declarations */
77 class BufferedSocket;
78 
81 class CoreExport SocketTimeout : public Timer
82 {
83  private:
86  BufferedSocket* sock;
87 
90  int sfd;
91 
92  public:
98  SocketTimeout(int fd, BufferedSocket* thesock, unsigned int secs_from_now)
99  : Timer(secs_from_now)
100  , sock(thesock)
101  , sfd(fd)
102  {
103  }
104 
107  bool Tick(time_t now) CXX11_OVERRIDE;
108 };
109 
114 class CoreExport StreamSocket : public EventHandler
115 {
116  public:
119  class SendQueue
120  {
121  public:
124  typedef std::string Element;
125 
128  typedef std::deque<Element> Container;
129 
132  typedef Container::const_iterator const_iterator;
133 
134  SendQueue() : nbytes(0) { }
135 
139  bool empty() const { return (nbytes == 0); }
140 
144  Container::size_type size() const { return data.size(); }
145 
149  size_t bytes() const { return nbytes; }
150 
154  const Element& front() const { return data.front(); }
155 
161  const_iterator begin() const { return data.begin(); }
162 
166  const_iterator end() const { return data.end(); }
167 
170  void pop_front()
171  {
172  nbytes -= data.front().length();
173  data.pop_front();
174  }
175 
179  void erase_front(Element::size_type n)
180  {
181  nbytes -= n;
182  data.front().erase(0, n);
183  }
184 
188  void push_front(const Element& newdata)
189  {
190  data.push_front(newdata);
191  nbytes += newdata.length();
192  }
193 
197  void push_back(const Element& newdata)
198  {
199  data.push_back(newdata);
200  nbytes += newdata.length();
201  }
202 
205  void clear()
206  {
207  data.clear();
208  nbytes = 0;
209  }
210 
211  void moveall(SendQueue& other)
212  {
213  nbytes += other.bytes();
214  data.insert(data.end(), other.data.begin(), other.data.end());
215  other.clear();
216  }
217 
218  private:
221  Container data;
222 
225  size_t nbytes;
226  };
227 
229  enum Type
230  {
231  SS_UNKNOWN,
232  SS_USER
233  };
234 
235  private:
237  bool closeonempty;
238 
240  bool closing;
241 
243  IOHook* iohook;
244 
247  SendQueue sendq;
248 
250  std::string error;
251 
255  void CheckError(BufferedSocketError err);
256 
259  void DoRead();
260 
265  void FlushSendQ(SendQueue& sq);
266 
271  int ReadToRecvQ(std::string& rq);
272 
281  int HookChainRead(IOHook* hook, std::string& rq);
282 
283  protected:
285  std::string recvq;
286 
290  void SwapInternals(StreamSocket& other);
291 
292  public:
293  const Type type;
294  StreamSocket(Type sstype = SS_UNKNOWN)
295  : closeonempty(false)
296  , closing(false)
297  , iohook(NULL)
298  , type(sstype)
299  {
300  }
301  IOHook* GetIOHook() const;
302  void AddIOHook(IOHook* hook);
303  void DelIOHook();
304 
307  void DoWrite();
308 
311  void OnEventHandlerRead() CXX11_OVERRIDE;
312 
315  void OnEventHandlerWrite() CXX11_OVERRIDE;
316 
320  void OnEventHandlerError(int errcode) CXX11_OVERRIDE;
321 
323  void SetError(const std::string& err) { if (error.empty()) error = err; }
324 
326  const std::string& getError() const { return error; }
327 
329  virtual void OnDataReady() = 0;
331  virtual void OnError(BufferedSocketError e) = 0;
332 
338  virtual bool OnSetEndPoint(const irc::sockets::sockaddrs& local, const irc::sockets::sockaddrs& remote);
339 
342  void WriteData(const std::string& data);
348  bool GetNextLine(std::string& line, char delim = '\n');
350  size_t getSendQSize() const;
351 
352  SendQueue& GetSendQ() { return sendq; }
353 
357  virtual void Close();
358 
360  void Close(bool writeblock);
361 
363  CullResult cull() CXX11_OVERRIDE;
364 
369  IOHook* GetModHook(Module* mod) const;
370 
374  IOHook* GetLastHook() const;
375 };
385 class CoreExport BufferedSocket : public StreamSocket
386 {
387  public:
391 
397  BufferedSocketState state;
398 
399  BufferedSocket();
407  BufferedSocket(int newfd);
408 
417  void DoConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned int maxtime);
418 
422  virtual void OnConnected();
423 
427  void OnDataReady() CXX11_OVERRIDE = 0;
428 
438  virtual void OnTimeout();
439 
440  virtual ~BufferedSocket();
441  protected:
442  void OnEventHandlerWrite() CXX11_OVERRIDE;
443  BufferedSocketError BeginConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned int timeout);
444 };
445 
446 inline IOHook* StreamSocket::GetIOHook() const { return iohook; }
447 inline void StreamSocket::DelIOHook() { iohook = NULL; }
Definition: inspsocket.h:386
SocketTimeout * Timeout
Definition: inspsocket.h:390
BufferedSocketState state
Definition: inspsocket.h:397
void OnDataReady() CXX11_OVERRIDE=0
Definition: base.h:36
Definition: socketengine.h:154
Definition: iohook.h:68
Definition: modules.h:318
Definition: inspsocket.h:82
SocketTimeout(int fd, BufferedSocket *thesock, unsigned int secs_from_now)
Definition: inspsocket.h:98
Definition: inspsocket.h:120
Container::size_type size() const
Definition: inspsocket.h:144
const_iterator end() const
Definition: inspsocket.h:166
void erase_front(Element::size_type n)
Definition: inspsocket.h:179
const Element & front() const
Definition: inspsocket.h:154
Container::const_iterator const_iterator
Definition: inspsocket.h:132
bool empty() const
Definition: inspsocket.h:139
void clear()
Definition: inspsocket.h:205
void push_front(const Element &newdata)
Definition: inspsocket.h:188
const_iterator begin() const
Definition: inspsocket.h:161
size_t bytes() const
Definition: inspsocket.h:149
void push_back(const Element &newdata)
Definition: inspsocket.h:197
std::deque< Element > Container
Definition: inspsocket.h:128
std::string Element
Definition: inspsocket.h:124
void pop_front()
Definition: inspsocket.h:170
Definition: inspsocket.h:115
Type
Definition: inspsocket.h:230
virtual void OnError(BufferedSocketError e)=0
std::string recvq
Definition: inspsocket.h:285
virtual void OnDataReady()=0
const std::string & getError() const
Definition: inspsocket.h:326
Definition: timer.h:42
virtual bool Tick(time_t TIME)=0
Definition: hashcomp.h:68
Definition: socket.h:63