SocketOption.DontLinger is Windows only

This commit is contained in:
Jordan Dominion
2023-10-16 11:26:08 -04:00
parent 6c4046ca8c
commit ef8b2e860f
5 changed files with 32 additions and 8 deletions
@@ -94,6 +94,11 @@ namespace Tgstation.Server.Host.Components
/// </summary>
readonly IConsole console;
/// <summary>
/// The <see cref="IPlatformIdentifier"/> for the <see cref="InstanceManager"/>.
/// </summary>
readonly IPlatformIdentifier platformIdentifier;
/// <summary>
/// The <see cref="ILogger"/> for the <see cref="InstanceManager"/>.
/// </summary>
@@ -168,6 +173,7 @@ namespace Tgstation.Server.Host.Components
/// <param name="serverPortProvider">The value of <see cref="serverPortProvider"/>.</param>
/// <param name="swarmServiceController">The value of <see cref="swarmServiceController"/>.</param>
/// <param name="console">The value of <see cref="console"/>.</param>
/// <param name="platformIdentifier">The value of <see cref="platformIdentifier"/>.</param>
/// <param name="generalConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the value of <see cref="generalConfiguration"/>.</param>
/// <param name="swarmConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the value of <see cref="swarmConfiguration"/>.</param>
/// <param name="logger">The value of <see cref="logger"/>.</param>
@@ -183,6 +189,7 @@ namespace Tgstation.Server.Host.Components
IServerPortProvider serverPortProvider,
ISwarmServiceController swarmServiceController,
IConsole console,
IPlatformIdentifier platformIdentifier,
IOptions<GeneralConfiguration> generalConfigurationOptions,
IOptions<SwarmConfiguration> swarmConfigurationOptions,
ILogger<InstanceManager> 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);
}
/// <summary>
@@ -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)
{
@@ -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
/// <summary>
/// Attempt to exclusively bind to a given <paramref name="port"/>.
/// </summary>
/// <param name="platformIdentifier">The <see cref="PlatformIdentifier"/> to use.</param>
/// <param name="port">The port number to bind to.</param>
/// <param name="includeIPv6">If IPV6 should be tested as well.</param>
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));
});
}
}
}
@@ -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
/// </summary>
readonly IDatabaseContext databaseContext;
/// <summary>
/// The <see cref="IPlatformIdentifier"/> for the <see cref="PortAllocator"/>.
/// </summary>
readonly IPlatformIdentifier platformIdentifier;
/// <summary>
/// The <see cref="ILogger"/> for the <see cref="PortAllocator"/>.
/// </summary>
@@ -43,16 +49,19 @@ namespace Tgstation.Server.Host.Utils
/// </summary>
/// <param name="serverPortProvider">The value of <see cref="serverPortProvider"/>.</param>
/// <param name="databaseContext">The value of <see cref="databaseContext"/>.</param>
/// <param name="platformIdentifier">The value of <see cref="platformIdentifier"/>.</param>
/// <param name="swarmConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the value of <see cref="swarmConfiguration"/>.</param>
/// <param name="logger">The value of <see cref="logger"/>.</param>
public PortAllocator(
IServerPortProvider serverPortProvider,
IDatabaseContext databaseContext,
IPlatformIdentifier platformIdentifier,
IOptions<SwarmConfiguration> swarmConfigurationOptions,
ILogger<PortAllocator> 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)
{
@@ -636,7 +636,7 @@ namespace Tgstation.Server.Tests.Live.Instance
{
try
{
SocketExtensions.BindTest(ddPort, false);
SocketExtensions.BindTest(new PlatformIdentifier(), ddPort, false);
break;
}
catch