From b4eea088479a95d717843a898b031b70cba43f1c Mon Sep 17 00:00:00 2001 From: Daniel Nachbaur Date: Wed, 1 Feb 2017 11:21:30 +0100 Subject: [PATCH] Expose OS-chosen address and port from async_server --- .../protocol/http/server/async_server.hpp | 26 +++++++++++++++++-- .../network/protocol/http/server/options.hpp | 14 ++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/boost/network/protocol/http/server/async_server.hpp b/boost/network/protocol/http/server/async_server.hpp index 4cbefe0d2..c1e3c662e 100644 --- a/boost/network/protocol/http/server/async_server.hpp +++ b/boost/network/protocol/http/server/async_server.hpp @@ -35,13 +35,17 @@ struct async_server_base : server_storage_base, socket_options_base { /// Defines the type for the connection pointer. typedef std::shared_ptr connection_ptr; + /// Defines the type for the options. + typedef server_options options; + /// Constructs and initializes the asynchronous server core. - explicit async_server_base(server_options const &options) + explicit async_server_base(options const &options) : server_storage_base(options), socket_options_base(options), handler(options.handler()), address_(options.address()), port_(options.port()), + protocol_family(options.protocol_family()), thread_pool(options.thread_pool() ? options.thread_pool() : std::make_shared()), @@ -108,11 +112,19 @@ struct async_server_base : server_storage_base, socket_options_base { } } + /// Returns the server socket address, either IPv4 or IPv6 depending on + /// options.protocol_family() + const string_type& address() const { return address_; } + + /// Returns the server socket port + const string_type& port() const { return port_; } + private: typedef std::unique_lock scoped_mutex_lock; Handler &handler; string_type address_, port_; + typename options::protocol_family_t protocol_family; std::shared_ptr thread_pool; boost::asio::ip::tcp::acceptor acceptor; bool stopping; @@ -165,7 +177,15 @@ struct async_server_base : server_storage_base, socket_options_base { // this allows repeated cycles of run -> stop -> run service_.reset(); tcp::resolver resolver(service_); - tcp::resolver::query query(address_, port_); + tcp::resolver::query query( [&]{ + switch(protocol_family) { + case options::ipv4: + return tcp::resolver::query(tcp::v4(), address_, port_); + case options::ipv6: + return tcp::resolver::query(tcp::v6(), address_, port_); + default: + return tcp::resolver::query(address_, port_); + }}()); tcp::resolver::iterator endpoint_iterator = resolver.resolve(query, error); if (error) { BOOST_NETWORK_MESSAGE("Error resolving '" << address_ << ':' << port_); @@ -185,6 +205,8 @@ struct async_server_base : server_storage_base, socket_options_base { << port_); return; } + address_ = acceptor.local_endpoint().address().to_string(); + port_ = std::to_string(acceptor.local_endpoint().port()); acceptor.listen(boost::asio::socket_base::max_connections, error); if (error) { BOOST_NETWORK_MESSAGE("Error listening on socket: '" diff --git a/boost/network/protocol/http/server/options.hpp b/boost/network/protocol/http/server/options.hpp index 2e0f5761f..e84188bf3 100644 --- a/boost/network/protocol/http/server/options.hpp +++ b/boost/network/protocol/http/server/options.hpp @@ -34,6 +34,7 @@ struct server_options { handler_(handler), address_("localhost"), port_("80"), + protocol_family_(undefined), reuse_address_(false), report_aborted_(false), non_blocking_io_(true), @@ -88,6 +89,14 @@ struct server_options { return *this; } + enum protocol_family_t { ipv4, ipv6, undefined }; + + /// Set the protocol family for address resolving. Default is AF_UNSPEC. + server_options &protocol_family(protocol_family_t v) { + protocol_family_ = v; + return *this; + } + /// Set whether to reuse the address (SO_REUSE_ADDR). Default is false. server_options &reuse_address(bool v) { reuse_address_ = v; @@ -159,6 +168,9 @@ struct server_options { /// Returns the port to listen on. string_type port() const { return port_; } + /// Returns the protocol family used for address resolving. + protocol_family_t protocol_family() const { return protocol_family_; } + /// Returns a reference to the provided handler. Handler &handler() const { return handler_; } @@ -215,6 +227,7 @@ struct server_options { swap(io_service_, other.io_service_); swap(address_, other.address_); swap(port_, other.port_); + swap(protocol_family_, other.protocol_family_); swap(reuse_address_, other.reuse_address_); swap(report_aborted_, other.report_aborted_); swap(non_blocking_io_, other.non_blocking_io_); @@ -233,6 +246,7 @@ struct server_options { Handler &handler_; string_type address_; string_type port_; + protocol_family_t protocol_family_; bool reuse_address_; bool report_aborted_; bool non_blocking_io_;