From ef8b2e860f3f4cc68e8ff904ac83255553e991c6 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Mon, 16 Oct 2023 11:26:08 -0400 Subject: [PATCH] SocketOption.DontLinger is Windows only --- .../Components/InstanceManager.cs | 10 +++++++++- .../Session/SessionControllerFactory.cs | 2 +- .../Extensions/SocketExtensions.cs | 15 +++++++++++---- src/Tgstation.Server.Host/Utils/PortAllocator.cs | 11 ++++++++++- .../Live/Instance/WatchdogTest.cs | 2 +- 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/InstanceManager.cs b/src/Tgstation.Server.Host/Components/InstanceManager.cs index ec66af63b1..e790294c09 100644 --- a/src/Tgstation.Server.Host/Components/InstanceManager.cs +++ b/src/Tgstation.Server.Host/Components/InstanceManager.cs @@ -94,6 +94,11 @@ namespace Tgstation.Server.Host.Components /// readonly IConsole console; + /// + /// The for the . + /// + readonly IPlatformIdentifier platformIdentifier; + /// /// The for the . /// @@ -168,6 +173,7 @@ namespace Tgstation.Server.Host.Components /// The value of . /// The value of . /// The value of . + /// The value of . /// The containing the value of . /// The containing the value of . /// The value of . @@ -183,6 +189,7 @@ namespace Tgstation.Server.Host.Components IServerPortProvider serverPortProvider, ISwarmServiceController swarmServiceController, IConsole console, + IPlatformIdentifier platformIdentifier, IOptions generalConfigurationOptions, IOptions swarmConfigurationOptions, ILogger logger) @@ -198,6 +205,7 @@ namespace Tgstation.Server.Host.Components this.serverPortProvider = serverPortProvider ?? throw new ArgumentNullException(nameof(serverPortProvider)); this.swarmServiceController = swarmServiceController ?? throw new ArgumentNullException(nameof(swarmServiceController)); this.console = console ?? throw new ArgumentNullException(nameof(console)); + this.platformIdentifier = platformIdentifier ?? throw new ArgumentNullException(nameof(platformIdentifier)); generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); swarmConfiguration = swarmConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); @@ -643,7 +651,7 @@ namespace Tgstation.Server.Host.Components // This runs before the real socket is opened, ensures we don't perform reattaches unless we're fairly certain the bind won't fail // If it does fail, DD will be killed. - SocketExtensions.BindTest(serverPortProvider.HttpApiPort, true); + SocketExtensions.BindTest(platformIdentifier, serverPortProvider.HttpApiPort, true); } /// diff --git a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs index d1ba7ff2c6..96f28e042e 100644 --- a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs +++ b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs @@ -135,7 +135,7 @@ namespace Tgstation.Server.Host.Components.Session try { logger.LogTrace("Bind test: {port}", port); - SocketExtensions.BindTest(port, false); + SocketExtensions.BindTest(platformIdentifier, port, false); } catch (SocketException ex) when (ex.SocketErrorCode == SocketError.AddressAlreadyInUse) { diff --git a/src/Tgstation.Server.Host/Extensions/SocketExtensions.cs b/src/Tgstation.Server.Host/Extensions/SocketExtensions.cs index 75adcf9a25..3c5d076e72 100644 --- a/src/Tgstation.Server.Host/Extensions/SocketExtensions.cs +++ b/src/Tgstation.Server.Host/Extensions/SocketExtensions.cs @@ -1,4 +1,5 @@ -using System.Net; +using System; +using System.Net; using System.Net.Sockets; using Tgstation.Server.Host.System; @@ -13,10 +14,13 @@ namespace Tgstation.Server.Host.Extensions /// /// Attempt to exclusively bind to a given . /// + /// The to use. /// The port number to bind to. /// If IPV6 should be tested as well. - public static void BindTest(ushort port, bool includeIPv6) - => ProcessExecutor.WithProcessLaunchExclusivity(() => + public static void BindTest(IPlatformIdentifier platformIdentifier, ushort port, bool includeIPv6) + { + ArgumentNullException.ThrowIfNull(platformIdentifier); + ProcessExecutor.WithProcessLaunchExclusivity(() => { using var socket = new Socket( includeIPv6 @@ -27,7 +31,9 @@ namespace Tgstation.Server.Host.Extensions socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, true); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false); - socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); + if (platformIdentifier.IsWindows) + socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); + if (includeIPv6) socket.DualMode = true; @@ -38,5 +44,6 @@ namespace Tgstation.Server.Host.Extensions : IPAddress.Any, port)); }); + } } } diff --git a/src/Tgstation.Server.Host/Utils/PortAllocator.cs b/src/Tgstation.Server.Host/Utils/PortAllocator.cs index c2337135bc..cf53aabe11 100644 --- a/src/Tgstation.Server.Host/Utils/PortAllocator.cs +++ b/src/Tgstation.Server.Host/Utils/PortAllocator.cs @@ -12,6 +12,7 @@ using Tgstation.Server.Host.Configuration; using Tgstation.Server.Host.Core; using Tgstation.Server.Host.Database; using Tgstation.Server.Host.Extensions; +using Tgstation.Server.Host.System; namespace Tgstation.Server.Host.Utils { @@ -28,6 +29,11 @@ namespace Tgstation.Server.Host.Utils /// readonly IDatabaseContext databaseContext; + /// + /// The for the . + /// + readonly IPlatformIdentifier platformIdentifier; + /// /// The for the . /// @@ -43,16 +49,19 @@ namespace Tgstation.Server.Host.Utils /// /// The value of . /// The value of . + /// The value of . /// The containing the value of . /// The value of . public PortAllocator( IServerPortProvider serverPortProvider, IDatabaseContext databaseContext, + IPlatformIdentifier platformIdentifier, IOptions swarmConfigurationOptions, ILogger logger) { this.serverPortProvider = serverPortProvider ?? throw new ArgumentNullException(nameof(serverPortProvider)); this.databaseContext = databaseContext ?? throw new ArgumentNullException(nameof(databaseContext)); + this.platformIdentifier = platformIdentifier ?? throw new ArgumentNullException(nameof(platformIdentifier)); swarmConfiguration = swarmConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); } @@ -92,7 +101,7 @@ namespace Tgstation.Server.Host.Utils try { - SocketExtensions.BindTest(port, false); + SocketExtensions.BindTest(platformIdentifier, port, false); } catch (Exception ex) { diff --git a/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs index ba69db8069..bde4f32658 100644 --- a/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs @@ -636,7 +636,7 @@ namespace Tgstation.Server.Tests.Live.Instance { try { - SocketExtensions.BindTest(ddPort, false); + SocketExtensions.BindTest(new PlatformIdentifier(), ddPort, false); break; } catch