E-MailRelay

gserverpeer.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2024 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 "geventlogging.h"
33#include "gexceptionsource.h"
34#include "gevent.h"
35#include "gstringview.h"
36#include <utility>
37#include <memory>
38#include <string>
39
40 namespace GNet
41{
42 class Server ;
43 class ServerPeer ;
44 class ServerPeerInfo ;
45}
46
47//| \class GNet::ServerPeer
48/// An abstract base class for the GNet::Server's connection to a remote
49/// client. Instances are created on the heap by the Server::newPeer()
50/// override. Exceptions thrown from event handlers are delivered to
51/// the owning Server and result in a call to the relevant ServerPeer's
52/// onDelete() method followed by its deletion. Every ServerPeer can
53/// do line buffering, but line-buffering can be effectively disabled
54/// by configuring the line buffer as transparent.
55///
56/// \see GNet::Server, GNet::EventHandler
57///
58 class GNet::ServerPeer : private EventHandler , public Connection , private SocketProtocolSink , public ExceptionSource , private EventLogging
59{
60 public:
61 G_EXCEPTION( IdleTimeout , tx("idle timeout") )
62
63 struct Config /// A configuration structure for GNet::ServerPeer.
64 {
65 SocketProtocol::Config socket_protocol_config ;
66 unsigned int idle_timeout {0U} ;
67 bool kick_idle_timer_on_send {false} ; // idle timeout when nothing received (false) or sent-or-received (true)
68 bool no_throw_on_peer_disconnect {false} ; // see SocketProtocolSink::onPeerDisconnect()
69 bool log_address {false} ;
70 bool log_port {false} ;
71 Config & set_socket_protocol_config( const SocketProtocol::Config & ) ;
72 Config & set_idle_timeout( unsigned int ) noexcept ;
73 Config & set_kick_idle_timer_on_send( bool = true ) noexcept ;
74 Config & set_no_throw_on_peer_disconnect( bool = true ) noexcept ;
75 Config & set_all_timeouts( unsigned int ) noexcept ;
76 Config & set_log_address( bool = true ) noexcept ;
77 Config & set_log_port( bool = true ) noexcept ;
78 } ;
79
80 ServerPeer( EventState , ServerPeerInfo && , const LineBuffer::Config & ) ;
81 ///< Constructor. This constructor is only used from within the
82 ///< override of GNet::Server::newPeer(). The EventState exception
83 ///< source refers to the owning Server.
84
85 ~ServerPeer() override ;
86 ///< Destructor.
87
88 bool send( const std::string & data ) ;
89 ///< Sends data down the socket to the peer. Returns true if completely
90 ///< sent; returns false if flow control asserted (see onSendComplete()).
91 ///< If flow control is asserted then there should be no new calls to
92 ///< send() until onSendComplete() is triggered.
93 ///< Throws on error.
94
95 bool send( std::string_view data ) ;
96 ///< Overload for string_view.
97
98 bool send( const std::vector<std::string_view> & data , std::size_t offset = 0U ) ;
99 ///< Overload to send data using scatter-gather segments. If false is
100 ///< returned then segment data pointers must stay valid until
101 ///< onSendComplete() is triggered.
102
103 Address localAddress() const override ;
104 ///< Returns the local address. Throws on error.
105 ///< Override from GNet::Connection.
106
107 Address peerAddress() const override ;
108 ///< Returns the peer address. Throws on error.
109 ///< Override from GNet::Connection.
110
111 std::string connectionState() const override ;
112 ///< Returns the connection state display string.
113 ///< Override from GNet::Connection.
114
115 std::string peerCertificate() const override ;
116 ///< Returns the peer's TLS certificate.
117 ///< Override from GNet::Connection.
118
119 LineBufferState lineBuffer() const ;
120 ///< Returns information about the state of the internal
121 ///< line-buffer.
122
123 void setIdleTimeout( unsigned int seconds ) ;
124 ///< Sets the idle timeout.
125
126 void doOnDelete( const std::string & reason , bool done ) ;
127 ///< Used by the GNet::Server class to call onDelete().
128
129 static std::string eventLoggingString( const Address & , const Config & ) ;
130 ///< Assembles an event logging string for a new
131 ///< ServerPeer object.
132
133 protected:
134 virtual void onSendComplete() = 0 ;
135 ///< Called after flow-control has been released and all
136 ///< residual data sent.
137
138 virtual bool onReceive( const char * data , std::size_t size , std::size_t eolsize , std::size_t linesize , char c0 ) = 0 ;
139 ///< Called on receipt of a complete line of data.
140 ///< This method is the sink function for the internal
141 ///< GNet::LineBuffer. See GNet::LineBuffer::apply().
142
143 virtual void onDelete( const std::string & reason ) = 0 ;
144 ///< Called just before the Server deletes this ServerPeer as
145 ///< the result of an exception (but not as a result of Server
146 ///< destruction). The reason is the empty string if caused
147 ///< by a GNet::Done exception. Consider making the implementation
148 ///< non-throwing, in the spirit of a destructor, since the
149 ///< ServerPeer object is about to be deleted.
150
151 void secureAccept() ;
152 ///< Waits for the peer to start a secure session. Uses a
153 ///< profile called "server" by default; see GSsl::Library::addProfile().
154 ///< The callback GNet::SocketProtocolSink::onSecure() is
155 ///< triggered when the secure session is established.
156
157 bool secureAcceptCapable() const ;
158 ///< Returns true if secureAccept() is usable.
159
160 StreamSocket & socket() ;
161 ///< Returns a reference to the client-server connection
162 ///< socket.
163
164 void dropReadHandler() ;
165 ///< Drops the socket() read handler.
166
167 void addReadHandler() ;
168 ///< Re-adds the socket() read handler.
169
170 void expect( std::size_t ) ;
171 ///< Modifies the line buffer state so that it delivers
172 ///< a chunk of non-line-delimited data.
173
174 void finish() ;
175 ///< Does a socket shutdown(). See also GNet::Client::finish().
176
177 private: // overrides
178 void readEvent() override ; // GNet::EventHandler
179 void writeEvent() override ; // GNet::EventHandler
180 void otherEvent( EventHandler::Reason ) override ; // GNet::EventHandler
181 void onPeerDisconnect() override ; // GNet::SocketProtocolSink
182 std::string_view eventLoggingString() const override ; // GNet::EventLogging
183
184 protected:
185 void onData( const char * , std::size_t ) override ;
186 ///< Override from GNet::SocketProtocolSink.
187 ///<
188 ///< Protected and non-final to allow derived classes
189 ///< to ignore incoming data for DoS prevention.
190
191 public:
192 ServerPeer( const ServerPeer & ) = delete ;
193 ServerPeer( ServerPeer && ) = delete ;
194 ServerPeer & operator=( const ServerPeer & ) = delete ;
195 ServerPeer & operator=( ServerPeer && ) = delete ;
196 bool send( const char * , std::size_t offset ) = delete ;
197 bool send( const char * ) = delete ;
198 bool send( const std::string & , std::size_t offset ) = delete ;
199
200 private:
201 void onIdleTimeout() ;
202 bool onDataImp( const char * , std::size_t , std::size_t , std::size_t , char ) ;
203
204 private:
205 EventState m_es ;
206 Address m_address ;
207 std::unique_ptr<StreamSocket> m_socket ; // order dependency -- first
208 SocketProtocol m_sp ; // order dependency -- second
209 LineBuffer m_line_buffer ;
210 Config m_config ;
211 Timer<ServerPeer> m_idle_timer ;
212 std::string m_event_logging_string ;
213} ;
214
215 inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_idle_timeout( unsigned int t ) noexcept { idle_timeout = t ; return *this ; }
216 inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_kick_idle_timer_on_send( bool b ) noexcept { kick_idle_timer_on_send = b ; return *this ; }
217 inline 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 ; }
218 inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_socket_protocol_config( const SocketProtocol::Config & config ) { socket_protocol_config = config ; return *this ; }
219 inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_no_throw_on_peer_disconnect( bool b ) noexcept { no_throw_on_peer_disconnect = b ; return *this ; }
220 inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_log_address( bool b ) noexcept { log_address = b ; return *this ; }
221 inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_log_port( bool b ) noexcept { log_port = b ; return *this ; }
222
223#endif
GNet::Address
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:63
GNet::Connection
An abstract interface which provides information about a network connection.
Definition: gconnection.h:38
GNet::EventHandler
A base class for classes that have a file descriptor and handle asynchronous events from the event lo...
Definition: geventhandler.h:48
GNet::EventLogging
An interface for GNet classes that define a logging context string.
Definition: geventlogging.h:47
GNet::EventState
A lightweight object containing an ExceptionHandler pointer, optional ExceptionSource pointer and opt...
Definition: geventstate.h:131
GNet::ExceptionSource
A mixin base class that identifies the source of an exception when delivered to GNet::ExceptionHandle...
Definition: gexceptionsource.h:39
GNet::LineBufferState
Provides information about the state of a line buffer.
Definition: glinebuffer.h:341
GNet::LineBuffer
A class that does line buffering, supporting auto-detection of line endings and fixed-size block extr...
Definition: glinebuffer.h:84
GNet::ServerPeerInfo
A move-only structure used in GNet::Server::newPeer() and containing the new socket.
Definition: gserver.h:142
GNet::ServerPeer
An abstract base class for the GNet::Server's connection to a remote client.
Definition: gserverpeer.h:59
GNet::ServerPeer::expect
void expect(std::size_t)
Modifies the line buffer state so that it delivers a chunk of non-line-delimited data.
Definition: gserverpeer.cpp:82
GNet::ServerPeer::addReadHandler
void addReadHandler()
Re-adds the socket() read handler.
Definition: gserverpeer.cpp:99
GNet::ServerPeer::dropReadHandler
void dropReadHandler()
Drops the socket() read handler.
Definition: gserverpeer.cpp:94
GNet::ServerPeer::~ServerPeer
~ServerPeer() override
Destructor.
Definition: gserverpeer.cpp:52
GNet::ServerPeer::eventLoggingString
static std::string eventLoggingString(const Address &, const Config &)
Assembles an event logging string for a new ServerPeer object.
Definition: gserverpeer.cpp:58
GNet::ServerPeer::secureAcceptCapable
bool secureAcceptCapable() const
Returns true if secureAccept() is usable.
Definition: gserverpeer.cpp:76
GNet::ServerPeer::secureAccept
void secureAccept()
Waits for the peer to start a secure session.
Definition: gserverpeer.cpp:71
GNet::ServerPeer::onReceive
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 a complete line of data.
GNet::ServerPeer::peerAddress
Address peerAddress() const override
Returns the peer address.
Definition: gserverpeer.cpp:121
GNet::ServerPeer::connectionState
std::string connectionState() const override
Returns the connection state display string.
Definition: gserverpeer.cpp:126
GNet::ServerPeer::doOnDelete
void doOnDelete(const std::string &reason, bool done)
Used by the GNet::Server class to call onDelete().
Definition: gserverpeer.cpp:165
GNet::ServerPeer::setIdleTimeout
void setIdleTimeout(unsigned int seconds)
Sets the idle timeout.
Definition: gserverpeer.cpp:204
GNet::ServerPeer::localAddress
Address localAddress() const override
Returns the local address.
Definition: gserverpeer.cpp:115
GNet::ServerPeer::lineBuffer
LineBufferState lineBuffer() const
Returns information about the state of the internal line-buffer.
Definition: gserverpeer.cpp:193
GNet::ServerPeer::ServerPeer
ServerPeer(EventState, ServerPeerInfo &&, const LineBuffer::Config &)
Constructor.
Definition: gserverpeer.cpp:29
GNet::ServerPeer::onDelete
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...
GNet::ServerPeer::peerCertificate
std::string peerCertificate() const override
Returns the peer's TLS certificate.
Definition: gserverpeer.cpp:131
GNet::ServerPeer::send
bool send(const std::string &data)
Sends data down the socket to the peer.
Definition: gserverpeer.cpp:136
GNet::ServerPeer::socket
StreamSocket & socket()
Returns a reference to the client-server connection socket.
Definition: gserverpeer.cpp:88
GNet::ServerPeer::onSendComplete
virtual void onSendComplete()=0
Called after flow-control has been released and all residual data sent.
GNet::ServerPeer::onData
void onData(const char *, std::size_t) override
Override from GNet::SocketProtocolSink.
Definition: gserverpeer.cpp:178
GNet::ServerPeer::finish
void finish()
Does a socket shutdown(). See also GNet::Client::finish().
Definition: gserverpeer.cpp:213
GNet::SocketProtocolSink
An interface used by GNet::SocketProtocol to deliver data from a socket.
Definition: gsocketprotocol.h:177
GNet::SocketProtocol
An interface for implementing a low-level TLS/SSL protocol layer on top of a connected non-blocking s...
Definition: gsocketprotocol.h:58
GNet::StreamSocket
A derivation of GNet::Socket for a stream socket.
Definition: gsocket.h:356
GNet::Timer
A timer class template in which the timeout is delivered to the specified method.
Definition: gtimer.h:141
gaddress.h
gconnection.h
gevent.h
geventlogging.h
gexception.h
gexceptionsource.h
glinebuffer.h
gsocket.h
gsocketprotocol.h
gstringview.h
gtimer.h
GNet
Network classes.
Definition: gdef.h:1243
G::tx
constexpr const char * tx(const char *p) noexcept
A briefer alternative to G::gettext_noop().
Definition: ggettext.h:84
GNet::LineBuffer::Config
A configuration structure for GNet::LineBuffer.
Definition: glinebuffer.h:92
GNet::ServerPeer::Config
A configuration structure for GNet::ServerPeer.
Definition: gserverpeer.h:64
GNet::SocketProtocol::Config
A configuration structure for GNet::SocketProtocol.
Definition: gsocketprotocol.h:70