diff --git a/src/evhelper.cpp b/src/evhelper.cpp index b914f85..98ee4c1 100644 --- a/src/evhelper.cpp +++ b/src/evhelper.cpp @@ -366,6 +366,7 @@ bool evbase::assertInRunningLoop() const } bool evsocket::canIPv6; +evsocket::ipstack_t evsocket::ipstack; evsocket::evsocket(int af, evutil_socket_t sock) :sock(sock) diff --git a/src/evhelper.h b/src/evhelper.h index 5f463df..b1f8370 100644 --- a/src/evhelper.h +++ b/src/evhelper.h @@ -251,6 +251,13 @@ struct PVXS_API evsocket bool canIPv6; static bool init_canIPv6(); + + enum ipstack_t { + Linsock, + Winsock, + GenericBSD, + }; + static ipstack_t ipstack; }; struct PVXS_API IfaceMap { diff --git a/src/os/WIN32/osdSockExt.cpp b/src/os/WIN32/osdSockExt.cpp index 4c120be..d56ca2e 100644 --- a/src/os/WIN32/osdSockExt.cpp +++ b/src/os/WIN32/osdSockExt.cpp @@ -19,6 +19,16 @@ #include #include +# include +# include + +static +bool is_wine() +{ + HMODULE nt = GetModuleHandle("ntdll.dll"); + return nt && GetProcAddress(nt, "wine_get_version"); +} + namespace pvxs { DEFINE_LOGGER(log, "pvxs.util"); @@ -48,6 +58,7 @@ void oseDoOnce(void*) cantProceed("Unable to get &WSARecvMsg!!"); evsocket::canIPv6 = evsocket::init_canIPv6(); + evsocket::ipstack = is_wine() ? evsocket::Linsock : evsocket::Winsock; } void osiSockAttachExt() diff --git a/src/os/default/osdSockExt.cpp b/src/os/default/osdSockExt.cpp index 8a68435..af4486c 100644 --- a/src/os/default/osdSockExt.cpp +++ b/src/os/default/osdSockExt.cpp @@ -44,6 +44,12 @@ static void oseDoOnce(void*) { evsocket::canIPv6 = evsocket::init_canIPv6(); +#ifdef __linux__ + // TODO: detect WSL1 somehow. (Is WSL2 really Linux IP stack?) + evsocket::ipstack = evsocket::Linsock; +#else + evsocket::ipstack = evsocket::GenericBSD; +#endif } void osiSockAttachExt() { diff --git a/src/server.cpp b/src/server.cpp index 894ba57..e95d171 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -416,8 +416,8 @@ Server::Pvt::Pvt(const Config &conf) listeners.push_back(manager.onSearch(any6, cb)); } -#ifndef _WIN32 - if(addr.addr.family()==AF_INET && !addr.addr.isAny() && !addr.addr.isMCast()) { + if(evsocket::ipstack!=evsocket::Winsock + && addr.addr.family()==AF_INET && !addr.addr.isAny() && !addr.addr.isMCast()) { /* An oddness of BSD sockets (not winsock) is that binding to * INADDR_ANY will receive unicast and broadcast, but binding to * a specific interface address receives only unicast. The trick @@ -429,7 +429,6 @@ Server::Pvt::Pvt(const Config &conf) listeners.push_back(manager.onSearch(bcast, cb)); } } -#endif } if(tcpifaces.empty()) { diff --git a/test/testsock.cpp b/test/testsock.cpp index 28f2f9b..26d712f 100644 --- a/test/testsock.cpp +++ b/test/testsock.cpp @@ -19,18 +19,6 @@ #include #include -#ifdef _WIN32 -# include -# include - -static -bool is_wine() -{ - HMODULE nt = GetModuleHandle("ntdll.dll"); - return nt && GetProcAddress(nt, "wine_get_version"); -} -#endif - namespace { using namespace pvxs; @@ -236,11 +224,11 @@ void test_mcast_scope() testShow()<<" RX2 bound to "<