mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-27 15:07:03 +01:00
Disallow address reuse for port bind tests
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -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
|
||||
/// <param name="port">The port number to test.</param>
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace Tgstation.Server.Host.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for the <see cref="Socket"/> <see langword="class"/>.
|
||||
/// </summary>
|
||||
static class SocketExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Attempt to exclusively bind to a given <paramref name="port"/>.
|
||||
/// </summary>
|
||||
/// <param name="port">The port number to bind to.</param>
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user