From acf1f2816f2358af68fe889dfc6c2af54561fcc5 Mon Sep 17 00:00:00 2001 From: Lev Stipakov Date: Thu, 14 Nov 2024 16:34:11 +0200 Subject: [PATCH] multipeer: support for dual-stack Enable bind for both IPv4 and IPv6 clients. Github: https://github.com/OpenVPN/ovpn-dco-win/issues/95 Signed-off-by: Lev Stipakov --- Driver.cpp | 2 +- peer.cpp | 2 +- socket.cpp | 15 ++++++++++++--- socket.h | 2 +- uapi/ovpn-dco.h | 1 + 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 52ee592..069dea1 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -408,7 +408,7 @@ OvpnMPStartVPN(POVPN_DEVICE device, WDFREQUEST request, ULONG_PTR* bytesReturned status = OvpnSocketInit(&driver->WskProviderNpi, &driver->WskRegistration, addrIn->ListenAddress.Addr4.sin_family, false, (PSOCKADDR)&addrIn->ListenAddress, NULL, - 0, device, &socket); + 0, device, &socket, addrIn->IPv6Only > 0 ? TRUE : FALSE); if (!NT_SUCCESS(status)) { LOG_ERROR("Socket create failed", TraceLoggingValue((UINT32)status), TraceLoggingHexUInt32(*(UINT32*)(&addrIn->ListenAddress.Addr4.sin_addr), "addr")); diff --git a/peer.cpp b/peer.cpp index bc80b2a..e068aa3 100644 --- a/peer.cpp +++ b/peer.cpp @@ -373,7 +373,7 @@ OvpnPeerNew(POVPN_DEVICE device, WDFREQUEST request) &driver->WskRegistration, peer->Local.Addr4.sin_family, proto_tcp, (PSOCKADDR)&peer->Local, (PSOCKADDR)&peer->Remote, - remoteAddrSize, device, &socket)); + remoteAddrSize, device, &socket, TRUE)); GOTO_IF_NOT_NT_SUCCESS(done, status, OvpnAddPeerToTable(device, &device->Peers, peerCtx)); diff --git a/socket.cpp b/socket.cpp index 9c2f515..6cb8dbc 100644 --- a/socket.cpp +++ b/socket.cpp @@ -521,7 +521,7 @@ const WSK_CLIENT_CONNECTION_DISPATCH OvpnSocketTcpDispatch = { OvpnSocketTcpRece _Use_decl_annotations_ NTSTATUS OvpnSocketInit(WSK_PROVIDER_NPI* wskProviderNpi, WSK_REGISTRATION* wskRegistration, ADDRESS_FAMILY addressFamily, BOOLEAN tcp, PSOCKADDR localAddr, - PSOCKADDR remoteAddr, SIZE_T remoteAddrSize, PVOID deviceContext, PWSK_SOCKET* socket) + PSOCKADDR remoteAddr, SIZE_T remoteAddrSize, PVOID deviceContext, PWSK_SOCKET* socket, BOOLEAN ipv6only) { NTSTATUS status; WSK_EVENT_CALLBACK_CONTROL eventCallbackControl = {}; @@ -563,6 +563,17 @@ OvpnSocketInit(WSK_PROVIDER_NPI* wskProviderNpi, WSK_REGISTRATION* wskRegistrati sizeof(tcpNoDelay), &tcpNoDelay, 0, NULL, &outputSizeReturned, NULL)); } else { + PWSK_PROVIDER_BASIC_DISPATCH basicDispatch = (PWSK_PROVIDER_BASIC_DISPATCH)(*socket)->Dispatch; + + if (!ipv6only) { + LOG_INFO("Enable dual-stack"); + // enable dual-stack + LOG_IF_NOT_NT_SUCCESS(status = OvpnSocketSyncOp("IPV6_V6ONLY", [basicDispatch, socket](PIRP irp) { + ULONG ipv6Only = 0; + return basicDispatch->WskControlSocket(*socket, WskSetOption, IPV6_V6ONLY, IPPROTO_IPV6, sizeof(ipv6Only), &ipv6Only, 0, NULL, NULL, irp); + }, [](PIRP) {})); + } + // bind PWSK_PROVIDER_DATAGRAM_DISPATCH datagramDispatch = (PWSK_PROVIDER_DATAGRAM_DISPATCH)(*socket)->Dispatch; @@ -577,8 +588,6 @@ OvpnSocketInit(WSK_PROVIDER_NPI* wskProviderNpi, WSK_REGISTRATION* wskRegistrati if (remoteAddr != NULL) { // set remote - PWSK_PROVIDER_BASIC_DISPATCH basicDispatch = (PWSK_PROVIDER_BASIC_DISPATCH)(*socket)->Dispatch; - GOTO_IF_NOT_NT_SUCCESS(error, status, OvpnSocketSyncOp("SetRemote", [basicDispatch, socket, remoteAddrSize, remoteAddr](PIRP irp) { return basicDispatch->WskControlSocket(*socket, WskIoctl, SIO_WSK_SET_REMOTE_ADDRESS, 0, remoteAddrSize, remoteAddr, 0, NULL, NULL, irp); }, [](PIRP) {})); diff --git a/socket.h b/socket.h index 187d5dd..11eb73c 100644 --- a/socket.h +++ b/socket.h @@ -61,7 +61,7 @@ _IRQL_requires_(PASSIVE_LEVEL) NTSTATUS OvpnSocketInit(_In_ WSK_PROVIDER_NPI* wskProviderNpi, _In_ WSK_REGISTRATION* wskRegistration, ADDRESS_FAMILY addrFamily, BOOLEAN tcp, _In_ PSOCKADDR localAddr, _In_opt_ PSOCKADDR remoteAddr, SIZE_T remoteAddrSize, - _In_ PVOID deviceContext, _Out_ PWSK_SOCKET* socket); + _In_ PVOID deviceContext, _Out_ PWSK_SOCKET* socket, BOOLEAN ipv6only); _Must_inspect_result_ _IRQL_requires_(PASSIVE_LEVEL) diff --git a/uapi/ovpn-dco.h b/uapi/ovpn-dco.h index f13ef62..8003ace 100644 --- a/uapi/ovpn-dco.h +++ b/uapi/ovpn-dco.h @@ -152,6 +152,7 @@ typedef struct _OVPN_MP_START_VPN { SOCKADDR_IN Addr4; SOCKADDR_IN6 Addr6; } ListenAddress; + int IPv6Only; } OVPN_MP_START_VPN, * POVPN_MP_START_VPN; typedef enum {