E-MailRelay

gmultiserver.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2021 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 gmultiserver.h
19///
20
21#ifndef G_NET_MULTISERVER_H
22#define G_NET_MULTISERVER_H
23
24#include "gdef.h"
25#include "gevent.h"
26#include "gserver.h"
27#include "gtimer.h"
28#include "ginterfaces.h"
29#include <vector>
30#include <utility> // std::pair<>
31
32 namespace GNet
33{
34 class MultiServer ;
35 class MultiServerImp ;
36}
37
38//| \class GNet::MultiServer
39/// A server that listens on more than one address using a facade
40/// pattern to multiple GNet::Server instances. Supports dynamic
41/// server instantiation based on available network interface
42/// addresses (see GNet::InterfacesHandler).
43///
44 class GNet::MultiServer : private InterfacesHandler
45{
46 public:
47 using AddressList = std::vector<Address> ;
48 G_EXCEPTION( NoListeningAddresses , "no listening addresses" ) ;
49 G_EXCEPTION( InvalidName , "invalid address or interface name" ) ;
50
51 struct ServerInfo /// A structure used in GNet::MultiServer::newPeer().
52 {
53 ServerInfo() ;
54 Address m_address ; ///< The server address that the peer connected to.
55 } ;
56
57 MultiServer( ExceptionSink listener_exception_sink , const G::StringArray & addresses ,
58 unsigned int port , const std::string & server_type , ServerPeerConfig server_peer_config ,
59 ServerConfig server_config ) ;
60 ///< Constructor. The server listens on on the specific local
61 ///< addresses, given as either interface names (eg. "eth0")
62 ///< or IP network addresses (eg. "::1") together with a
63 ///< fixed port number. Throws if there are no addresses in the
64 ///< list and the GNet::Interfaces implementation is not active().
65 ///< Listens on "0.0.0.0" and "::" if the list is empty.
66
67 ~MultiServer() override ;
68 ///< Destructor.
69
70 bool hasPeers() const ;
71 ///< Returns true if peers() is not empty.
72
73 std::vector<std::weak_ptr<ServerPeer> > peers() ;
74 ///< Returns the list of ServerPeer-derived objects.
75
76 static bool canBind( const AddressList & listening_address_list , bool do_throw ) ;
77 ///< Checks that all the specified addresses can be
78 ///< bound. Throws CannotBind if any of those addresses
79 ///< cannot be bound and 'do_throw' is true.
80
81 std::unique_ptr<ServerPeer> doNewPeer( ExceptionSinkUnbound , const ServerPeerInfo & , const ServerInfo & ) ;
82 ///< Pseudo-private method used by the pimple class.
83
84 protected:
85 virtual std::unique_ptr<ServerPeer> newPeer( ExceptionSinkUnbound , ServerPeerInfo , ServerInfo ) = 0 ;
86 ///< A factory method which new()s a ServerPeer-derived
87 ///< object. See GNet::Server for the details.
88
89 void serverCleanup() ;
90 ///< Should be called from all derived classes' destructors
91 ///< so that peer objects can use their Server objects
92 ///< safely during their own destruction.
93
94 void serverReport() const ;
95 ///< Writes to the system log a summary of the underlying server
96 ///< objects and their addresses.
97
98 private: // overrides
99 void onInterfaceEvent( const std::string & ) override ; // GNet::InterfacesHandler
100
101 public:
102 MultiServer( const MultiServer & ) = delete ;
103 MultiServer( MultiServer && ) = delete ;
104 void operator=( const MultiServer & ) = delete ;
105 void operator=( MultiServer && ) = delete ;
106
107 private:
108 friend class GNet::MultiServerImp ;
109 AddressList addresses( unsigned int ) const ;
110 AddressList addresses( unsigned int , G::StringArray & , G::StringArray & , G::StringArray & ) const ;
111 void init( const AddressList & address_list ) ;
112 bool gotServerFor( const Address & ) const ;
113 void onInterfaceEventTimeout() ;
114 static bool match( const Address & , const Address & ) ;
115 static std::string displayString( const Address & ) ;
116
117 private:
118 using ServerPtr = std::unique_ptr<MultiServerImp> ;
119 using ServerList = std::vector<ServerPtr> ;
120 ExceptionSink m_es ;
121 G::StringArray m_interfaces ;
122 unsigned int m_port ;
123 std::string m_server_type ;
124 ServerPeerConfig m_server_peer_config ;
125 ServerConfig m_server_config ;
126 Interfaces m_if ;
127 ServerList m_server_list ;
128 Timer<MultiServer> m_interface_event_timer ;
129} ;
130
131//| \class GNet::MultiServerImp
132/// A GNet::Server class used in GNet::MultiServer.
133///
134 class GNet::MultiServerImp : public GNet::Server
135{
136 public:
137 MultiServerImp( MultiServer & , ExceptionSink , const Address & , ServerPeerConfig , ServerConfig ) ;
138 ///< Constructor.
139
140 ~MultiServerImp() override ;
141 ///< Destructor.
142
143 std::unique_ptr<ServerPeer> newPeer( ExceptionSinkUnbound , ServerPeerInfo ) final ;
144 ///< Called by the base class to create a new ServerPeer.
145
146 void cleanup() ;
147 ///< Calls GNet::Server::serverCleanup().
148
149 public:
150 MultiServerImp( const MultiServerImp & ) = delete ;
151 MultiServerImp( MultiServerImp && ) = delete ;
152 void operator=( const MultiServerImp & ) = delete ;
153 void operator=( MultiServerImp && ) = delete ;
154
155 private:
156 MultiServer & m_ms ;
157 Address m_address ;
158} ;
159
160#endif
GNet::Address
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:53
GNet::ExceptionSinkUnbound
A potential ExceptionSink that is realised by bind()ing an exception source pointer.
Definition: gexceptionsink.h:154
GNet::ExceptionSink
A tuple containing an ExceptionHandler interface pointer and a bound 'exception source' pointer.
Definition: gexceptionsink.h:100
GNet::InterfacesHandler
An interface for receiving notification of network changes.
Definition: ginterfaces.h:143
GNet::Interfaces
A class for getting a list of network interfaces and their addresses.
Definition: ginterfaces.h:45
GNet::MultiServerImp
A GNet::Server class used in GNet::MultiServer.
Definition: gmultiserver.h:135
GNet::MultiServerImp::newPeer
std::unique_ptr< ServerPeer > newPeer(ExceptionSinkUnbound, ServerPeerInfo) final
Called by the base class to create a new ServerPeer.
Definition: gmultiserver.cpp:267
GNet::MultiServerImp::~MultiServerImp
~MultiServerImp() override
Destructor.
GNet::MultiServerImp::MultiServerImp
MultiServerImp(MultiServer &, ExceptionSink, const Address &, ServerPeerConfig, ServerConfig)
Constructor.
Definition: gmultiserver.cpp:251
GNet::MultiServerImp::cleanup
void cleanup()
Calls GNet::Server::serverCleanup().
Definition: gmultiserver.cpp:262
GNet::MultiServer
A server that listens on more than one address using a facade pattern to multiple GNet::Server instan...
Definition: gmultiserver.h:45
GNet::MultiServer::~MultiServer
~MultiServer() override
Destructor.
Definition: gmultiserver.cpp:81
GNet::MultiServer::canBind
static bool canBind(const AddressList &listening_address_list, bool do_throw)
Checks that all the specified addresses can be bound.
Definition: gmultiserver.cpp:202
GNet::MultiServer::hasPeers
bool hasPeers() const
Returns true if peers() is not empty.
Definition: gmultiserver.cpp:227
GNet::MultiServer::peers
std::vector< std::weak_ptr< ServerPeer > > peers()
Returns the list of ServerPeer-derived objects.
Definition: gmultiserver.cpp:237
GNet::MultiServer::serverReport
void serverReport() const
Writes to the system log a summary of the underlying server objects and their addresses.
Definition: gmultiserver.cpp:213
GNet::MultiServer::MultiServer
MultiServer(ExceptionSink listener_exception_sink, const G::StringArray &addresses, unsigned int port, const std::string &server_type, ServerPeerConfig server_peer_config, ServerConfig server_config)
Constructor.
Definition: gmultiserver.cpp:31
GNet::MultiServer::serverCleanup
void serverCleanup()
Should be called from all derived classes' destructors so that peer objects can use their Server obje...
Definition: gmultiserver.cpp:86
GNet::MultiServer::newPeer
virtual std::unique_ptr< ServerPeer > newPeer(ExceptionSinkUnbound, ServerPeerInfo, ServerInfo)=0
A factory method which new()s a ServerPeer-derived object.
GNet::MultiServer::doNewPeer
std::unique_ptr< ServerPeer > doNewPeer(ExceptionSinkUnbound, const ServerPeerInfo &, const ServerInfo &)
Pseudo-private method used by the pimple class.
Definition: gmultiserver.cpp:221
GNet::ServerPeerConfig
A structure that GNet::Server uses to configure its ServerPeer objects.
Definition: gserverpeer.h:51
GNet::ServerPeerInfo
A structure used in GNet::Server::newPeer().
Definition: gserver.h:142
GNet::Server
A network server class which listens on a specific port and spins off ServerPeer objects for each inc...
Definition: gserver.h:62
GNet::Timer
A timer class template in which the timeout is delivered to the specified method.
Definition: gtimer.h:129
gevent.h
ginterfaces.h
gserver.h
gtimer.h
GNet
Network classes.
Definition: gdef.h:1115
G::StringArray
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:31
GNet::MultiServer::ServerInfo
A structure used in GNet::MultiServer::newPeer().
Definition: gmultiserver.h:52
GNet::MultiServer::ServerInfo::m_address
Address m_address
The server address that the peer connected to.
Definition: gmultiserver.h:54
GNet::ServerConfig
A configuration structure for GNet::Server.
Definition: gserver.h:50