Skip to content

Conversation

simon-lemay-unity
Copy link
Contributor

Purpose of this PR

The regex we used to validate hostnames did not accept single words as valid hostnames. But single words can be valid hostnames. The most common is of course "localhost" but one can edit one's hosts file to define any word as something the local resolver will resolve to an IP address.

This PR addresses this by removing any validation of the provided hostname. We could modify the validity check to accept single words too, but the regex is pretty indigestible already and it's simpler to just let the resolver fail if the user provided garbage. UTP will signal this through a disconnection event with an appropriate reason (which we'll be able to map to a nice error message once this PR lands).

While I was at it, I also made a few cleanups and improvements:

  • Removed the UTP_TRANSPORT_2_4_ABOVE define. NGO depends on UTP 2.4.0 so it can be safely assumed that users will have it installed. No need to conditionally compile the code that depends on it.
  • Added a test that establishes a connection using hostname resolution.
  • Simplified the logic around connections and avoid bypassing the Connect method when connecting to a hostname.
  • Deprecated ConnectionAddressData.ServerEndPoint. We don't use it anymore, it doesn't work with hostnames, and it's not providing any value over just calling NetworkEndpoint.Parse. And worst of all: its capitalization of "endpoint" doesn't match what we use elsewhere.
  • Modified the listen address logic so that if a domain name is used, by default if remote connections are allowed we will listen on :: (the IPv6 "any" address) instead of 0.0.0.0. This can still be overridden using SetConnectionData. The reason for this change is that the resolver in UTP prioritizes IPv6 addresses over IPv4. So if we listen on IPv4 by default, we're likely to get issues if the resolver then ends up with an IPv6 address. In current versions of UTP for instance, this causes errors on Windows (a fix is on the way). I'm looking into changing the behavior of the resolver to prefer IPv4, but that's an engine change so might take a while to land. In the meantime defaulting to IPv6 seems like the best approach.

Changelog

  • Fixed: Fixed an issue where UnityTransport would not accept single words as valid hostnames (notably "localhost").
  • Changed: Marked UnityTransport.ConnectionAddressData.ServerEndPoint as obsolete. It can't work when using hostnames as the server address, and its functionality can easily be replicated using NetworkEndpoint.Parse.

Documentation

No documentation changes or additions were necessary.

Testing & QA

Tested with manual and automated tests.

Backport

Hostname resolution is only supported in UTP 2.4+ and Unity 6.1+, so no backport necessary.

@simon-lemay-unity simon-lemay-unity changed the title fix: Accept singles words as valid hostnames fix: Accept single words as valid hostnames Aug 11, 2025
Copy link
Collaborator

@michalChrobot michalChrobot left a comment

Choose a reason for hiding this comment

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

Looks good from my side, I would still wait for Noel or Emma to also approve/comment

@michalChrobot
Copy link
Collaborator

michalChrobot commented Aug 13, 2025

FYI the CMB Service Test failure is a know issue that Noel is addressing

*update, it was fixed and I merged latest content from develop-2.0.0

Copy link
Collaborator

@NoelStephensUnity NoelStephensUnity left a comment

Choose a reason for hiding this comment

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

@simon-lemay-unity
A bunch of good stuff in here, but I have concerns on how this will impact the connection flow with users. Primarily, with this update the behavior changes the default behavior which is to provide meaningful information if the user is using an FQDN (which is what I believe vast majority of usage would be) that is malformed, just like we would with an IP address, to the behavior of not doing anything and allowing everything to run as if it is "ok" until the hostname resolution fails due to a malformed FQDN. This was my original concern when hostname support was initially added.

This also removes script that actually reduces user pain:

  • Before: If a user uses an invalid FQDN it would immediately throw an error with a clear message as to the problem and NetworkManager would shutdown.
    • The user can quickly determine the issue.
  • Now: If a user uses an invalid FQDN it waits for before transport trickles up a disconnect/unable to connect message.
    • Albeit, we could improve the error message via the PR mentioned...but we still are changing the connection flow behavior where upon starting NetworkManager if it returns "true" then that meant a bunch of things are "correct"...and if we detected something wrong with the configuration (i.e. invalid IP address or the like) then we would log an error and shutdown the NetworkManager.

There are a very few special case scenarios where someone would want to use an unqualified name as opposed to a FQDN. The localhost is a default internal machine specific unqualified domain name, which we could have just as easily checked to see if the address provided only contained the word "localhost" (removing any capitalization) since that would (most likely) be the most widely used single word hostname.

Any other unqualified hostnames would require being specifically configured in the local machine's DNS table or on a local network name server or it would be a NetBIOS name. Which I think a very small percentage of our users would have that kind of configuration...which the ones that do would most likely be using it for development purposes. The vast majority of netcode projects are connecting via the internet where FQDNs are required.

I guess my question is why remove this check that would reduce user pain as opposed to adding something like an isFQDN flag that could be disabled for the special cases and some additional script to check for the basic kinds of things like "localhost" when isFQDN is still enabled (which would be the default)? (We could even provide users a way to configure a set of "valid" unqualified names that it would treat as FQDNs and allow/bypass the check.)

@simon-lemay-unity
Copy link
Contributor Author

@NoelStephensUnity

My main objective with this PR is getting "localhost" resolution to work, because if someone sees in a release note that they can now use domain resolution and they then attempt to use the obvious test case of "localhost" and it doesn't work, then it's a pretty bad look. The rationale behind removing the validation is just that this was the simplest way to achieve that goal and had the benefit of simplifying the code to boot.

If you feel however that a validation check is important at the moment of starting a client, I don't mind adding that in. It won't be through that regex however since it's wrong in other ways too (e.g. it doesn't accept FQDNs with their trailing dot).

@simon-lemay-unity
Copy link
Contributor Author

@NoelStephensUnity I added a validation step in StartClient to ensure that the provided hostname is valid, and a test to verify it. The method I'm using even handles all the cases that were not handled correctly by the previous regex, including localhost.

Copy link
Collaborator

@NoelStephensUnity NoelStephensUnity left a comment

Choose a reason for hiding this comment

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

@simon-lemay-unity
Thank you very much... and I like your way of handling the host name check (way simpler with more coverage than what I had put together).
:godmode: 🥇

@NoelStephensUnity NoelStephensUnity enabled auto-merge (squash) August 14, 2025 23:02
@NoelStephensUnity NoelStephensUnity merged commit b21d4ad into develop-2.0.0 Aug 15, 2025
25 checks passed
@NoelStephensUnity NoelStephensUnity deleted the fix/localhost-resolution branch August 15, 2025 00:06
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.

4 participants