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;
|
||||
|
||||
|
||||
import zutil.net.dns.packet.DnsPacket;
|
||||
|
||||
public interface DnsResolutionListener {
|
||||
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.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.ThreadedUDPNetworkThread;
|
||||
import zutil.parser.binary.BinaryStructInputStream;
|
||||
|
|
@ -40,9 +43,12 @@ import java.util.HashSet;
|
|||
import java.util.logging.Level;
|
||||
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
|
||||
* 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="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{
|
||||
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 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.BinaryStructOutputStream;
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package zutil.net.dns;
|
||||
package zutil.net.dns.packet;
|
||||
|
||||
import zutil.parser.binary.BinaryStruct;
|
||||
|
||||
|
|
@ -22,16 +22,10 @@
|
|||
* 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 java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* @see <a href="http://tools.ietf.org/html/rfc1035">DNS Spec (rfc1035)</a>
|
||||
* @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.
|
||||
*/
|
||||
|
||||
package zutil.net.dns;
|
||||
package zutil.net.dns.packet;
|
||||
|
||||
import zutil.parser.binary.BinaryStruct;
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ public class DnsPacketResource implements BinaryStruct {
|
|||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
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 zutil.converter.Converter;
|
||||
import zutil.net.dns.packet.*;
|
||||
import zutil.parser.binary.BinaryStructInputStream;
|
||||
import zutil.parser.binary.BinaryStructOutputStream;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package zutil.net.dns;
|
|||
import zutil.io.MultiPrintStream;
|
||||
import zutil.log.CompactLogFormatter;
|
||||
import zutil.log.LogUtil;
|
||||
import zutil.net.dns.packet.DnsPacket;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue