Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,8 @@ Barotrauma/**/GameAnalyticsKeys.cs
Deploy/DeployAll/PrivateKey.*
.github/ISSUE_TEMPLATE/release-checklist.md

#Rider
# Rider
*.DotSettings.user

# VSCode
.vscode/
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#nullable enable
using DnsClient;
using System.Linq;

namespace Barotrauma.Networking
{
internal static class DnsSrvResolver
{
private static readonly LookupClient lookup = new();
private const string Service = "_barotrauma";
private const string Proto = "_udp";

/// <summary>Returns true if a SRV record was found.</summary>
public static bool TryResolve(string host, string service, string proto, out string targetHost, out int targetPort)
{
targetHost = "";
targetPort = 0;
var queryName = $"{service}.{proto}.{host.TrimEnd('.')}";

IDnsQueryResponse result;
try
{
result = lookup.Query(queryName, QueryType.SRV);
}
catch
{
return false;
}

var record = result.Answers
.SrvRecords()
.OrderBy(r => r.Priority)
.ThenByDescending(r => r.Weight)
.FirstOrDefault();
if (record is null) return false;

targetHost = record.Target.Value.TrimEnd('.');
targetPort = record.Port;

return true;
}

/// <summary>Returns true if a SRV record was found.</summary>
public static bool TryResolve(string host, out string targetHost, out int targetPort)
=> TryResolve(host, Service, Proto, out targetHost, out targetPort);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ public static Option<LidgrenEndpoint> ParseFromWithHostNameCheck(string endpoint
port = int.TryParse(split[1], out var tmpPort) ? tmpPort : port;
}

// SRV look-up: only when the user did not specify a port
if (port == NetConfig.DefaultPort
&& tryParseHostName
&& DnsSrvResolver.TryResolve(hostName, out var srvHost, out var srvPort))
{
hostName = srvHost;
port = srvPort;
}

if (LidgrenAddress.Parse(hostName).TryUnwrap(out var adr) ||
(tryParseHostName && LidgrenAddress.ParseHostName(hostName).TryUnwrap(out adr)))
{
Expand Down
26 changes: 26 additions & 0 deletions Barotrauma/BarotraumaTest/DnsSrvResolverTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Add extern alias to pick up WindowsClient reference
extern alias Client;

using System;
using Xunit;

namespace WindowsTest
{
public class DnsSrvResolverTests
{
[Fact]
public void DefaultTryResolve_NoSrvRecord_ReturnsFalse()
=> Assert.False(Client::Barotrauma.Networking.DnsSrvResolver.TryResolve("example.com", out _, out _));

[Fact]
public void OverloadedTryResolve_XmppJabber_ReturnsTrue()
{
// jabber.org provides a stable XMPP server SRV record
bool ok = Client::Barotrauma.Networking.DnsSrvResolver.TryResolve(
"jabber.org", "_xmpp-server", "_tcp", out var host, out var port);
Assert.True(ok, "Expected SRV record for _xmpp-server._tcp.jabber.org");
Assert.EndsWith("jabber.org", host);
Assert.True(port > 0);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

<ItemGroup>
<ProjectReference Include="..\..\XNATypes\XNATypes.csproj" />
<PackageReference Include="DnsClient" Version="1.8.0" />
</ItemGroup>

</Project>