aboutsummaryrefslogtreecommitdiff
path: root/zenhttp/httpasio.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2022-12-07 14:24:13 +0100
committerGitHub <[email protected]>2022-12-07 05:24:13 -0800
commitde76241479f30ab52298de47439c7268dd45391e (patch)
tree7e8f5040cce7d438fa60d5b6bc56d0cfb31eb053 /zenhttp/httpasio.cpp
parent0.2.0-pre0 (diff)
downloadzen-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.cpp30
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()