diff --git a/src/Tgstation.Server.Host/Components/InstanceManager.cs b/src/Tgstation.Server.Host/Components/InstanceManager.cs
index 9a6ecd8b62..085dc79c32 100644
--- a/src/Tgstation.Server.Host/Components/InstanceManager.cs
+++ b/src/Tgstation.Server.Host/Components/InstanceManager.cs
@@ -5,8 +5,6 @@ using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Net;
-using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Api.Models;
@@ -16,6 +14,7 @@ using Tgstation.Server.Host.Configuration;
using Tgstation.Server.Host.Controllers;
using Tgstation.Server.Host.Core;
using Tgstation.Server.Host.Database;
+using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.IO;
using Tgstation.Server.Host.Jobs;
using Tgstation.Server.Host.Security;
@@ -482,8 +481,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.
- using var hostingSocket = new Socket(SocketType.Stream, ProtocolType.Tcp);
- hostingSocket.Bind(new IPEndPoint(IPAddress.Any, serverPortProvider.HttpApiPort));
+ SocketExtensions.BindTest(serverPortProvider.HttpApiPort);
}
///
diff --git a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs
index 3b859791ab..84c2ca9667 100644
--- a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs
+++ b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs
@@ -2,7 +2,6 @@
using System;
using System.Globalization;
using System.Linq;
-using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
@@ -16,6 +15,7 @@ using Tgstation.Server.Host.Components.Deployment;
using Tgstation.Server.Host.Components.Interop;
using Tgstation.Server.Host.Components.Interop.Bridge;
using Tgstation.Server.Host.Core;
+using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.IO;
using Tgstation.Server.Host.Jobs;
using Tgstation.Server.Host.Security;
@@ -118,11 +118,9 @@ namespace Tgstation.Server.Host.Components.Session
/// The port number to test.
static void PortBindTest(ushort port)
{
- using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
-
try
{
- socket.Bind(new IPEndPoint(IPAddress.Any, port));
+ SocketExtensions.BindTest(port);
}
catch (SocketException ex)
{
diff --git a/src/Tgstation.Server.Host/Extensions/SocketExtensions.cs b/src/Tgstation.Server.Host/Extensions/SocketExtensions.cs
new file mode 100644
index 0000000000..6d4ae76323
--- /dev/null
+++ b/src/Tgstation.Server.Host/Extensions/SocketExtensions.cs
@@ -0,0 +1,23 @@
+using System.Net;
+using System.Net.Sockets;
+
+namespace Tgstation.Server.Host.Extensions
+{
+ ///
+ /// Extension methods for the .
+ ///
+ static class SocketExtensions
+ {
+ ///
+ /// Attempt to exclusively bind to a given .
+ ///
+ /// The port number to bind to.
+ public static void BindTest(ushort port)
+ {
+ using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, true);
+ socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false);
+ socket.Bind(new IPEndPoint(IPAddress.Any, port));
+ }
+ }
+}
diff --git a/tests/Tgstation.Server.Tests/Instance/JobsRequiredTest.cs b/tests/Tgstation.Server.Tests/Instance/JobsRequiredTest.cs
index 258e69de57..6594f345e2 100644
--- a/tests/Tgstation.Server.Tests/Instance/JobsRequiredTest.cs
+++ b/tests/Tgstation.Server.Tests/Instance/JobsRequiredTest.cs
@@ -36,7 +36,8 @@ namespace Tgstation.Server.Tests.Instance
}
if (expectFailure ^ job.ExceptionDetails != null)
- Assert.Fail(job.ExceptionDetails ?? $"Expected job \"{job.Id}\" \"{job.Description}\" to fail but it didn't");
+ Assert.Fail(job.ExceptionDetails
+ ?? $"Expected job \"{job.Id}\" \"{job.Description}\" to fail {(expectedCode.HasValue ? $"with ErrorCode \"{expectedCode.Value}\" " : String.Empty)}but it didn't");
if (expectedCode.HasValue)
Assert.AreEqual(expectedCode.Value, job.ErrorCode, job.ExceptionDetails);
diff --git a/tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs b/tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs
index d8e666560f..532c18d704 100644
--- a/tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs
+++ b/tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs
@@ -141,6 +141,8 @@ namespace Tgstation.Server.Tests.Instance
Job startJob;
using (var blockSocket = new Socket(SocketType.Stream, ProtocolType.Tcp))
{
+ blockSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, true);
+ blockSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false);
blockSocket.Bind(new IPEndPoint(IPAddress.Any, 1337));
startJob = await instanceClient.DreamDaemon.Start(cancellationToken).ConfigureAwait(false);
diff --git a/tests/Tgstation.Server.Tests/IntegrationTest.cs b/tests/Tgstation.Server.Tests/IntegrationTest.cs
index b842dd6345..3f02965eca 100644
--- a/tests/Tgstation.Server.Tests/IntegrationTest.cs
+++ b/tests/Tgstation.Server.Tests/IntegrationTest.cs
@@ -200,6 +200,8 @@ namespace Tgstation.Server.Tests
// http bind test https://github.com/tgstation/tgstation-server/issues/1065
using (var blockingSocket = new Socket(SocketType.Stream, ProtocolType.Tcp))
{
+ blockingSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, true);
+ blockingSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false);
blockingSocket.Bind(new IPEndPoint(IPAddress.Any, server.Url.Port));
try
{