I'm implementing a DNS server with DatagramSocket (UDP) in Java and the code looks like:
try (DatagramSocket socket = new DatagramSocket(new InetSocketAddress("0.0.0.0", 53))) {
DatagramPacket request = ... // Init Packet
socket.receive(request);
... // Parse request, Resolve, then Generate reesponse
socket.send(response);
}
It works fine on my PC and most servers (including aws, linode, etc), but does not work well on a server with double ethernet adapter.
This server has a network config:
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 192.168.1.204
netmask 255.255.255.0
auto eth1
iface eth1 inet static
address 192.168.1.207
netmask 255.255.255.0
When I test this DNS, I get:
# nslookup
> server 192.168.1.207
Default server: 192.168.1.207
Address: 192.168.1.207#53
> info.dev.
;; reply from unexpected source: 192.168.1.204#53, expected 192.168.1.207#53
;; reply from unexpected source: 192.168.1.204#53, expected 192.168.1.207#53
;; reply from unexpected source: 192.168.1.204#53, expected 192.168.1.207#53
;; connection timed out; no servers could be reached
>
It seems to receive a packet from eth1 (192.168.1.207) but send to eth0 (192.168.1.204). And my code does not know which interface the packet is received from.
try (DatagramSocket socket = new DatagramSocket(new InetSocketAddress("0.0.0.0", 53))) {
...
socket.receive(request); // local socket address not known :-(
...
socket.send(response); // local socket address not known :-(
}
Socket (TCP) can do this but I do not know whether DatagramSocket (UDP) can do so.
UPDATE-1:
bind one interface instead of 0.0.0.0, it works fine.
UPDATE-2:
Socket (TCP) can get both local and remote address:
try (ServerSocket server = new ServerSocket(23)) {
try (Socket socket = server.accept()) {
System.out.println(socket.getLocalSocketAddress());
System.out.println(socket.getRemoteSocketAddress());
}
}
0.0.0.0
basically means "all interfaces", couldn't you bind the socket to one interface? – Anders R. BystrupDatagramSocket
is 0.0.0.0:53. The one you specified when you constructed it. Which interface it uses to reply on is determined by the static IP routing tables. Not by this code. Not a programming question: off topic. – user207421