简体   繁体   中英

UDP socket binding and sending behavior on Windows 1709

I've been debugging a UDP network issue on Windows Server 1709 which boils down to the following code:

public class SendUDP {
  public static void main(String[] args) throws IOException {
    byte[] buffer = {0};
    InetAddress address = InetAddress.getByName(args[0]);
    int port = Integer.parseInt(args[1]);

    DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port);

    System.out.println("Sending packet to " + packet.getSocketAddress().toString());

    InetSocketAddress localhost = new InetSocketAddress(args[2], 0);
    DatagramSocket datagramSocket = new DatagramSocket(localhost);
    System.out.println("Sending socket bound to " + datagramSocket.getLocalSocketAddress());

    datagramSocket.send(packet);
  }
}

The intended arguments are: <address to send to> <port to send to> <local address to bind to> . So all this does is create a locally bound UDP socket and send a packet out on it.

On Linux, Mac and Windows < 1709 (Workstation 10 and Server 2016) this works fine if the locally bound address is 127.0.0.1 and the address to send to is the IP of the same host (I'm just sending a packet to a local process). However , on Server 1709 I get the following exception:

$ java SendUDP 10.128.0.3 500 127.0.0.1
Sending packet to /10.128.0.3:500
Sending socket bound to /127.0.0.1:50209
Exception in thread "main" java.net.SocketException: Network is unreachable: Datagram send failed
        at java.net.DualStackPlainDatagramSocketImpl.socketSend(Native Method)
        at java.net.DualStackPlainDatagramSocketImpl.send(DualStackPlainDatagramSocketImpl.java:136)
        at java.net.DatagramSocket.send(DatagramSocket.java:693)
        at SendUDP.main(SendUDP.java:20)

On this system it seems I have to ensure that I either bind to all interfaces ( 0.0.0.0 ) or the sending address is the same as the bound address. So, for the above example, 10.128.0.3 500 0.0.0.0 works just fine. Similarly, 127.0.0.1 500 127.0.0.1 works and 10.128.0.3 500 10.128.0.3 also works. I've tested this with Java 1.8.1_181.

I'm not really a networking specialist, but it would seem that even when a socket is bound to some arbitrary local address, the OS should be able to route the outbound packets, sent on that socket, correctly. Is this something broken in this version of Windows or are my assumptions about sending UDP packets wrong?

it would seem that even when a socket is bound to some arbitrary local address, the OS should be able to route the outbound packets, sent on that socket, correctly.

Which it is, actually. When a socket is bound locally to 127.0.0.1 explicitly (or any specific local IP, for that matter), that socket can only send to destinations that are reachable by the network interface that IP belongs to.

When a socket is bound to 127.0.0.1 (the local loopback interface), only the loopback interface is reachable (which includes sockets bound to 0.0.0.0 for all interfaces). That is what loopback is meant for.

So, the error is technically correct, you should not be able to send to 10.128.0.3 when explicitly bound to 127.0.0.1 . The two IPs should be on different interfaces, with no route between them. Thus, this send should not work on any system under normal conditions.

Is this something broken in this version of Windows

If anything, it sounds like a bug in the older versions, that was fixed in the new version. But that doesn't explain why it works on Linux and Mac, because it should not work. It sounds more like 10.128.0.3 is somehow getting mapped to the same loopback interface as 127.0.0.1 , or the loopback adapter on some machines is more flexible than others and allows routes with other local interfaces. Thus allowing communications between 127.0.0.1 and 10.128.0.3 . But that is not a typical scenario. Sounds more like a bad network configuration. The loopback interface is supposed to be isolated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM