Class Ipv4UdpPortProbe

java.lang.Object
org.mockserver.lifecycle.Ipv4UdpPortProbe

public final class Ipv4UdpPortProbe extends Object
The UDP counterpart of the TCP listeners' LoopbackShadowProbe, for the HTTP/3 and DNS listeners. On macOS a dual-stack UDP bind succeeds on a port another socket holds on 0.0.0.0, which then receives the localhost datagrams. The probe must run BEFORE the server binds: on macOS and Linux an IPv4 bind also fails against the same process's own dual-stack socket, so a later probe cannot tell the two apart; a socket that takes the port in between is caught after the bind by loopbackReachesAnotherSocket(io.netty.channel.Channel), which sends a datagram instead. No probe sets SO_REUSEADDR. Internal, not API: public only so the listeners in other packages can share it.
  • Method Details

    • listenerAddress

      public static InetSocketAddress listenerAddress(String localBoundIP, int port)
      Returns:
      the address a UDP listener binds: localBoundIP when it is set, as the TCP listeners do, otherwise every address
    • shadowedOnIpv4

      public static boolean shadowedOnIpv4(InetSocketAddress listenerAddress)
      Only a wildcard bind is checked: a bind of one address fails against a socket on 0.0.0.0:port, and a socket on one address is sent every datagram for that address.
      Returns:
      true if the server's bind of listenerAddress would share its port with a socket on the IPv4 wildcard, which would then get the localhost datagrams
    • shadowedOnIpv4

      public static boolean shadowedOnIpv4(int port)
      Returns:
      true if a dual-stack wildcard bind of port, as the server makes, would succeed although another socket holds the port on the IPv4 wildcard; false wherever that bind fails as well (Linux), so the server's own bind then reports the conflict
    • heldOnIpv4

      public static boolean heldOnIpv4(int port)
      Returns:
      true if binding 0.0.0.0:port fails with a BindException, i.e. another socket holds the port on IPv4 (or the port cannot be bound at all, which the server's own bind then reports); false if the port was free on IPv4 or IPv4 is unavailable
    • dualStackBindSucceeds

      public static boolean dualStackBindSucceeds(int port)
      Returns:
      true if a dual-stack wildcard bind of port, as the server makes, succeeds. The channel is never registered with a selector, so closing it releases the port at once; a Netty channel's socket stays bound until its event loop next deregisters it.
    • portFreeOnIpv4

      public static int portFreeOnIpv4()
      Returns:
      a port the IPv4 allocator chose, so no socket held it on IPv4 when it was chosen, or 0 if IPv4 is unavailable
    • loopbackReachesAnotherSocket

      public static boolean loopbackReachesAnotherSocket(io.netty.channel.Channel boundChannel)
      The check after the bind, for a socket that took the port on 0.0.0.0 between shadowedOnIpv4(java.net.InetSocketAddress) and the server's bind: a datagram is sent to 127.0.0.1 on the bound port, and must arrive on boundChannel. The probe datagram is taken off the channel's pipeline, so no handler sees it. Waits uninterruptibly, for about a second at most, and keeps the caller's interrupt. Made only on macOS, where that bind can succeed.
      Returns:
      true if the probe reached another socket; false if it reached boundChannel, the platform is not macOS, the channel is not bound to a wildcard address, nothing listens on 127.0.0.1 at that port, or the check could not be made (its event loop stalled or IPv4 unavailable)
    • ipv4WildcardConflict

      public static BindException ipv4WildcardConflict(int port, String traffic, String portProperty)
      Parameters:
      traffic - what reaches the other socket, such as HTTP/3 requests
      portProperty - the configuration property that set the port