Refactored Dns classes and added initial implementation of a MDNS Server
This commit is contained in:
parent
e8491617c6
commit
e50027906d
12 changed files with 201 additions and 56 deletions
|
|
@ -24,6 +24,8 @@
|
||||||
package zutil.net.dns;
|
package zutil.net.dns;
|
||||||
|
|
||||||
|
|
||||||
|
import zutil.net.dns.packet.DnsPacket;
|
||||||
|
|
||||||
public interface DnsResolutionListener {
|
public interface DnsResolutionListener {
|
||||||
void receivedResponse(DnsPacket packet);
|
void receivedResponse(DnsPacket packet);
|
||||||
}
|
}
|
||||||
16
src/zutil/net/dns/DnsService.java
Executable file
16
src/zutil/net/dns/DnsService.java
Executable file
|
|
@ -0,0 +1,16 @@
|
||||||
|
package zutil.net.dns;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class contains data about a service that
|
||||||
|
* can be looked up through DNS and MDNS.
|
||||||
|
*/
|
||||||
|
public class DnsService {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String dns;
|
||||||
|
private InetAddress host;
|
||||||
|
private HashMap properties;
|
||||||
|
}
|
||||||
|
|
@ -26,6 +26,9 @@ package zutil.net.dns;
|
||||||
|
|
||||||
import zutil.io.MultiPrintStream;
|
import zutil.io.MultiPrintStream;
|
||||||
import zutil.log.LogUtil;
|
import zutil.log.LogUtil;
|
||||||
|
import zutil.net.dns.packet.DnsConstants;
|
||||||
|
import zutil.net.dns.packet.DnsPacket;
|
||||||
|
import zutil.net.dns.packet.DnsPacketQuestion;
|
||||||
import zutil.net.threaded.ThreadedUDPNetwork;
|
import zutil.net.threaded.ThreadedUDPNetwork;
|
||||||
import zutil.net.threaded.ThreadedUDPNetworkThread;
|
import zutil.net.threaded.ThreadedUDPNetworkThread;
|
||||||
import zutil.parser.binary.BinaryStructInputStream;
|
import zutil.parser.binary.BinaryStructInputStream;
|
||||||
|
|
@ -40,9 +43,12 @@ import java.util.HashSet;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import static zutil.net.dns.MulticastDnsServer.MDNS_MULTICAST_ADDR;
|
||||||
|
import static zutil.net.dns.MulticastDnsServer.MDNS_MULTICAST_PORT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class implements a MDNS Client. MDNS is a version
|
* This class implements a MDNS Client. MDNS is a version
|
||||||
* of the DNS protocol but used a Zeroconf application.
|
* of the DNS protocol but supports Zeroconf.
|
||||||
*
|
*
|
||||||
* @see <a href="http://tools.ietf.org/html/rfc1035">DNS Spec (rfc1035)</a>
|
* @see <a href="http://tools.ietf.org/html/rfc1035">DNS Spec (rfc1035)</a>
|
||||||
* @see <a href="https://tools.ietf.org/html/rfc6763">DNS-SD Spec (rfc6763)</a>
|
* @see <a href="https://tools.ietf.org/html/rfc6763">DNS-SD Spec (rfc6763)</a>
|
||||||
|
|
@ -51,9 +57,6 @@ import java.util.logging.Logger;
|
||||||
public class MulticastDnsClient extends ThreadedUDPNetwork implements ThreadedUDPNetworkThread{
|
public class MulticastDnsClient extends ThreadedUDPNetwork implements ThreadedUDPNetworkThread{
|
||||||
private static final Logger logger = LogUtil.getLogger();
|
private static final Logger logger = LogUtil.getLogger();
|
||||||
|
|
||||||
private static final String MDNS_MULTICAST_ADDR = "224.0.0.251";
|
|
||||||
private static final int MDNS_MULTICAST_PORT = 5353;
|
|
||||||
|
|
||||||
|
|
||||||
private HashSet<Integer> activeProbes;
|
private HashSet<Integer> activeProbes;
|
||||||
private DnsResolutionListener listener;
|
private DnsResolutionListener listener;
|
||||||
|
|
|
||||||
119
src/zutil/net/dns/MulticastDnsServer.java
Executable file
119
src/zutil/net/dns/MulticastDnsServer.java
Executable file
|
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Ziver Koc
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package zutil.net.dns;
|
||||||
|
|
||||||
|
import zutil.log.LogUtil;
|
||||||
|
import zutil.net.dns.packet.DnsPacket;
|
||||||
|
import zutil.net.dns.packet.DnsPacketQuestion;
|
||||||
|
import zutil.net.dns.packet.DnsPacketResource;
|
||||||
|
import zutil.net.threaded.ThreadedUDPNetwork;
|
||||||
|
import zutil.net.threaded.ThreadedUDPNetworkThread;
|
||||||
|
import zutil.parser.binary.BinaryStructInputStream;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements a MDNS Server. MDNS is a version
|
||||||
|
* of the DNS protocol but supports Zeroconf.
|
||||||
|
*
|
||||||
|
* @see <a href="http://tools.ietf.org/html/rfc1035">DNS Spec (rfc1035)</a>
|
||||||
|
* @see <a href="https://tools.ietf.org/html/rfc6763">DNS-SD Spec (rfc6763)</a>
|
||||||
|
* @author Ziver
|
||||||
|
*/
|
||||||
|
public class MulticastDnsServer extends ThreadedUDPNetwork implements ThreadedUDPNetworkThread{
|
||||||
|
private static final Logger logger = LogUtil.getLogger();
|
||||||
|
|
||||||
|
protected static final String MDNS_MULTICAST_ADDR = "224.0.0.251";
|
||||||
|
protected static final int MDNS_MULTICAST_PORT = 5353;
|
||||||
|
|
||||||
|
|
||||||
|
private HashMap<String,ArrayList> entries = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public MulticastDnsServer() throws IOException {
|
||||||
|
super(MDNS_MULTICAST_ADDR, MDNS_MULTICAST_PORT);
|
||||||
|
setThread( this );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a domain name specific data that will be returned to a requesting client
|
||||||
|
*
|
||||||
|
* @param name is the domain name to add the entry under
|
||||||
|
* @param type {@link zutil.net.dns.packet.DnsConstants.TYPE}
|
||||||
|
* @param clazz {@link zutil.net.dns.packet.DnsConstants.CLASS}
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
public void addEntry(String name, int type, int clazz, String data){
|
||||||
|
DnsPacketResource resource = new DnsPacketResource();
|
||||||
|
resource.name = name;
|
||||||
|
resource.type = type;
|
||||||
|
resource.clazz = clazz;
|
||||||
|
//resource.ttl = 10; ???
|
||||||
|
resource.length = data.length();
|
||||||
|
resource.data = data;
|
||||||
|
|
||||||
|
addEntry(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addEntry(DnsPacketResource resource) {
|
||||||
|
if ( ! entries.containsKey(resource.name))
|
||||||
|
entries.put(resource.name, new ArrayList());
|
||||||
|
entries.get(resource.name).add(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receivedPacket(DatagramPacket packet, ThreadedUDPNetwork network) {
|
||||||
|
try {
|
||||||
|
ByteArrayInputStream buffer = new ByteArrayInputStream(packet.getData(),
|
||||||
|
packet.getOffset(), packet.getLength());
|
||||||
|
BinaryStructInputStream in = new BinaryStructInputStream(buffer);
|
||||||
|
DnsPacket dnsPacket = DnsPacket.read(in);
|
||||||
|
|
||||||
|
// Just handle queries and no responses
|
||||||
|
if ( ! dnsPacket.getHeader().flagQueryResponse){
|
||||||
|
for (DnsPacketQuestion question : dnsPacket.getQuestions()){
|
||||||
|
if (entries.containsKey(question.name)){
|
||||||
|
// Respond with entries
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e){
|
||||||
|
logger.log(Level.WARNING, null, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package zutil.net.dns;
|
package zutil.net.dns.packet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package zutil.net.dns;
|
package zutil.net.dns.packet;
|
||||||
|
|
||||||
import zutil.parser.binary.BinaryStructInputStream;
|
import zutil.parser.binary.BinaryStructInputStream;
|
||||||
import zutil.parser.binary.BinaryStructOutputStream;
|
import zutil.parser.binary.BinaryStructOutputStream;
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package zutil.net.dns;
|
package zutil.net.dns.packet;
|
||||||
|
|
||||||
import zutil.parser.binary.BinaryStruct;
|
import zutil.parser.binary.BinaryStruct;
|
||||||
|
|
||||||
|
|
@ -22,16 +22,10 @@
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package zutil.net.dns;
|
package zutil.net.dns.packet;
|
||||||
|
|
||||||
import zutil.parser.binary.BinaryFieldData;
|
|
||||||
import zutil.parser.binary.BinaryFieldSerializer;
|
|
||||||
import zutil.parser.binary.BinaryStruct;
|
import zutil.parser.binary.BinaryStruct;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see <a href="http://tools.ietf.org/html/rfc1035">DNS Spec (rfc1035)</a>
|
* @see <a href="http://tools.ietf.org/html/rfc1035">DNS Spec (rfc1035)</a>
|
||||||
* @author Ziver
|
* @author Ziver
|
||||||
|
|
@ -96,44 +90,4 @@ public class DnsPacketQuestion implements BinaryStruct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class FQDNStringSerializer implements BinaryFieldSerializer<String> {
|
|
||||||
|
|
||||||
public String read(InputStream in, BinaryFieldData field) throws IOException {
|
|
||||||
StringBuilder str = new StringBuilder();
|
|
||||||
int c = in.read();
|
|
||||||
// Is this a pointer
|
|
||||||
if ((c & 0b1100_0000) == 0b1100_0000 ){
|
|
||||||
int offset = (c & 0b0011_1111) << 8;
|
|
||||||
offset |= in.read() & 0b1111_1111;
|
|
||||||
str.append(offset);
|
|
||||||
}
|
|
||||||
// Normal Domain String
|
|
||||||
else {
|
|
||||||
while (c > 0) {
|
|
||||||
for (int i = 0; i < c; ++i) {
|
|
||||||
str.append((char) in.read());
|
|
||||||
}
|
|
||||||
c = in.read();
|
|
||||||
if (c > 0)
|
|
||||||
str.append('.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return str.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(OutputStream out, String domain, BinaryFieldData field) throws IOException {
|
|
||||||
if (domain != null){
|
|
||||||
String[] labels = domain.split("\\.");
|
|
||||||
for (String label : labels) {
|
|
||||||
out.write(label.length());
|
|
||||||
out.write(label.getBytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out.write(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package zutil.net.dns;
|
package zutil.net.dns.packet;
|
||||||
|
|
||||||
import zutil.parser.binary.BinaryStruct;
|
import zutil.parser.binary.BinaryStruct;
|
||||||
|
|
||||||
|
|
@ -65,7 +65,7 @@ public class DnsPacketResource implements BinaryStruct {
|
||||||
/**
|
/**
|
||||||
* a domain name to which this resource record pertains.
|
* a domain name to which this resource record pertains.
|
||||||
*/
|
*/
|
||||||
@CustomBinaryField(index=10, serializer=DnsPacketQuestion.FQDNStringSerializer.class)
|
@CustomBinaryField(index=10, serializer=FQDNStringSerializer.class)
|
||||||
public String name;
|
public String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
49
src/zutil/net/dns/packet/FQDNStringSerializer.java
Executable file
49
src/zutil/net/dns/packet/FQDNStringSerializer.java
Executable file
|
|
@ -0,0 +1,49 @@
|
||||||
|
package zutil.net.dns.packet;
|
||||||
|
|
||||||
|
import zutil.parser.binary.BinaryFieldData;
|
||||||
|
import zutil.parser.binary.BinaryFieldSerializer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A serializer class that can read and write a DNS FQDN in binary format.
|
||||||
|
*/
|
||||||
|
public class FQDNStringSerializer implements BinaryFieldSerializer<String> {
|
||||||
|
|
||||||
|
public String read(InputStream in, BinaryFieldData field) throws IOException {
|
||||||
|
StringBuilder str = new StringBuilder();
|
||||||
|
int c = in.read();
|
||||||
|
// Is this a pointer
|
||||||
|
if ((c & 0b1100_0000) == 0b1100_0000) {
|
||||||
|
int offset = (c & 0b0011_1111) << 8;
|
||||||
|
offset |= in.read() & 0b1111_1111;
|
||||||
|
str.append(offset);
|
||||||
|
}
|
||||||
|
// Normal Domain String
|
||||||
|
else {
|
||||||
|
while (c > 0) {
|
||||||
|
for (int i = 0; i < c; ++i) {
|
||||||
|
str.append((char) in.read());
|
||||||
|
}
|
||||||
|
c = in.read();
|
||||||
|
if (c > 0)
|
||||||
|
str.append('.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(OutputStream out, String domain, BinaryFieldData field) throws IOException {
|
||||||
|
if (domain != null) {
|
||||||
|
String[] labels = domain.split("\\.");
|
||||||
|
for (String label : labels) {
|
||||||
|
out.write(label.length());
|
||||||
|
out.write(label.getBytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.write(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -26,6 +26,7 @@ package zutil.net.dns;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import zutil.converter.Converter;
|
import zutil.converter.Converter;
|
||||||
|
import zutil.net.dns.packet.*;
|
||||||
import zutil.parser.binary.BinaryStructInputStream;
|
import zutil.parser.binary.BinaryStructInputStream;
|
||||||
import zutil.parser.binary.BinaryStructOutputStream;
|
import zutil.parser.binary.BinaryStructOutputStream;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package zutil.net.dns;
|
||||||
import zutil.io.MultiPrintStream;
|
import zutil.io.MultiPrintStream;
|
||||||
import zutil.log.CompactLogFormatter;
|
import zutil.log.CompactLogFormatter;
|
||||||
import zutil.log.LogUtil;
|
import zutil.log.LogUtil;
|
||||||
|
import zutil.net.dns.packet.DnsPacket;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue