Class StunMessage

java.lang.Object
com.hypixel.hytale.server.core.io.ice.StunMessage

public final class StunMessage extends Object
STUN message codec, covering what ICE connectivity checks need.

Mirrors the client codec in HytaleClient/Networking/NatTraversal. The two are verified against the same RFC 5769 sample messages, which is what keeps them from drifting apart on the wire.

See Also:
  • Field Details

  • Constructor Details

    • StunMessage

      public StunMessage(int messageType, @Nonnull byte[] transactionId)
  • Method Details

    • request

      public static StunMessage request()
    • response

      public static StunMessage response(@Nonnull byte[] transactionId)
    • errorResponse

      public static StunMessage errorResponse(@Nonnull byte[] transactionId, int code, @Nonnull String reason)
    • getMessageType

      public int getMessageType()
    • getTransactionId

      public byte[] getTransactionId()
    • isRequest

      public boolean isRequest()
    • isResponse

      public boolean isResponse()
    • getAttribute

      @Nullable public byte[] getAttribute(int type)
    • hasAttribute

      public boolean hasAttribute(int type)
    • getUsername

      @Nullable public String getUsername()
    • getPriority

      public long getPriority()
    • getMappedAddress

      @Nullable public InetSocketAddress getMappedAddress()
      Reads the address a Binding response reports this sender to have.

      XOR-MAPPED-ADDRESS wins over MAPPED-ADDRESS, which only servers predating RFC 5389 send.

      Returns:
      the reported address, or null when no attribute carries a well-formed one
    • addAttribute

      public void addAttribute(int type, @Nonnull byte[] value)
    • addUsername

      public void addUsername(@Nonnull String username)
    • addPriority

      public void addPriority(long priority)
    • addUseCandidate

      public void addUseCandidate()
    • addIceRole

      public void addIceRole(boolean controlling, long tiebreaker)
    • addXorMappedAddress

      public void addXorMappedAddress(@Nonnull InetSocketAddress address)
      Adds XOR-MAPPED-ADDRESS, which tells the peer the address its check arrived from. That is how a peer behind a symmetric NAT learns the mapping its own NAT created.
    • appendMessageIntegrity

      public void appendMessageIntegrity(@Nonnull byte[] key)
      Appends MESSAGE-INTEGRITY over every attribute added so far.

      The HMAC covers the message with the header length field already counting the attribute that does not exist yet, per RFC 5389 section 15.4. Must be added after every other attribute except FINGERPRINT.

    • appendFingerprint

      public void appendFingerprint()
      Appends FINGERPRINT, which must be the final attribute.
    • verifyMessageIntegrity

      public static boolean verifyMessageIntegrity(@Nonnull byte[] datagram, int length, @Nonnull byte[] key)
      Verifies MESSAGE-INTEGRITY against the bytes as received. Re-serializing would not reproduce the sender's digest, so the original datagram is required.
    • verifyMessageIntegrity

      public static boolean verifyMessageIntegrity(@Nonnull ByteBuffer datagram, @Nonnull byte[] key)
      Verifies MESSAGE-INTEGRITY without copying the received datagram.
    • toBytes

      public byte[] toBytes()
    • parse

      @Nullable public static StunMessage parse(@Nonnull byte[] datagram, int length)
      Parses a datagram, rejecting anything malformed rather than trusting the declared lengths.
      Returns:
      the parsed message, or null when the bytes are not a well-formed STUN message
    • parse

      @Nullable public static StunMessage parse(@Nonnull ByteBuffer datagram)
      Parses the remaining bytes without copying the received datagram or changing its position.
      Returns:
      the parsed message, or null when the bytes are not a well-formed STUN message
    • looksLikeStun

      public static boolean looksLikeStun(@Nonnull byte[] datagram, int length)
      Whether a datagram is STUN rather than QUIC.

      RFC 7983 assigns 0..3 to STUN and QUIC sets the fixed bit, but RFC 9287 lets a negotiated endpoint clear that bit, so the cookie and the length are checked too.

    • looksLikeStun

      public static boolean looksLikeStun(@Nonnull ByteBuffer datagram)