Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for mDNS by allowing multicast server address #147

Open
ka2ddo opened this issue Jan 5, 2021 · 8 comments · May be fixed by #148
Open

Add support for mDNS by allowing multicast server address #147

ka2ddo opened this issue Jan 5, 2021 · 8 comments · May be fixed by #148

Comments

@ka2ddo
Copy link

ka2ddo commented Jan 5, 2021

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();
@ka2ddo
Copy link
Author

ka2ddo commented Jan 6, 2021

Attached is a somewhat larger patch diff that also supports multiple mDNS servers responding instead of only the first response. No behavior change if a unicast address is specified for the DNS server.
mDNS.patch.txt

@ibauersachs
Copy link
Member

Why don't you create a pull request that I could review?

@ka2ddo
Copy link
Author

ka2ddo commented Jan 6, 2021 via email

@ka2ddo
Copy link
Author

ka2ddo commented Jan 6, 2021 via email

@ibauersachs
Copy link
Member

You need to fork the repository to your account, then push your branch there. You can create a pull request in GitHub's web ui afterwards. See e.g. this guide here: https://guides.github.com/activities/forking/

@ka2ddo
Copy link
Author

ka2ddo commented Jan 6, 2021 via email

@ibauersachs
Copy link
Member

You need to fork the repository to your account so that it appears here: https://github.com/ka2ddo?tab=repositories

Then change the origin of your local clone, push and create the pull request. It's all explained in the link I posted before.

I don't have my devenv with me atm, so I can't even look at the patch. And a PR would automatically run all tests and checks :-)

@ka2ddo
Copy link
Author

ka2ddo commented Jan 6, 2021

Pull request now available.

@ibauersachs ibauersachs linked a pull request Jan 6, 2021 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants