2
3
6
7
13#include <restinio/connection_count_limiter.hpp>
15#include <restinio/impl/include_fmtlib.hpp>
17#include <restinio/impl/connection.hpp>
19#include <restinio/utils/suppress_exceptions.hpp>
32
33
34
35
36
37
38
39
40template <
typename Socket >
44 template <
typename Settings >
49 asio_ns::io_context & io_context )
52 m_sockets.reserve( settings.concurrent_accepts_count() );
55 std::back_inserter( m_sockets ),
56 settings.concurrent_accepts_count(),
58 return Socket{m_io_context};
61 assert( m_sockets.size() == settings.concurrent_accepts_count() );
70 return m_sockets.at( idx );
87 return m_sockets.size();
103
104
105
106
107
108
109
110template<
typename Ip_Blocker >
115 template<
typename Settings >
117 const Settings & settings )
121 template<
typename Socket >
125 return m_ip_blocker->inspect(
126 restinio::ip_blocker::incoming_info_t{
127 socket.lowest_layer().remote_endpoint()
133
134
135
136
137
138
139
146 template<
typename Socket >
161template <
typename Traits >
162class acceptor_t
final
163 :
public std::enable_shared_from_this< acceptor_t< Traits > >
185 template <
typename Settings >
189 asio_ns::io_context & io_context,
196 ,
m_port{ settings.port() }
210 settings.max_parallel_connections()
213 settings.concurrent_accepts_count()
233 asio_ns::ip::tcp::endpoint ep{ m_protocol, m_port };
235 const auto actual_address = try_extract_actual_address_from_variant(
238 ep.address( *actual_address );
254 (*m_acceptor_options_setter)( options );
259 m_acceptor_post_bind_hook( m_acceptor );
266 m_acceptor.listen( asio_ns::socket_base::max_connections );
269 for( std::size_t i = 0; i<
this->concurrent_accept_sockets_count(); ++i )
285 catch(
const std::exception & ex )
294 "failed to start server on {}: {}" ),
335
336
341 this->socket( index ).lowest_layer(),
342 asio_ns::bind_executor(
344 [index, ctx =
this->shared_from_this()]
345 (
const auto & ec )
noexcept
349 ctx->accept_current_connection( index, ec );
355
356
361 asio_ns::bind_executor(
363 [index, ctx =
this->shared_from_this()]()
noexcept
365 ctx->accept_next( index );
370
371
372
373
374
384
385
386
387
388
389
390
391
400
401
402
407 const std::error_code & ec )
noexcept
413 "accept_current_connection",
425 "failed to accept connection on socket #{}: {}" ),
436
437
438
439
440
441
442
448 auto incoming_socket =
this->move_socket( i );
450 auto remote_endpoint =
451 incoming_socket.lowest_layer().remote_endpoint();
456 "accept connection from {} on socket #{}" ),
463 const auto inspection_result =
this->inspect_incoming(
466 switch( inspection_result )
468 case restinio::ip_blocker::inspection_result_t::deny:
473 "accepted connection from {} on socket #{} denied by"
481 case restinio::ip_blocker::inspection_result_t::allow:
484 std::move(incoming_socket)
,
495 auto create_and_init_connection =
496 [sock = std::move(incoming_socket),
497 factory = m_connection_factory,
498 ep = std::move(remote_endpoint),
499 lifetime_monitor = connection_lifetime_monitor_t{
500 &m_connection_count_limiter
508 "do_accept_current_connection.create_and_init_connection",
514 auto conn = factory->create_new_connection(
517 std::move(lifetime_monitor) );
528 std::move( create_and_init_connection ) );
532 create_and_init_connection();
576
577
594
595
596
597
601
602
603
604
605
606
607
609 static std::optional< asio_ns::ip::address >
611 const restinio::details::address_variant_t & from )
613 std::optional< asio_ns::ip::address > result;
615 if(
auto * str_v = std::get_if<std::string>( &from ) )
617 auto str_addr = *str_v;
618 if( str_addr ==
"localhost" )
619 str_addr =
"127.0.0.1";
620 else if( str_addr ==
"ip6-localhost" )
623 result = asio_ns::ip::address::from_string( str_addr );
625 else if(
auto * addr_v = std::get_if<asio_ns::ip::address>( &from ) )
An interface of acceptor to be used by connection count limiters.
void open()
Start listen on port specified in ctor.
asio_ns::ip::tcp::acceptor m_acceptor
void close_impl()
Close opened acceptor.
void accept_connection_for_socket_with_index(std::size_t i)
Performs actual actions for accepting a new connection.
::restinio::connection_count_limits::impl::acceptor_callback_iface_t * self_as_acceptor_callback() noexcept
Helper for suppressing warnings of using this in initilizer list.
typename Traits::strand_t strand_t
static std::optional< asio_ns::ip::address > try_extract_actual_address_from_variant(const restinio::details::address_variant_t &from)
Helper for extraction of an actual IP-address from an instance of address_variant.
const asio_ns::ip::tcp m_protocol
connection_factory_shared_ptr_t m_connection_factory
Factory for creating connections.
connection_count_limiter_t m_connection_count_limiter
Actual limiter of active parallel connections.
impl::connection_factory_t< Traits > connection_factory_t
strand_t m_open_close_operations_executor
void do_accept_current_connection(stream_socket_t incoming_socket, endpoint_t remote_endpoint)
void accept_next(std::size_t i) noexcept
Set a callback for a new connection.
void schedule_next_accept_attempt(std::size_t index) noexcept override
typename Traits::stream_socket_t stream_socket_t
void call_accept_now(std::size_t index) noexcept override
typename connection_count_limit_types< Traits >::limiter_t connection_count_limiter_t
const std::uint16_t m_port
Server endpoint.
std::shared_ptr< connection_factory_t > connection_factory_shared_ptr_t
void accept_current_connection(std::size_t i, const std::error_code &ec) noexcept
Accept current connection.
std::unique_ptr< acceptor_options_setter_t > m_acceptor_options_setter
Server port listener and connection receiver routine.
auto & get_open_close_operations_executor() noexcept
Get an executor for close operation.
void close()
Close listener if any.
acceptor_post_bind_hook_t m_acceptor_post_bind_hook
A hook to be called just after a successful call to bind for acceptor.
const restinio::details::address_variant_t m_address
acceptor_details::ip_blocker_holder_t< typename Traits::ip_blocker_t > ip_blocker_base_t
typename Traits::logger_t logger_t
typename connection_count_limit_types< Traits >::lifetime_monitor_t connection_lifetime_monitor_t
default_asio_executor m_executor
Asio executor.
const bool m_separate_accept_and_create_connect
Do separate an accept operation and connection instantiation.
auto & get_executor() noexcept
Get executor for acceptor.
socket_supplier_t< stream_socket_t > socket_holder_base_t
acceptor_t(Settings &settings, asio_ns::io_context &io_context, connection_factory_shared_ptr_t connection_factory, logger_t &logger)
auto concurrent_accept_sockets_count() const noexcept
The number of sockets that can be used for cuncurrent accept operations.
Socket & socket(std::size_t idx)
Get the reference to socket.
std::vector< Socket > m_sockets
A temporary socket for receiving new connections.
socket_supplier_t(Settings &settings, asio_ns::io_context &io_context)
Socket move_socket(std::size_t idx)
Extract the socket via move.
asio_ns::io_context & m_io_context
io_context for sockets to run on.
#define RESTINIO_FMT_FORMAT_STRING(s)
restinio::utils::tagged_scalar_t< std::size_t, max_parallel_connections_tag > max_parallel_connections_t
A kind of strict typedef for maximum count of active connections.
restinio::utils::tagged_scalar_t< std::size_t, max_active_accepts_tag > max_active_accepts_t
A kind of strict typedef for maximum count of active accepts.
asio_ns::ip::tcp::endpoint endpoint_t
An alias for endpoint type from Asio.
A kind of metafunction that deduces actual types related to connection count limiter in the dependecy...
A class for holding actual IP-blocker.
restinio::ip_blocker::inspection_result_t inspect_incoming(Socket &socket) const noexcept
std::shared_ptr< Ip_Blocker > m_ip_blocker
ip_blocker_holder_t(const Settings &settings)