From 68f69952cf624f8f1a12434fe8c287eb45214163 Mon Sep 17 00:00:00 2001 From: Robin Rolf Date: Mon, 13 Feb 2023 16:41:05 +0100 Subject: [PATCH] fix: Only use IPv4 address without dual mode Previously, if the DNS resolve returned an IPv6 address as the first entry it would use that Notable for connecting to "localhost" which resolves to ::1 (ipv6) first on windows --- kcp2k/Assets/kcp2k/highlevel/KcpClient.cs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/kcp2k/Assets/kcp2k/highlevel/KcpClient.cs b/kcp2k/Assets/kcp2k/highlevel/KcpClient.cs index 46ee0e41..174c2f53 100644 --- a/kcp2k/Assets/kcp2k/highlevel/KcpClient.cs +++ b/kcp2k/Assets/kcp2k/highlevel/KcpClient.cs @@ -69,7 +69,28 @@ public void Connect(string address, ushort port, KcpConfig config) OnDisconnected(); return; } + IPAddress resolvedAddress = null; + // resolved address might return v6, even when we're configured to not use v6 + // so we need to do some filtering + foreach (IPAddress ipAddress in addresses) + { + if (ipAddress.AddressFamily == AddressFamily.InterNetwork || + config.DualMode && ipAddress.AddressFamily == AddressFamily.InterNetworkV6) + { + resolvedAddress = ipAddress; + break; + } + } + + if (resolvedAddress == null) + { + // pass error to user callback. no need to log it manually. + OnError(ErrorCode.DnsResolve, $"Failed to resolve host '{address}' to a IPv4{(config.DualMode ? "/IPv6" : "")} address"); + OnDisconnected(); + return; + } + // create fresh peer for each new session peer = new KcpPeer(RawSend, OnAuthenticatedWrap, OnData, OnDisconnectedWrap, OnError, config); @@ -94,7 +115,7 @@ void OnDisconnectedWrap() Log.Info($"KcpClient: connect to {address}:{port}"); // create socket - remoteEndPoint = new IPEndPoint(addresses[0], port); + remoteEndPoint = new IPEndPoint(resolvedAddress, port); socket = new Socket(remoteEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp); // configure buffer sizes: