diff options
author | Roman Smrž <roman.smrz@seznam.cz> | 2024-07-05 11:07:27 +0200 |
---|---|---|
committer | Roman Smrž <roman.smrz@seznam.cz> | 2024-07-05 22:13:09 +0200 |
commit | bd351e8d555001647e8501ac2d38c675a2a3c005 (patch) | |
tree | 413c35487f3fd752d7fe1efe941cb58e7474645b /src | |
parent | 7729f1be60bf2c4d38758971bd95d4c6445fde1e (diff) |
Broadcast address lookup on Windows
Diffstat (limited to 'src')
-rw-r--r-- | src/Erebos/Network.hs | 16 | ||||
-rw-r--r-- | src/Erebos/Network/ifaddrs.c | 50 |
2 files changed, 60 insertions, 6 deletions
diff --git a/src/Erebos/Network.hs b/src/Erebos/Network.hs index 41b6279..3896829 100644 --- a/src/Erebos/Network.hs +++ b/src/Erebos/Network.hs @@ -301,10 +301,11 @@ startServer opt serverOrigHead logd' serverServices = do forkServerThread server $ forever $ do (paddr, msg) <- readFlowIO serverRawPath - case paddr of - DatagramAddress addr -> void $ S.sendTo sock msg addr + handle (\(e :: IOException) -> atomically . logd $ "failed to send packet to " ++ show paddr ++ ": " ++ show e) $ do + case paddr of + DatagramAddress addr -> void $ S.sendTo sock msg addr #ifdef ENABLE_ICE_SUPPORT - PeerIceSession ice -> iceSend ice msg + PeerIceSession ice -> iceSend ice msg #endif forkServerThread server $ forever $ do @@ -922,6 +923,9 @@ getBroadcastAddresses port = do w <- peekElemOff ptr i if w == 0 then return [] else (SockAddrInet port w:) <$> parse (i + 1) - addrs <- parse 0 - cFree ptr - return addrs + if ptr == nullPtr + then return [] + else do + addrs <- parse 0 + cFree ptr + return addrs diff --git a/src/Erebos/Network/ifaddrs.c b/src/Erebos/Network/ifaddrs.c index 37c3e00..efeca18 100644 --- a/src/Erebos/Network/ifaddrs.c +++ b/src/Erebos/Network/ifaddrs.c @@ -1,5 +1,7 @@ #include "ifaddrs.h" +#ifndef _WIN32 + #include <arpa/inet.h> #include <ifaddrs.h> #include <net/if.h> @@ -39,3 +41,51 @@ uint32_t * broadcast_addresses(void) ret[count] = 0; return ret; } + +#else // _WIN32 + +#include <winsock2.h> +#include <ws2tcpip.h> + +#pragma comment(lib, "ws2_32.lib") + +uint32_t * broadcast_addresses(void) +{ + uint32_t * ret = NULL; + SOCKET wsock = INVALID_SOCKET; + + struct WSAData wsaData; + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) + return NULL; + + wsock = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0); + if (wsock == INVALID_SOCKET) + goto cleanup; + + INTERFACE_INFO InterfaceList[32]; + unsigned long nBytesReturned; + + if (WSAIoctl(wsock, SIO_GET_INTERFACE_LIST, 0, 0, + InterfaceList, sizeof(InterfaceList), + &nBytesReturned, 0, 0) == SOCKET_ERROR) + goto cleanup; + + int numInterfaces = nBytesReturned / sizeof(INTERFACE_INFO); + + size_t capacity = 16, count = 0; + ret = malloc(sizeof(uint32_t) * capacity); + + for (int i = 0; i < numInterfaces && count < capacity - 1; i++) + if (InterfaceList[i].iiFlags & IFF_BROADCAST) + ret[count++] = InterfaceList[i].iiBroadcastAddress.AddressIn.sin_addr.s_addr; + + ret[count] = 0; +cleanup: + if (wsock != INVALID_SOCKET) + closesocket(wsock); + WSACleanup(); + + return ret; +} + +#endif |