Skip to content

Add support for mDNS by allowing multicast server address #147

@ka2ddo

Description

@ka2ddo

The present version of the NioUdpClient code in dnsjava does not support specifying the mDNS multicast address (224.0.0.251 or [FF02::FB]) and port 5353 for the DNS server address, because the UDP socket is connected to the remote address, which will never be seen in a reply to a multicast query. Included is the diff of a proposed change to allow receiving data from the first mDNS server to respond (the most minimal form of an mDNS client, as defined by RFC6762), where the DatagramChannel is not connected to the remote address if the remote address is multicast, so that any mDNS server's unicast reply packet can be accepted.

diff --git a/src/main/java/org/xbill/DNS/NioUdpClient.java b/src/main/java/org/xbill/DNS/NioUdpClient.java
index 2c7df72..57a26c4 100644
--- a/src/main/java/org/xbill/DNS/NioUdpClient.java
+++ b/src/main/java/org/xbill/DNS/NioUdpClient.java
@@ -3,9 +3,7 @@ package org.xbill.DNS;
 
 import java.io.EOFException;
 import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketException;
-import java.net.SocketTimeoutException;
+import java.net.*;
 import java.nio.ByteBuffer;
 import java.nio.channels.DatagramChannel;
 import java.nio.channels.SelectionKey;
@@ -84,6 +82,7 @@ final class NioUdpClient extends Client {
     private final int max;
     private final long endTime;
     private final DatagramChannel channel;
+    private final SocketAddress remoteSocketAddress;
     private final CompletableFuture<byte[]> f;
 
     void send() throws IOException {
@@ -91,9 +90,9 @@ final class NioUdpClient extends Client {
       verboseLog(
           "UDP write",
           channel.socket().getLocalSocketAddress(),
-          channel.socket().getRemoteSocketAddress(),
+          remoteSocketAddress,
           data);
-      int n = channel.send(buffer, channel.socket().getRemoteSocketAddress());
+      int n = channel.send(buffer, remoteSocketAddress);
       if (n <= 0) {
         throw new EOFException();
       }
@@ -109,10 +108,12 @@ final class NioUdpClient extends Client {
 
       DatagramChannel channel = (DatagramChannel) key.channel();
       ByteBuffer buffer = ByteBuffer.allocate(max);
+      SocketAddress source;
       int read;
       try {
-        read = channel.read(buffer);
-        if (read <= 0) {
+        source = channel.receive(buffer);
+        read = buffer.position();
+        if (read <= 0 || source == null) {
           throw new EOFException();
         }
       } catch (IOException e) {
@@ -128,7 +129,7 @@ final class NioUdpClient extends Client {
       verboseLog(
           "UDP read",
           channel.socket().getLocalSocketAddress(),
-          channel.socket().getRemoteSocketAddress(),
+          source,
           data);
       silentCloseChannel();
       f.complete(data);
@@ -185,9 +186,11 @@ final class NioUdpClient extends Client {
         }
       }
 
-      channel.connect(remote);
+      if (!remote.getAddress().isMulticastAddress()) {
+        channel.connect(remote);
+      }
       long endTime = System.nanoTime() + timeout.toNanos();
-      Transaction t = new Transaction(data, max, endTime, channel, f);
+      Transaction t = new Transaction(data, max, endTime, channel, remote, f);
       pendingTransactions.add(t);
       registrationQueue.add(t);
       selector.wakeup();

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions