Uploaded image for project: 'Spigot'
  1. Spigot
  2. SPIGOT-6913

Floodgate Players can't connect over IPv6 behind BungeeCord with ip_forward

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Minor Minor
    • None
    • None
    • Dual mode Java/Bedrock server behind BungeeCord with GeyserMC (Bedrock translation layer) and Floodgate (Plugin to allow Geyser connections, player account linking and provide some interoperability with Plugins like AntiCheat) installed.

    • CraftBukkit version 3413-Spigot-862678e-13670b4 (MC: 1.18.1) (Implementing API version 1.18.1-R0.1-SNAPSHOT)
    • Floodgate
    • Yes

      I found a problem/bug when connecting over IPv6 to a server with floodgate running behind a BungeeCord/Geyser proxy. When the client tries to connect, he immediately gets kicked with the message:

      Kicked whilst connecting to server: If you wish to use IP forwarding, please enable it in your BungeeCord config as well! 

      On the Proxy "ip_forward" is true and on the server "bungeecord" is true as well. This only happens with IPv6 for bedrock players. It doesn't with IPv4 in any case and also not with java players on IPv6.

      Digging down in the source code I found "HOST_PATTERN" in "net/minecraft/network/protocol/handshake/PacketHandshakingInSetProtocol.java" to be the problem. Because if an IPv6 java player logs in the log locks like this

      [Server thread/INFO]: Bennet96[/[2003:d4:df0d:b801:6e7e:a7a4:44e:3280]:56047] logged in with entity id 15446 at ([world]-220.7278616902495, 122.78937476759972, 74.67083019292772)

      And with a bedrock IPv6 player like thisĀ 

      [Server thread/INFO]: /[2003:d4:df12:c901:d001:2408:564e:fd99%0]:41753 lost connection: If you wish to use IP forwarding, please enable it in your BungeeCord config as well!
      

      When the bedrock player connects, the forwarded IP address has the zone identifier included, which is legal by RFC6874 but not covered by the HOST_PATTERN regex. The zone identifier seams to present by default when parsing IP addresses with java because it also appears for java player in the Bungee logs, but Bungee normally seams to truncate it before sending it of in the Handshake packet. It reemerges for Bedrock players because Floodgate intercepts the packet and replaces it with the appropriate value for the Bedrock player (see here). It didn't found out where exactly they get the IP from but I assume it is in some way parsed as java.net.InetAddress so it includes the zone identifier again.

      I know, strictly speaking this might not be a Spigot Bug, but one of another plugin, but they abide by the rules of how an IPv6 address should look like, so I think that it might needs fixing here. But I would also understand if a fix in the plugin is preferred. In this case I would open an issue there tomorrow.

      Looking at RFC6874 section 2 explicitly states, that there is specific character set for that identifier.

      According to IPv6 Scoped Address syntax [RFC4007], a zone identifier
      is attached to the textual representation of an IPv6 address by
      concatenating "%" followed by <zone_id>, where <zone_id> is a string
      identifying the zone of the address. However, the IPv6 Scoped
      Address Architecture specification gives no precise definition of the
      character set allowed in <zone_id>. There are no rules or de facto
      standards for this. For example, the first Ethernet interface in a
      host might be called %0, %1, %en1, %eth0, or whatever the implementer
      happened to choose.

      So a regex for the whole IP is probably not very useful. Which means that if a validity check is desirable then it could be an option trying to parse it as java.net.InetSocketAddress or java.net.InetAddress or to truncate the address at the "%" and apply the regex to the first part. But all 3 options seam kind of bad because an InetSocketAddress apperently always makes a DNS lookup, an InetAddress takes the IP as bytes and the regex (in its current from) still allows malformed addresses with too few or too many block or too long blocks etc. And if half a check is good enough that might not check it at all and assume that the data Bungee sends is probably correct. A 4th and 5th option would be to use the Google Guava library to parse it with com.google.common.net.InetAddresses#forString but I'm not sure how hard it would be to use an external library it a patched Mojang file or implementing a full on IP parser there, but catching each edge case for every possible IP notation is notoriously a pain in the neck.

            Unassigned Unassigned
            bennet0496 Bennet Becker
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: