OD uses UDP, so bind test to account for that

This commit is contained in:
Jordan Dominion
2023-11-11 14:51:38 -05:00
parent de714c3369
commit 7310359f0b
6 changed files with 31 additions and 12 deletions
@@ -648,7 +648,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(platformIdentifier, serverPortProvider.HttpApiPort, true);
SocketExtensions.BindTest(platformIdentifier, serverPortProvider.HttpApiPort, true, false);
}
/// <summary>
@@ -130,9 +130,10 @@ namespace Tgstation.Server.Host.Components.Session
/// Check if a given <paramref name="port"/> can be bound to.
/// </summary>
/// <param name="port">The port number to test.</param>
/// <param name="engineType">The <see cref="EngineType"/> we're bind testing for.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
async ValueTask PortBindTest(ushort port, CancellationToken cancellationToken)
async ValueTask PortBindTest(ushort port, EngineType engineType, CancellationToken cancellationToken)
{
logger.LogTrace("Bind test: {port}", port);
try
@@ -142,7 +143,7 @@ namespace Tgstation.Server.Host.Components.Session
for (var i = 0; i < MaxAttempts; ++i)
try
{
SocketExtensions.BindTest(platformIdentifier, port, false);
SocketExtensions.BindTest(platformIdentifier, port, false, engineType == EngineType.OpenDream);
if (i > 0)
logger.LogDebug("Clearing the socket took {iterations} attempts :/", i + 1);
@@ -271,7 +272,7 @@ namespace Tgstation.Server.Host.Components.Session
if (engineType == EngineType.Byond)
await CheckPagerIsNotRunning();
await PortBindTest(launchParameters.Port.Value, cancellationToken);
await PortBindTest(launchParameters.Port.Value, engineType, cancellationToken);
string outputFilePath = null;
var preserveLogFile = true;
@@ -17,7 +17,8 @@ namespace Tgstation.Server.Host.Extensions
/// <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(IPlatformIdentifier platformIdentifier, ushort port, bool includeIPv6)
/// <param name="udp">If we're bind testing for UDP. If <see langword="false"/> TCP will be checked.</param>
public static void BindTest(IPlatformIdentifier platformIdentifier, ushort port, bool includeIPv6, bool udp)
{
ArgumentNullException.ThrowIfNull(platformIdentifier);
ProcessExecutor.WithProcessLaunchExclusivity(() =>
@@ -26,12 +27,16 @@ namespace Tgstation.Server.Host.Extensions
includeIPv6
? AddressFamily.InterNetworkV6
: AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
udp
? SocketType.Dgram
: SocketType.Stream,
udp
? ProtocolType.Udp
: ProtocolType.Tcp);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, true);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false);
if (platformIdentifier.IsWindows)
if (!udp && platformIdentifier.IsWindows)
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
if (includeIPv6)
@@ -101,7 +101,8 @@ namespace Tgstation.Server.Host.Utils
try
{
SocketExtensions.BindTest(platformIdentifier, port, false);
SocketExtensions.BindTest(platformIdentifier, port, false, true);
SocketExtensions.BindTest(platformIdentifier, port, false, false);
}
catch (Exception ex)
{
@@ -1,5 +1,6 @@
using Byond.TopicSender;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -19,6 +20,7 @@ using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics.Arm;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -39,6 +41,8 @@ using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.IO;
using Tgstation.Server.Host.System;
using static NuGet.Frameworks.FrameworkConstants;
namespace Tgstation.Server.Tests.Live.Instance
{
sealed class WatchdogTest : JobsRequiredTest
@@ -544,10 +548,19 @@ namespace Tgstation.Server.Tests.Live.Instance
JobResponse startJob;
if (new PlatformIdentifier().IsWindows) // Can't get address reuse to trigger on linux for some reason
using (var blockSocket = new Socket(SocketType.Stream, ProtocolType.Tcp))
using (var blockSocket = new Socket(
testVersion.Engine.Value == EngineType.OpenDream
? SocketType.Dgram
: SocketType.Stream,
testVersion.Engine.Value == EngineType.OpenDream
? ProtocolType.Udp
: ProtocolType.Tcp))
{
blockSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, true);
blockSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false);
if (testVersion.Engine.Value != EngineType.OpenDream)
blockSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
blockSocket.Bind(new IPEndPoint(IPAddress.Any, ddPort));
// Don't use StartDD here
@@ -742,7 +755,7 @@ namespace Tgstation.Server.Tests.Live.Instance
{
try
{
SocketExtensions.BindTest(new PlatformIdentifier(), ddPort, false);
SocketExtensions.BindTest(new PlatformIdentifier(), ddPort, false, testVersion.Engine == EngineType.OpenDream);
break;
}
catch
@@ -546,7 +546,6 @@ namespace Tgstation.Server.Tests.Live
{
// cleanup existing directories
new LiveTestingServer(null, false).Dispose();
const string PrivateKey = "adlfj73ywifhks7iwrgfegjs";
var controllerAddress = new Uri("http://localhost:15011");