37 m_server_peer_config(server_peer_config) ,
40 G_DEBUG(
"GNet::Server::ctor: listening on socket " << m_socket.
asString()
43 bool uds = listening_address.
family() == Address::Family::local ;
46 bool open = server_config.uds_open_permissions ;
47 using Mode = G::Process::Umask::Mode ;
50 m_socket.
bind( listening_address ) ;
55 m_socket.
bind( listening_address ) ;
58 m_socket.
listen( std::max(1,server_config.listen_queue) ) ;
65 if( path.size() > 1U && path.at(0U) ==
'/' )
84 if( !reason.empty() && do_throw )
86 return reason.empty() ;
91 bool with_scope = true ;
92 Address result = m_socket.getLocalAddress() ;
94 result.
setScopeId( m_socket.getBoundScopeId() ) ;
98void GNet::Server::readEvent()
101 G_DEBUG(
"GNet::Server::readEvent: " <<
this ) ;
106 accept( peer_info ) ;
114 G_DEBUG(
"GNet::Server::readEvent: new connection from " << peer_info.m_address.displayString()
115 <<
" on " << peer_info.m_socket->asString() ) ;
127 if( peer ==
nullptr )
129 G_WARNING(
"GNet::Server::readEvent: connection rejected from " << peer_info.m_address.displayString() ) ;
133 G_DEBUG(
"GNet::Server::readEvent: new connection accepted" ) ;
134 m_peer_list.push_back( std::shared_ptr<ServerPeer>(peer.release()) ) ;
138void GNet::Server::accept( ServerPeerInfo & peer_info )
140 AcceptPair accept_pair ;
143 accept_pair = m_socket.accept() ;
145 peer_info.m_socket = accept_pair.socket_ptr ;
146 peer_info.m_address = accept_pair.address ;
149void GNet::Server::onException( ExceptionSource * esrc , std::exception & e ,
bool done )
151 G_DEBUG(
"GNet::Server::onException: exception=[" << e.what() <<
"] esrc=[" <<
static_cast<void*
>(esrc) <<
"]" ) ;
152 bool handled = false ;
153 if( esrc !=
nullptr )
155 for(
auto list_p = m_peer_list.begin() ; list_p != m_peer_list.end() ; ++list_p )
157 if( (*list_p).get() == esrc )
159 std::shared_ptr<ServerPeer> peer_p = *list_p ;
160 m_peer_list.erase( list_p ) ;
161 (*peer_p).doOnDelete( e.what() , done ) ;
169 G_WARNING(
"GNet::Server::onException: unhandled exception: " << e.what() ) ;
176 m_peer_list.clear() ;
181 return !m_peer_list.empty() ;
186 using Peers = std::vector<std::weak_ptr<ServerPeer> > ;
188 result.reserve( m_peer_list.size() ) ;
189 for(
auto & peer : m_peer_list )
190 result.push_back( std::weak_ptr<ServerPeer>(peer) ) ;
194void GNet::Server::writeEvent()
196 G_DEBUG(
"GNet::Server::writeEvent" ) ;
199bool GNet::Server::unlink(
G::SignalSafe ,
const char * path )
noexcept
201 return path ? ( std::remove(path) == 0 ) :
true ;
206GNet::ServerPeerInfo::ServerPeerInfo( Server * server , ServerPeerConfig config ) :
207 m_address(Address::defaultAddress()) ,
The GNet::Address class encapsulates a TCP/UDP transport address.
Address & setScopeId(unsigned long)
Sets the scope-id.
Family family() const
Returns the address family enumeration.
std::string hostPartString(bool raw=false) const
Returns a string which represents the network address.
std::string displayString(bool with_scope_id=false) const
Returns a string which represents the transport address.
A class that sets the G::LogOuput::context() while in scope.
A potential ExceptionSink that is realised by bind()ing an exception source pointer.
A tuple containing an ExceptionHandler interface pointer and a bound 'exception source' pointer.
An interface for a network listener.
static void addServer(const Listener &server)
Adds a server.
static void removeServer(const Listener &server) noexcept
Removes a server.
A structure that GNet::Server uses to configure its ServerPeer objects.
A structure used in GNet::Server::newPeer().
~Server() override
Destructor.
Address address() const override
Returns the listening address.
bool hasPeers() const
Returns true if peers() is not empty.
Server(ExceptionSink, const Address &listening_address, ServerPeerConfig, ServerConfig)
Constructor.
std::vector< std::weak_ptr< GNet::ServerPeer > > peers()
Returns the list of ServerPeer objects.
void serverCleanup()
Should be called by the most-derived class's destructor in order to trigger early deletion of peer ob...
static bool canBind(const Address &listening_address, bool do_throw)
Checks that the specified address can be bound.
std::string asString() const
Returns the socket handle as a string.
void addReadHandler(EventHandler &, ExceptionSink)
Adds this socket to the event source list so that the given handler receives read events.
void bind(const Address &)
Binds the socket with the given address.
static std::string canBindHint(const Address &address, bool stream_socket=true)
Returns the empty string if a socket could probably be bound with the given address or a failure reas...
void listen(int backlog=1)
Starts the socket listening on the bound address for incoming connections or incoming datagrams.
A derivation of GNet::Socket for a stream socket.
static const char * strdup(const char *)
A strdup() function that makes it clear in the stack trace that leaks are expected.
static void add(bool(*fn)(SignalSafe, const char *), const char *arg)
Adds the given handler to the list of handlers that are to be called when the process terminates abno...
Used to temporarily modify the process umask.
A class which acquires the process's special privileges on construction and releases them on destruct...
An empty structure that is used to indicate a signal-safe, reentrant implementation.
A configuration structure for GNet::Server.