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
40namespace 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///
58class GNet::ServerPeer : private EventHandler , public Connection , private SocketProtocolSink , public ExceptionSource , private EventLogging
59{
60public:
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
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
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
133protected:
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
177private: // 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
184protected:
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
191public:
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
200private:
201 void onIdleTimeout() ;
202 bool onDataImp( const char * , std::size_t , std::size_t , std::size_t , char ) ;
203
204private:
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
215inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_idle_timeout( unsigned int t ) noexcept { idle_timeout = t ; return *this ; }
216inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_kick_idle_timer_on_send( bool b ) noexcept { kick_idle_timer_on_send = b ; return *this ; }
217inline 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 ; }
218inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_socket_protocol_config( const SocketProtocol::Config & config ) { socket_protocol_config = config ; return *this ; }
219inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_no_throw_on_peer_disconnect( bool b ) noexcept { no_throw_on_peer_disconnect = b ; return *this ; }
220inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_log_address( bool b ) noexcept { log_address = b ; return *this ; }
221inline GNet::ServerPeer::Config & GNet::ServerPeer::Config::set_log_port( bool b ) noexcept { log_port = b ; return *this ; }
222
223#endif
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:63
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
An interface for GNet classes that define a logging context string.
Definition: geventlogging.h:47
A lightweight object containing an ExceptionHandler pointer, optional ExceptionSource pointer and opt...
Definition: geventstate.h:131
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:341
A class that does line buffering, supporting auto-detection of line endings and fixed-size block extr...
Definition: glinebuffer.h:84
A move-only structure used in GNet::Server::newPeer() and containing the new socket.
Definition: gserver.h:142
An abstract base class for the GNet::Server's connection to a remote client.
Definition: gserverpeer.h:59
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
void addReadHandler()
Re-adds the socket() read handler.
Definition: gserverpeer.cpp:99
void dropReadHandler()
Drops the socket() read handler.
Definition: gserverpeer.cpp:94
~ServerPeer() override
Destructor.
Definition: gserverpeer.cpp:52
static std::string eventLoggingString(const Address &, const Config &)
Assembles an event logging string for a new ServerPeer object.
Definition: gserverpeer.cpp:58
bool secureAcceptCapable() const
Returns true if secureAccept() is usable.
Definition: gserverpeer.cpp:76
void secureAccept()
Waits for the peer to start a secure session.
Definition: gserverpeer.cpp:71
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.
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 GNet::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.
ServerPeer(EventState, ServerPeerInfo &&, const LineBuffer::Config &)
Constructor.
Definition: gserverpeer.cpp:29
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:88
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.
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:356
A timer class template in which the timeout is delivered to the specified method.
Definition: gtimer.h:141
Network classes.
Definition: gdef.h:1243
constexpr const char * tx(const char *p) noexcept
A briefer alternative to G::gettext_noop().
Definition: ggettext.h:84
A configuration structure for GNet::LineBuffer.
Definition: glinebuffer.h:92
A configuration structure for GNet::ServerPeer.
Definition: gserverpeer.h:64
A configuration structure for GNet::SocketProtocol.