E-MailRelay

gserverpeer.cpp
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.cpp
19///
20
21#include "gdef.h"
22#include "gserver.h"
23#include "gmonitor.h"
24#include "glog.h"
25#include "gassert.h"
26#include <sstream>
27#include <utility>
28
29 GNet::ServerPeer::ServerPeer( EventState es , ServerPeerInfo && peer_info , const LineBuffer::Config & line_buffer_config ) : // NOLINT
30 EventLogging(es.logging()) ,
31 m_es(es.logging(this)) ,
32 m_address(peer_info.m_address) ,
33 m_socket(std::move(peer_info.m_socket)) ,
34 m_sp(*this,m_es,*this,*m_socket,peer_info.m_server_peer_config.socket_protocol_config) ,
35 m_line_buffer(line_buffer_config) ,
36 m_config(peer_info.m_server_peer_config) ,
37 m_idle_timer(*this,&ServerPeer::onIdleTimeout,m_es) ,
38 m_event_logging_string(eventLoggingString(peerAddress(),peer_info.m_server_peer_config))
39{
40 G_ASSERT( peer_info.m_server != nullptr ) ;
41 G_ASSERT( m_socket.get() ) ;
42 G_DEBUG( "GNet::ServerPeer::ctor: [" << this << "]: port " << m_address.port() ) ;
43
44 if( m_config.idle_timeout )
45 m_idle_timer.startTimer( m_config.idle_timeout ) ;
46
47 m_socket->addReadHandler( *this , m_es ) ;
48 m_socket->addOtherHandler( *this , m_es ) ;
49 Monitor::addServerPeer( *this ) ;
50}
51
52 GNet::ServerPeer::~ServerPeer()
53{
54 G_DEBUG( "GNet::ServerPeer::dtor: [" << this << "]: port " << m_address.port() ) ;
55 Monitor::removeServerPeer( *this ) ;
56}
57
58std::string GNet::ServerPeer::eventLoggingString( const Address & a , const Config & config )
59{
60 // (semi-colon to simplify fail2ban regexes)
61 if( config.log_address && config.log_port )
62 return a.hostPartString().append(1U,';').append(std::to_string(a.port())).append(": ",2U) ;
63 else if( config.log_address )
64 return a.hostPartString().append("; ",2U) ;
65 else if( config.log_port )
66 return std::to_string(a.port()).append(": ",2U) ;
67 else
68 return {} ;
69}
70
71 void GNet::ServerPeer::secureAccept()
72{
73 m_sp.secureAccept() ;
74}
75
76 bool GNet::ServerPeer::secureAcceptCapable() const
77{
78 return m_sp.secureAcceptCapable() ;
79}
80
81#ifndef G_LIB_SMALL
82 void GNet::ServerPeer::expect( std::size_t n )
83{
84 m_line_buffer.expect( n ) ;
85}
86#endif
87
88 GNet::StreamSocket & GNet::ServerPeer::socket()
89{
90 G_ASSERT( m_socket != nullptr ) ;
91 return *m_socket ;
92}
93
94 void GNet::ServerPeer::dropReadHandler()
95{
96 socket().dropReadHandler() ;
97}
98
99 void GNet::ServerPeer::addReadHandler()
100{
101 socket().addReadHandler( *this , m_es ) ;
102}
103
104 void GNet::ServerPeer::otherEvent( EventHandler::Reason reason )
105{
106 m_sp.otherEvent( reason , m_config.no_throw_on_peer_disconnect ) ;
107}
108
109 void GNet::ServerPeer::readEvent()
110{
111 if( m_sp.readEvent( m_config.no_throw_on_peer_disconnect ) )
112 onSendComplete() ;
113}
114
115 GNet::Address GNet::ServerPeer::localAddress() const
116{
117 G_ASSERT( m_socket != nullptr ) ;
118 return m_socket->getLocalAddress() ;
119}
120
121 GNet::Address GNet::ServerPeer::peerAddress() const
122{
123 return m_address ;
124}
125
126std::string GNet::ServerPeer::connectionState() const
127{
128 return m_address.displayString() ;
129}
130
131std::string GNet::ServerPeer::peerCertificate() const
132{
133 return m_sp.peerCertificate() ;
134}
135
136 bool GNet::ServerPeer::send( const std::string & data )
137{
138 if( m_config.kick_idle_timer_on_send && m_config.idle_timeout )
139 m_idle_timer.startTimer( m_config.idle_timeout ) ;
140 return m_sp.send( data , 0U ) ;
141}
142
143 bool GNet::ServerPeer::send( std::string_view data )
144{
145 if( m_config.kick_idle_timer_on_send && m_config.idle_timeout )
146 m_idle_timer.startTimer( m_config.idle_timeout ) ;
147 return m_sp.send( data ) ;
148}
149
150#ifndef G_LIB_SMALL
151 bool GNet::ServerPeer::send( const std::vector<std::string_view> & segments , std::size_t offset )
152{
153 if( m_config.kick_idle_timer_on_send && m_config.idle_timeout )
154 m_idle_timer.startTimer( m_config.idle_timeout ) ;
155 return m_sp.send( segments , offset ) ;
156}
157#endif
158
159 void GNet::ServerPeer::writeEvent()
160{
161 if( m_sp.writeEvent() )
162 onSendComplete() ;
163}
164
165 void GNet::ServerPeer::doOnDelete( const std::string & reason , bool done )
166{
167 G_DEBUG( "GNet::ServerPeer::doOnDelete: reason=[" << reason << "]" ) ;
168 onDelete( done ? std::string() : reason ) ;
169}
170
171 void GNet::ServerPeer::onIdleTimeout()
172{
173 std::ostringstream ss ;
174 ss << "no activity after " << m_config.idle_timeout << "s" ;
175 throw IdleTimeout( ss.str() ) ;
176}
177
178 void GNet::ServerPeer::onData( const char * data , std::size_t size )
179{
180 if( m_config.idle_timeout )
181 m_idle_timer.startTimer( m_config.idle_timeout ) ;
182
183 bool fragments = m_line_buffer.transparent() ;
184 m_line_buffer.apply( this , &ServerPeer::onDataImp , data , size , fragments ) ;
185}
186
187 bool GNet::ServerPeer::onDataImp( const char * data , std::size_t size , std::size_t eolsize ,
188 std::size_t linesize , char c0 )
189{
190 return onReceive( data , size , eolsize , linesize , c0 ) ;
191}
192
193 GNet::LineBufferState GNet::ServerPeer::lineBuffer() const
194{
195 return LineBufferState( m_line_buffer ) ;
196}
197
198std::string_view GNet::ServerPeer::eventLoggingString() const
199{
200 if( m_event_logging_string.empty() ) return {} ;
201 return m_event_logging_string ;
202}
203
204 void GNet::ServerPeer::setIdleTimeout( unsigned int s )
205{
206 m_config.idle_timeout = s ;
207 m_idle_timer.cancelTimer() ;
208 if( m_config.idle_timeout )
209 m_idle_timer.startTimer( m_config.idle_timeout ) ;
210}
211
212#ifndef G_LIB_SMALL
213 void GNet::ServerPeer::finish()
214{
215 m_sp.shutdown() ;
216}
217#endif
218
219 void GNet::ServerPeer::onPeerDisconnect()
220{
221}
222
GNet::Address
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:63
GNet::Address::port
unsigned int port() const
Returns port part of the address.
Definition: gaddress.cpp:435
GNet::Address::hostPartString
std::string hostPartString() const
Returns a printable string that represents the network address.
Definition: gaddress.cpp:365
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::LineBufferState
Provides information about the state of a line buffer.
Definition: glinebuffer.h:341
GNet::Monitor::addServerPeer
static void addServerPeer(const Connection &server_peer)
Adds a server connection.
Definition: gmonitor.cpp:122
GNet::Monitor::removeServerPeer
static void removeServerPeer(const Connection &server_peer) noexcept
Removes a server connection.
Definition: gmonitor.cpp:132
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::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::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::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::StreamSocket
A derivation of GNet::Socket for a stream socket.
Definition: gsocket.h:356
gassert.h
glog.h
gmonitor.h
gserver.h
std
STL namespace.
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