Search code examples
javaicmp

the timeout parameter for InetAddress.isReachable() doesn't match the value of netem delay


I used netem to add packet delay for certain IP address.

tc filter add dev ens33 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.106.182 flowid 1:1

The ping tool indicated that it worked.

PING 192.168.106.182 (192.168.106.182) 56(84) bytes of data.
64 bytes from 192.168.106.182: icmp_seq=1 ttl=63 time=2003 ms

Following was my code for test

import java.io.IOException;
import java.net.InetAddress;


public class PingTimeoutTest {
    public static void main(String[] args) throws IOException {
        InetAddress inetAddress = InetAddress.getByName(args[0]);
        int timeoutStepMilli = 20;
        int timeoutBase = 10;
        while (!inetAddress.isReachable(timeoutBase)) {
            System.out.println(timeoutBase + ": bad");
            timeoutBase += timeoutStepMilli;
        }
        System.out.println(timeoutBase + ": ok");
    }
}

And the result is

10: bad
30: bad
50: bad
70: bad
90: bad
110: bad
130: bad
150: bad
170: bad
190: bad
210: bad
230: bad
250: bad
270: bad
290: ok

I have no idea why this happened. It's the same 290ms timeout when I set 2000ms netem delay both on this side or remote side.

Any help will be grateful.


Solution

  • I think you can use the Socket class to establish a TCP connection instead of isReachable!

    check this out:

    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.Socket;
    
    public class PingTimeoutTest {
        public static void main(String[] args) {
            String ipAddress = args[0];
            int timeoutStepMilli = 20;
            int timeoutBase = 10;
            boolean reachable = false;
    
            while (!reachable && timeoutBase <= 2000) {
                try (Socket socket = new Socket()) {
                    socket.connect(new InetSocketAddress(ipAddress, 80), timeoutBase);
                    reachable = true;
                } catch (IOException e) {
                    System.out.println(timeoutBase + ": bad");
                    timeoutBase += timeoutStepMilli;
                }
            }
    
            if (reachable) {
                System.out.println(timeoutBase + ": ok");
            } else {
                System.out.println("Connection not successful");
            }
        }
    }