From a412911435addd750f778d3495996e13b1b8f686 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid Date: Wed, 22 Jan 2020 23:26:37 +0200 Subject: [PATCH] Enable NetworkAddressChange on FreeBSD (#1602) --- .../System.Native/Interop.NetworkChange.cs | 0 .../Native/Unix/System.Native/CMakeLists.txt | 6 ++ .../Unix/System.Native/pal_networkchange.c | 57 ++++++++++++++++++- .../Unix/System.Native/pal_networkchange.h | 1 - .../src/System.Net.NetworkInformation.csproj | 13 +++-- ....Linux.cs => NetworkAddressChange.Unix.cs} | 0 .../NetworkAddressChangedTests.cs | 2 - .../NetworkAvailabilityChangedTests.cs | 5 -- 8 files changed, 69 insertions(+), 15 deletions(-) rename src/libraries/Common/src/Interop/{Linux => Unix}/System.Native/Interop.NetworkChange.cs (100%) rename src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/{NetworkAddressChange.Linux.cs => NetworkAddressChange.Unix.cs} (100%) diff --git a/src/libraries/Common/src/Interop/Linux/System.Native/Interop.NetworkChange.cs b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.NetworkChange.cs similarity index 100% rename from src/libraries/Common/src/Interop/Linux/System.Native/Interop.NetworkChange.cs rename to src/libraries/Common/src/Interop/Unix/System.Native/Interop.NetworkChange.cs diff --git a/src/libraries/Native/Unix/System.Native/CMakeLists.txt b/src/libraries/Native/Unix/System.Native/CMakeLists.txt index 73e8ccdf8dd..74214368eb2 100644 --- a/src/libraries/Native/Unix/System.Native/CMakeLists.txt +++ b/src/libraries/Native/Unix/System.Native/CMakeLists.txt @@ -29,6 +29,12 @@ if (CMAKE_SYSTEM_NAME STREQUAL Linux) if (!HAVE_LINUX_RTNETLINK_H) message(FATAL_ERROR "Could not find linux/rtnetlink.h") endif () +elseif (CMAKE_SYSTEM_NAME STREQUAL FreeBSD) + set(NATIVE_SOURCES ${NATIVE_SOURCES} pal_networkchange.c) + + if (!HAVE_RT_MSGHDR) + message(FATAL_ERROR "Could not find net/route.h") + endif () endif () if (GEN_SHARED_LIB) diff --git a/src/libraries/Native/Unix/System.Native/pal_networkchange.c b/src/libraries/Native/Unix/System.Native/pal_networkchange.c index dc1378ccfdd..7dd6d793931 100644 --- a/src/libraries/Native/Unix/System.Native/pal_networkchange.c +++ b/src/libraries/Native/Unix/System.Native/pal_networkchange.c @@ -10,28 +10,40 @@ #include "pal_utilities.h" #include -#include #include #include #include #include #include +#if HAVE_LINUX_RTNETLINK_H +#include +#elif HAVE_RT_MSGHDR +#include +#else +#error System must have linux/rtnetlink.h or net/route.h. +#endif #pragma clang diagnostic ignored "-Wcast-align" // NLMSG_* macros trigger this Error SystemNative_CreateNetworkChangeListenerSocket(int32_t* retSocket) { +#if HAVE_LINUX_RTNETLINK_H struct sockaddr_nl sa; memset(&sa, 0, sizeof(struct sockaddr_nl)); sa.nl_family = AF_NETLINK; sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE; int32_t sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); +#elif HAVE_RT_MSGHDR + int32_t sock = socket(PF_ROUTE, SOCK_RAW, 0); +#endif if (sock == -1) { *retSocket = -1; return (Error)(SystemNative_ConvertErrorPlatformToPal(errno)); } + +#if HAVE_LINUX_RTNETLINK_H if (bind(sock, (struct sockaddr*)(&sa), sizeof(sa)) != 0) { *retSocket = -1; @@ -39,6 +51,7 @@ Error SystemNative_CreateNetworkChangeListenerSocket(int32_t* retSocket) close(sock); return palError; } +#endif *retSocket = sock; return Error_SUCCESS; @@ -50,6 +63,7 @@ Error SystemNative_CloseNetworkChangeListenerSocket(int32_t socket) return err == 0 || CheckInterrupted(err) ? Error_SUCCESS : (Error)(SystemNative_ConvertErrorPlatformToPal(errno)); } +#if HAVE_LINUX_RTNETLINK_H static NetworkChangeKind ReadNewLinkMessage(struct nlmsghdr* hdr) { assert(hdr != NULL); @@ -117,3 +131,44 @@ void SystemNative_ReadEvents(int32_t sock, NetworkChangeEvent onNetworkChange) } } } +#elif HAVE_RT_MSGHDR +void SystemNative_ReadEvents(int32_t sock, NetworkChangeEvent onNetworkChange) +{ + char buffer[4096]; + ssize_t count = read(sock, buffer, sizeof(buffer)); + if (count < 0) + { + return; + } + + struct rt_msghdr msghdr; + for (char *ptr = buffer; (ptr + sizeof(struct rt_msghdr)) <= (buffer + count); ptr += msghdr.rtm_msglen) + { + memcpy(&msghdr, ptr, sizeof(msghdr)); + if (msghdr.rtm_version != RTM_VERSION) + { + // version mismatch + return; + } + + switch (msghdr.rtm_type) + { + case RTM_NEWADDR: + onNetworkChange(sock, AddressAdded); + break; + case RTM_DELADDR: + onNetworkChange(sock, AddressRemoved); + break; + case RTM_ADD: + case RTM_DELETE: + case RTM_REDIRECT: + { + onNetworkChange(sock, AvailabilityChanged); + return; + } + default: + break; + } + } +} +#endif diff --git a/src/libraries/Native/Unix/System.Native/pal_networkchange.h b/src/libraries/Native/Unix/System.Native/pal_networkchange.h index d27161c0c46..727f17b5b14 100644 --- a/src/libraries/Native/Unix/System.Native/pal_networkchange.h +++ b/src/libraries/Native/Unix/System.Native/pal_networkchange.h @@ -6,7 +6,6 @@ #include "pal_compiler.h" #include "pal_types.h" -#include typedef enum { diff --git a/src/libraries/System.Net.NetworkInformation/src/System.Net.NetworkInformation.csproj b/src/libraries/System.Net.NetworkInformation/src/System.Net.NetworkInformation.csproj index cb61b39acb9..23575826d3a 100644 --- a/src/libraries/System.Net.NetworkInformation/src/System.Net.NetworkInformation.csproj +++ b/src/libraries/System.Net.NetworkInformation/src/System.Net.NetworkInformation.csproj @@ -189,7 +189,6 @@ - @@ -212,9 +211,6 @@ Common\Interop\Linux\Interop.LinuxNetDeviceFlags.cs - - Common\Interop\Linux\System.Native\Interop.NetworkChange.cs - @@ -260,11 +256,16 @@ - Common\Interop\FreeBSD\Interop.Libraries.cs + + + + Common\Interop\Unix\System.Native\Interop.NetworkChange.cs + + @@ -293,7 +294,7 @@ - + diff --git a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/NetworkAddressChange.Linux.cs b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/NetworkAddressChange.Unix.cs similarity index 100% rename from src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/NetworkAddressChange.Linux.cs rename to src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/NetworkAddressChange.Unix.cs diff --git a/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/NetworkAddressChangedTests.cs b/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/NetworkAddressChangedTests.cs index 25d68212236..a3d0ed4902f 100644 --- a/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/NetworkAddressChangedTests.cs +++ b/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/NetworkAddressChangedTests.cs @@ -13,7 +13,6 @@ public partial class NetworkChangedTests private readonly NetworkAddressChangedEventHandler _addressHandler = delegate { }; [Fact] - [ActiveIssue("https://github.com/dotnet/corefx/issues/33530", TestPlatforms.FreeBSD)] public void NetworkAddressChanged_AddRemove_Success() { NetworkChange.NetworkAddressChanged += _addressHandler; @@ -21,7 +20,6 @@ public void NetworkAddressChanged_AddRemove_Success() } [Fact] - [ActiveIssue("https://github.com/dotnet/corefx/issues/33530", TestPlatforms.FreeBSD)] public void NetworkAddressChanged_JustRemove_Success() { NetworkChange.NetworkAddressChanged -= _addressHandler; diff --git a/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/NetworkAvailabilityChangedTests.cs b/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/NetworkAvailabilityChangedTests.cs index b13c458beb5..1a968959a02 100644 --- a/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/NetworkAvailabilityChangedTests.cs +++ b/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/NetworkAvailabilityChangedTests.cs @@ -13,7 +13,6 @@ public partial class NetworkChangedTests private readonly NetworkAvailabilityChangedEventHandler _availabilityHandler = delegate { }; [Fact] - [ActiveIssue("https://github.com/dotnet/corefx/issues/33530", TestPlatforms.FreeBSD)] public void NetworkAvailabilityChanged_AddRemove_Success() { NetworkChange.NetworkAvailabilityChanged += _availabilityHandler; @@ -21,14 +20,12 @@ public void NetworkAvailabilityChanged_AddRemove_Success() } [Fact] - [ActiveIssue("https://github.com/dotnet/corefx/issues/33530", TestPlatforms.FreeBSD)] public void NetworkAvailabilityChanged_JustRemove_Success() { NetworkChange.NetworkAvailabilityChanged -= _availabilityHandler; } [Fact] - [ActiveIssue("https://github.com/dotnet/corefx/issues/33530", TestPlatforms.FreeBSD)] public void NetworkAddressChanged_Add_DoesNotBlock() { // Register without unregistering. @@ -42,7 +39,6 @@ public void NetworkAddressChanged_Add_DoesNotBlock() } [Fact] - [ActiveIssue("https://github.com/dotnet/corefx/issues/33530", TestPlatforms.FreeBSD)] public void NetworkAddressChanged_AddAndRemove_NetworkAvailabilityChanged_JustRemove_Success() { NetworkChange.NetworkAddressChanged += _addressHandler; @@ -55,7 +51,6 @@ public void NetworkAddressChanged_AddAndRemove_NetworkAvailabilityChanged_JustRe [InlineData(false, true)] [InlineData(true, false)] [InlineData(true, true)] - [ActiveIssue("https://github.com/dotnet/corefx/issues/33530", TestPlatforms.FreeBSD)] public void NetworkAvailabilityChanged_NetworkAddressChanged_AddAndRemove_Success(bool addAddressFirst, bool removeAddressFirst) { if (addAddressFirst) -- GitLab