#Dedicated Server Feedback

1 messages · Page 1 of 1 (latest)

frigid ocean
#

Putting content in thread posts due to discord length limits.

#

On Friday I chased down what was going on for me, I happened to be using wine, but this diagnostic applies to both Linux and Windows the same. This is what is happening with the stun code (direct connect, but not direct IP patch):

  • The code starts with a gethostname() then does a getaddrinfo(hostname) in order to try to determine the systems local IP. This will only work for some servers some of the time - if the host has more than one interface and/or more than one IP address this can result in an arbitrary IP address being returned. The code later uses this address to bind() the UDP socket used for direct connection attempts (both the server and the client do this). On Linux systems this results in the STUN client socket being bound to 127.0.0.1 or 127.0.1.1 under typical circumstances. On Windows this results in the LAN address of teh server sometimes but if the server is multi-homed it might result in a binding to e.g. a dead wifi interface or a disconnected VPN interface. One of the reasons that you see some reports for some users that "VPN works better" is that a VPN program with a "kill switch" will reorganized the network configuration such that the gethostname path more consistently results in the VPN interface IP, but this is somewhat of a fluke, it's a happenstance side effect of how "kill switch" is implemented.
#
  • The more correct and portable way to handle looking up a local LAN IP to bind the STUN socket to is to either: a) bind to AF_UNSPEC (0.0.0.0) and just use sendto/sendmsg, or b) if you really want to know the local IP (e.g. for stun candidates), then do a connect(2) after the AF_UNSPEC bind and then use getsockname to get the local address. The connect(2) sends no packets, but it sets the destination address for write(2) calls which has the side effect of binding the local side socket to a route that can reach the destination specified in the connect call.
  • Linux servers are further impacted by the fact that the code tries to bind() a single port multiple times, but only SO_REUSEADDR is set. On Linux SO_RUSEADDR and SO_REUSEPORT have subtle different meanings, but with the intent of the code the right fix here is to set SO_REUSEADDR and SO_REUSEPORT and then the code will work correctly on both windows and on linux under wine (also on linux proper).
  • A workaround to enable direct connections on Windows and Linux is to add a hosts file entry for the system hostname that points to the LAN IP of the host - this fixes the STUN setup code path. I've verified this hack works, though I would not recommend having users apply this, just fix the code instead, this change would have other weird side effects potentially even negative security impacts in some cases (where some other software is expecting the same resolve to return AF_LOCAL for example).
#

I tried the direct connection patch just now too. It works, but it's quite dependent on users reading and being careful.

  • if a user doesn't read the markdown, and they put "NA" in the region option in the JSON, the server will effectively break. it should probably fall back to latency selection on bad values, or crash, sitting like a plumb means diagnosis requires users/support reading the logs.
  • it would be nice if the server would still advertise to the coordination servers with the invite code - the static address should just be a stun/ice candidate, and it should work all the time.
  • it would be really nice if the direct connection port could be specified alone, all other addresses should default to AF_UNSPEC and if a port is specified (given the above is done too) then specifying a port should essentially just fix game and stun traffic to a single bind on that port, serving both functions.

In both cases it'd be really nice if passwords could be saved (and connection details in general in the new direct connection patch) - it's just a gameserver password not a sensitive one.