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(),
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 >
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 > >
188 template <
typename Settings >
192 asio_ns::io_context & io_context,
199 ,
m_port{ settings.port() }
213 settings.max_parallel_connections()
216 settings.concurrent_accepts_count()
236 asio_ns::ip::tcp::endpoint ep{ m_protocol, m_port };
238 const auto actual_address = try_extract_actual_address_from_variant(
241 ep.address( *actual_address );
257 (*m_acceptor_options_setter)( options );
262 m_acceptor_post_bind_hook( m_acceptor );
269 m_acceptor.listen( asio_ns::socket_base::max_listen_connections );
272 for( std::size_t i = 0; i<
this->concurrent_accept_sockets_count(); ++i )
288 catch(
const std::exception & ex )
297 "failed to start server on {}: {}" ),
338
339
344 this->socket( index ).lowest_layer(),
345 asio_ns::bind_executor(
347 [index, ctx =
this->shared_from_this()]
348 (
const auto & ec )
noexcept
352 ctx->accept_current_connection( index, ec );
358
359
364 asio_ns::bind_executor(
366 [index, ctx =
this->shared_from_this()]()
noexcept
368 ctx->accept_next( index );
373
374
375
376
377
387
388
389
390
391
392
393
394
403
404
405
410 const std::error_code & ec )
noexcept
416 "accept_current_connection",
428 "failed to accept connection on socket #{}: {}" ),
439
440
441
442
443
444
445
451 auto incoming_socket =
this->move_socket( i );
453 auto remote_endpoint =
454 incoming_socket.lowest_layer().remote_endpoint();
459 "accept connection from {} on socket #{}" ),
466 const auto inspection_result =
this->inspect_incoming(
469 switch( inspection_result )
471 case restinio::ip_blocker::inspection_result_t::deny:
476 "accepted connection from {} on socket #{} denied by"
484 case restinio::ip_blocker::inspection_result_t::allow:
487 std::move(incoming_socket)
,
498 auto create_and_init_connection =
499 [sock = std::move(incoming_socket),
500 factory = m_connection_factory,
501 ep = std::move(remote_endpoint),
502 lifetime_monitor = connection_lifetime_monitor_t{
504 &m_connection_count_limiter
512 "do_accept_current_connection.create_and_init_connection",
518 auto conn = factory->create_new_connection(
521 std::move(lifetime_monitor) );
532 std::move( create_and_init_connection ) );
536 create_and_init_connection();
580
581
598
599
600
601
605
606
607
608
609
610
611
613 static std::optional< asio_ns::ip::address >
615 const restinio::details::address_variant_t & from )
617 std::optional< asio_ns::ip::address > result;
619 if(
auto * str_v = std::get_if<std::string>( &from ) )
621 auto str_addr = *str_v;
622 if( str_addr ==
"localhost" )
623 str_addr =
"127.0.0.1";
624 else if( str_addr ==
"ip6-localhost" )
627 result = asio_ns::ip::make_address( str_addr );
629 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
std::shared_ptr< connection_factory_t > connection_factory_shared_ptr_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 connection_count_limit_types< Traits >::lifetime_monitor_t connection_lifetime_monitor_t
An alias for actual connection lifetime monitor type.
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
An alias for actual connection count limiter type.
const std::uint16_t m_port
Server endpoint.
acceptor_details::ip_blocker_holder_t< typename Traits::ip_blocker_t > ip_blocker_base_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
typename Traits::logger_t logger_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_active_accepts_tag > max_active_accepts_t
A kind of strict typedef for maximum count of active accepts.
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.
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)