From fa8f9e785a74f1aea8baa897a573adab7d1503c3 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Wed, 20 Aug 2025 13:14:46 +0300
Subject: [PATCH 1/4] [dotnet] Fix find port for IPv4 only environments
---
.../src/webdriver/Internal/PortUtilities.cs | 28 ++++++++++++++++---
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/dotnet/src/webdriver/Internal/PortUtilities.cs b/dotnet/src/webdriver/Internal/PortUtilities.cs
index a739e5ccd32f6..8ab2ebe45ba2d 100644
--- a/dotnet/src/webdriver/Internal/PortUtilities.cs
+++ b/dotnet/src/webdriver/Internal/PortUtilities.cs
@@ -33,10 +33,30 @@ public static class PortUtilities
/// A random, free port to be listened on.
public static int FindFreePort()
{
- using var socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
- socket.DualMode = true;
- socket.Bind(new IPEndPoint(IPAddress.IPv6Loopback, 0));
- return (socket.LocalEndPoint as IPEndPoint)!.Port;
+ // Prefer IPv6 dual-mode when available, but fall back robustly to IPv4
+ try
+ {
+ using var ipV6socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
+ // Some platforms may not support DualMode or IPv6 at all; ignore failures and let bind decide
+ try
+ {
+ ipV6socket.DualMode = true;
+ }
+ catch
+ {
+ // Ignored; we'll still attempt to bind to IPv6 loopback
+ }
+
+ ipV6socket.Bind(new IPEndPoint(IPAddress.IPv6Loopback, 0));
+ return ((IPEndPoint)ipV6socket.LocalEndPoint!).Port;
+ }
+ catch(SocketException)
+ {
+ // If creating/binding the IPv6 socket fails for any reason, fall back to IPv4
+ using var ipV4socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ ipV4socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
+ return ((IPEndPoint)ipV4socket.LocalEndPoint!).Port;
+ }
}
}
From 80190d829ac3a800ce5908df407d7e97c08ae7be Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Tue, 26 Aug 2025 21:26:23 +0300
Subject: [PATCH 2/4] Try ipv4 and fallback to ipv6
---
.../src/webdriver/Internal/PortUtilities.cs | 27 ++++++-------------
1 file changed, 8 insertions(+), 19 deletions(-)
diff --git a/dotnet/src/webdriver/Internal/PortUtilities.cs b/dotnet/src/webdriver/Internal/PortUtilities.cs
index 8ab2ebe45ba2d..d7c1a3553fca3 100644
--- a/dotnet/src/webdriver/Internal/PortUtilities.cs
+++ b/dotnet/src/webdriver/Internal/PortUtilities.cs
@@ -33,30 +33,19 @@ public static class PortUtilities
/// A random, free port to be listened on.
public static int FindFreePort()
{
- // Prefer IPv6 dual-mode when available, but fall back robustly to IPv4
+ // Prefer IPv4, but fall back robustly to IPv6
try
{
- using var ipV6socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
-
- // Some platforms may not support DualMode or IPv6 at all; ignore failures and let bind decide
- try
- {
- ipV6socket.DualMode = true;
- }
- catch
- {
- // Ignored; we'll still attempt to bind to IPv6 loopback
- }
-
- ipV6socket.Bind(new IPEndPoint(IPAddress.IPv6Loopback, 0));
- return ((IPEndPoint)ipV6socket.LocalEndPoint!).Port;
- }
- catch(SocketException)
- {
- // If creating/binding the IPv6 socket fails for any reason, fall back to IPv4
using var ipV4socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ipV4socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
return ((IPEndPoint)ipV4socket.LocalEndPoint!).Port;
}
+ catch (SocketException)
+ {
+ // If creating/binding the IPv4 socket fails for any reason, fall back to IPv6
+ using var ipV6socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
+ ipV6socket.Bind(new IPEndPoint(IPAddress.IPv6Loopback, 0));
+ return ((IPEndPoint)ipV6socket.LocalEndPoint!).Port;
+ }
}
}
From b6f22ffae6e68c41c3769d60ab6ffdcf03e34ed8 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Tue, 26 Aug 2025 21:28:04 +0300
Subject: [PATCH 3/4] Update PortUtilities.cs
---
dotnet/src/webdriver/Internal/PortUtilities.cs | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/dotnet/src/webdriver/Internal/PortUtilities.cs b/dotnet/src/webdriver/Internal/PortUtilities.cs
index d7c1a3553fca3..e07c18750a328 100644
--- a/dotnet/src/webdriver/Internal/PortUtilities.cs
+++ b/dotnet/src/webdriver/Internal/PortUtilities.cs
@@ -28,12 +28,11 @@ namespace OpenQA.Selenium.Internal;
public static class PortUtilities
{
///
- /// Finds a random, free port to be listened on.
+ /// Finds a random, free port to be listened on. Prefers IPv4, but falls back to IPv6 if necessary.
///
/// A random, free port to be listened on.
public static int FindFreePort()
{
- // Prefer IPv4, but fall back robustly to IPv6
try
{
using var ipV4socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
@@ -42,7 +41,6 @@ public static int FindFreePort()
}
catch (SocketException)
{
- // If creating/binding the IPv4 socket fails for any reason, fall back to IPv6
using var ipV6socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
ipV6socket.Bind(new IPEndPoint(IPAddress.IPv6Loopback, 0));
return ((IPEndPoint)ipV6socket.LocalEndPoint!).Port;
From 2114addd6a5165828d2fac3cf2f518db95a3f1d5 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Tue, 26 Aug 2025 21:45:45 +0300
Subject: [PATCH 4/4] Move tech desription to remarks
---
dotnet/src/webdriver/Internal/PortUtilities.cs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/dotnet/src/webdriver/Internal/PortUtilities.cs b/dotnet/src/webdriver/Internal/PortUtilities.cs
index e07c18750a328..6f67d5abbd4b6 100644
--- a/dotnet/src/webdriver/Internal/PortUtilities.cs
+++ b/dotnet/src/webdriver/Internal/PortUtilities.cs
@@ -28,8 +28,11 @@ namespace OpenQA.Selenium.Internal;
public static class PortUtilities
{
///
- /// Finds a random, free port to be listened on. Prefers IPv4, but falls back to IPv6 if necessary.
+ /// Finds a random, free port to be listened on.
///
+ ///
+ /// Prefers IPv4, but falls back to IPv6 if necessary.
+ ///
/// A random, free port to be listened on.
public static int FindFreePort()
{