Skip to content

Basic IPV6 Support#2566

Merged
Measurity merged 7 commits intoSubnauticaNitrox:masterfrom
oliver408i:ipv6-support
Dec 3, 2025
Merged

Basic IPV6 Support#2566
Measurity merged 7 commits intoSubnauticaNitrox:masterfrom
oliver408i:ipv6-support

Conversation

@oliver408i
Copy link
Copy Markdown
Contributor

IPv6 connectivity is increasingly common (especially on modern home networks). This PR aims to add basic ipv6 support to Nitrox.
These changes let Nitrox host/join over IPv6 while preserving existing IPv4 behavior.

All changes were pretty much just in general networking, so I don't expect anything in game to have changed.
Some hardcoded IPv4 strings were changed to allow ipv6 to show up, but by default everything still shows IPv4. However, this allows IPv6-only networks (if somehow someone was using one of those) to function with nitrox.

A note:
LiteNetLib was still IPv4-only, helper utilities filtered to IPv4, and address handling broke when IPv6 literals or mapped addresses appeared (e.g., discovery showing ::ffff:). This was fixed with changes to NetHelper.cs. These changes also added support for ipv6 to a few helper functions too.

Test: Open a server, try connecting to it with ::1 (IPv6 loopback). Confirm it works (it should also give you admin perms).

A note on authorship: Codex was used to review the code to see where code needed to be changed to use IPv6 and it also directly wrote a few of the helper functions in NetHelper.cs (mostly the IPv6 local ip detection). As this is pretty common code (not specific to Nitrox or Subnautica), I believe this is ok. I have reviewed and tested all changes.

A note on why add IPv6:

  • Allows IPv6-only networks to use Nitrox
  • Future proof (IPv6 connectivity continues to grow worldwide)
  • Removes some hardcoded IPv4 logic
  • No NAT on IPv6 (but firewalls still exist. In some situations, this can help a bit)
  • It's nice to have I guess... There aren't any tradeoffs I can see.

IPv6 LAN discovery is NOT added in this PR, that could be future work.

Copy link
Copy Markdown
Collaborator

@Coding-Hen Coding-Hen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to have some ipv6 support but I have some comments on the code below

}

if (ipv6Candidate == null
&& address.AddressFamily == AddressFamily.InterNetworkV6
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also combine this if with the one above to reduce your code paths but it might be better to have them apart for readability

if (address.AddressFamily is AddressFamily.InterNetwork or AddressFamily.InterNetworkV6)
{
yield return (ip.Address, ni.Name.Replace("VPN", "").Trim());
if (address.IsIPv4MappedToIPv6)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe if you restructure this as an if else and then have it drop out to the return below the ifs then you can move the normalise there and allow the inner works of that to mean you don't have to call it here

/// </summary>
public static bool IsPrivate(this IPAddress address)
{
address = NormalizeAddress(address);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what the benefit of doing this at a high scope is, can we not move this with the range method below as the other range method calls it itself anyway

string name = parts[0].Trim();
return new Entry(name, address, port);

static string ParseAddressWithOptionalPort(string value, out int parsedPort)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not saying there is but I feel like there must be a better c# way of splitting an ipv6 and port off each other than having to do searches for indexes of : in the strings as well. I do know that ipv6 is not an easy thing to parse out with all the :: etc that can go on.

I assume we are then expecting people to put their ipv6 addresses in the server box in a particular format with the [ ] around it do we need to highlight this to them?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You only use the [] in urls and ssh (for example) when you need to specify the username or need to add :port after the ip. See RFC3986 for more info.

I'll look into splitting the ipv6, but since the user is supposed to put the port in a different box in the ui anyway I don't think this is a big concern.

{
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
IPAddress address = ip.Address;
if (address.IsIPv4MappedToIPv6)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you either don't need this check here or you don't have it in the method you call to avoid doubling up the IsIPv4MappedToIPv6 call

&& !address.IsIPv6LinkLocal
&& !address.IsIPv6Multicast)
{
ipv6Candidate = address;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I have missed something why would you want to continue looping after assigning here rather than just returning early after assigning the cache

@oliver408i oliver408i requested a review from Coding-Hen November 2, 2025 21:17
@Kiaos
Copy link
Copy Markdown
Contributor

Kiaos commented Nov 4, 2025

Did a play test and it works. Did the test on the test server. Then we tested on my own server.

@Kiaos
Copy link
Copy Markdown
Contributor

Kiaos commented Nov 4, 2025

After this is merged i have a update for server logs and what not here: Kiaos/Nitrox@master...Kiaos:Nitrox:pr-2566

you can check it out. this needs to be merged first.

@dartasen dartasen requested a review from Measurity November 23, 2025 21:01
Copy link
Copy Markdown
Collaborator

@Coding-Hen Coding-Hen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few comments. Overall looks good though. Will be nice to add ipv6 support

@Measurity Measurity requested a review from Coding-Hen November 24, 2025 21:01
Copy link
Copy Markdown
Collaborator

@Coding-Hen Coding-Hen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@github-actions
Copy link
Copy Markdown

Test Results

244 tests  +1   243 ✅ +1   6s ⏱️ ±0s
  1 suites ±0     1 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 7c35917. ± Comparison against base commit f9ef1f4.

This pull request removes 2 and adds 3 tests. Note that renamed tests count towards both.
Nitrox.Model.Helper.NetHelperTest ‑ ShouldMatchLocalhostIps
Nitrox.Model.Helper.NetHelperTest ‑ ShouldMatchPrivateIps
Nitrox.Model.Extensions.IpAddressExtensionsTest ‑ ShouldMatchLocalhostIps
Nitrox.Model.Extensions.IpAddressExtensionsTest ‑ ShouldMatchPrivateIps
Nitrox.Test.Patcher.Patches.PatchesTranspilerTest ‑ AllPatchesTranspilerSanity (NitroxPatcher.Patches.Dynamic.ErrorMessage_OnLateUpdate_Patch,0)

@Measurity Measurity merged commit 064b974 into SubnauticaNitrox:master Dec 3, 2025
@Measurity Measurity added this to the 1.8.0.2 milestone Dec 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants