E-MailRelay
gserverpeer.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2023 Graeme Walker <graeme_walker@users.sourceforge.net>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16// ===
17///
18/// \file gserverpeer.h
19///
20
21#ifndef G_NET_SERVER_PEER_H
22#define G_NET_SERVER_PEER_H
23
24#include "gdef.h"
25#include "gsocket.h"
26#include "gsocketprotocol.h"
27#include "gexception.h"
28#include "gaddress.h"
29#include "glinebuffer.h"
30#include "gtimer.h"
31#include "gconnection.h"
32#include "gexceptionsource.h"
33#include "gevent.h"
34#include "gstringview.h"
35#include <utility>
36#include <memory>
37#include <string>
38
39namespace GNet
40{
41 class Server ;
42 class ServerPeer ;
43 class ServerPeerInfo ;
44}
45
46//| \class GNet::ServerPeer
47/// An abstract base class for the GNet::Server's connection to a remote
48/// client. Instances are created on the heap by the Server::newPeer()
49/// override. Exceptions thrown from event handlers are delivered to
50/// the owning Server and result in a call to the relevant ServerPeer's
51/// onDelete() method followed by its deletion. Every ServerPeer can
52/// do line buffering, but line-buffering can be effectively disabled
53/// by configuring the line buffer as transparent.
54///
55/// \see GNet::Server, GNet::EventHandler
56///
58{
59public:
60 G_EXCEPTION( IdleTimeout , tx("idle timeout") ) ;
61
62 struct Config /// A configuration structure for GNet::ServerPeer.
63 {
64 SocketProtocol::Config socket_protocol_config ;
65 unsigned int idle_timeout {0U} ;
66 bool kick_idle_timer_on_send {false} ; // idle timeout when nothing received (false) or sent-or-received (true)
67 bool no_throw_on_peer_disconnect {false} ; // see SocketProtocolSink::onPeerDisconnect()
68 Config & set_socket_protocol_config( const SocketProtocol::Config & ) ;
69 Config & set_idle_timeout( unsigned int ) noexcept ;
70 Config & set_kick_idle_timer_on_send( bool = true ) noexcept ;
71 Config & set_no_throw_on_peer_disconnect( bool = true ) noexcept ;
72 Config & set_all_timeouts( unsigned int ) noexcept ;
73 } ;
74
76 ///< Constructor. This constructor is only used from within the
77 ///< override of GNet::Server::newPeer(). The ExceptionSink refers
78 ///< to the owning Server.
79
80 ~ServerPeer() override ;
81 ///< Destructor.
82
83 bool send( const std::string & data ) ;
84 ///< Sends data down the socket to the peer. Returns true if completely
85 ///< sent; returns false if flow control asserted (see onSendComplete()).
86 ///< If flow control is asserted then there should be no new calls to
87 ///< send() until onSendComplete() is triggered.
88 ///< Throws on error.
89
90 bool send( G::string_view data ) ;
91 ///< Overload for string_view.
92
93 bool send( const std::vector<G::string_view> & data , std::size_t offset = 0U ) ;
94 ///< Overload to send data using scatter-gather segments. If false is
95 ///< returned then segment data pointers must stay valid until
96 ///< onSendComplete() is triggered.
97
98 Address localAddress() const override ;
99 ///< Returns the local address. Throws on error.
100 ///< Override from GNet::Connection.
101
102 Address peerAddress() const override ;
103 ///< Returns the peer address. Throws on error.
104 ///< Override from GNet::Connection.
105
106 std::string connectionState() const override ;
107 ///< Returns the connection state display string.
108 ///< Override from GNet::Connection.
109
110 std::string peerCertificate() const override ;
111 ///< Returns the peer's TLS certificate.
112 ///< Override from GNet::Connection.
113
114 void doOnDelete( const std::string & reason , bool done ) ;
115 ///< Used by the Server class to call onDelete().
116
118 ///< Returns information about the state of the internal
119 ///< line-buffer.
120
121 void setIdleTimeout( unsigned int seconds ) ;
122 ///< Sets the idle timeout.
123
124protected:
125 virtual void onSendComplete() = 0 ;
126 ///< Called after flow-control has been released and all
127 ///< residual data sent.
128
129 virtual bool onReceive( const char * data , std::size_t size , std::size_t eolsize , std::size_t linesize , char c0 ) = 0 ;
130 ///< Called on receipt of data. See GNet::LineBuffer.
131
132 virtual void onDelete( const std::string & reason ) = 0 ;
133 ///< Called just before the Server deletes this ServerPeer as
134 ///< the result of an exception (but not as a result of Server
135 ///< destruction). The reason is the empty string if caused
136 ///< by a GNet::Done exception. Consider making the implementation
137 ///< non-throwing, in the spirit of a destructor, since the
138 ///< ServerPeer object is about to be deleted.
139
140 void secureAccept() ;
141 ///< Waits for the peer to start a secure session. Uses a
142 ///< profile called "server" by default; see GSsl::Library::addProfile().
143 ///< The callback GNet::SocketProtocolSink::onSecure() is
144 ///< triggered when the secure session is established.
145
146 bool secureAcceptCapable() const ;
147 ///< Returns true if secureAccept() is usable.
148
149 StreamSocket & socket() ;
150 ///< Returns a reference to the client-server connection
151 ///< socket.
152
153 void dropReadHandler() ;
154 ///< Drops the socket() read handler.
155
156 void addReadHandler() ;
157 ///< Re-adds the socket() read handler.
158
159 void expect( std::size_t ) ;
160 ///< Modifies the line buffer state so that it delivers
161 ///< a chunk of non-line-delimited data.
162
163 void finish() ;
164 ///< Does a socket shutdown(). See also GNet::Client::finish().
165
166private: // overrides
167 void readEvent() override ; // Override from GNet::EventHandler.
168 void writeEvent() override ; // Override from GNet::EventHandler.
169 void otherEvent( EventHandler::Reason ) override ; // Override from GNet::EventHandler.
170 void onPeerDisconnect() override ; // Override from GNet::SocketProtocolSink.
171 std::string exceptionSourceId() const override ; // Override from GNet::ExceptionSource.
172
173protected:
174 void onData( const char * , std::size_t ) override ;
175 ///< Override from GNet::SocketProtocolSink.
176 ///<
177 ///< Protected and non-final to allow derived classes
178 ///< to ignore incoming data for DoS prevention.
179
180public:
181 ServerPeer( const ServerPeer & ) = delete ;
182 ServerPeer( ServerPeer && ) = delete ;
183 ServerPeer & operator=( const ServerPeer & ) = delete ;
184 ServerPeer & operator=( ServerPeer && ) = delete ;
185 bool send( const char * , std::size_t offset ) = delete ;
186 bool send( const char * ) = delete ;
187 bool send( const std::string & , std::size_t offset ) = delete ;
188
189private:
190 void onIdleTimeout() ;
191 bool onDataImp( const char * , std::size_t , std::size_t , std::size_t , char ) ;
192
193private:
194 ExceptionSink m_es ;
195 Address m_address ;
196 std::unique_ptr<StreamSocket> m_socket ; // order dependency -- first
197 SocketProtocol m_sp ; // order dependency -- second
198 LineBuffer m_line_buffer ;
199 Config m_config ;
200 Timer<ServerPeer> m_idle_timer ;
201 mutable std::string m_exception_source_id ;
202} ;
203
204inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_idle_timeout( unsigned int t ) noexcept { idle_timeout = t ; return *this ; }
205inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_kick_idle_timer_on_send( bool b ) noexcept { kick_idle_timer_on_send = b ; return *this ; }
206inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_all_timeouts( unsigned int t ) noexcept { idle_timeout = t ; socket_protocol_config.secure_connection_timeout = t ; return *this ; }
207inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_socket_protocol_config( const SocketProtocol::Config & config ) { socket_protocol_config = config ; return *this ; }
208inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_no_throw_on_peer_disconnect( bool b ) noexcept { no_throw_on_peer_disconnect = b ; return *this ; }
209
210#endif
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:62
An abstract interface which provides information about a network connection.
Definition: gconnection.h:38
A base class for classes that have a file descriptor and handle asynchronous events from the event lo...
Definition: geventhandler.h:48
A tuple containing an ExceptionHandler interface pointer and a bound 'exception source' pointer.
A mixin base class that identifies the source of an exception when delivered to GNet::ExceptionHandle...
Provides information about the state of a line buffer.
Definition: glinebuffer.h:340
A class that does line buffering, supporting auto-detection of line endings and fixed-size block extr...
Definition: glinebuffer.h:83
A move-only structure used in GNet::Server::newPeer() and containing the new socket.
Definition: gserver.h:140
An abstract base class for the GNet::Server's connection to a remote client.
Definition: gserverpeer.h:58
void expect(std::size_t)
Modifies the line buffer state so that it delivers a chunk of non-line-delimited data.
Definition: gserverpeer.cpp:69
void addReadHandler()
Re-adds the socket() read handler.
Definition: gserverpeer.cpp:86
void dropReadHandler()
Drops the socket() read handler.
Definition: gserverpeer.cpp:81
~ServerPeer() override
Destructor.
Definition: gserverpeer.cpp:52
bool secureAcceptCapable() const
Returns true if secureAccept() is usable.
Definition: gserverpeer.cpp:63
void secureAccept()
Waits for the peer to start a secure session.
Definition: gserverpeer.cpp:58
virtual bool onReceive(const char *data, std::size_t size, std::size_t eolsize, std::size_t linesize, char c0)=0
Called on receipt of data. See GNet::LineBuffer.
Address peerAddress() const override
Returns the peer address.
std::string connectionState() const override
Returns the connection state display string.
void doOnDelete(const std::string &reason, bool done)
Used by the Server class to call onDelete().
void setIdleTimeout(unsigned int seconds)
Sets the idle timeout.
Address localAddress() const override
Returns the local address.
LineBufferState lineBuffer() const
Returns information about the state of the internal line-buffer.
virtual void onDelete(const std::string &reason)=0
Called just before the Server deletes this ServerPeer as the result of an exception (but not as a res...
std::string peerCertificate() const override
Returns the peer's TLS certificate.
bool send(const std::string &data)
Sends data down the socket to the peer.
StreamSocket & socket()
Returns a reference to the client-server connection socket.
Definition: gserverpeer.cpp:75
virtual void onSendComplete()=0
Called after flow-control has been released and all residual data sent.
void onData(const char *, std::size_t) override
Override from GNet::SocketProtocolSink.
ServerPeer(ExceptionSink, ServerPeerInfo &&, const LineBuffer::Config &)
Constructor.
Definition: gserverpeer.cpp:30
void finish()
Does a socket shutdown(). See also GNet::Client::finish().
An interface used by GNet::SocketProtocol to deliver data from a socket.
An interface for implementing a low-level TLS/SSL protocol layer on top of a connected non-blocking s...
A derivation of GNet::Socket for a stream socket.
Definition: gsocket.h:341
A timer class template in which the timeout is delivered to the specified method.
Definition: gtimer.h:141
A class like c++17's std::string_view.
Definition: gstringview.h:51
Network classes.
Definition: gdef.h:1144
constexpr const char * tx(const char *p)
A briefer alternative to G::gettext_noop().
Definition: ggettext.h:84
A configuration structure for GNet::LineBuffer.
Definition: glinebuffer.h:91
A configuration structure for GNet::ServerPeer.
Definition: gserverpeer.h:63
A configuration structure for GNet::SocketProtocol.