40template <
typename Socket >
44 template <
typename Settings >
49 asio_ns::io_context & io_context )
52 m_sockets.reserve( settings.concurrent_accepts_count() );
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 );
79 return std::move( socket(idx ) );
87 return m_sockets.size();
99namespace acceptor_details
110template<
typename Ip_Blocker >
115 template<
typename Settings >
117 const Settings & settings )
118 : m_ip_blocker{ settings.ip_blocker() }
121 template<
typename Socket >
125 return m_ip_blocker->inspect(
127 socket.lowest_layer().remote_endpoint()
143 template<
typename Settings >
146 template<
typename Socket >
161template <
typename Traits >
163 :
public std::enable_shared_from_this< acceptor_t< Traits > >
169 typename Traits::ip_blocker_t >;
179 std::shared_ptr< connection_factory_t >;
185 template <
typename Settings >
189 asio_ns::io_context & io_context,
196 , m_port{ settings.port() }
197 , m_protocol{ settings.protocol() }
198 , m_address{ settings.address() }
199 , m_acceptor_options_setter{ settings.acceptor_options_setter() }
200 , m_acceptor{ io_context }
201 , m_acceptor_post_bind_hook{ settings.giveaway_acceptor_post_bind_hook() }
202 , m_executor{ io_context.get_executor() }
203 , m_open_close_operations_executor{ io_context.get_executor() }
204 , m_separate_accept_and_create_connect{ settings.separate_accept_and_create_connect() }
205 , m_connection_factory{
std::move( connection_factory ) }
207 , m_connection_count_limiter{
208 self_as_acceptor_callback(),
209 restinio::connection_count_limits::max_parallel_connections_t{
210 settings.max_parallel_connections()
212 restinio::connection_count_limits::max_active_accepts_t{
213 settings.concurrent_accepts_count()
222 if( m_acceptor.is_open() )
224 const auto ep = m_acceptor.local_endpoint();
228 fmtlib_tools::streamed(
ep ) );
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 );
245 fmtlib_tools::streamed(
ep ) );
248 m_acceptor.open(
ep.protocol() );
254 (*m_acceptor_options_setter)( options );
257 m_acceptor.bind(
ep );
259 m_acceptor_post_bind_hook( m_acceptor );
263 ep = m_acceptor.local_endpoint();
266 m_acceptor.listen( asio_ns::socket_base::max_connections );
269 for( std::size_t i = 0; i< this->concurrent_accept_sockets_count(); ++i )
282 fmtlib_tools::streamed(
ep ) );
285 catch(
const std::exception & ex )
288 if( m_acceptor.is_open() )
291 m_logger.error( [&]() ->
auto {
294 "failed to start server on {}: {}" ),
295 fmtlib_tools::streamed(
ep ),
307 if( m_acceptor.is_open() )
324 return m_open_close_operations_executor;
338 m_acceptor.async_accept(
339 this->socket( index ).lowest_layer(),
340 asio_ns::bind_executor(
342 [index, ctx = this->shared_from_this()]
343 (
const auto & ec )
noexcept
347 ctx->accept_current_connection( index, ec );
359 asio_ns::bind_executor(
361 [index, ctx = this->shared_from_this()]()
noexcept
363 ctx->accept_next( index );
393 m_connection_count_limiter.accept_next( i );
405 const std::error_code & ec )
noexcept
411 "accept_current_connection",
413 accept_connection_for_socket_with_index( i );
423 "failed to accept connection on socket #{}: {}" ),
446 auto incoming_socket = this->move_socket( i );
448 auto remote_endpoint =
449 incoming_socket.lowest_layer().remote_endpoint();
454 "accept connection from {} on socket #{}" ),
455 fmtlib_tools::streamed( remote_endpoint ),
461 const auto inspection_result = this->inspect_incoming(
464 switch( inspection_result )
471 "accepted connection from {} on socket #{} denied by"
473 fmtlib_tools::streamed( remote_endpoint ),
481 do_accept_current_connection(
482 std::move(incoming_socket),
493 auto create_and_init_connection =
494 [sock = std::move(incoming_socket),
495 factory = m_connection_factory,
496 ep = std::move(remote_endpoint),
498 &m_connection_count_limiter
506 "do_accept_current_connection.create_and_init_connection",
512 auto conn = factory->create_new_connection(
515 std::move(lifetime_monitor) );
522 if( m_separate_accept_and_create_connect )
526 std::move( create_and_init_connection ) );
530 create_and_init_connection();
538 const auto ep = m_acceptor.local_endpoint();
546 fmtlib_tools::streamed(
ep ) );
554 fmtlib_tools::streamed(
ep ) );
611 if(
auto * str_v = get_if<std::string>( &from ) )
613 auto str_addr = *str_v;
614 if( str_addr ==
"localhost" )
615 str_addr =
"127.0.0.1";
616 else if( str_addr ==
"ip6-localhost" )
619 result = asio_ns::ip::address::from_string( str_addr );
621 else if(
auto * addr_v = get_if<asio_ns::ip::address>( &from ) )
An adapter for setting acceptor options before running server.
Helper type for controlling the lifetime of the connection.
An interface of acceptor to be used by connection count limiters.
Context for accepting http connections.
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
std::shared_ptr< connection_factory_t > connection_factory_shared_ptr_t
const asio_ns::ip::tcp m_protocol
connection_factory_shared_ptr_t m_connection_factory
Factory for creating connections.
typename connection_count_limit_types< Traits >::limiter_t connection_count_limiter_t
connection_count_limiter_t m_connection_count_limiter
Actual limiter of active parallel connections.
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
typename connection_count_limit_types< Traits >::lifetime_monitor_t connection_lifetime_monitor_t
void call_accept_now(std::size_t index) noexcept override
const std::uint16_t m_port
Server endpoint.
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.
static RESTINIO_NODISCARD optional_t< 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.
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.
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.
An information about new incoming connection to be passed to IP-blocker object.
#define RESTINIO_NODISCARD
Stuff related to limits of active parallel connections.
A special wrapper around fmtlib include files.
#define RESTINIO_FMT_FORMAT_STRING(s)
inspection_result_t
Enumeration of result of inspecting new incoming connection.
@ deny
New connection is disabled and should be closed.
@ allow
New connection is allowed to be processed further.
void suppress_exceptions(Logger &&logger, const char *block_description, Lambda &&lambda) noexcept
Helper function for execution a block of code with suppression of any exceptions raised inside that b...
void log_error_noexcept(Logger &&logger, Message_Builder &&builder) noexcept
void log_trace_noexcept(Logger &&logger, Message_Builder &&builder) noexcept
std::function< void(asio_ns::ip::tcp::acceptor &) > acceptor_post_bind_hook_t
A type of callback to be called after a successful invocation of bind() function for the acceptor.
asio_ns::executor default_asio_executor
asio_ns::ip::tcp::endpoint endpoint_t
An alias for endpoint type from Asio.
typename std::conditional< Traits::use_connection_count_limiter, connection_count_limits::connection_count_limiter_t< typename Traits::strand_t >, connection_count_limits::noop_connection_count_limiter_t >::type limiter_t
restinio::ip_blocker::inspection_result_t inspect_incoming(Socket &) const noexcept
ip_blocker_holder_t(const Settings &)
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)
The default no-op IP-blocker.
Utilities for suppressing exceptions from some code block.