diff options
| author | Dan Engelbrecht <[email protected]> | 2022-12-07 14:24:13 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-12-07 05:24:13 -0800 |
| commit | de76241479f30ab52298de47439c7268dd45391e (patch) | |
| tree | 7e8f5040cce7d438fa60d5b6bc56d0cfb31eb053 /zenhttp/httpasio.cpp | |
| parent | 0.2.0-pre0 (diff) | |
| download | zen-de76241479f30ab52298de47439c7268dd45391e.tar.xz zen-de76241479f30ab52298de47439c7268dd45391e.zip | |
Fix asio port sharing options (#203)
* Windows: explicitly set the special SO_EXCLUSIVEADDRUSE flag
* changelog
Diffstat (limited to 'zenhttp/httpasio.cpp')
| -rw-r--r-- | zenhttp/httpasio.cpp | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/zenhttp/httpasio.cpp b/zenhttp/httpasio.cpp index 39a363711..68984c86d 100644 --- a/zenhttp/httpasio.cpp +++ b/zenhttp/httpasio.cpp @@ -932,22 +932,42 @@ HttpRequest::OnMessageComplete() struct HttpAcceptor { - HttpAcceptor(HttpAsioServerImpl& Server, asio::io_service& IoService, uint16_t Port) + HttpAcceptor(HttpAsioServerImpl& Server, asio::io_service& IoService, uint16_t BasePort) : m_Server(Server) , m_IoService(IoService) , m_Acceptor(m_IoService, asio::ip::tcp::v6()) { m_Acceptor.set_option(asio::ip::v6_only(false)); - m_Acceptor.set_option(asio::socket_base::reuse_address(true)); +#if ZEN_PLATFORM_WINDOWS + // Special option for Windows settings as !asio::socket_base::reuse_address is not the same as exclusive access on Windows platforms + typedef asio::detail::socket_option::boolean<ASIO_OS_DEF(SOL_SOCKET), SO_EXCLUSIVEADDRUSE> excluse_address; + m_Acceptor.set_option(excluse_address(true)); +#else // ZEN_PLATFORM_WINDOWS + m_Acceptor.set_option(asio::socket_base::reuse_address(false)); +#endif // ZEN_PLATFORM_WINDOWS + m_Acceptor.set_option(asio::ip::tcp::no_delay(true)); m_Acceptor.set_option(asio::socket_base::receive_buffer_size(128 * 1024)); m_Acceptor.set_option(asio::socket_base::send_buffer_size(256 * 1024)); + uint16_t EffectivePort = BasePort; + asio::error_code BindErrorCode; - m_Acceptor.bind(asio::ip::tcp::endpoint(asio::ip::address_v6::any(), Port), BindErrorCode); + m_Acceptor.bind(asio::ip::tcp::endpoint(asio::ip::address_v6::any(), EffectivePort), BindErrorCode); + // Sharing violation implies the port is being used by another process + for (uint16_t PortOffset = 1; (BindErrorCode == asio::error::address_in_use) && (PortOffset < 10); ++PortOffset) + { + EffectivePort = BasePort + (PortOffset * 100); + m_Acceptor.bind(asio::ip::tcp::endpoint(asio::ip::address_v6::any(), EffectivePort), BindErrorCode); + } if (BindErrorCode == asio::error::access_denied) { - m_Acceptor.bind(asio::ip::tcp::endpoint(asio::ip::address_v6::any(), 0)); + EffectivePort = 0; + m_Acceptor.bind(asio::ip::tcp::endpoint(asio::ip::address_v6::any(), EffectivePort), BindErrorCode); + } + if (BindErrorCode) + { + ZEN_ERROR("Unable open asio service, error '{}'", BindErrorCode.message()); } #if ZEN_PLATFORM_WINDOWS @@ -969,6 +989,8 @@ struct HttpAcceptor 0); #endif m_Acceptor.listen(); + + ZEN_INFO("Started asio server at port '{}'", EffectivePort); } void Start() |