ip6Addresses) {
+ ServiceInfoImpl si = new ServiceInfoImpl(type, name, "", port, 0, 0, text);
+ for (Inet4Address a : ip4Addresses) si.addAddress(a);
+ for (Inet6Address a : ip6Addresses) si.addAddress(a);
+ return si;
+ }
+
+ /**
+ * Returns true if the service info is filled with data.
+ *
+ * @return true
if the service info has data, false
otherwise.
+ */
+ public abstract boolean hasData();
+
+ /**
+ * Fully qualified service type name, such as _http._tcp.local.
+ *
+ * @return service type name
+ */
+ public abstract String getType();
+
+ /**
+ * Fully qualified service type name with the subtype if appropriate, such as
+ * _printer._sub._http._tcp.local.
+ *
+ * @return service type name
+ */
+ public abstract String getTypeWithSubtype();
+
+ /**
+ * Unqualified service instance name, such as foobar
.
+ *
+ * @return service name
+ */
+ public abstract String getName();
+
+ /**
+ * The key is used to retrieve service info in hash tables.
+ * The key is the lower case qualified name.
+ *
+ * @return the key
+ */
+ public abstract String getKey();
+
+ /**
+ * Fully qualified service name, such as foobar._http._tcp.local.
.
+ *
+ * @return qualified service name
+ */
+ public abstract String getQualifiedName();
+
+ /**
+ * Get the name of the server.
+ *
+ * @return server name
+ */
+ public abstract String getServer();
+
+ /**
+ * Returns a list of all IPv4 InetAddresses that can be used for this service.
+ *
+ * In a multi-homed environment service info can be associated with more than one address.
+ *
+ * @return list of InetAddress objects
+ */
+ public abstract Inet4Address[] getInet4Addresses();
+
+ /**
+ * Returns a list of all IPv6 InetAddresses that can be used for this service.
+ *
+ *
In a multi-homed environment service info can be associated with more than one address.
+ *
+ * @return list of InetAddress objects
+ */
+ public abstract Inet6Address[] getInet6Addresses();
+
+ /**
+ * Get the port for the service.
+ *
+ * @return service port
+ */
+ public abstract int getPort();
+
+ /**
+ * Get the priority of the service.
+ *
+ * @return service priority
+ */
+ public abstract int getPriority();
+
+ /**
+ * Get the weight of the service.
+ *
+ * @return service weight
+ */
+ public abstract int getWeight();
+
+ /**
+ * Get the text for the service as raw bytes.
+ *
+ * @return raw service text
+ */
+ public abstract byte[] getTextBytes();
+
+ /**
+ * Returns the domain of the service info suitable for printing.
+ *
+ * @return service domain
+ */
+ public abstract String getDomain();
+
+ /**
+ * Returns the protocol of the service info suitable for printing.
+ *
+ * @return service protocol
+ */
+ public abstract String getProtocol();
+
+ /**
+ * Returns the application of the service info suitable for printing.
+ *
+ * @return service application
+ */
+ public abstract String getApplication();
+
+ /**
+ * Returns the sub type of the service info suitable for printing.
+ *
+ * @return service sub type
+ */
+ public abstract String getSubtype();
+
+ /**
+ * Returns a dictionary of the fully qualified name component of this service.
+ *
+ * @return dictionary of the fully qualified name components
+ */
+ public abstract Map getQualifiedNameMap();
+
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Object#clone()
+ */
+ @Override
+ public ServiceInfo clone() throws CloneNotSupportedException {
+ return (ServiceInfo) super.clone();
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSEntry.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSEntry.java
index 1f90e988c..a49b9934f 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSEntry.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSEntry.java
@@ -4,214 +4,226 @@
package io.libp2p.discovery.mdns.impl;
+import io.libp2p.discovery.mdns.ServiceInfo.Fields;
import io.libp2p.discovery.mdns.impl.constants.DNSRecordClass;
import io.libp2p.discovery.mdns.impl.constants.DNSRecordType;
-
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
-import io.libp2p.discovery.mdns.ServiceInfo.Fields;
-
/**
* DNS entry with a name, type, and class. This is the base class for questions and records.
*
* @author Arthur van Hoff, Pierre Frisch, Rick Blair
*/
public abstract class DNSEntry {
- // private static Logger logger = LoggerFactory.getLogger(DNSEntry.class.getName());
- private final String _key;
-
- private final String _name;
-
- private final String _type;
-
- private final DNSRecordType _recordType;
-
- private final DNSRecordClass _dnsClass;
-
- private final boolean _unique;
-
- final Map _qualifiedNameMap;
-
- /**
- * Create an entry.
- */
- DNSEntry(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
- _name = name;
- // _key = (name != null ? name.trim().toLowerCase() : null);
- _recordType = type;
- _dnsClass = recordClass;
- _unique = unique;
- _qualifiedNameMap = ServiceInfoImpl.decodeQualifiedNameMapForType(this.getName());
- String domain = _qualifiedNameMap.get(Fields.Domain);
- String protocol = _qualifiedNameMap.get(Fields.Protocol);
- String application = _qualifiedNameMap.get(Fields.Application);
- String instance = _qualifiedNameMap.get(Fields.Instance).toLowerCase();
- _type = (application.length() > 0 ? "_" + application + "." : "") + (protocol.length() > 0 ? "_" + protocol + "." : "") + domain + ".";
- _key = ((instance.length() > 0 ? instance + "." : "") + _type).toLowerCase();
- }
-
- /*
- * (non-Javadoc)
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object obj) {
- boolean result = false;
- if (obj instanceof DNSEntry) {
- DNSEntry other = (DNSEntry) obj;
- result = this.getKey().equals(other.getKey()) && this.getRecordType().equals(other.getRecordType()) && this.getRecordClass() == other.getRecordClass();
- }
- return result;
- }
-
- /**
- * Check if two entries have exactly the same name, type, and class.
- *
- * @param entry
- * @return true
if the two entries have are for the same record, false
otherwise
- */
- public boolean isSameEntry(DNSEntry entry) {
- return this.getKey().equals(entry.getKey()) && this.matchRecordType(entry.getRecordType()) && this.matchRecordClass(entry.getRecordClass());
- }
-
- /**
- * Check if the requested record class match the current record class
- *
- * @param recordClass
- * @return true
if the two entries have compatible class, false
otherwise
- */
- public boolean matchRecordClass(DNSRecordClass recordClass) {
- return (DNSRecordClass.CLASS_ANY == recordClass) || (DNSRecordClass.CLASS_ANY == this.getRecordClass()) || this.getRecordClass().equals(recordClass);
- }
-
- /**
- * Check if the requested record tyep match the current record type
- *
- * @param recordType
- * @return true
if the two entries have compatible type, false
otherwise
- */
- public boolean matchRecordType(DNSRecordType recordType) {
- return this.getRecordType().equals(recordType);
- }
-
- /**
- * Returns the subtype of this entry
- *
- * @return subtype of this entry
- */
- public String getSubtype() {
- String subtype = this.getQualifiedNameMap().get(Fields.Subtype);
- return (subtype != null ? subtype : "");
- }
-
- /**
- * Returns the name of this entry
- *
- * @return name of this entry
- */
- public String getName() {
- return (_name != null ? _name : "");
- }
-
- /**
- * @return the type
- */
- public String getType() {
- return (_type != null ? _type : "");
- }
-
- /**
- * Returns the key for this entry. The key is the lower case name.
- *
- * @return key for this entry
- */
- public String getKey() {
- return (_key != null ? _key : "");
- }
-
- /**
- * @return record type
- */
- public DNSRecordType getRecordType() {
- return (_recordType != null ? _recordType : DNSRecordType.TYPE_IGNORE);
- }
-
- /**
- * @return record class
- */
- public DNSRecordClass getRecordClass() {
- return (_dnsClass != null ? _dnsClass : DNSRecordClass.CLASS_UNKNOWN);
- }
-
- /**
- * @return true if unique
- */
- public boolean isUnique() {
- return _unique;
- }
-
- public Map getQualifiedNameMap() {
- return Collections.unmodifiableMap(_qualifiedNameMap);
- }
-
- /**
- * Check if the record is expired.
- *
- * @param now
- * update date
- * @return true
is the record is expired, false
otherwise.
- */
- public abstract boolean isExpired(long now);
-
- /**
- * @param dout
- * @exception IOException
- */
- protected void toByteArray(DataOutputStream dout) throws IOException {
- dout.write(this.getName().getBytes("UTF8"));
- dout.writeShort(this.getRecordType().indexValue());
- dout.writeShort(this.getRecordClass().indexValue());
- }
-
- /**
- * Creates a byte array representation of this record. This is needed for tie-break tests according to draft-cheshire-dnsext-multicastdns-04.txt chapter 9.2.
- *
- * @return byte array representation
- */
- protected byte[] toByteArray() {
- try {
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- DataOutputStream dout = new DataOutputStream(bout);
- this.toByteArray(dout);
- dout.close();
- return bout.toByteArray();
- } catch (IOException e) {
- throw new InternalError();
- }
- }
-
- /**
- * Overriden, to return a value which is consistent with the value returned by equals(Object).
- */
- @Override
- public int hashCode() {
- return this.getKey().hashCode() + this.getRecordType().indexValue() + this.getRecordClass().indexValue();
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder(200);
- sb.append('[').append(this.getClass().getSimpleName()).append('@').append(System.identityHashCode(this));
- sb.append(" type: ").append(this.getRecordType());
- sb.append(", class: ").append(this.getRecordClass());
- sb.append((_unique ? "-unique," : ","));
- sb.append(" name: ").append( _name);
- sb.append(']');
-
- return sb.toString();
- }
+ // private static Logger logger = LoggerFactory.getLogger(DNSEntry.class.getName());
+ private final String _key;
+
+ private final String _name;
+
+ private final String _type;
+
+ private final DNSRecordType _recordType;
+
+ private final DNSRecordClass _dnsClass;
+
+ private final boolean _unique;
+
+ final Map _qualifiedNameMap;
+
+ /** Create an entry. */
+ DNSEntry(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+ _name = name;
+ // _key = (name != null ? name.trim().toLowerCase() : null);
+ _recordType = type;
+ _dnsClass = recordClass;
+ _unique = unique;
+ _qualifiedNameMap = ServiceInfoImpl.decodeQualifiedNameMapForType(this.getName());
+ String domain = _qualifiedNameMap.get(Fields.Domain);
+ String protocol = _qualifiedNameMap.get(Fields.Protocol);
+ String application = _qualifiedNameMap.get(Fields.Application);
+ String instance = _qualifiedNameMap.get(Fields.Instance).toLowerCase();
+ _type =
+ (application.length() > 0 ? "_" + application + "." : "")
+ + (protocol.length() > 0 ? "_" + protocol + "." : "")
+ + domain
+ + ".";
+ _key = ((instance.length() > 0 ? instance + "." : "") + _type).toLowerCase();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ boolean result = false;
+ if (obj instanceof DNSEntry) {
+ DNSEntry other = (DNSEntry) obj;
+ result =
+ this.getKey().equals(other.getKey())
+ && this.getRecordType().equals(other.getRecordType())
+ && this.getRecordClass() == other.getRecordClass();
+ }
+ return result;
+ }
+
+ /**
+ * Check if two entries have exactly the same name, type, and class.
+ *
+ * @param entry
+ * @return true
if the two entries have are for the same record, false
+ * otherwise
+ */
+ public boolean isSameEntry(DNSEntry entry) {
+ return this.getKey().equals(entry.getKey())
+ && this.matchRecordType(entry.getRecordType())
+ && this.matchRecordClass(entry.getRecordClass());
+ }
+
+ /**
+ * Check if the requested record class match the current record class
+ *
+ * @param recordClass
+ * @return true
if the two entries have compatible class, false
+ * otherwise
+ */
+ public boolean matchRecordClass(DNSRecordClass recordClass) {
+ return (DNSRecordClass.CLASS_ANY == recordClass)
+ || (DNSRecordClass.CLASS_ANY == this.getRecordClass())
+ || this.getRecordClass().equals(recordClass);
+ }
+
+ /**
+ * Check if the requested record tyep match the current record type
+ *
+ * @param recordType
+ * @return true
if the two entries have compatible type, false
otherwise
+ */
+ public boolean matchRecordType(DNSRecordType recordType) {
+ return this.getRecordType().equals(recordType);
+ }
+
+ /**
+ * Returns the subtype of this entry
+ *
+ * @return subtype of this entry
+ */
+ public String getSubtype() {
+ String subtype = this.getQualifiedNameMap().get(Fields.Subtype);
+ return (subtype != null ? subtype : "");
+ }
+
+ /**
+ * Returns the name of this entry
+ *
+ * @return name of this entry
+ */
+ public String getName() {
+ return (_name != null ? _name : "");
+ }
+
+ /**
+ * @return the type
+ */
+ public String getType() {
+ return (_type != null ? _type : "");
+ }
+
+ /**
+ * Returns the key for this entry. The key is the lower case name.
+ *
+ * @return key for this entry
+ */
+ public String getKey() {
+ return (_key != null ? _key : "");
+ }
+
+ /**
+ * @return record type
+ */
+ public DNSRecordType getRecordType() {
+ return (_recordType != null ? _recordType : DNSRecordType.TYPE_IGNORE);
+ }
+
+ /**
+ * @return record class
+ */
+ public DNSRecordClass getRecordClass() {
+ return (_dnsClass != null ? _dnsClass : DNSRecordClass.CLASS_UNKNOWN);
+ }
+
+ /**
+ * @return true if unique
+ */
+ public boolean isUnique() {
+ return _unique;
+ }
+
+ public Map getQualifiedNameMap() {
+ return Collections.unmodifiableMap(_qualifiedNameMap);
+ }
+
+ /**
+ * Check if the record is expired.
+ *
+ * @param now update date
+ * @return true
is the record is expired, false
otherwise.
+ */
+ public abstract boolean isExpired(long now);
+
+ /**
+ * @param dout
+ * @exception IOException
+ */
+ protected void toByteArray(DataOutputStream dout) throws IOException {
+ dout.write(this.getName().getBytes("UTF8"));
+ dout.writeShort(this.getRecordType().indexValue());
+ dout.writeShort(this.getRecordClass().indexValue());
+ }
+
+ /**
+ * Creates a byte array representation of this record. This is needed for tie-break tests
+ * according to draft-cheshire-dnsext-multicastdns-04.txt chapter 9.2.
+ *
+ * @return byte array representation
+ */
+ protected byte[] toByteArray() {
+ try {
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ DataOutputStream dout = new DataOutputStream(bout);
+ this.toByteArray(dout);
+ dout.close();
+ return bout.toByteArray();
+ } catch (IOException e) {
+ throw new InternalError();
+ }
+ }
+
+ /** Overriden, to return a value which is consistent with the value returned by equals(Object). */
+ @Override
+ public int hashCode() {
+ return this.getKey().hashCode()
+ + this.getRecordType().indexValue()
+ + this.getRecordClass().indexValue();
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder(200);
+ sb.append('[')
+ .append(this.getClass().getSimpleName())
+ .append('@')
+ .append(System.identityHashCode(this));
+ sb.append(" type: ").append(this.getRecordType());
+ sb.append(", class: ").append(this.getRecordClass());
+ sb.append((_unique ? "-unique," : ","));
+ sb.append(" name: ").append(_name);
+ sb.append(']');
+
+ return sb.toString();
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSIncoming.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSIncoming.java
index f71bf1e29..078832553 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSIncoming.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSIncoming.java
@@ -4,594 +4,666 @@
package io.libp2p.discovery.mdns.impl;
+import io.libp2p.discovery.mdns.impl.constants.DNSConstants;
+import io.libp2p.discovery.mdns.impl.constants.DNSLabel;
+import io.libp2p.discovery.mdns.impl.constants.DNSOptionCode;
+import io.libp2p.discovery.mdns.impl.constants.DNSRecordClass;
+import io.libp2p.discovery.mdns.impl.constants.DNSRecordType;
+import io.libp2p.discovery.mdns.impl.constants.DNSResultCode;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
-
-import io.libp2p.discovery.mdns.impl.constants.DNSRecordClass;
-import io.libp2p.discovery.mdns.impl.constants.DNSRecordType;
-import io.libp2p.discovery.mdns.impl.constants.DNSResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.libp2p.discovery.mdns.impl.constants.DNSConstants;
-import io.libp2p.discovery.mdns.impl.constants.DNSLabel;
-import io.libp2p.discovery.mdns.impl.constants.DNSOptionCode;
-
/**
* Parse an incoming DNS message into its components.
*
* @author Arthur van Hoff, Werner Randelshofer, Pierre Frisch, Daniel Bobbert
*/
public final class DNSIncoming extends DNSMessage {
- private static Logger logger = LoggerFactory.getLogger(DNSIncoming.class.getName());
-
- // This is a hack to handle a bug in the BonjourConformanceTest
- // It is sending out target strings that don't follow the "domain name" format.
- public static boolean USE_DOMAIN_NAME_FORMAT_FOR_SRV_TARGET = true;
-
- public static class MessageInputStream extends ByteArrayInputStream {
- private static Logger logger1 = LoggerFactory.getLogger(MessageInputStream.class.getName());
+ private static Logger logger = LoggerFactory.getLogger(DNSIncoming.class.getName());
- final Map _names;
+ // This is a hack to handle a bug in the BonjourConformanceTest
+ // It is sending out target strings that don't follow the "domain name" format.
+ public static boolean USE_DOMAIN_NAME_FORMAT_FOR_SRV_TARGET = true;
- public MessageInputStream(byte[] buffer, int length) {
- this(buffer, 0, length);
- }
-
- /**
- * @param buffer
- * @param offset
- * @param length
- */
- public MessageInputStream(byte[] buffer, int offset, int length) {
- super(buffer, offset, length);
- _names = new HashMap();
- }
+ public static class MessageInputStream extends ByteArrayInputStream {
+ private static Logger logger1 = LoggerFactory.getLogger(MessageInputStream.class.getName());
- public int readByte() {
- return this.read();
- }
+ final Map _names;
- public int readUnsignedByte() {
- return (this.read() & 0xFF);
- }
+ public MessageInputStream(byte[] buffer, int length) {
+ this(buffer, 0, length);
+ }
- public int readUnsignedShort() {
- return (this.readUnsignedByte() << 8) | this.readUnsignedByte();
- }
+ /**
+ * @param buffer
+ * @param offset
+ * @param length
+ */
+ public MessageInputStream(byte[] buffer, int offset, int length) {
+ super(buffer, offset, length);
+ _names = new HashMap();
+ }
- public int readInt() {
- return (this.readUnsignedShort() << 16) | this.readUnsignedShort();
- }
+ public int readByte() {
+ return this.read();
+ }
- public byte[] readBytes(int len) {
- byte bytes[] = new byte[len];
- this.read(bytes, 0, len);
- return bytes;
- }
+ public int readUnsignedByte() {
+ return (this.read() & 0xFF);
+ }
- public String readUTF(int len) {
- final StringBuilder sb = new StringBuilder(len);
- for (int index = 0; index < len; index++) {
- int ch = this.readUnsignedByte();
- switch (ch >> 4) {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- // 0xxxxxxx
- break;
- case 12:
- case 13:
- // 110x xxxx 10xx xxxx
- ch = ((ch & 0x1F) << 6) | (this.readUnsignedByte() & 0x3F);
- index++;
- break;
- case 14:
- // 1110 xxxx 10xx xxxx 10xx xxxx
- ch = ((ch & 0x0f) << 12) | ((this.readUnsignedByte() & 0x3F) << 6) | (this.readUnsignedByte() & 0x3F);
- index++;
- index++;
- break;
- default:
- // 10xx xxxx, 1111 xxxx
- ch = ((ch & 0x3F) << 4) | (this.readUnsignedByte() & 0x0f);
- index++;
- break;
- }
- sb.append((char) ch);
- }
- return sb.toString();
- }
+ public int readUnsignedShort() {
+ return (this.readUnsignedByte() << 8) | this.readUnsignedByte();
+ }
- protected synchronized int peek() {
- return (pos < count) ? (buf[pos] & 0xff) : -1;
- }
+ public int readInt() {
+ return (this.readUnsignedShort() << 16) | this.readUnsignedShort();
+ }
- public String readName() {
- Map names = new HashMap();
- final StringBuilder sb = new StringBuilder();
- boolean finished = false;
- while (!finished) {
- int len = this.readUnsignedByte();
- if (len == 0) {
- finished = true;
- break;
- }
- switch (DNSLabel.labelForByte(len)) {
- case Standard:
- int offset = pos - 1;
- String label = this.readUTF(len) + ".";
- sb.append(label);
- for (StringBuilder previousLabel : names.values()) {
- previousLabel.append(label);
- }
- names.put(Integer.valueOf(offset), new StringBuilder(label));
- break;
- case Compressed:
- int index = (DNSLabel.labelValue(len) << 8) | this.readUnsignedByte();
- String compressedLabel = _names.get(Integer.valueOf(index));
- if (compressedLabel == null) {
- logger1.warn("Bad domain name: possible circular name detected. Bad offset: 0x{} at 0x{}",
- Integer.toHexString(index),
- Integer.toHexString(pos - 2)
- );
- compressedLabel = "";
- }
- sb.append(compressedLabel);
- for (StringBuilder previousLabel : names.values()) {
- previousLabel.append(compressedLabel);
- }
- finished = true;
- break;
- case Extended:
- // int extendedLabelClass = DNSLabel.labelValue(len);
- logger1.debug("Extended label are not currently supported.");
- break;
- case Unknown:
- default:
- logger1.warn("Unsupported DNS label type: '{}'", Integer.toHexString(len & 0xC0) );
- }
- }
- for (final Map.Entry entry : names.entrySet()) {
- final Integer index = entry.getKey();
- _names.put(index, entry.getValue().toString());
- }
- return sb.toString();
- }
+ public byte[] readBytes(int len) {
+ byte bytes[] = new byte[len];
+ this.read(bytes, 0, len);
+ return bytes;
+ }
- public String readNonNameString() {
- int len = this.readUnsignedByte();
- return this.readUTF(len);
+ public String readUTF(int len) {
+ final StringBuilder sb = new StringBuilder(len);
+ for (int index = 0; index < len; index++) {
+ int ch = this.readUnsignedByte();
+ switch (ch >> 4) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ // 0xxxxxxx
+ break;
+ case 12:
+ case 13:
+ // 110x xxxx 10xx xxxx
+ ch = ((ch & 0x1F) << 6) | (this.readUnsignedByte() & 0x3F);
+ index++;
+ break;
+ case 14:
+ // 1110 xxxx 10xx xxxx 10xx xxxx
+ ch =
+ ((ch & 0x0f) << 12)
+ | ((this.readUnsignedByte() & 0x3F) << 6)
+ | (this.readUnsignedByte() & 0x3F);
+ index++;
+ index++;
+ break;
+ default:
+ // 10xx xxxx, 1111 xxxx
+ ch = ((ch & 0x3F) << 4) | (this.readUnsignedByte() & 0x0f);
+ index++;
+ break;
}
-
+ sb.append((char) ch);
+ }
+ return sb.toString();
}
- private final DatagramPacket _packet;
-
- private final long _receivedTime;
-
- private final MessageInputStream _messageInputStream;
-
- private int _senderUDPPayload;
-
- /**
- * Parse a message from a datagram packet.
- *
- * @param packet
- * @exception IOException
- */
- public DNSIncoming(DatagramPacket packet) throws IOException {
- super(0, 0, packet.getPort() == DNSConstants.MDNS_PORT);
- this._packet = packet;
- InetAddress source = packet.getAddress();
- this._messageInputStream = new MessageInputStream(packet.getData(), packet.getLength());
- this._receivedTime = System.currentTimeMillis();
- this._senderUDPPayload = DNSConstants.MAX_MSG_TYPICAL;
-
- try {
- this.setId(_messageInputStream.readUnsignedShort());
- this.setFlags(_messageInputStream.readUnsignedShort());
- if (this.getOperationCode() > 0) {
- throw new IOException("Received a message with a non standard operation code. Currently unsupported in the specification.");
- }
- int numQuestions = _messageInputStream.readUnsignedShort();
- int numAnswers = _messageInputStream.readUnsignedShort();
- int numAuthorities = _messageInputStream.readUnsignedShort();
- int numAdditionals = _messageInputStream.readUnsignedShort();
-
- logger.debug("DNSIncoming() questions:{} answers:{} authorities:{} additionals:{}",
- numQuestions,
- numAnswers,
- numAuthorities,
- numAdditionals
- );
-
- // We need some sanity checks
- // A question is at least 5 bytes and answer 11 so check what we have
-
- if ((numQuestions * 5 + (numAnswers + numAuthorities + numAdditionals) * 11) > packet.getLength()) {
- throw new IOException("questions:" + numQuestions + " answers:" + numAnswers + " authorities:" + numAuthorities + " additionals:" + numAdditionals);
- }
-
- // parse questions
- for (int i = 0; i < numQuestions; i++) {
- DNSQuestion question = this.readQuestion();
- if (question != null)
- _questions.add(question);
- }
-
- // parse answers
- for (int i = 0; i < numAnswers; i++) {
- DNSRecord rec = this.readAnswer();
- if (rec != null) {
- // Add a record, if we were able to create one.
- _answers.add(rec);
- }
- }
-
- for (int i = 0; i < numAuthorities; i++) {
- DNSRecord rec = this.readAnswer();
- if (rec != null) {
- // Add a record, if we were able to create one.
- _authoritativeAnswers.add(rec);
- }
- }
+ protected synchronized int peek() {
+ return (pos < count) ? (buf[pos] & 0xff) : -1;
+ }
- for (int i = 0; i < numAdditionals; i++) {
- DNSRecord rec = this.readAnswer();
- if (rec != null) {
- // Add a record, if we were able to create one.
- _additionals.add(rec);
- }
+ public String readName() {
+ Map names = new HashMap();
+ final StringBuilder sb = new StringBuilder();
+ boolean finished = false;
+ while (!finished) {
+ int len = this.readUnsignedByte();
+ if (len == 0) {
+ finished = true;
+ break;
+ }
+ switch (DNSLabel.labelForByte(len)) {
+ case Standard:
+ int offset = pos - 1;
+ String label = this.readUTF(len) + ".";
+ sb.append(label);
+ for (StringBuilder previousLabel : names.values()) {
+ previousLabel.append(label);
}
-
- // We should have drained the entire stream by now
- if (_messageInputStream.available() > 0) {
- throw new IOException("Received a message with the wrong length.");
+ names.put(Integer.valueOf(offset), new StringBuilder(label));
+ break;
+ case Compressed:
+ int index = (DNSLabel.labelValue(len) << 8) | this.readUnsignedByte();
+ String compressedLabel = _names.get(Integer.valueOf(index));
+ if (compressedLabel == null) {
+ logger1.warn(
+ "Bad domain name: possible circular name detected. Bad offset: 0x{} at 0x{}",
+ Integer.toHexString(index),
+ Integer.toHexString(pos - 2));
+ compressedLabel = "";
}
- } catch (Exception e) {
- logger.warn("DNSIncoming() dump " + print(true) + "\n exception ", e);
- // This ugly but some JVM don't implement the cause on IOException
- IOException ioe = new IOException("DNSIncoming corrupted message");
- ioe.initCause(e);
- throw ioe;
- } finally {
- try {
- _messageInputStream.close();
- } catch (Exception e) {
- logger.warn("MessageInputStream close error");
+ sb.append(compressedLabel);
+ for (StringBuilder previousLabel : names.values()) {
+ previousLabel.append(compressedLabel);
}
+ finished = true;
+ break;
+ case Extended:
+ // int extendedLabelClass = DNSLabel.labelValue(len);
+ logger1.debug("Extended label are not currently supported.");
+ break;
+ case Unknown:
+ default:
+ logger1.warn("Unsupported DNS label type: '{}'", Integer.toHexString(len & 0xC0));
}
+ }
+ for (final Map.Entry entry : names.entrySet()) {
+ final Integer index = entry.getKey();
+ _names.put(index, entry.getValue().toString());
+ }
+ return sb.toString();
}
- private DNSIncoming(int flags, int id, boolean multicast, DatagramPacket packet, long receivedTime) {
- super(flags, id, multicast);
- this._packet = packet;
- this._messageInputStream = new MessageInputStream(packet.getData(), packet.getLength());
- this._receivedTime = receivedTime;
+ public String readNonNameString() {
+ int len = this.readUnsignedByte();
+ return this.readUTF(len);
}
+ }
+
+ private final DatagramPacket _packet;
+
+ private final long _receivedTime;
+
+ private final MessageInputStream _messageInputStream;
+
+ private int _senderUDPPayload;
+
+ /**
+ * Parse a message from a datagram packet.
+ *
+ * @param packet
+ * @exception IOException
+ */
+ public DNSIncoming(DatagramPacket packet) throws IOException {
+ super(0, 0, packet.getPort() == DNSConstants.MDNS_PORT);
+ this._packet = packet;
+ InetAddress source = packet.getAddress();
+ this._messageInputStream = new MessageInputStream(packet.getData(), packet.getLength());
+ this._receivedTime = System.currentTimeMillis();
+ this._senderUDPPayload = DNSConstants.MAX_MSG_TYPICAL;
+
+ try {
+ this.setId(_messageInputStream.readUnsignedShort());
+ this.setFlags(_messageInputStream.readUnsignedShort());
+ if (this.getOperationCode() > 0) {
+ throw new IOException(
+ "Received a message with a non standard operation code. Currently unsupported in the specification.");
+ }
+ int numQuestions = _messageInputStream.readUnsignedShort();
+ int numAnswers = _messageInputStream.readUnsignedShort();
+ int numAuthorities = _messageInputStream.readUnsignedShort();
+ int numAdditionals = _messageInputStream.readUnsignedShort();
+
+ logger.debug(
+ "DNSIncoming() questions:{} answers:{} authorities:{} additionals:{}",
+ numQuestions,
+ numAnswers,
+ numAuthorities,
+ numAdditionals);
+
+ // We need some sanity checks
+ // A question is at least 5 bytes and answer 11 so check what we have
+
+ if ((numQuestions * 5 + (numAnswers + numAuthorities + numAdditionals) * 11)
+ > packet.getLength()) {
+ throw new IOException(
+ "questions:"
+ + numQuestions
+ + " answers:"
+ + numAnswers
+ + " authorities:"
+ + numAuthorities
+ + " additionals:"
+ + numAdditionals);
+ }
+
+ // parse questions
+ for (int i = 0; i < numQuestions; i++) {
+ DNSQuestion question = this.readQuestion();
+ if (question != null) _questions.add(question);
+ }
+
+ // parse answers
+ for (int i = 0; i < numAnswers; i++) {
+ DNSRecord rec = this.readAnswer();
+ if (rec != null) {
+ // Add a record, if we were able to create one.
+ _answers.add(rec);
+ }
+ }
- /*
- * (non-Javadoc)
- * @see java.lang.Object#clone()
- */
- @Override
- public DNSIncoming clone() {
- DNSIncoming in = new DNSIncoming(this.getFlags(), this.getId(), this.isMulticast(), this._packet, this._receivedTime);
- in._senderUDPPayload = this._senderUDPPayload;
- in._questions.addAll(this._questions);
- in._answers.addAll(this._answers);
- in._authoritativeAnswers.addAll(this._authoritativeAnswers);
- in._additionals.addAll(this._additionals);
- return in;
- }
+ for (int i = 0; i < numAuthorities; i++) {
+ DNSRecord rec = this.readAnswer();
+ if (rec != null) {
+ // Add a record, if we were able to create one.
+ _authoritativeAnswers.add(rec);
+ }
+ }
- private DNSQuestion readQuestion() {
- String domain = _messageInputStream.readName();
- DNSRecordType type = DNSRecordType.typeForIndex(_messageInputStream.readUnsignedShort());
- if (type == DNSRecordType.TYPE_IGNORE) {
- logger.warn("Could not find record type: {}", this.print(true));
+ for (int i = 0; i < numAdditionals; i++) {
+ DNSRecord rec = this.readAnswer();
+ if (rec != null) {
+ // Add a record, if we were able to create one.
+ _additionals.add(rec);
}
- int recordClassIndex = _messageInputStream.readUnsignedShort();
- DNSRecordClass recordClass = DNSRecordClass.classForIndex(recordClassIndex);
- boolean unique = recordClass.isUnique(recordClassIndex);
- return DNSQuestion.newQuestion(domain, type, recordClass, unique);
+ }
+
+ // We should have drained the entire stream by now
+ if (_messageInputStream.available() > 0) {
+ throw new IOException("Received a message with the wrong length.");
+ }
+ } catch (Exception e) {
+ logger.warn("DNSIncoming() dump " + print(true) + "\n exception ", e);
+ // This ugly but some JVM don't implement the cause on IOException
+ IOException ioe = new IOException("DNSIncoming corrupted message");
+ ioe.initCause(e);
+ throw ioe;
+ } finally {
+ try {
+ _messageInputStream.close();
+ } catch (Exception e) {
+ logger.warn("MessageInputStream close error");
+ }
}
-
- private DNSRecord readAnswer() {
- String domain = _messageInputStream.readName();
- DNSRecordType type = DNSRecordType.typeForIndex(_messageInputStream.readUnsignedShort());
- if (type == DNSRecordType.TYPE_IGNORE) {
- logger.warn("Could not find record type. domain: {}\n{}", domain, this.print(true));
+ }
+
+ private DNSIncoming(
+ int flags, int id, boolean multicast, DatagramPacket packet, long receivedTime) {
+ super(flags, id, multicast);
+ this._packet = packet;
+ this._messageInputStream = new MessageInputStream(packet.getData(), packet.getLength());
+ this._receivedTime = receivedTime;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Object#clone()
+ */
+ @Override
+ public DNSIncoming clone() {
+ DNSIncoming in =
+ new DNSIncoming(
+ this.getFlags(), this.getId(), this.isMulticast(), this._packet, this._receivedTime);
+ in._senderUDPPayload = this._senderUDPPayload;
+ in._questions.addAll(this._questions);
+ in._answers.addAll(this._answers);
+ in._authoritativeAnswers.addAll(this._authoritativeAnswers);
+ in._additionals.addAll(this._additionals);
+ return in;
+ }
+
+ private DNSQuestion readQuestion() {
+ String domain = _messageInputStream.readName();
+ DNSRecordType type = DNSRecordType.typeForIndex(_messageInputStream.readUnsignedShort());
+ if (type == DNSRecordType.TYPE_IGNORE) {
+ logger.warn("Could not find record type: {}", this.print(true));
+ }
+ int recordClassIndex = _messageInputStream.readUnsignedShort();
+ DNSRecordClass recordClass = DNSRecordClass.classForIndex(recordClassIndex);
+ boolean unique = recordClass.isUnique(recordClassIndex);
+ return DNSQuestion.newQuestion(domain, type, recordClass, unique);
+ }
+
+ private DNSRecord readAnswer() {
+ String domain = _messageInputStream.readName();
+ DNSRecordType type = DNSRecordType.typeForIndex(_messageInputStream.readUnsignedShort());
+ if (type == DNSRecordType.TYPE_IGNORE) {
+ logger.warn("Could not find record type. domain: {}\n{}", domain, this.print(true));
+ }
+ int recordClassIndex = _messageInputStream.readUnsignedShort();
+ DNSRecordClass recordClass =
+ (type == DNSRecordType.TYPE_OPT
+ ? DNSRecordClass.CLASS_UNKNOWN
+ : DNSRecordClass.classForIndex(recordClassIndex));
+ if ((recordClass == DNSRecordClass.CLASS_UNKNOWN) && (type != DNSRecordType.TYPE_OPT)) {
+ logger.warn(
+ "Could not find record class. domain: {} type: {}\n{}", domain, type, this.print(true));
+ }
+ boolean unique = recordClass.isUnique(recordClassIndex);
+ int ttl = _messageInputStream.readInt();
+ int len = _messageInputStream.readUnsignedShort();
+ DNSRecord rec = null;
+
+ switch (type) {
+ case TYPE_A: // IPv4
+ rec =
+ new DNSRecord.IPv4Address(
+ domain, recordClass, unique, ttl, _messageInputStream.readBytes(len));
+ break;
+ case TYPE_AAAA: // IPv6
+ rec =
+ new DNSRecord.IPv6Address(
+ domain, recordClass, unique, ttl, _messageInputStream.readBytes(len));
+ break;
+ case TYPE_CNAME:
+ case TYPE_PTR:
+ String service = "";
+ service = _messageInputStream.readName();
+ if (service.length() > 0) {
+ rec = new DNSRecord.Pointer(domain, recordClass, unique, ttl, service);
+ } else {
+ logger.warn(
+ "PTR record of class: {}, there was a problem reading the service name of the answer for domain: {}",
+ recordClass,
+ domain);
}
- int recordClassIndex = _messageInputStream.readUnsignedShort();
- DNSRecordClass recordClass = (type == DNSRecordType.TYPE_OPT ? DNSRecordClass.CLASS_UNKNOWN : DNSRecordClass.classForIndex(recordClassIndex));
- if ((recordClass == DNSRecordClass.CLASS_UNKNOWN) && (type != DNSRecordType.TYPE_OPT)) {
- logger.warn("Could not find record class. domain: {} type: {}\n{}", domain, type, this.print(true));
+ break;
+ case TYPE_TXT:
+ rec =
+ new DNSRecord.Text(
+ domain, recordClass, unique, ttl, _messageInputStream.readBytes(len));
+ break;
+ case TYPE_SRV:
+ int priority = _messageInputStream.readUnsignedShort();
+ int weight = _messageInputStream.readUnsignedShort();
+ int port = _messageInputStream.readUnsignedShort();
+ String target = "";
+ // This is a hack to handle a bug in the BonjourConformanceTest
+ // It is sending out target strings that don't follow the "domain name" format.
+ if (USE_DOMAIN_NAME_FORMAT_FOR_SRV_TARGET) {
+ target = _messageInputStream.readName();
+ } else {
+ // [PJYF Nov 13 2010] Do we still need this? This looks really bad. All label are supposed
+ // to start by a length.
+ target = _messageInputStream.readNonNameString();
}
- boolean unique = recordClass.isUnique(recordClassIndex);
- int ttl = _messageInputStream.readInt();
- int len = _messageInputStream.readUnsignedShort();
- DNSRecord rec = null;
-
- switch (type) {
- case TYPE_A: // IPv4
- rec = new DNSRecord.IPv4Address(domain, recordClass, unique, ttl, _messageInputStream.readBytes(len));
- break;
- case TYPE_AAAA: // IPv6
- rec = new DNSRecord.IPv6Address(domain, recordClass, unique, ttl, _messageInputStream.readBytes(len));
- break;
- case TYPE_CNAME:
- case TYPE_PTR:
- String service = "";
- service = _messageInputStream.readName();
- if (service.length() > 0) {
- rec = new DNSRecord.Pointer(domain, recordClass, unique, ttl, service);
- } else {
- logger.warn("PTR record of class: {}, there was a problem reading the service name of the answer for domain: {}", recordClass, domain);
+ rec =
+ new DNSRecord.Service(domain, recordClass, unique, ttl, priority, weight, port, target);
+ break;
+ case TYPE_HINFO:
+ final StringBuilder sb = new StringBuilder();
+ sb.append(_messageInputStream.readUTF(len));
+ int index = sb.indexOf(" ");
+ String cpu = (index > 0 ? sb.substring(0, index) : sb.toString()).trim();
+ String os = (index > 0 ? sb.substring(index + 1) : "").trim();
+ rec = new DNSRecord.HostInformation(domain, recordClass, unique, ttl, cpu, os);
+ break;
+ case TYPE_OPT:
+ DNSResultCode extendedResultCode = DNSResultCode.resultCodeForFlags(this.getFlags(), ttl);
+ int version = (ttl & 0x00ff0000) >> 16;
+ if (version == 0) {
+ _senderUDPPayload = recordClassIndex;
+ while (_messageInputStream.available() > 0) {
+ // Read RDData
+ int optionCodeInt = 0;
+ DNSOptionCode optionCode = null;
+ if (_messageInputStream.available() >= 2) {
+ optionCodeInt = _messageInputStream.readUnsignedShort();
+ optionCode = DNSOptionCode.resultCodeForFlags(optionCodeInt);
+ } else {
+ logger.warn("There was a problem reading the OPT record. Ignoring.");
+ break;
+ }
+ int optionLength = 0;
+ if (_messageInputStream.available() >= 2) {
+ optionLength = _messageInputStream.readUnsignedShort();
+ } else {
+ logger.warn("There was a problem reading the OPT record. Ignoring.");
+ break;
+ }
+ byte[] optiondata = new byte[0];
+ if (_messageInputStream.available() >= optionLength) {
+ optiondata = _messageInputStream.readBytes(optionLength);
+ }
+ //
+ // We should really do something with those options.
+ switch (optionCode) {
+ case Owner:
+ // Valid length values are 8, 14, 18 and 20
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // |Opt|Len|V|S|Primary MAC|Wakeup MAC | Password |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ //
+ int ownerVersion = 0;
+ int ownerSequence = 0;
+ byte[] ownerPrimaryMacAddress = null;
+ byte[] ownerWakeupMacAddress = null;
+ byte[] ownerPassword = null;
+ try {
+ ownerVersion = optiondata[0];
+ ownerSequence = optiondata[1];
+ ownerPrimaryMacAddress =
+ new byte[] {
+ optiondata[2],
+ optiondata[3],
+ optiondata[4],
+ optiondata[5],
+ optiondata[6],
+ optiondata[7]
+ };
+ ownerWakeupMacAddress = ownerPrimaryMacAddress;
+ if (optiondata.length > 8) {
+ // We have a wakeupMacAddress.
+ ownerWakeupMacAddress =
+ new byte[] {
+ optiondata[8],
+ optiondata[9],
+ optiondata[10],
+ optiondata[11],
+ optiondata[12],
+ optiondata[13]
+ };
+ }
+ if (optiondata.length == 18) {
+ // We have a short password.
+ ownerPassword =
+ new byte[] {optiondata[14], optiondata[15], optiondata[16], optiondata[17]};
+ }
+ if (optiondata.length == 22) {
+ // We have a long password.
+ ownerPassword =
+ new byte[] {
+ optiondata[14],
+ optiondata[15],
+ optiondata[16],
+ optiondata[17],
+ optiondata[18],
+ optiondata[19],
+ optiondata[20],
+ optiondata[21]
+ };
+ }
+ } catch (Exception exception) {
+ logger.warn(
+ "Malformed OPT answer. Option code: Owner data: {}",
+ this._hexString(optiondata));
}
- break;
- case TYPE_TXT:
- rec = new DNSRecord.Text(domain, recordClass, unique, ttl, _messageInputStream.readBytes(len));
- break;
- case TYPE_SRV:
- int priority = _messageInputStream.readUnsignedShort();
- int weight = _messageInputStream.readUnsignedShort();
- int port = _messageInputStream.readUnsignedShort();
- String target = "";
- // This is a hack to handle a bug in the BonjourConformanceTest
- // It is sending out target strings that don't follow the "domain name" format.
- if (USE_DOMAIN_NAME_FORMAT_FOR_SRV_TARGET) {
- target = _messageInputStream.readName();
- } else {
- // [PJYF Nov 13 2010] Do we still need this? This looks really bad. All label are supposed to start by a length.
- target = _messageInputStream.readNonNameString();
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "Unhandled Owner OPT version: {} sequence: {} MAC address: {} {}{} {}{}",
+ ownerVersion,
+ ownerSequence,
+ this._hexString(ownerPrimaryMacAddress),
+ (ownerWakeupMacAddress != ownerPrimaryMacAddress
+ ? " wakeup MAC address: "
+ : ""),
+ (ownerWakeupMacAddress != ownerPrimaryMacAddress
+ ? this._hexString(ownerWakeupMacAddress)
+ : ""),
+ (ownerPassword != null ? " password: " : ""),
+ (ownerPassword != null ? this._hexString(ownerPassword) : ""));
}
- rec = new DNSRecord.Service(domain, recordClass, unique, ttl, priority, weight, port, target);
break;
- case TYPE_HINFO:
- final StringBuilder sb = new StringBuilder();
- sb.append(_messageInputStream.readUTF(len));
- int index = sb.indexOf(" ");
- String cpu = (index > 0 ? sb.substring(0, index) : sb.toString()).trim();
- String os = (index > 0 ? sb.substring(index + 1) : "").trim();
- rec = new DNSRecord.HostInformation(domain, recordClass, unique, ttl, cpu, os);
+ case LLQ:
+ case NSID:
+ case UL:
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "There was an OPT answer. Option code: {} data: {}",
+ optionCode,
+ this._hexString(optiondata));
+ }
break;
- case TYPE_OPT:
- DNSResultCode extendedResultCode = DNSResultCode.resultCodeForFlags(this.getFlags(), ttl);
- int version = (ttl & 0x00ff0000) >> 16;
- if (version == 0) {
- _senderUDPPayload = recordClassIndex;
- while (_messageInputStream.available() > 0) {
- // Read RDData
- int optionCodeInt = 0;
- DNSOptionCode optionCode = null;
- if (_messageInputStream.available() >= 2) {
- optionCodeInt = _messageInputStream.readUnsignedShort();
- optionCode = DNSOptionCode.resultCodeForFlags(optionCodeInt);
- } else {
- logger.warn("There was a problem reading the OPT record. Ignoring.");
- break;
- }
- int optionLength = 0;
- if (_messageInputStream.available() >= 2) {
- optionLength = _messageInputStream.readUnsignedShort();
- } else {
- logger.warn("There was a problem reading the OPT record. Ignoring.");
- break;
- }
- byte[] optiondata = new byte[0];
- if (_messageInputStream.available() >= optionLength) {
- optiondata = _messageInputStream.readBytes(optionLength);
- }
- //
- // We should really do something with those options.
- switch (optionCode) {
- case Owner:
- // Valid length values are 8, 14, 18 and 20
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // |Opt|Len|V|S|Primary MAC|Wakeup MAC | Password |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- //
- int ownerVersion = 0;
- int ownerSequence = 0;
- byte[] ownerPrimaryMacAddress = null;
- byte[] ownerWakeupMacAddress = null;
- byte[] ownerPassword = null;
- try {
- ownerVersion = optiondata[0];
- ownerSequence = optiondata[1];
- ownerPrimaryMacAddress = new byte[] { optiondata[2], optiondata[3], optiondata[4], optiondata[5], optiondata[6], optiondata[7] };
- ownerWakeupMacAddress = ownerPrimaryMacAddress;
- if (optiondata.length > 8) {
- // We have a wakeupMacAddress.
- ownerWakeupMacAddress = new byte[] { optiondata[8], optiondata[9], optiondata[10], optiondata[11], optiondata[12], optiondata[13] };
- }
- if (optiondata.length == 18) {
- // We have a short password.
- ownerPassword = new byte[] { optiondata[14], optiondata[15], optiondata[16], optiondata[17] };
- }
- if (optiondata.length == 22) {
- // We have a long password.
- ownerPassword = new byte[] { optiondata[14], optiondata[15], optiondata[16], optiondata[17], optiondata[18], optiondata[19], optiondata[20], optiondata[21] };
- }
- } catch (Exception exception) {
- logger.warn("Malformed OPT answer. Option code: Owner data: {}", this._hexString(optiondata));
- }
- if (logger.isDebugEnabled()) {
- logger.debug("Unhandled Owner OPT version: {} sequence: {} MAC address: {} {}{} {}{}",
- ownerVersion,
- ownerSequence,
- this._hexString(ownerPrimaryMacAddress),
- (ownerWakeupMacAddress != ownerPrimaryMacAddress ? " wakeup MAC address: " : ""),
- (ownerWakeupMacAddress != ownerPrimaryMacAddress ? this._hexString(ownerWakeupMacAddress) : ""),
- (ownerPassword != null ? " password: ": ""),
- (ownerPassword != null ? this._hexString(ownerPassword) : "")
- );
- }
- break;
- case LLQ:
- case NSID:
- case UL:
- if (logger.isDebugEnabled()) {
- logger.debug("There was an OPT answer. Option code: {} data: {}", optionCode, this._hexString(optiondata));
- }
- break;
- case Unknown:
- if (optionCodeInt >= 65001 && optionCodeInt <= 65534) {
- // RFC 6891 defines this range as used for experimental/local purposes.
- logger.debug("There was an OPT answer using an experimental/local option code: {} data: {}", optionCodeInt, this._hexString(optiondata));
- } else {
- logger.warn("There was an OPT answer. Not currently handled. Option code: {} data: {}", optionCodeInt, this._hexString(optiondata));
- }
- break;
- default:
- // This is to keep the compiler happy.
- break;
- }
- }
+ case Unknown:
+ if (optionCodeInt >= 65001 && optionCodeInt <= 65534) {
+ // RFC 6891 defines this range as used for experimental/local purposes.
+ logger.debug(
+ "There was an OPT answer using an experimental/local option code: {} data: {}",
+ optionCodeInt,
+ this._hexString(optiondata));
} else {
- logger.warn("There was an OPT answer. Wrong version number: {} result code: {}", version, extendedResultCode);
+ logger.warn(
+ "There was an OPT answer. Not currently handled. Option code: {} data: {}",
+ optionCodeInt,
+ this._hexString(optiondata));
}
break;
- default:
- logger.debug("DNSIncoming() unknown type: {}", type);
- _messageInputStream.skip(len);
+ default:
+ // This is to keep the compiler happy.
break;
+ }
+ }
+ } else {
+ logger.warn(
+ "There was an OPT answer. Wrong version number: {} result code: {}",
+ version,
+ extendedResultCode);
}
- return rec;
+ break;
+ default:
+ logger.debug("DNSIncoming() unknown type: {}", type);
+ _messageInputStream.skip(len);
+ break;
}
-
- /**
- * Debugging.
- */
- String print(boolean dump) {
- final StringBuilder sb = new StringBuilder();
- sb.append(this.print());
- if (dump) {
- byte[] data = new byte[_packet.getLength()];
- System.arraycopy(_packet.getData(), 0, data, 0, data.length);
- sb.append(this.print(data));
- }
- return sb.toString();
+ return rec;
+ }
+
+ /** Debugging. */
+ String print(boolean dump) {
+ final StringBuilder sb = new StringBuilder();
+ sb.append(this.print());
+ if (dump) {
+ byte[] data = new byte[_packet.getLength()];
+ System.arraycopy(_packet.getData(), 0, data, 0, data.length);
+ sb.append(this.print(data));
}
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append(isQuery() ? "dns[query," : "dns[response,");
- if (_packet.getAddress() != null) {
- sb.append(_packet.getAddress().getHostAddress());
- }
- sb.append(':');
- sb.append(_packet.getPort());
- sb.append(", length=");
- sb.append(_packet.getLength());
- sb.append(", id=0x");
- sb.append(Integer.toHexString(this.getId()));
- if (this.getFlags() != 0) {
- sb.append(", flags=0x");
- sb.append(Integer.toHexString(this.getFlags()));
- if ((this.getFlags() & DNSConstants.FLAGS_QR_RESPONSE) != 0) {
- sb.append(":r");
- }
- if ((this.getFlags() & DNSConstants.FLAGS_AA) != 0) {
- sb.append(":aa");
- }
- if ((this.getFlags() & DNSConstants.FLAGS_TC) != 0) {
- sb.append(":tc");
- }
- }
- if (this.getNumberOfQuestions() > 0) {
- sb.append(", questions=");
- sb.append(this.getNumberOfQuestions());
- }
- if (this.getNumberOfAnswers() > 0) {
- sb.append(", answers=");
- sb.append(this.getNumberOfAnswers());
- }
- if (this.getNumberOfAuthorities() > 0) {
- sb.append(", authorities=");
- sb.append(this.getNumberOfAuthorities());
- }
- if (this.getNumberOfAdditionals() > 0) {
- sb.append(", additionals=");
- sb.append(this.getNumberOfAdditionals());
- }
- if (this.getNumberOfQuestions() > 0) {
- sb.append("\nquestions:");
- for (DNSQuestion question : _questions) {
- sb.append("\n\t");
- sb.append(question);
- }
- }
- if (this.getNumberOfAnswers() > 0) {
- sb.append("\nanswers:");
- for (DNSRecord record : _answers) {
- sb.append("\n\t");
- sb.append(record);
- }
- }
- if (this.getNumberOfAuthorities() > 0) {
- sb.append("\nauthorities:");
- for (DNSRecord record : _authoritativeAnswers) {
- sb.append("\n\t");
- sb.append(record);
- }
- }
- if (this.getNumberOfAdditionals() > 0) {
- sb.append("\nadditionals:");
- for (DNSRecord record : _additionals) {
- sb.append("\n\t");
- sb.append(record);
- }
- }
- sb.append(']');
-
- return sb.toString();
+ return sb.toString();
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append(isQuery() ? "dns[query," : "dns[response,");
+ if (_packet.getAddress() != null) {
+ sb.append(_packet.getAddress().getHostAddress());
}
-
- public int elapseSinceArrival() {
- return (int) (System.currentTimeMillis() - _receivedTime);
+ sb.append(':');
+ sb.append(_packet.getPort());
+ sb.append(", length=");
+ sb.append(_packet.getLength());
+ sb.append(", id=0x");
+ sb.append(Integer.toHexString(this.getId()));
+ if (this.getFlags() != 0) {
+ sb.append(", flags=0x");
+ sb.append(Integer.toHexString(this.getFlags()));
+ if ((this.getFlags() & DNSConstants.FLAGS_QR_RESPONSE) != 0) {
+ sb.append(":r");
+ }
+ if ((this.getFlags() & DNSConstants.FLAGS_AA) != 0) {
+ sb.append(":aa");
+ }
+ if ((this.getFlags() & DNSConstants.FLAGS_TC) != 0) {
+ sb.append(":tc");
+ }
}
-
- /**
- * This will return the default UDP payload except if an OPT record was found with a different size.
- *
- * @return the senderUDPPayload
- */
- public int getSenderUDPPayload() {
- return this._senderUDPPayload;
+ if (this.getNumberOfQuestions() > 0) {
+ sb.append(", questions=");
+ sb.append(this.getNumberOfQuestions());
}
-
- private static final char[] _nibbleToHex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
-
- /**
- * Returns a hex-string for printing
- *
- * @param bytes
- * @return Returns a hex-string which can be used within a SQL expression
- */
- private String _hexString(byte[] bytes) {
-
- final StringBuilder result = new StringBuilder(2 * bytes.length);
-
- for (int i = 0; i < bytes.length; i++) {
- int b = bytes[i] & 0xFF;
- result.append(_nibbleToHex[b / 16]);
- result.append(_nibbleToHex[b % 16]);
- }
-
- return result.toString();
+ if (this.getNumberOfAnswers() > 0) {
+ sb.append(", answers=");
+ sb.append(this.getNumberOfAnswers());
+ }
+ if (this.getNumberOfAuthorities() > 0) {
+ sb.append(", authorities=");
+ sb.append(this.getNumberOfAuthorities());
+ }
+ if (this.getNumberOfAdditionals() > 0) {
+ sb.append(", additionals=");
+ sb.append(this.getNumberOfAdditionals());
+ }
+ if (this.getNumberOfQuestions() > 0) {
+ sb.append("\nquestions:");
+ for (DNSQuestion question : _questions) {
+ sb.append("\n\t");
+ sb.append(question);
+ }
+ }
+ if (this.getNumberOfAnswers() > 0) {
+ sb.append("\nanswers:");
+ for (DNSRecord record : _answers) {
+ sb.append("\n\t");
+ sb.append(record);
+ }
+ }
+ if (this.getNumberOfAuthorities() > 0) {
+ sb.append("\nauthorities:");
+ for (DNSRecord record : _authoritativeAnswers) {
+ sb.append("\n\t");
+ sb.append(record);
+ }
+ }
+ if (this.getNumberOfAdditionals() > 0) {
+ sb.append("\nadditionals:");
+ for (DNSRecord record : _additionals) {
+ sb.append("\n\t");
+ sb.append(record);
+ }
+ }
+ sb.append(']');
+
+ return sb.toString();
+ }
+
+ public int elapseSinceArrival() {
+ return (int) (System.currentTimeMillis() - _receivedTime);
+ }
+
+ /**
+ * This will return the default UDP payload except if an OPT record was found with a different
+ * size.
+ *
+ * @return the senderUDPPayload
+ */
+ public int getSenderUDPPayload() {
+ return this._senderUDPPayload;
+ }
+
+ private static final char[] _nibbleToHex = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+ };
+
+ /**
+ * Returns a hex-string for printing
+ *
+ * @param bytes
+ * @return Returns a hex-string which can be used within a SQL expression
+ */
+ private String _hexString(byte[] bytes) {
+
+ final StringBuilder result = new StringBuilder(2 * bytes.length);
+
+ for (int i = 0; i < bytes.length; i++) {
+ int b = bytes[i] & 0xFF;
+ result.append(_nibbleToHex[b / 16]);
+ result.append(_nibbleToHex[b % 16]);
}
+ return result.toString();
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSMessage.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSMessage.java
index a22a63a42..24a6cc812 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSMessage.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSMessage.java
@@ -1,16 +1,13 @@
-/**
- *
- */
+/** */
package io.libp2p.discovery.mdns.impl;
+import io.libp2p.discovery.mdns.impl.constants.DNSConstants;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
-import io.libp2p.discovery.mdns.impl.constants.DNSConstants;
-
/**
* DNSMessage define a DNS message either incoming or outgoing.
*
@@ -18,318 +15,315 @@
*/
public abstract class DNSMessage {
- /**
- *
- */
- public static final boolean MULTICAST = true;
-
- /**
- *
- */
- public static final boolean UNICAST = false;
-
- // protected DatagramPacket _packet;
- // protected int _off;
- // protected int _len;
- // protected byte[] _data;
-
- private int _id;
-
- boolean _multicast;
-
- private int _flags;
-
- protected final List _questions;
-
- protected final List _answers;
-
- protected final List _authoritativeAnswers;
-
- protected final List _additionals;
-
- /**
- * @param flags
- * @param id
- * @param multicast
- */
- protected DNSMessage(int flags, int id, boolean multicast) {
- super();
- _flags = flags;
- _id = id;
- _multicast = multicast;
- _questions = Collections.synchronizedList(new LinkedList());
- _answers = Collections.synchronizedList(new LinkedList());
- _authoritativeAnswers = Collections.synchronizedList(new LinkedList());
- _additionals = Collections.synchronizedList(new LinkedList());
+ /** */
+ public static final boolean MULTICAST = true;
+
+ /** */
+ public static final boolean UNICAST = false;
+
+ // protected DatagramPacket _packet;
+ // protected int _off;
+ // protected int _len;
+ // protected byte[] _data;
+
+ private int _id;
+
+ boolean _multicast;
+
+ private int _flags;
+
+ protected final List _questions;
+
+ protected final List _answers;
+
+ protected final List _authoritativeAnswers;
+
+ protected final List _additionals;
+
+ /**
+ * @param flags
+ * @param id
+ * @param multicast
+ */
+ protected DNSMessage(int flags, int id, boolean multicast) {
+ super();
+ _flags = flags;
+ _id = id;
+ _multicast = multicast;
+ _questions = Collections.synchronizedList(new LinkedList());
+ _answers = Collections.synchronizedList(new LinkedList());
+ _authoritativeAnswers = Collections.synchronizedList(new LinkedList());
+ _additionals = Collections.synchronizedList(new LinkedList());
+ }
+
+ // public DatagramPacket getPacket() {
+ // return _packet;
+ // }
+ //
+ // public int getOffset() {
+ // return _off;
+ // }
+ //
+ // public int getLength() {
+ // return _len;
+ // }
+ //
+ // public byte[] getData() {
+ // if ( _data == null ) _data = new byte[DNSConstants.MAX_MSG_TYPICAL];
+ // return _data;
+ // }
+
+ /**
+ * @return message id
+ */
+ public int getId() {
+ return (_multicast ? 0 : _id);
+ }
+
+ /**
+ * @param id the id to set
+ */
+ public void setId(int id) {
+ this._id = id;
+ }
+
+ /**
+ * @return message flags
+ */
+ public int getFlags() {
+ return _flags;
+ }
+
+ /**
+ * @param flags the flags to set
+ */
+ public void setFlags(int flags) {
+ this._flags = flags;
+ }
+
+ /**
+ * @return true if multicast
+ */
+ public boolean isMulticast() {
+ return _multicast;
+ }
+
+ /**
+ * @return list of questions
+ */
+ public Collection extends DNSQuestion> getQuestions() {
+ return _questions;
+ }
+
+ /**
+ * @return number of questions in the message
+ */
+ public int getNumberOfQuestions() {
+ return this.getQuestions().size();
+ }
+
+ public List getAllAnswers() {
+ List aList =
+ new ArrayList(
+ _answers.size() + _authoritativeAnswers.size() + _additionals.size());
+ aList.addAll(_answers);
+ aList.addAll(_authoritativeAnswers);
+ aList.addAll(_additionals);
+ return aList;
+ }
+
+ /**
+ * @return list of answers
+ */
+ public Collection extends DNSRecord> getAnswers() {
+ return _answers;
+ }
+
+ /**
+ * @return number of answers in the message
+ */
+ public int getNumberOfAnswers() {
+ return this.getAnswers().size();
+ }
+
+ /**
+ * @return list of authorities
+ */
+ public Collection extends DNSRecord> getAuthorities() {
+ return _authoritativeAnswers;
+ }
+
+ /**
+ * @return number of authorities in the message
+ */
+ public int getNumberOfAuthorities() {
+ return this.getAuthorities().size();
+ }
+
+ /**
+ * @return list of additional answers
+ */
+ public Collection extends DNSRecord> getAdditionals() {
+ return _additionals;
+ }
+
+ /**
+ * @return number of additional in the message
+ */
+ public int getNumberOfAdditionals() {
+ return this.getAdditionals().size();
+ }
+
+ /**
+ * Check is the response code is valid
+ * The only valid value is zero all other values signify an error and the message must be ignored.
+ *
+ * @return true if the message has a valid response code.
+ */
+ public boolean isValidResponseCode() {
+ return (_flags & DNSConstants.FLAGS_RCODE) == 0;
+ }
+
+ /**
+ * Returns the operation code value. Currently only standard query 0 is valid.
+ *
+ * @return The operation code value.
+ */
+ public int getOperationCode() {
+ return (_flags & DNSConstants.FLAGS_OPCODE) >> 11;
+ }
+
+ /**
+ * Check if the message is truncated.
+ *
+ * @return true if the message was truncated
+ */
+ public boolean isTruncated() {
+ return (_flags & DNSConstants.FLAGS_TC) != 0;
+ }
+
+ /**
+ * Check if the message is an authoritative answer.
+ *
+ * @return true if the message is an authoritative answer
+ */
+ public boolean isAuthoritativeAnswer() {
+ return (_flags & DNSConstants.FLAGS_AA) != 0;
+ }
+
+ /**
+ * Check if the message is a query.
+ *
+ * @return true is the message is a query
+ */
+ public boolean isQuery() {
+ return (_flags & DNSConstants.FLAGS_QR_MASK) == DNSConstants.FLAGS_QR_QUERY;
+ }
+
+ /**
+ * Check if the message is a response.
+ *
+ * @return true is the message is a response
+ */
+ public boolean isResponse() {
+ return (_flags & DNSConstants.FLAGS_QR_MASK) == DNSConstants.FLAGS_QR_RESPONSE;
+ }
+
+ /**
+ * Check if the message is empty
+ *
+ * @return true is the message is empty
+ */
+ public boolean isEmpty() {
+ return (this.getNumberOfQuestions()
+ + this.getNumberOfAnswers()
+ + this.getNumberOfAuthorities()
+ + this.getNumberOfAdditionals())
+ == 0;
+ }
+
+ /** Debugging. */
+ String print() {
+ final StringBuilder sb = new StringBuilder(200);
+ sb.append(this.toString());
+ sb.append("\n");
+ for (final DNSQuestion question : _questions) {
+ sb.append("\tquestion: ");
+ sb.append(question);
+ sb.append("\n");
}
-
- // public DatagramPacket getPacket() {
- // return _packet;
- // }
- //
- // public int getOffset() {
- // return _off;
- // }
- //
- // public int getLength() {
- // return _len;
- // }
- //
- // public byte[] getData() {
- // if ( _data == null ) _data = new byte[DNSConstants.MAX_MSG_TYPICAL];
- // return _data;
- // }
-
- /**
- * @return message id
- */
- public int getId() {
- return (_multicast ? 0 : _id);
- }
-
- /**
- * @param id
- * the id to set
- */
- public void setId(int id) {
- this._id = id;
- }
-
- /**
- * @return message flags
- */
- public int getFlags() {
- return _flags;
- }
-
- /**
- * @param flags
- * the flags to set
- */
- public void setFlags(int flags) {
- this._flags = flags;
+ for (final DNSRecord answer : _answers) {
+ sb.append("\tanswer: ");
+ sb.append(answer);
+ sb.append("\n");
}
-
- /**
- * @return true if multicast
- */
- public boolean isMulticast() {
- return _multicast;
+ for (final DNSRecord answer : _authoritativeAnswers) {
+ sb.append("\tauthoritative: ");
+ sb.append(answer);
+ sb.append("\n");
}
-
- /**
- * @return list of questions
- */
- public Collection extends DNSQuestion> getQuestions() {
- return _questions;
- }
-
- /**
- * @return number of questions in the message
- */
- public int getNumberOfQuestions() {
- return this.getQuestions().size();
- }
-
- public List getAllAnswers() {
- List aList = new ArrayList(_answers.size() + _authoritativeAnswers.size() + _additionals.size());
- aList.addAll(_answers);
- aList.addAll(_authoritativeAnswers);
- aList.addAll(_additionals);
- return aList;
- }
-
- /**
- * @return list of answers
- */
- public Collection extends DNSRecord> getAnswers() {
- return _answers;
+ for (DNSRecord answer : _additionals) {
+ sb.append("\tadditional: ");
+ sb.append(answer);
+ sb.append("\n");
}
-
- /**
- * @return number of answers in the message
- */
- public int getNumberOfAnswers() {
- return this.getAnswers().size();
- }
-
- /**
- * @return list of authorities
- */
- public Collection extends DNSRecord> getAuthorities() {
- return _authoritativeAnswers;
- }
-
- /**
- * @return number of authorities in the message
- */
- public int getNumberOfAuthorities() {
- return this.getAuthorities().size();
- }
-
- /**
- * @return list of additional answers
- */
- public Collection extends DNSRecord> getAdditionals() {
- return _additionals;
- }
-
- /**
- * @return number of additional in the message
- */
- public int getNumberOfAdditionals() {
- return this.getAdditionals().size();
- }
-
- /**
- * Check is the response code is valid
- * The only valid value is zero all other values signify an error and the message must be ignored.
- *
- * @return true if the message has a valid response code.
- */
- public boolean isValidResponseCode() {
- return (_flags & DNSConstants.FLAGS_RCODE) == 0;
- }
-
- /**
- * Returns the operation code value. Currently only standard query 0 is valid.
- *
- * @return The operation code value.
- */
- public int getOperationCode() {
- return (_flags & DNSConstants.FLAGS_OPCODE) >> 11;
- }
-
- /**
- * Check if the message is truncated.
- *
- * @return true if the message was truncated
- */
- public boolean isTruncated() {
- return (_flags & DNSConstants.FLAGS_TC) != 0;
- }
-
- /**
- * Check if the message is an authoritative answer.
- *
- * @return true if the message is an authoritative answer
- */
- public boolean isAuthoritativeAnswer() {
- return (_flags & DNSConstants.FLAGS_AA) != 0;
- }
-
- /**
- * Check if the message is a query.
- *
- * @return true is the message is a query
- */
- public boolean isQuery() {
- return (_flags & DNSConstants.FLAGS_QR_MASK) == DNSConstants.FLAGS_QR_QUERY;
- }
-
- /**
- * Check if the message is a response.
- *
- * @return true is the message is a response
- */
- public boolean isResponse() {
- return (_flags & DNSConstants.FLAGS_QR_MASK) == DNSConstants.FLAGS_QR_RESPONSE;
- }
-
- /**
- * Check if the message is empty
- *
- * @return true is the message is empty
- */
- public boolean isEmpty() {
- return (this.getNumberOfQuestions() + this.getNumberOfAnswers() + this.getNumberOfAuthorities() + this.getNumberOfAdditionals()) == 0;
- }
-
- /**
- * Debugging.
- */
- String print() {
- final StringBuilder sb = new StringBuilder(200);
- sb.append(this.toString());
- sb.append("\n");
- for (final DNSQuestion question : _questions) {
- sb.append("\tquestion: ");
- sb.append(question);
- sb.append("\n");
+ return sb.toString();
+ }
+
+ /**
+ * Debugging.
+ *
+ * @param data
+ * @return data dump
+ */
+ protected String print(byte[] data) {
+ final StringBuilder sb = new StringBuilder(4000);
+ for (int off = 0, len = data.length; off < len; off += 32) {
+ int n = Math.min(32, len - off);
+ if (off < 0x10) {
+ sb.append(' ');
+ }
+ if (off < 0x100) {
+ sb.append(' ');
+ }
+ if (off < 0x1000) {
+ sb.append(' ');
+ }
+ sb.append(Integer.toHexString(off));
+ sb.append(':');
+ int index = 0;
+ for (index = 0; index < n; index++) {
+ if ((index % 8) == 0) {
+ sb.append(' ');
}
- for (final DNSRecord answer : _answers) {
- sb.append("\tanswer: ");
- sb.append(answer);
- sb.append("\n");
+ sb.append(Integer.toHexString((data[off + index] & 0xF0) >> 4));
+ sb.append(Integer.toHexString((data[off + index] & 0x0F) >> 0));
+ }
+ // for incomplete lines
+ if (index < 32) {
+ for (int i = index; i < 32; i++) {
+ if ((i % 8) == 0) {
+ sb.append(' ');
+ }
+ sb.append(" ");
}
- for (final DNSRecord answer : _authoritativeAnswers) {
- sb.append("\tauthoritative: ");
- sb.append(answer);
- sb.append("\n");
+ }
+ sb.append(" ");
+ for (index = 0; index < n; index++) {
+ if ((index % 8) == 0) {
+ sb.append(' ');
}
- for (DNSRecord answer : _additionals) {
- sb.append("\tadditional: ");
- sb.append(answer);
- sb.append("\n");
- }
- return sb.toString();
+ int ch = data[off + index] & 0xFF;
+ sb.append(((ch > ' ') && (ch < 127)) ? (char) ch : '.');
+ }
+ sb.append("\n");
+
+ // limit message size
+ if (off + 32 >= 2048) {
+ sb.append("....\n");
+ break;
+ }
}
-
- /**
- * Debugging.
- *
- * @param data
- * @return data dump
- */
- protected String print(byte[] data) {
- final StringBuilder sb = new StringBuilder(4000);
- for (int off = 0, len = data.length; off < len; off += 32) {
- int n = Math.min(32, len - off);
- if (off < 0x10) {
- sb.append(' ');
- }
- if (off < 0x100) {
- sb.append(' ');
- }
- if (off < 0x1000) {
- sb.append(' ');
- }
- sb.append(Integer.toHexString(off));
- sb.append(':');
- int index = 0;
- for (index = 0; index < n; index++) {
- if ((index % 8) == 0) {
- sb.append(' ');
- }
- sb.append(Integer.toHexString((data[off + index] & 0xF0) >> 4));
- sb.append(Integer.toHexString((data[off + index] & 0x0F) >> 0));
- }
- // for incomplete lines
- if (index < 32) {
- for (int i = index; i < 32; i++) {
- if ((i % 8) == 0) {
- sb.append(' ');
- }
- sb.append(" ");
- }
- }
- sb.append(" ");
- for (index = 0; index < n; index++) {
- if ((index % 8) == 0) {
- sb.append(' ');
- }
- int ch = data[off + index] & 0xFF;
- sb.append(((ch > ' ') && (ch < 127)) ? (char) ch : '.');
- }
- sb.append("\n");
-
- // limit message size
- if (off + 32 >= 2048) {
- sb.append("....\n");
- break;
- }
- }
- return sb.toString();
- }
-
+ return sb.toString();
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSOutgoing.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSOutgoing.java
index fe2b33242..3b42a1738 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSOutgoing.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSOutgoing.java
@@ -4,425 +4,426 @@
package io.libp2p.discovery.mdns.impl;
+import io.libp2p.discovery.mdns.impl.constants.DNSConstants;
import io.libp2p.discovery.mdns.impl.constants.DNSRecordClass;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
-import io.libp2p.discovery.mdns.impl.constants.DNSConstants;
-
/**
* An outgoing DNS message.
*
* @author Arthur van Hoff, Rick Blair, Werner Randelshofer
*/
public final class DNSOutgoing extends DNSMessage {
- public static class MessageOutputStream extends ByteArrayOutputStream {
- private final DNSOutgoing _out;
-
- private final int _offset;
-
- /**
- * Creates a new message stream, with a buffer capacity of the specified size, in bytes.
- *
- * @param size
- * the initial size.
- * @exception IllegalArgumentException
- * if size is negative.
- */
- MessageOutputStream(int size, DNSOutgoing out) {
- this(size, out, 0);
- }
+ public static class MessageOutputStream extends ByteArrayOutputStream {
+ private final DNSOutgoing _out;
- MessageOutputStream(int size, DNSOutgoing out, int offset) {
- super(size);
- _out = out;
- _offset = offset;
- }
+ private final int _offset;
- void writeByte(int value) {
- this.write(value & 0xFF);
- }
+ /**
+ * Creates a new message stream, with a buffer capacity of the specified size, in bytes.
+ *
+ * @param size the initial size.
+ * @exception IllegalArgumentException if size is negative.
+ */
+ MessageOutputStream(int size, DNSOutgoing out) {
+ this(size, out, 0);
+ }
- void writeBytes(String str, int off, int len) {
- for (int i = 0; i < len; i++) {
- writeByte(str.charAt(off + i));
- }
- }
+ MessageOutputStream(int size, DNSOutgoing out, int offset) {
+ super(size);
+ _out = out;
+ _offset = offset;
+ }
- public void writeBytes(byte data[]) {
- if (data != null) {
- writeBytes(data, 0, data.length);
- }
- }
+ void writeByte(int value) {
+ this.write(value & 0xFF);
+ }
- void writeBytes(byte data[], int off, int len) {
- for (int i = 0; i < len; i++) {
- writeByte(data[off + i]);
- }
- }
+ void writeBytes(String str, int off, int len) {
+ for (int i = 0; i < len; i++) {
+ writeByte(str.charAt(off + i));
+ }
+ }
- void writeShort(int value) {
- writeByte(value >> 8);
- writeByte(value);
- }
+ public void writeBytes(byte data[]) {
+ if (data != null) {
+ writeBytes(data, 0, data.length);
+ }
+ }
- void writeInt(int value) {
- writeShort(value >> 16);
- writeShort(value);
- }
+ void writeBytes(byte data[], int off, int len) {
+ for (int i = 0; i < len; i++) {
+ writeByte(data[off + i]);
+ }
+ }
- void writeUTF(String str, int off, int len) {
- // compute utf length
- int utflen = 0;
- for (int i = 0; i < len; i++) {
- int ch = str.charAt(off + i);
- if ((ch >= 0x0001) && (ch <= 0x007F)) {
- utflen += 1;
- } else {
- if (ch > 0x07FF) {
- utflen += 3;
- } else {
- utflen += 2;
- }
- }
- }
- // write utf length
- writeByte(utflen);
- // write utf data
- for (int i = 0; i < len; i++) {
- int ch = str.charAt(off + i);
- if ((ch >= 0x0001) && (ch <= 0x007F)) {
- writeByte(ch);
- } else {
- if (ch > 0x07FF) {
- writeByte(0xE0 | ((ch >> 12) & 0x0F));
- writeByte(0x80 | ((ch >> 6) & 0x3F));
- writeByte(0x80 | ((ch >> 0) & 0x3F));
- } else {
- writeByte(0xC0 | ((ch >> 6) & 0x1F));
- writeByte(0x80 | ((ch >> 0) & 0x3F));
- }
- }
- }
- }
+ void writeShort(int value) {
+ writeByte(value >> 8);
+ writeByte(value);
+ }
- void writeName(String name) {
- writeName(name, true);
- }
+ void writeInt(int value) {
+ writeShort(value >> 16);
+ writeShort(value);
+ }
- void writeName(String name, boolean useCompression) {
- String aName = name;
- while (true) {
- int n = indexOfSeparator(aName);
- if (n < 0) {
- n = aName.length();
- }
- if (n <= 0) {
- writeByte(0);
- return;
- }
- String label = aName.substring(0, n).replace("\\.", ".");
- if (useCompression && USE_DOMAIN_NAME_COMPRESSION) {
- Integer offset = _out._names.get(aName);
- if (offset != null) {
- int val = offset.intValue();
- writeByte((val >> 8) | 0xC0);
- writeByte(val & 0xFF);
- return;
- }
- _out._names.put(aName, Integer.valueOf(this.size() + _offset));
- writeUTF(label, 0, label.length());
- } else {
- writeUTF(label, 0, label.length());
- }
- aName = aName.substring(n);
- if (aName.startsWith(".")) {
- aName = aName.substring(1);
- }
- }
+ void writeUTF(String str, int off, int len) {
+ // compute utf length
+ int utflen = 0;
+ for (int i = 0; i < len; i++) {
+ int ch = str.charAt(off + i);
+ if ((ch >= 0x0001) && (ch <= 0x007F)) {
+ utflen += 1;
+ } else {
+ if (ch > 0x07FF) {
+ utflen += 3;
+ } else {
+ utflen += 2;
+ }
}
+ }
+ // write utf length
+ writeByte(utflen);
+ // write utf data
+ for (int i = 0; i < len; i++) {
+ int ch = str.charAt(off + i);
+ if ((ch >= 0x0001) && (ch <= 0x007F)) {
+ writeByte(ch);
+ } else {
+ if (ch > 0x07FF) {
+ writeByte(0xE0 | ((ch >> 12) & 0x0F));
+ writeByte(0x80 | ((ch >> 6) & 0x3F));
+ writeByte(0x80 | ((ch >> 0) & 0x3F));
+ } else {
+ writeByte(0xC0 | ((ch >> 6) & 0x1F));
+ writeByte(0x80 | ((ch >> 0) & 0x3F));
+ }
+ }
+ }
+ }
- private static int indexOfSeparator(String aName) {
- int offset = 0;
- int n = 0;
-
- while (true) {
- n = aName.indexOf('.', offset);
- if (n < 0)
- return -1;
-
- if (n == 0 || aName.charAt(n - 1) != '\\')
- return n;
+ void writeName(String name) {
+ writeName(name, true);
+ }
- offset = n + 1;
- }
+ void writeName(String name, boolean useCompression) {
+ String aName = name;
+ while (true) {
+ int n = indexOfSeparator(aName);
+ if (n < 0) {
+ n = aName.length();
}
-
- void writeQuestion(DNSQuestion question) {
- writeName(question.getName());
- writeShort(question.getRecordType().indexValue());
- writeShort(question.getRecordClass().indexValue());
+ if (n <= 0) {
+ writeByte(0);
+ return;
}
-
- void writeRecord(DNSRecord rec, long now) {
- writeName(rec.getName());
- writeShort(rec.getRecordType().indexValue());
- writeShort(rec.getRecordClass().indexValue() | ((rec.isUnique() && _out.isMulticast()) ? DNSRecordClass.CLASS_UNIQUE : 0));
- writeInt((now == 0) ? rec.getTTL() : rec.getRemainingTTL(now));
-
- // We need to take into account the 2 size bytes
- MessageOutputStream record = new MessageOutputStream(512, _out, _offset + this.size() + 2);
- rec.write(record);
- byte[] byteArray = record.toByteArray();
-
- writeShort(byteArray.length);
- write(byteArray, 0, byteArray.length);
+ String label = aName.substring(0, n).replace("\\.", ".");
+ if (useCompression && USE_DOMAIN_NAME_COMPRESSION) {
+ Integer offset = _out._names.get(aName);
+ if (offset != null) {
+ int val = offset.intValue();
+ writeByte((val >> 8) | 0xC0);
+ writeByte(val & 0xFF);
+ return;
+ }
+ _out._names.put(aName, Integer.valueOf(this.size() + _offset));
+ writeUTF(label, 0, label.length());
+ } else {
+ writeUTF(label, 0, label.length());
}
-
+ aName = aName.substring(n);
+ if (aName.startsWith(".")) {
+ aName = aName.substring(1);
+ }
+ }
}
- /**
- * This can be used to turn off domain name compression. This was helpful for tracking problems interacting with other mdns implementations.
- */
- public static boolean USE_DOMAIN_NAME_COMPRESSION = true;
-
- Map _names;
+ private static int indexOfSeparator(String aName) {
+ int offset = 0;
+ int n = 0;
- private int _maxUDPPayload;
+ while (true) {
+ n = aName.indexOf('.', offset);
+ if (n < 0) return -1;
- private final MessageOutputStream _questionsBytes;
+ if (n == 0 || aName.charAt(n - 1) != '\\') return n;
- private final MessageOutputStream _answersBytes;
-
- private final MessageOutputStream _authoritativeAnswersBytes;
-
- private final MessageOutputStream _additionalsAnswersBytes;
-
- private final static int HEADER_SIZE = 12;
-
- private InetSocketAddress _destination;
-
- /**
- * Create an outgoing multicast query or response.
- *
- * @param flags
- */
- public DNSOutgoing(int flags) {
- this(flags, true, DNSConstants.MAX_MSG_TYPICAL);
+ offset = n + 1;
+ }
}
- /**
- * Create an outgoing query or response.
- *
- * @param flags
- * @param multicast
- * @param senderUDPPayload
- * The sender's UDP payload size is the number of bytes of the largest UDP payload that can be reassembled and delivered in the sender's network stack.
- */
- public DNSOutgoing(int flags, boolean multicast, int senderUDPPayload) {
- super(flags, 0, multicast);
- _names = new HashMap();
- _maxUDPPayload = (senderUDPPayload > 0 ? senderUDPPayload : DNSConstants.MAX_MSG_TYPICAL);
- _questionsBytes = new MessageOutputStream(senderUDPPayload, this);
- _answersBytes = new MessageOutputStream(senderUDPPayload, this);
- _authoritativeAnswersBytes = new MessageOutputStream(senderUDPPayload, this);
- _additionalsAnswersBytes = new MessageOutputStream(senderUDPPayload, this);
+ void writeQuestion(DNSQuestion question) {
+ writeName(question.getName());
+ writeShort(question.getRecordType().indexValue());
+ writeShort(question.getRecordClass().indexValue());
}
- /**
- * Get the forced destination address if a specific one was set.
- *
- * @return a forced destination address or null if no address is forced.
- */
- public InetSocketAddress getDestination() {
- return _destination;
+ void writeRecord(DNSRecord rec, long now) {
+ writeName(rec.getName());
+ writeShort(rec.getRecordType().indexValue());
+ writeShort(
+ rec.getRecordClass().indexValue()
+ | ((rec.isUnique() && _out.isMulticast()) ? DNSRecordClass.CLASS_UNIQUE : 0));
+ writeInt((now == 0) ? rec.getTTL() : rec.getRemainingTTL(now));
+
+ // We need to take into account the 2 size bytes
+ MessageOutputStream record = new MessageOutputStream(512, _out, _offset + this.size() + 2);
+ rec.write(record);
+ byte[] byteArray = record.toByteArray();
+
+ writeShort(byteArray.length);
+ write(byteArray, 0, byteArray.length);
}
-
- /**
- * Force a specific destination address if packet is sent.
- *
- * @param destination
- * Set a destination address a packet should be sent to (instead the default one). You could use null to unset the forced destination.
- */
- public void setDestination(InetSocketAddress destination) {
- _destination = destination;
- }
-
- /**
- * Return the number of byte available in the message.
- *
- * @return available space
- */
- public int availableSpace() {
- return _maxUDPPayload - HEADER_SIZE - _questionsBytes.size() - _answersBytes.size() - _authoritativeAnswersBytes.size() - _additionalsAnswersBytes.size();
+ }
+
+ /**
+ * This can be used to turn off domain name compression. This was helpful for tracking problems
+ * interacting with other mdns implementations.
+ */
+ public static boolean USE_DOMAIN_NAME_COMPRESSION = true;
+
+ Map _names;
+
+ private int _maxUDPPayload;
+
+ private final MessageOutputStream _questionsBytes;
+
+ private final MessageOutputStream _answersBytes;
+
+ private final MessageOutputStream _authoritativeAnswersBytes;
+
+ private final MessageOutputStream _additionalsAnswersBytes;
+
+ private static final int HEADER_SIZE = 12;
+
+ private InetSocketAddress _destination;
+
+ /**
+ * Create an outgoing multicast query or response.
+ *
+ * @param flags
+ */
+ public DNSOutgoing(int flags) {
+ this(flags, true, DNSConstants.MAX_MSG_TYPICAL);
+ }
+
+ /**
+ * Create an outgoing query or response.
+ *
+ * @param flags
+ * @param multicast
+ * @param senderUDPPayload The sender's UDP payload size is the number of bytes of the largest UDP
+ * payload that can be reassembled and delivered in the sender's network stack.
+ */
+ public DNSOutgoing(int flags, boolean multicast, int senderUDPPayload) {
+ super(flags, 0, multicast);
+ _names = new HashMap();
+ _maxUDPPayload = (senderUDPPayload > 0 ? senderUDPPayload : DNSConstants.MAX_MSG_TYPICAL);
+ _questionsBytes = new MessageOutputStream(senderUDPPayload, this);
+ _answersBytes = new MessageOutputStream(senderUDPPayload, this);
+ _authoritativeAnswersBytes = new MessageOutputStream(senderUDPPayload, this);
+ _additionalsAnswersBytes = new MessageOutputStream(senderUDPPayload, this);
+ }
+
+ /**
+ * Get the forced destination address if a specific one was set.
+ *
+ * @return a forced destination address or null if no address is forced.
+ */
+ public InetSocketAddress getDestination() {
+ return _destination;
+ }
+
+ /**
+ * Force a specific destination address if packet is sent.
+ *
+ * @param destination Set a destination address a packet should be sent to (instead the default
+ * one). You could use null to unset the forced destination.
+ */
+ public void setDestination(InetSocketAddress destination) {
+ _destination = destination;
+ }
+
+ /**
+ * Return the number of byte available in the message.
+ *
+ * @return available space
+ */
+ public int availableSpace() {
+ return _maxUDPPayload
+ - HEADER_SIZE
+ - _questionsBytes.size()
+ - _answersBytes.size()
+ - _authoritativeAnswersBytes.size()
+ - _additionalsAnswersBytes.size();
+ }
+
+ /**
+ * Add a question to the message.
+ *
+ * @param rec
+ * @exception IOException
+ */
+ public void addQuestion(DNSQuestion rec) throws IOException {
+ MessageOutputStream record = new MessageOutputStream(512, this);
+ record.writeQuestion(rec);
+ byte[] byteArray = record.toByteArray();
+ record.close();
+ if (byteArray.length < this.availableSpace()) {
+ _questions.add(rec);
+ _questionsBytes.write(byteArray, 0, byteArray.length);
+ } else {
+ throw new IOException("message full");
}
-
- /**
- * Add a question to the message.
- *
- * @param rec
- * @exception IOException
- */
- public void addQuestion(DNSQuestion rec) throws IOException {
+ }
+
+ /**
+ * Add an answer if it is not suppressed.
+ *
+ * @param rec
+ * @exception IOException
+ */
+ public void addAnswer(DNSRecord rec) throws IOException {
+ this.addAnswer(rec, 0);
+ }
+
+ /**
+ * Add an answer to the message.
+ *
+ * @param rec
+ * @param now
+ * @exception IOException
+ */
+ public void addAnswer(DNSRecord rec, long now) throws IOException {
+ if (rec != null) {
+ if ((now == 0) || !rec.isExpired(now)) {
MessageOutputStream record = new MessageOutputStream(512, this);
- record.writeQuestion(rec);
+ record.writeRecord(rec, now);
byte[] byteArray = record.toByteArray();
record.close();
if (byteArray.length < this.availableSpace()) {
- _questions.add(rec);
- _questionsBytes.write(byteArray, 0, byteArray.length);
+ _answers.add(rec);
+ _answersBytes.write(byteArray, 0, byteArray.length);
} else {
- throw new IOException("message full");
+ throw new IOException("message full");
}
+ }
}
-
- /**
- * Add an answer if it is not suppressed.
- *
- * @param rec
- * @exception IOException
- */
- public void addAnswer(DNSRecord rec) throws IOException {
- this.addAnswer(rec, 0);
+ }
+
+ /**
+ * Builds the final message buffer to be send and returns it.
+ *
+ * @return bytes to send.
+ */
+ public byte[] data() {
+ long now = System.currentTimeMillis(); // System.currentTimeMillis()
+ _names.clear();
+
+ MessageOutputStream message = new MessageOutputStream(_maxUDPPayload, this);
+ message.writeShort(_multicast ? 0 : this.getId());
+ message.writeShort(this.getFlags());
+ message.writeShort(this.getNumberOfQuestions());
+ message.writeShort(this.getNumberOfAnswers());
+ message.writeShort(this.getNumberOfAuthorities());
+ message.writeShort(this.getNumberOfAdditionals());
+ for (DNSQuestion question : _questions) {
+ message.writeQuestion(question);
}
-
- /**
- * Add an answer to the message.
- *
- * @param rec
- * @param now
- * @exception IOException
- */
- public void addAnswer(DNSRecord rec, long now) throws IOException {
- if (rec != null) {
- if ((now == 0) || !rec.isExpired(now)) {
- MessageOutputStream record = new MessageOutputStream(512, this);
- record.writeRecord(rec, now);
- byte[] byteArray = record.toByteArray();
- record.close();
- if (byteArray.length < this.availableSpace()) {
- _answers.add(rec);
- _answersBytes.write(byteArray, 0, byteArray.length);
- } else {
- throw new IOException("message full");
- }
- }
- }
+ for (DNSRecord record : _answers) {
+ message.writeRecord(record, now);
}
-
- /**
- * Builds the final message buffer to be send and returns it.
- *
- * @return bytes to send.
- */
- public byte[] data() {
- long now = System.currentTimeMillis(); // System.currentTimeMillis()
- _names.clear();
-
- MessageOutputStream message = new MessageOutputStream(_maxUDPPayload, this);
- message.writeShort(_multicast ? 0 : this.getId());
- message.writeShort(this.getFlags());
- message.writeShort(this.getNumberOfQuestions());
- message.writeShort(this.getNumberOfAnswers());
- message.writeShort(this.getNumberOfAuthorities());
- message.writeShort(this.getNumberOfAdditionals());
- for (DNSQuestion question : _questions) {
- message.writeQuestion(question);
- }
- for (DNSRecord record : _answers) {
- message.writeRecord(record, now);
- }
- for (DNSRecord record : _authoritativeAnswers) {
- message.writeRecord(record, now);
- }
- for (DNSRecord record : _additionals) {
- message.writeRecord(record, now);
- }
- byte[] result = message.toByteArray();
- try {
- message.close();
- } catch (IOException exception) {}
- return result;
+ for (DNSRecord record : _authoritativeAnswers) {
+ message.writeRecord(record, now);
}
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append(isQuery() ? "dns[query:" : "dns[response:");
- sb.append(" id=0x");
- sb.append(Integer.toHexString(this.getId()));
- if (this.getFlags() != 0) {
- sb.append(", flags=0x");
- sb.append(Integer.toHexString(this.getFlags()));
- if (this.isResponse()) {
- sb.append(":r");
- }
- if (this.isAuthoritativeAnswer()) {
- sb.append(":aa");
- }
- if (this.isTruncated()) {
- sb.append(":tc");
- }
- }
- if (this.getNumberOfQuestions() > 0) {
- sb.append(", questions=");
- sb.append(this.getNumberOfQuestions());
- }
- if (this.getNumberOfAnswers() > 0) {
- sb.append(", answers=");
- sb.append(this.getNumberOfAnswers());
- }
- if (this.getNumberOfAuthorities() > 0) {
- sb.append(", authorities=");
- sb.append(this.getNumberOfAuthorities());
- }
- if (this.getNumberOfAdditionals() > 0) {
- sb.append(", additionals=");
- sb.append(this.getNumberOfAdditionals());
- }
- if (this.getNumberOfQuestions() > 0) {
- sb.append("\nquestions:");
- for (DNSQuestion question : _questions) {
- sb.append("\n\t");
- sb.append(question);
- }
- }
- if (this.getNumberOfAnswers() > 0) {
- sb.append("\nanswers:");
- for (DNSRecord record : _answers) {
- sb.append("\n\t");
- sb.append(record);
- }
- }
- if (this.getNumberOfAuthorities() > 0) {
- sb.append("\nauthorities:");
- for (DNSRecord record : _authoritativeAnswers) {
- sb.append("\n\t");
- sb.append(record);
- }
- }
- if (this.getNumberOfAdditionals() > 0) {
- sb.append("\nadditionals:");
- for (DNSRecord record : _additionals) {
- sb.append("\n\t");
- sb.append(record);
- }
- }
- sb.append("\nnames=");
- sb.append(_names);
- sb.append("]");
- return sb.toString();
+ for (DNSRecord record : _additionals) {
+ message.writeRecord(record, now);
}
-
- /**
- * @return the maxUDPPayload
- */
- public int getMaxUDPPayload() {
- return this._maxUDPPayload;
+ byte[] result = message.toByteArray();
+ try {
+ message.close();
+ } catch (IOException exception) {
}
-
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append(isQuery() ? "dns[query:" : "dns[response:");
+ sb.append(" id=0x");
+ sb.append(Integer.toHexString(this.getId()));
+ if (this.getFlags() != 0) {
+ sb.append(", flags=0x");
+ sb.append(Integer.toHexString(this.getFlags()));
+ if (this.isResponse()) {
+ sb.append(":r");
+ }
+ if (this.isAuthoritativeAnswer()) {
+ sb.append(":aa");
+ }
+ if (this.isTruncated()) {
+ sb.append(":tc");
+ }
+ }
+ if (this.getNumberOfQuestions() > 0) {
+ sb.append(", questions=");
+ sb.append(this.getNumberOfQuestions());
+ }
+ if (this.getNumberOfAnswers() > 0) {
+ sb.append(", answers=");
+ sb.append(this.getNumberOfAnswers());
+ }
+ if (this.getNumberOfAuthorities() > 0) {
+ sb.append(", authorities=");
+ sb.append(this.getNumberOfAuthorities());
+ }
+ if (this.getNumberOfAdditionals() > 0) {
+ sb.append(", additionals=");
+ sb.append(this.getNumberOfAdditionals());
+ }
+ if (this.getNumberOfQuestions() > 0) {
+ sb.append("\nquestions:");
+ for (DNSQuestion question : _questions) {
+ sb.append("\n\t");
+ sb.append(question);
+ }
+ }
+ if (this.getNumberOfAnswers() > 0) {
+ sb.append("\nanswers:");
+ for (DNSRecord record : _answers) {
+ sb.append("\n\t");
+ sb.append(record);
+ }
+ }
+ if (this.getNumberOfAuthorities() > 0) {
+ sb.append("\nauthorities:");
+ for (DNSRecord record : _authoritativeAnswers) {
+ sb.append("\n\t");
+ sb.append(record);
+ }
+ }
+ if (this.getNumberOfAdditionals() > 0) {
+ sb.append("\nadditionals:");
+ for (DNSRecord record : _additionals) {
+ sb.append("\n\t");
+ sb.append(record);
+ }
+ }
+ sb.append("\nnames=");
+ sb.append(_names);
+ sb.append("]");
+ return sb.toString();
+ }
+
+ /**
+ * @return the maxUDPPayload
+ */
+ public int getMaxUDPPayload() {
+ return this._maxUDPPayload;
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSQuestion.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSQuestion.java
index 789aaf418..ed87bb56f 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSQuestion.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSQuestion.java
@@ -4,87 +4,89 @@
package io.libp2p.discovery.mdns.impl;
-import java.util.Set;
-
+import io.libp2p.discovery.mdns.ServiceInfo;
+import io.libp2p.discovery.mdns.impl.constants.DNSConstants;
import io.libp2p.discovery.mdns.impl.constants.DNSRecordClass;
import io.libp2p.discovery.mdns.impl.constants.DNSRecordType;
+import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.libp2p.discovery.mdns.ServiceInfo;
-import io.libp2p.discovery.mdns.impl.constants.DNSConstants;
-
/**
* A DNS question.
*
* @author Arthur van Hoff, Pierre Frisch
*/
public class DNSQuestion extends DNSEntry {
- private static Logger logger = LoggerFactory.getLogger(DNSQuestion.class.getName());
-
- /**
- * Pointer question.
- */
- private static class Pointer extends DNSQuestion {
- Pointer(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
- super(name, type, recordClass, unique);
- }
+ private static Logger logger = LoggerFactory.getLogger(DNSQuestion.class.getName());
- @Override
- public void addAnswers(JmDNSImpl jmDNSImpl, Set answers) {
- // find matching services
- for (ServiceInfo serviceInfo : jmDNSImpl.getServices().values()) {
- this.addAnswersForServiceInfo(jmDNSImpl, answers, (ServiceInfoImpl) serviceInfo);
- }
- }
+ /** Pointer question. */
+ private static class Pointer extends DNSQuestion {
+ Pointer(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+ super(name, type, recordClass, unique);
}
- DNSQuestion(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
- super(name, type, recordClass, unique);
+ @Override
+ public void addAnswers(JmDNSImpl jmDNSImpl, Set answers) {
+ // find matching services
+ for (ServiceInfo serviceInfo : jmDNSImpl.getServices().values()) {
+ this.addAnswersForServiceInfo(jmDNSImpl, answers, (ServiceInfoImpl) serviceInfo);
+ }
}
+ }
- /**
- * Create a question.
- *
- * @param name
- * DNS name to be resolved
- * @param type
- * Record type to resolve
- * @param recordClass
- * Record class to resolve
- * @param unique
- * Request unicast response (Currently not supported in this implementation)
- * @return new question
- */
- public static DNSQuestion newQuestion(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
- return (type == DNSRecordType.TYPE_PTR)
- ? new Pointer(name, type, recordClass, unique)
- : null;
- }
+ DNSQuestion(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+ super(name, type, recordClass, unique);
+ }
- /**
- * Adds answers to the list for our question.
- *
- * @param jmDNSImpl
- * DNS holding the records
- * @param answers
- * List of previous answer to append.
- */
- public void addAnswers(JmDNSImpl jmDNSImpl, Set answers) {
- // By default we do nothing
- }
+ /**
+ * Create a question.
+ *
+ * @param name DNS name to be resolved
+ * @param type Record type to resolve
+ * @param recordClass Record class to resolve
+ * @param unique Request unicast response (Currently not supported in this implementation)
+ * @return new question
+ */
+ public static DNSQuestion newQuestion(
+ String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+ return (type == DNSRecordType.TYPE_PTR) ? new Pointer(name, type, recordClass, unique) : null;
+ }
- protected void addAnswersForServiceInfo(JmDNSImpl jmDNSImpl, Set answers, ServiceInfoImpl info) {
- if (info != null) {
- if (this.getName().equalsIgnoreCase(info.getQualifiedName()) || this.getName().equalsIgnoreCase(info.getType()) || this.getName().equalsIgnoreCase(info.getTypeWithSubtype())) {
- answers.addAll(info.answers(this.getRecordClass(), DNSRecordClass.UNIQUE, DNSConstants.DNS_TTL, jmDNSImpl.getLocalHost()));
- }
- logger.debug("{} DNSQuestion({}).addAnswersForServiceInfo(): info: {}\n{}", jmDNSImpl.getName(), this.getName(), info, answers);
- }
- }
+ /**
+ * Adds answers to the list for our question.
+ *
+ * @param jmDNSImpl DNS holding the records
+ * @param answers List of previous answer to append.
+ */
+ public void addAnswers(JmDNSImpl jmDNSImpl, Set answers) {
+ // By default we do nothing
+ }
- @Override
- public boolean isExpired(long now) {
- return false;
+ protected void addAnswersForServiceInfo(
+ JmDNSImpl jmDNSImpl, Set answers, ServiceInfoImpl info) {
+ if (info != null) {
+ if (this.getName().equalsIgnoreCase(info.getQualifiedName())
+ || this.getName().equalsIgnoreCase(info.getType())
+ || this.getName().equalsIgnoreCase(info.getTypeWithSubtype())) {
+ answers.addAll(
+ info.answers(
+ this.getRecordClass(),
+ DNSRecordClass.UNIQUE,
+ DNSConstants.DNS_TTL,
+ jmDNSImpl.getLocalHost()));
+ }
+ logger.debug(
+ "{} DNSQuestion({}).addAnswersForServiceInfo(): info: {}\n{}",
+ jmDNSImpl.getName(),
+ this.getName(),
+ info,
+ answers);
}
-}
\ No newline at end of file
+ }
+
+ @Override
+ public boolean isExpired(long now) {
+ return false;
+ }
+}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSRecord.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSRecord.java
index 6e75a6c47..6201af584 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSRecord.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/DNSRecord.java
@@ -8,9 +8,6 @@
import io.libp2p.discovery.mdns.impl.constants.DNSRecordClass;
import io.libp2p.discovery.mdns.impl.constants.DNSRecordType;
import io.libp2p.discovery.mdns.impl.util.ByteWrangler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
@@ -18,7 +15,8 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Objects;
-
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* DNS record
@@ -26,358 +24,378 @@
* @author Arthur van Hoff, Rick Blair, Werner Randelshofer, Pierre Frisch
*/
public abstract class DNSRecord extends DNSEntry {
- private static Logger logger = LoggerFactory.getLogger(DNSRecord.class.getName());
-
- private int _ttl;
- private long _created;
-
- /**
- * Create a DNSRecord with a name, type, class, and ttl.
- */
- DNSRecord(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique, int ttl) {
- super(name, type, recordClass, unique);
- this._ttl = ttl;
- this._created = System.currentTimeMillis();
+ private static Logger logger = LoggerFactory.getLogger(DNSRecord.class.getName());
+
+ private int _ttl;
+ private long _created;
+
+ /** Create a DNSRecord with a name, type, class, and ttl. */
+ DNSRecord(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique, int ttl) {
+ super(name, type, recordClass, unique);
+ this._ttl = ttl;
+ this._created = System.currentTimeMillis();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return (other instanceof DNSRecord) && super.equals(other) && sameValue((DNSRecord) other);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), _ttl, _created);
+ }
+
+ abstract boolean sameValue(DNSRecord other);
+
+ /** Get the expiration time of this record. */
+ long getExpirationTime(int percent) {
+ // ttl is in seconds the constant 10 is 1000 ms / 100 %
+ return _created + (percent * ((long) _ttl) * 10L);
+ }
+
+ /** Get the remaining TTL for this record. */
+ int getRemainingTTL(long now) {
+ return (int) Math.max(0, (getExpirationTime(100) - now) / 1000);
+ }
+
+ @Override
+ public boolean isExpired(long now) {
+ return getExpirationTime(100) <= now;
+ }
+
+ abstract void write(MessageOutputStream out);
+
+ public static class IPv4Address extends Address {
+ IPv4Address(
+ String name, DNSRecordClass recordClass, boolean unique, int ttl, InetAddress addr) {
+ super(name, DNSRecordType.TYPE_A, recordClass, unique, ttl, addr);
}
- @Override
- public boolean equals(Object other) {
- return (other instanceof DNSRecord) && super.equals(other) && sameValue((DNSRecord) other);
+ IPv4Address(
+ String name, DNSRecordClass recordClass, boolean unique, int ttl, byte[] rawAddress) {
+ super(name, DNSRecordType.TYPE_A, recordClass, unique, ttl, rawAddress);
}
@Override
- public int hashCode() {
- return Objects.hash(super.hashCode(), _ttl, _created);
+ void write(MessageOutputStream out) {
+ if (_addr != null) {
+ byte[] buffer = _addr.getAddress();
+ // If we have a type A records we should answer with a IPv4 address
+ if (_addr instanceof Inet4Address) {
+ // All is good
+ } else {
+ // Get the last four bytes
+ byte[] tempbuffer = buffer;
+ buffer = new byte[4];
+ System.arraycopy(tempbuffer, 12, buffer, 0, 4);
+ }
+ int length = buffer.length;
+ out.writeBytes(buffer, 0, length);
+ }
}
+ }
- abstract boolean sameValue(DNSRecord other);
-
- /**
- * Get the expiration time of this record.
- */
- long getExpirationTime(int percent) {
- // ttl is in seconds the constant 10 is 1000 ms / 100 %
- return _created + (percent * ((long)_ttl) * 10L);
+ public static class IPv6Address extends Address {
+ IPv6Address(
+ String name, DNSRecordClass recordClass, boolean unique, int ttl, InetAddress addr) {
+ super(name, DNSRecordType.TYPE_AAAA, recordClass, unique, ttl, addr);
}
- /**
- * Get the remaining TTL for this record.
- */
- int getRemainingTTL(long now) {
- return (int) Math.max(0, (getExpirationTime(100) - now) / 1000);
+ IPv6Address(
+ String name, DNSRecordClass recordClass, boolean unique, int ttl, byte[] rawAddress) {
+ super(name, DNSRecordType.TYPE_AAAA, recordClass, unique, ttl, rawAddress);
}
@Override
- public boolean isExpired(long now) {
- return getExpirationTime(100) <= now;
- }
-
- abstract void write(MessageOutputStream out);
-
- public static class IPv4Address extends Address {
- IPv4Address(String name, DNSRecordClass recordClass, boolean unique, int ttl, InetAddress addr) {
- super(name, DNSRecordType.TYPE_A, recordClass, unique, ttl, addr);
- }
-
- IPv4Address(String name, DNSRecordClass recordClass, boolean unique, int ttl, byte[] rawAddress) {
- super(name, DNSRecordType.TYPE_A, recordClass, unique, ttl, rawAddress);
- }
-
- @Override
- void write(MessageOutputStream out) {
- if (_addr != null) {
- byte[] buffer = _addr.getAddress();
- // If we have a type A records we should answer with a IPv4 address
- if (_addr instanceof Inet4Address) {
- // All is good
- } else {
- // Get the last four bytes
- byte[] tempbuffer = buffer;
- buffer = new byte[4];
- System.arraycopy(tempbuffer, 12, buffer, 0, 4);
- }
- int length = buffer.length;
- out.writeBytes(buffer, 0, length);
+ void write(MessageOutputStream out) {
+ if (_addr != null) {
+ byte[] buffer = _addr.getAddress();
+ // If we have a type AAAA records we should answer with a IPv6 address
+ if (_addr instanceof Inet4Address) {
+ byte[] tempbuffer = buffer;
+ buffer = new byte[16];
+ for (int i = 0; i < 16; i++) {
+ if (i < 11) {
+ buffer[i] = tempbuffer[i - 12];
+ } else {
+ buffer[i] = 0;
}
+ }
}
+ int length = buffer.length;
+ out.writeBytes(buffer, 0, length);
+ }
}
-
- public static class IPv6Address extends Address {
- IPv6Address(String name, DNSRecordClass recordClass, boolean unique, int ttl, InetAddress addr) {
- super(name, DNSRecordType.TYPE_AAAA, recordClass, unique, ttl, addr);
- }
-
- IPv6Address(String name, DNSRecordClass recordClass, boolean unique, int ttl, byte[] rawAddress) {
- super(name, DNSRecordType.TYPE_AAAA, recordClass, unique, ttl, rawAddress);
- }
-
- @Override
- void write(MessageOutputStream out) {
- if (_addr != null) {
- byte[] buffer = _addr.getAddress();
- // If we have a type AAAA records we should answer with a IPv6 address
- if (_addr instanceof Inet4Address) {
- byte[] tempbuffer = buffer;
- buffer = new byte[16];
- for (int i = 0; i < 16; i++) {
- if (i < 11) {
- buffer[i] = tempbuffer[i - 12];
- } else {
- buffer[i] = 0;
- }
- }
- }
- int length = buffer.length;
- out.writeBytes(buffer, 0, length);
- }
- }
+ }
+
+ /** Address record. */
+ public abstract static class Address extends DNSRecord {
+ InetAddress _addr;
+
+ protected Address(
+ String name,
+ DNSRecordType type,
+ DNSRecordClass recordClass,
+ boolean unique,
+ int ttl,
+ InetAddress addr) {
+ super(name, type, recordClass, unique, ttl);
+ this._addr = addr;
}
- /**
- * Address record.
- */
- public static abstract class Address extends DNSRecord {
- InetAddress _addr;
-
- protected Address(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique, int ttl, InetAddress addr) {
- super(name, type, recordClass, unique, ttl);
- this._addr = addr;
- }
+ protected Address(
+ String name,
+ DNSRecordType type,
+ DNSRecordClass recordClass,
+ boolean unique,
+ int ttl,
+ byte[] rawAddress) {
+ super(name, type, recordClass, unique, ttl);
+ try {
+ this._addr = InetAddress.getByAddress(rawAddress);
+ } catch (UnknownHostException exception) {
+ logger.warn("Address() exception ", exception);
+ }
+ }
- protected Address(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique, int ttl, byte[] rawAddress) {
- super(name, type, recordClass, unique, ttl);
- try {
- this._addr = InetAddress.getByAddress(rawAddress);
- } catch (UnknownHostException exception) {
- logger.warn("Address() exception ", exception);
- }
+ @Override
+ boolean sameValue(DNSRecord other) {
+ try {
+ if (!(other instanceof Address)) {
+ return false;
}
-
- @Override
- boolean sameValue(DNSRecord other) {
- try {
- if (!(other instanceof Address)) {
- return false;
- }
- Address address = (Address) other;
- if ((this.getAddress() == null) && (address.getAddress() != null)) {
- return false;
- }
- return this.getAddress().equals(address.getAddress());
- } catch (Exception e) {
- logger.info("Failed to compare addresses of DNSRecords", e);
- return false;
- }
- }
-
- public InetAddress getAddress() {
- return _addr;
+ Address address = (Address) other;
+ if ((this.getAddress() == null) && (address.getAddress() != null)) {
+ return false;
}
+ return this.getAddress().equals(address.getAddress());
+ } catch (Exception e) {
+ logger.info("Failed to compare addresses of DNSRecords", e);
+ return false;
+ }
+ }
- /**
- * Creates a byte array representation of this record. This is needed for tie-break tests according to draft-cheshire-dnsext-multicastdns-04.txt chapter 9.2.
- */
- @Override
- protected void toByteArray(DataOutputStream dout) throws IOException {
- super.toByteArray(dout);
- byte[] buffer = this.getAddress().getAddress();
- for (int i = 0; i < buffer.length; i++) {
- dout.writeByte(buffer[i]);
- }
- }
+ public InetAddress getAddress() {
+ return _addr;
}
/**
- * Pointer record.
+ * Creates a byte array representation of this record. This is needed for tie-break tests
+ * according to draft-cheshire-dnsext-multicastdns-04.txt chapter 9.2.
*/
- public static class Pointer extends DNSRecord {
- private final String _alias;
-
- public Pointer(String name, DNSRecordClass recordClass, boolean unique, int ttl, String alias) {
- super(name, DNSRecordType.TYPE_PTR, recordClass, unique, ttl);
- this._alias = alias;
- }
-
- @Override
- public boolean isSameEntry(DNSEntry entry) {
- return super.isSameEntry(entry) && (entry instanceof Pointer) && this.sameValue((Pointer) entry);
- }
+ @Override
+ protected void toByteArray(DataOutputStream dout) throws IOException {
+ super.toByteArray(dout);
+ byte[] buffer = this.getAddress().getAddress();
+ for (int i = 0; i < buffer.length; i++) {
+ dout.writeByte(buffer[i]);
+ }
+ }
+ }
- @Override
- void write(MessageOutputStream out) {
- out.writeName(_alias);
- }
+ /** Pointer record. */
+ public static class Pointer extends DNSRecord {
+ private final String _alias;
- @Override
- boolean sameValue(DNSRecord other) {
- if (!(other instanceof Pointer)) {
- return false;
- }
- Pointer pointer = (Pointer) other;
- if ((_alias == null) && (pointer._alias != null)) {
- return false;
- }
- return _alias.equals(pointer._alias);
- }
+ public Pointer(String name, DNSRecordClass recordClass, boolean unique, int ttl, String alias) {
+ super(name, DNSRecordType.TYPE_PTR, recordClass, unique, ttl);
+ this._alias = alias;
}
- public static class Text extends DNSRecord {
- private final byte[] _text;
+ @Override
+ public boolean isSameEntry(DNSEntry entry) {
+ return super.isSameEntry(entry)
+ && (entry instanceof Pointer)
+ && this.sameValue((Pointer) entry);
+ }
- public Text(String name, DNSRecordClass recordClass, boolean unique, int ttl, byte text[]) {
- super(name, DNSRecordType.TYPE_TXT, recordClass, unique, ttl);
- this._text = (text != null && text.length > 0 ? text : ByteWrangler.EMPTY_TXT);
- }
+ @Override
+ void write(MessageOutputStream out) {
+ out.writeName(_alias);
+ }
- /**
- * @return the text
- */
- public byte[] getText() {
- return this._text;
- }
+ @Override
+ boolean sameValue(DNSRecord other) {
+ if (!(other instanceof Pointer)) {
+ return false;
+ }
+ Pointer pointer = (Pointer) other;
+ if ((_alias == null) && (pointer._alias != null)) {
+ return false;
+ }
+ return _alias.equals(pointer._alias);
+ }
+ }
- @Override
- void write(MessageOutputStream out) {
- out.writeBytes(_text, 0, _text.length);
- }
+ public static class Text extends DNSRecord {
+ private final byte[] _text;
- @Override
- boolean sameValue(DNSRecord other) {
- if (!(other instanceof Text)) {
- return false;
- }
- Text txt = (Text) other;
- if ((_text == null) && (txt._text != null)) {
- return false;
- }
- if (txt._text.length != _text.length) {
- return false;
- }
- for (int i = _text.length; i-- > 0;) {
- if (txt._text[i] != _text[i]) {
- return false;
- }
- }
- return true;
- }
+ public Text(String name, DNSRecordClass recordClass, boolean unique, int ttl, byte text[]) {
+ super(name, DNSRecordType.TYPE_TXT, recordClass, unique, ttl);
+ this._text = (text != null && text.length > 0 ? text : ByteWrangler.EMPTY_TXT);
}
/**
- * Service record.
+ * @return the text
*/
- public static class Service extends DNSRecord {
- private final int _priority;
- private final int _weight;
- private final int _port;
- private final String _server;
-
- public Service(String name, DNSRecordClass recordClass, boolean unique, int ttl, int priority, int weight, int port, String server) {
- super(name, DNSRecordType.TYPE_SRV, recordClass, unique, ttl);
- this._priority = priority;
- this._weight = weight;
- this._port = port;
- this._server = server;
- }
+ public byte[] getText() {
+ return this._text;
+ }
- @Override
- void write(MessageOutputStream out) {
- out.writeShort(_priority);
- out.writeShort(_weight);
- out.writeShort(_port);
- if (DNSIncoming.USE_DOMAIN_NAME_FORMAT_FOR_SRV_TARGET) {
- out.writeName(_server);
- } else {
- // [PJYF Nov 13 2010] Do we still need this? This looks really bad. All label are supposed to start by a length.
- out.writeUTF(_server, 0, _server.length());
+ @Override
+ void write(MessageOutputStream out) {
+ out.writeBytes(_text, 0, _text.length);
+ }
- // add a zero byte to the end just to be safe, this is the strange form
- // used by the BonjourConformanceTest
- out.writeByte(0);
- }
+ @Override
+ boolean sameValue(DNSRecord other) {
+ if (!(other instanceof Text)) {
+ return false;
+ }
+ Text txt = (Text) other;
+ if ((_text == null) && (txt._text != null)) {
+ return false;
+ }
+ if (txt._text.length != _text.length) {
+ return false;
+ }
+ for (int i = _text.length; i-- > 0; ) {
+ if (txt._text[i] != _text[i]) {
+ return false;
}
+ }
+ return true;
+ }
+ }
+
+ /** Service record. */
+ public static class Service extends DNSRecord {
+ private final int _priority;
+ private final int _weight;
+ private final int _port;
+ private final String _server;
+
+ public Service(
+ String name,
+ DNSRecordClass recordClass,
+ boolean unique,
+ int ttl,
+ int priority,
+ int weight,
+ int port,
+ String server) {
+ super(name, DNSRecordType.TYPE_SRV, recordClass, unique, ttl);
+ this._priority = priority;
+ this._weight = weight;
+ this._port = port;
+ this._server = server;
+ }
- @Override
- protected void toByteArray(DataOutputStream dout) throws IOException {
- super.toByteArray(dout);
- dout.writeShort(_priority);
- dout.writeShort(_weight);
- dout.writeShort(_port);
- try {
- dout.write(_server.getBytes("UTF-8"));
- } catch (UnsupportedEncodingException exception) {
- /* UTF-8 is always present */
- }
- }
+ @Override
+ void write(MessageOutputStream out) {
+ out.writeShort(_priority);
+ out.writeShort(_weight);
+ out.writeShort(_port);
+ if (DNSIncoming.USE_DOMAIN_NAME_FORMAT_FOR_SRV_TARGET) {
+ out.writeName(_server);
+ } else {
+ // [PJYF Nov 13 2010] Do we still need this? This looks really bad. All label are supposed
+ // to start by a length.
+ out.writeUTF(_server, 0, _server.length());
+
+ // add a zero byte to the end just to be safe, this is the strange form
+ // used by the BonjourConformanceTest
+ out.writeByte(0);
+ }
+ }
- /**
- * @return the weight
- */
- public int getWeight() {
- return this._weight;
- }
+ @Override
+ protected void toByteArray(DataOutputStream dout) throws IOException {
+ super.toByteArray(dout);
+ dout.writeShort(_priority);
+ dout.writeShort(_weight);
+ dout.writeShort(_port);
+ try {
+ dout.write(_server.getBytes("UTF-8"));
+ } catch (UnsupportedEncodingException exception) {
+ /* UTF-8 is always present */
+ }
+ }
- /**
- * @return the port
- */
- public int getPort() {
- return this._port;
- }
+ /**
+ * @return the weight
+ */
+ public int getWeight() {
+ return this._weight;
+ }
- @Override
- boolean sameValue(DNSRecord other) {
- if (!(other instanceof Service)) {
- return false;
- }
- Service s = (Service) other;
- return (_priority == s._priority) && (_weight == s._weight) && (_port == s._port) && _server.equals(s._server);
- }
+ /**
+ * @return the port
+ */
+ public int getPort() {
+ return this._port;
}
- public static class HostInformation extends DNSRecord {
- String _os;
- String _cpu;
-
- /**
- * @param name
- * @param recordClass
- * @param unique
- * @param ttl
- * @param cpu
- * @param os
- */
- public HostInformation(String name, DNSRecordClass recordClass, boolean unique, int ttl, String cpu, String os) {
- super(name, DNSRecordType.TYPE_HINFO, recordClass, unique, ttl);
- _cpu = cpu;
- _os = os;
- }
+ @Override
+ boolean sameValue(DNSRecord other) {
+ if (!(other instanceof Service)) {
+ return false;
+ }
+ Service s = (Service) other;
+ return (_priority == s._priority)
+ && (_weight == s._weight)
+ && (_port == s._port)
+ && _server.equals(s._server);
+ }
+ }
- /*
- * (non-Javadoc)
- * @see javax.jmdns.impl.DNSRecord#sameValue(javax.jmdns.impl.DNSRecord)
- */
- @Override
- boolean sameValue(DNSRecord other) {
- if (!(other instanceof HostInformation)) {
- return false;
- }
- HostInformation hinfo = (HostInformation) other;
- if ((_cpu == null) && (hinfo._cpu != null)) {
- return false;
- }
- if ((_os == null) && (hinfo._os != null)) {
- return false;
- }
- return _cpu.equals(hinfo._cpu) && _os.equals(hinfo._os);
- }
+ public static class HostInformation extends DNSRecord {
+ String _os;
+ String _cpu;
- @Override
- void write(MessageOutputStream out) {
- String hostInfo = _cpu + " " + _os;
- out.writeUTF(hostInfo, 0, hostInfo.length());
- }
+ /**
+ * @param name
+ * @param recordClass
+ * @param unique
+ * @param ttl
+ * @param cpu
+ * @param os
+ */
+ public HostInformation(
+ String name, DNSRecordClass recordClass, boolean unique, int ttl, String cpu, String os) {
+ super(name, DNSRecordType.TYPE_HINFO, recordClass, unique, ttl);
+ _cpu = cpu;
+ _os = os;
}
- public int getTTL() {
- return _ttl;
+ /*
+ * (non-Javadoc)
+ * @see javax.jmdns.impl.DNSRecord#sameValue(javax.jmdns.impl.DNSRecord)
+ */
+ @Override
+ boolean sameValue(DNSRecord other) {
+ if (!(other instanceof HostInformation)) {
+ return false;
+ }
+ HostInformation hinfo = (HostInformation) other;
+ if ((_cpu == null) && (hinfo._cpu != null)) {
+ return false;
+ }
+ if ((_os == null) && (hinfo._os != null)) {
+ return false;
+ }
+ return _cpu.equals(hinfo._cpu) && _os.equals(hinfo._os);
+ }
+
+ @Override
+ void write(MessageOutputStream out) {
+ String hostInfo = _cpu + " " + _os;
+ out.writeUTF(hostInfo, 0, hostInfo.length());
}
+ }
+
+ public int getTTL() {
+ return _ttl;
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/HostInfo.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/HostInfo.java
index c93d6d983..3db3ca6b6 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/HostInfo.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/HostInfo.java
@@ -7,7 +7,6 @@
import java.io.IOException;
import java.net.*;
import java.util.*;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -17,185 +16,192 @@
* @author Pierre Frisch, Werner Randelshofer
*/
public class HostInfo {
- private static Logger logger = LoggerFactory.getLogger(HostInfo.class.getName());
-
- protected String _name;
-
- protected InetAddress _address;
-
- protected NetworkInterface _interface;
-
- /**
- * @param address
- * IP address to bind
- * @param dns
- * JmDNS instance
- * @param jmdnsName
- * JmDNS name
- * @return new HostInfo
- */
- public static HostInfo newHostInfo(InetAddress address, JmDNSImpl dns, String jmdnsName) {
- HostInfo localhost = null;
- String aName = (jmdnsName != null ? jmdnsName : "");
- InetAddress addr = address;
- try {
- if (addr == null) {
- String ip = System.getProperty("net.mdns.interface");
- if (ip != null) {
- addr = InetAddress.getByName(ip);
- } else {
- addr = InetAddress.getLocalHost();
- if (addr.isLoopbackAddress()) {
- // Find local address that isn't a loopback address
- InetAddress[] addresses = getInetAddresses();
- if (addresses.length > 0) {
- addr = addresses[0];
- }
- }
- }
- if (addr.isLoopbackAddress()) {
- logger.warn("Could not find any address beside the loopback.");
- }
- }
- if (aName.length() == 0) {
- aName = addr.getHostName();
+ private static Logger logger = LoggerFactory.getLogger(HostInfo.class.getName());
+
+ protected String _name;
+
+ protected InetAddress _address;
+
+ protected NetworkInterface _interface;
+
+ /**
+ * @param address IP address to bind
+ * @param dns JmDNS instance
+ * @param jmdnsName JmDNS name
+ * @return new HostInfo
+ */
+ public static HostInfo newHostInfo(InetAddress address, JmDNSImpl dns, String jmdnsName) {
+ HostInfo localhost = null;
+ String aName = (jmdnsName != null ? jmdnsName : "");
+ InetAddress addr = address;
+ try {
+ if (addr == null) {
+ String ip = System.getProperty("net.mdns.interface");
+ if (ip != null) {
+ addr = InetAddress.getByName(ip);
+ } else {
+ addr = InetAddress.getLocalHost();
+ if (addr.isLoopbackAddress()) {
+ // Find local address that isn't a loopback address
+ InetAddress[] addresses = getInetAddresses();
+ if (addresses.length > 0) {
+ addr = addresses[0];
}
- if (aName.contains("in-addr.arpa") || (aName.equals(addr.getHostAddress()))) {
- aName = ((jmdnsName != null) && (jmdnsName.length() > 0) ? jmdnsName : addr.getHostAddress());
- }
- } catch (final IOException e) {
- logger.warn("Could not initialize the host network interface on " + address + "because of an error: " + e.getMessage(), e);
- // This is only used for running unit test on Debian / Ubuntu
- addr = loopbackAddress();
- aName = ((jmdnsName != null) && (jmdnsName.length() > 0) ? jmdnsName : "computer");
+ }
}
- // A host name with "." is illegal. so strip off everything and append .local.
- // We also need to be carefull that the .local may already be there
- int index = aName.indexOf(".local");
- if (index > 0) {
- aName = aName.substring(0, index);
+ if (addr.isLoopbackAddress()) {
+ logger.warn("Could not find any address beside the loopback.");
}
- aName = aName.replaceAll("[:%\\.]", "-");
- aName += ".local.";
- localhost = new HostInfo(addr, aName, dns);
- return localhost;
+ }
+ if (aName.length() == 0) {
+ aName = addr.getHostName();
+ }
+ if (aName.contains("in-addr.arpa") || (aName.equals(addr.getHostAddress()))) {
+ aName =
+ ((jmdnsName != null) && (jmdnsName.length() > 0) ? jmdnsName : addr.getHostAddress());
+ }
+ } catch (final IOException e) {
+ logger.warn(
+ "Could not initialize the host network interface on "
+ + address
+ + "because of an error: "
+ + e.getMessage(),
+ e);
+ // This is only used for running unit test on Debian / Ubuntu
+ addr = loopbackAddress();
+ aName = ((jmdnsName != null) && (jmdnsName.length() > 0) ? jmdnsName : "computer");
}
-
- private static InetAddress[] getInetAddresses() {
- Set result = new HashSet();
- try {
-
- for (Enumeration nifs = NetworkInterface.getNetworkInterfaces(); nifs.hasMoreElements();) {
- NetworkInterface nif = nifs.nextElement();
- if (useInterface(nif)) {
- for (Enumeration iaenum = nif.getInetAddresses(); iaenum.hasMoreElements();) {
- InetAddress interfaceAddress = iaenum.nextElement();
- logger.trace("Found NetworkInterface/InetAddress: {} -- {}", nif , interfaceAddress);
- result.add(interfaceAddress);
- }
- }
- }
- } catch (SocketException se) {
- logger.warn("Error while fetching network interfaces addresses: " + se);
- }
- return result.toArray(new InetAddress[result.size()]);
+ // A host name with "." is illegal. so strip off everything and append .local.
+ // We also need to be carefull that the .local may already be there
+ int index = aName.indexOf(".local");
+ if (index > 0) {
+ aName = aName.substring(0, index);
}
-
- private static boolean useInterface(NetworkInterface networkInterface) {
- try {
- if (!networkInterface.isUp()) {
- return false;
- }
-
- if (!networkInterface.supportsMulticast()) {
- return false;
- }
-
- if (networkInterface.isLoopback()) {
- return false;
- }
-
- return true;
- } catch (Exception exception) {
- return false;
+ aName = aName.replaceAll("[:%\\.]", "-");
+ aName += ".local.";
+ localhost = new HostInfo(addr, aName, dns);
+ return localhost;
+ }
+
+ private static InetAddress[] getInetAddresses() {
+ Set result = new HashSet();
+ try {
+
+ for (Enumeration nifs = NetworkInterface.getNetworkInterfaces();
+ nifs.hasMoreElements(); ) {
+ NetworkInterface nif = nifs.nextElement();
+ if (useInterface(nif)) {
+ for (Enumeration iaenum = nif.getInetAddresses();
+ iaenum.hasMoreElements(); ) {
+ InetAddress interfaceAddress = iaenum.nextElement();
+ logger.trace("Found NetworkInterface/InetAddress: {} -- {}", nif, interfaceAddress);
+ result.add(interfaceAddress);
+ }
}
+ }
+ } catch (SocketException se) {
+ logger.warn("Error while fetching network interfaces addresses: " + se);
}
-
- private static InetAddress loopbackAddress() {
- try {
- return InetAddress.getByName(null);
- } catch (UnknownHostException exception) {
- return null;
- }
+ return result.toArray(new InetAddress[result.size()]);
+ }
+
+ private static boolean useInterface(NetworkInterface networkInterface) {
+ try {
+ if (!networkInterface.isUp()) {
+ return false;
+ }
+
+ if (!networkInterface.supportsMulticast()) {
+ return false;
+ }
+
+ if (networkInterface.isLoopback()) {
+ return false;
+ }
+
+ return true;
+ } catch (Exception exception) {
+ return false;
}
+ }
- private HostInfo(final InetAddress address, final String name, final JmDNSImpl dns) {
- super();
- this._address = address;
- this._name = name;
- if (address != null) {
- try {
- _interface = NetworkInterface.getByInetAddress(address);
- } catch (Exception exception) {
- logger.warn("LocalHostInfo() exception ", exception);
- }
- }
+ private static InetAddress loopbackAddress() {
+ try {
+ return InetAddress.getByName(null);
+ } catch (UnknownHostException exception) {
+ return null;
}
-
- public String getName() {
- return _name;
+ }
+
+ private HostInfo(final InetAddress address, final String name, final JmDNSImpl dns) {
+ super();
+ this._address = address;
+ this._name = name;
+ if (address != null) {
+ try {
+ _interface = NetworkInterface.getByInetAddress(address);
+ } catch (Exception exception) {
+ logger.warn("LocalHostInfo() exception ", exception);
+ }
}
-
- public InetAddress getInetAddress() {
- return _address;
- }
-
- public NetworkInterface getInterface() {
- return _interface;
- }
-
- boolean shouldIgnorePacket(DatagramPacket packet) {
- boolean result = false;
- if (this.getInetAddress() != null) {
- InetAddress from = packet.getAddress();
- if (from != null) {
- if ((this.getInetAddress().isLinkLocalAddress() || this.getInetAddress().isMCLinkLocal()) && (!from.isLinkLocalAddress())) {
- // A host sending Multicast DNS queries to a link-local destination
- // address (including the 224.0.0.251 and FF02::FB link-local multicast
- // addresses) MUST only accept responses to that query that originate
- // from the local link, and silently discard any other response packets.
- // Without this check, it could be possible for remote rogue hosts to
- // send spoof answer packets (perhaps unicast to the victim host) which
- // the receiving machine could misinterpret as having originated on the
- // local link.
- result = true;
- }
- // if (from.isLinkLocalAddress() && (!this.getInetAddress().isLinkLocalAddress())) {
- // // Ignore linklocal packets on regular interfaces, unless this is
- // // also a linklocal interface. This is to avoid duplicates. This is
- // // a terrible hack caused by the lack of an API to get the address
- // // of the interface on which the packet was received.
- // result = true;
- // }
- if (from.isLoopbackAddress() && (!this.getInetAddress().isLoopbackAddress())) {
- // Ignore loopback packets on a regular interface unless this is also a loopback interface.
- result = true;
- }
- }
+ }
+
+ public String getName() {
+ return _name;
+ }
+
+ public InetAddress getInetAddress() {
+ return _address;
+ }
+
+ public NetworkInterface getInterface() {
+ return _interface;
+ }
+
+ boolean shouldIgnorePacket(DatagramPacket packet) {
+ boolean result = false;
+ if (this.getInetAddress() != null) {
+ InetAddress from = packet.getAddress();
+ if (from != null) {
+ if ((this.getInetAddress().isLinkLocalAddress() || this.getInetAddress().isMCLinkLocal())
+ && (!from.isLinkLocalAddress())) {
+ // A host sending Multicast DNS queries to a link-local destination
+ // address (including the 224.0.0.251 and FF02::FB link-local multicast
+ // addresses) MUST only accept responses to that query that originate
+ // from the local link, and silently discard any other response packets.
+ // Without this check, it could be possible for remote rogue hosts to
+ // send spoof answer packets (perhaps unicast to the victim host) which
+ // the receiving machine could misinterpret as having originated on the
+ // local link.
+ result = true;
}
- return result;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder(1024);
- sb.append("local host info[");
- sb.append(getName() != null ? getName() : "no name");
- sb.append(", ");
- sb.append(getInterface() != null ? getInterface().getDisplayName() : "???");
- sb.append(":");
- sb.append(getInetAddress() != null ? getInetAddress().getHostAddress() : "no address");
- sb.append("]");
- return sb.toString();
+ // if (from.isLinkLocalAddress() && (!this.getInetAddress().isLinkLocalAddress())) {
+ // // Ignore linklocal packets on regular interfaces, unless this is
+ // // also a linklocal interface. This is to avoid duplicates. This is
+ // // a terrible hack caused by the lack of an API to get the address
+ // // of the interface on which the packet was received.
+ // result = true;
+ // }
+ if (from.isLoopbackAddress() && (!this.getInetAddress().isLoopbackAddress())) {
+ // Ignore loopback packets on a regular interface unless this is also a loopback
+ // interface.
+ result = true;
+ }
+ }
}
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder(1024);
+ sb.append("local host info[");
+ sb.append(getName() != null ? getName() : "no name");
+ sb.append(", ");
+ sb.append(getInterface() != null ? getInterface().getDisplayName() : "???");
+ sb.append(":");
+ sb.append(getInetAddress() != null ? getInetAddress().getHostAddress() : "no address");
+ sb.append("]");
+ return sb.toString();
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/JmDNSImpl.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/JmDNSImpl.java
index d050053c4..82d9e4b13 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/JmDNSImpl.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/JmDNSImpl.java
@@ -12,9 +12,6 @@
import io.libp2p.discovery.mdns.impl.tasks.Responder;
import io.libp2p.discovery.mdns.impl.tasks.ServiceResolver;
import io.libp2p.discovery.mdns.impl.util.NamedThreadFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.Inet6Address;
@@ -39,431 +36,426 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.ReentrantLock;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Derived from mDNS implementation in Java.
*
- * @author Arthur van Hoff, Rick Blair, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Scott Lewis, Kai Kreuzer, Victor Toni
+ * @author Arthur van Hoff, Rick Blair, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Scott
+ * Lewis, Kai Kreuzer, Victor Toni
*/
public class JmDNSImpl extends JmDNS {
- private static Logger logger = LoggerFactory.getLogger(JmDNSImpl.class.getName());
-
- /**
- * This is the multicast group, we are listening to for multicast DNS messages.
- */
- private volatile InetAddress _group;
- /**
- * This is our multicast socket.
- */
- private volatile MulticastSocket _socket;
-
- private final ConcurrentMap> _answerListeners;
- private final ConcurrentMap _serviceResolvers;
-
- /**
- * This hashtable holds the services that have been registered. Keys are instances of String which hold an all lower-case version of the fully qualified service name. Values are instances of ServiceInfo.
- */
- private final ConcurrentMap _services;
-
- /**
- * Handle on the local host
- */
- private HostInfo _localHost;
-
- private SocketListener _incomingListener;
-
- private final ExecutorService _executor = Executors.newSingleThreadExecutor(new NamedThreadFactory("JmDNS"));
-
- /**
- * The source for random values. This is used to introduce random delays in responses. This reduces the potential for collisions on the network.
- */
- private final static Random _random = new Random();
-
- /**
- * This lock is used to coordinate processing of incoming and outgoing messages. This is needed, because the Rendezvous Conformance Test does not forgive race conditions.
- */
- private final ReentrantLock _ioLock = new ReentrantLock();
-
- private final String _name;
-
- /**
- * Create an instance of JmDNS and bind it to a specific network interface given its IP-address.
- *
- * @param address IP address to bind to.
- * @param name name of the newly created JmDNS
- * @throws IOException
- */
- public JmDNSImpl(InetAddress address, String name) {
- super();
- logger.debug("JmDNS instance created");
-
- _answerListeners = new ConcurrentHashMap<>();
- _serviceResolvers = new ConcurrentHashMap<>();
-
- _services = new ConcurrentHashMap<>(20);
-
- _localHost = HostInfo.newHostInfo(address, this, name);
- _name = (name != null ? name : _localHost.getName());
- }
-
- public void start() throws IOException {
- // Bind to multicast socket
- this.openMulticastSocket(this.getLocalHost());
- this.start(this.getServices().values());
+ private static Logger logger = LoggerFactory.getLogger(JmDNSImpl.class.getName());
+
+ /** This is the multicast group, we are listening to for multicast DNS messages. */
+ private volatile InetAddress _group;
+
+ /** This is our multicast socket. */
+ private volatile MulticastSocket _socket;
+
+ private final ConcurrentMap> _answerListeners;
+ private final ConcurrentMap _serviceResolvers;
+
+ /**
+ * This hashtable holds the services that have been registered. Keys are instances of String which
+ * hold an all lower-case version of the fully qualified service name. Values are instances of
+ * ServiceInfo.
+ */
+ private final ConcurrentMap _services;
+
+ /** Handle on the local host */
+ private HostInfo _localHost;
+
+ private SocketListener _incomingListener;
+
+ private final ExecutorService _executor =
+ Executors.newSingleThreadExecutor(new NamedThreadFactory("JmDNS"));
+
+ /**
+ * The source for random values. This is used to introduce random delays in responses. This
+ * reduces the potential for collisions on the network.
+ */
+ private static final Random _random = new Random();
+
+ /**
+ * This lock is used to coordinate processing of incoming and outgoing messages. This is needed,
+ * because the Rendezvous Conformance Test does not forgive race conditions.
+ */
+ private final ReentrantLock _ioLock = new ReentrantLock();
+
+ private final String _name;
+
+ /**
+ * Create an instance of JmDNS and bind it to a specific network interface given its IP-address.
+ *
+ * @param address IP address to bind to.
+ * @param name name of the newly created JmDNS
+ * @throws IOException
+ */
+ public JmDNSImpl(InetAddress address, String name) {
+ super();
+ logger.debug("JmDNS instance created");
+
+ _answerListeners = new ConcurrentHashMap<>();
+ _serviceResolvers = new ConcurrentHashMap<>();
+
+ _services = new ConcurrentHashMap<>(20);
+
+ _localHost = HostInfo.newHostInfo(address, this, name);
+ _name = (name != null ? name : _localHost.getName());
+ }
+
+ public void start() throws IOException {
+ // Bind to multicast socket
+ this.openMulticastSocket(this.getLocalHost());
+ this.start(this.getServices().values());
+ }
+
+ private void start(Collection extends ServiceInfo> serviceInfos) {
+ if (_incomingListener == null) {
+ _incomingListener = new SocketListener(this);
+ _incomingListener.start();
}
-
- private void start(Collection extends ServiceInfo> serviceInfos) {
- if (_incomingListener == null) {
- _incomingListener = new SocketListener(this);
- _incomingListener.start();
- }
- for (ServiceInfo info : serviceInfos) {
- try {
- this.registerService(new ServiceInfoImpl(info));
- } catch (final Exception exception) {
- logger.warn("start() Registration exception ", exception);
- }
- }
- }
-
- private void openMulticastSocket(HostInfo hostInfo) throws IOException {
- if (_group == null) {
- if (hostInfo.getInetAddress() instanceof Inet6Address) {
- _group = InetAddress.getByName(DNSConstants.MDNS_GROUP_IPV6);
- } else {
- _group = InetAddress.getByName(DNSConstants.MDNS_GROUP);
- }
- }
- if (_socket != null) {
- this.closeMulticastSocket();
- }
- // SocketAddress address = new InetSocketAddress((hostInfo != null ? hostInfo.getInetAddress() : null), DNSConstants.MDNS_PORT);
- // System.out.println("Socket Address: " + address);
- // try {
- // _socket = new MulticastSocket(address);
- // } catch (Exception exception) {
- // logger.warn("openMulticastSocket() Open socket exception Address: " + address + ", ", exception);
- // // The most likely cause is a duplicate address lets open without specifying the address
- // _socket = new MulticastSocket(DNSConstants.MDNS_PORT);
- // }
- _socket = new MulticastSocket(DNSConstants.MDNS_PORT);
- if ((hostInfo != null) && (hostInfo.getInterface() != null)) {
- final SocketAddress multicastAddr = new InetSocketAddress(_group, DNSConstants.MDNS_PORT);
- _socket.setNetworkInterface(hostInfo.getInterface());
-
- logger.trace("Trying to joinGroup({}, {})", multicastAddr, hostInfo.getInterface());
-
- // this joinGroup() might be less surprisingly so this is the default
- _socket.joinGroup(multicastAddr, hostInfo.getInterface());
- } else {
- logger.trace("Trying to joinGroup({})", _group);
- _socket.joinGroup(_group);
- }
-
- _socket.setTimeToLive(255);
+ for (ServiceInfo info : serviceInfos) {
+ try {
+ this.registerService(new ServiceInfoImpl(info));
+ } catch (final Exception exception) {
+ logger.warn("start() Registration exception ", exception);
+ }
}
-
- private void closeMulticastSocket() {
- // jP: 20010-01-18. See below. We'll need this monitor...
- // assert (Thread.holdsLock(this));
- logger.debug("closeMulticastSocket()");
- if (_socket != null) {
- // close socket
- try {
- try {
- _socket.leaveGroup(_group);
- } catch (SocketException exception) {
- //
- }
- _socket.close();
- } catch (final Exception exception) {
- logger.warn("closeMulticastSocket() Close socket exception ", exception);
- }
- _socket = null;
- }
+ }
+
+ private void openMulticastSocket(HostInfo hostInfo) throws IOException {
+ if (_group == null) {
+ if (hostInfo.getInetAddress() instanceof Inet6Address) {
+ _group = InetAddress.getByName(DNSConstants.MDNS_GROUP_IPV6);
+ } else {
+ _group = InetAddress.getByName(DNSConstants.MDNS_GROUP);
+ }
}
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getName() {
- return _name;
+ if (_socket != null) {
+ this.closeMulticastSocket();
}
-
- /**
- * Returns the local host info
- *
- * @return local host info
- */
- public HostInfo getLocalHost() {
- return _localHost;
+ // SocketAddress address = new InetSocketAddress((hostInfo != null ? hostInfo.getInetAddress() :
+ // null), DNSConstants.MDNS_PORT);
+ // System.out.println("Socket Address: " + address);
+ // try {
+ // _socket = new MulticastSocket(address);
+ // } catch (Exception exception) {
+ // logger.warn("openMulticastSocket() Open socket exception Address: " + address + ", ",
+ // exception);
+ // // The most likely cause is a duplicate address lets open without specifying the address
+ // _socket = new MulticastSocket(DNSConstants.MDNS_PORT);
+ // }
+ _socket = new MulticastSocket(DNSConstants.MDNS_PORT);
+ if ((hostInfo != null) && (hostInfo.getInterface() != null)) {
+ final SocketAddress multicastAddr = new InetSocketAddress(_group, DNSConstants.MDNS_PORT);
+ _socket.setNetworkInterface(hostInfo.getInterface());
+
+ logger.trace("Trying to joinGroup({}, {})", multicastAddr, hostInfo.getInterface());
+
+ // this joinGroup() might be less surprisingly so this is the default
+ _socket.joinGroup(multicastAddr, hostInfo.getInterface());
+ } else {
+ logger.trace("Trying to joinGroup({})", _group);
+ _socket.joinGroup(_group);
}
- void handleServiceAnswers(List answers) {
- DNSRecord ptr = answers.get(0);
- if (!DNSRecordType.TYPE_PTR.equals(ptr.getRecordType()))
- return;
- List list = _answerListeners.get(ptr.getKey());
-
- if ((list != null) && (!list.isEmpty())) {
- final List listCopy;
- synchronized (list) {
- listCopy = new ArrayList<>(list);
- }
- for (final AnswerListener listener : listCopy) {
- _executor.submit(new Runnable() {
- @Override
- public void run() {
- listener.answersReceived(answers);
- }
- });
- }
- }
- }
+ _socket.setTimeToLive(255);
+ }
- @Override
- public void addAnswerListener(String type, int queryInterval, AnswerListener listener) {
- final String loType = type.toLowerCase();
- List list = _answerListeners.get(loType);
- if (list == null) {
- _answerListeners.putIfAbsent(loType, new LinkedList<>());
- list = _answerListeners.get(loType);
- }
- if (list != null) {
- synchronized (list) {
- if (!list.contains(listener)) {
- list.add(listener);
- }
- }
+ private void closeMulticastSocket() {
+ // jP: 20010-01-18. See below. We'll need this monitor...
+ // assert (Thread.holdsLock(this));
+ logger.debug("closeMulticastSocket()");
+ if (_socket != null) {
+ // close socket
+ try {
+ try {
+ _socket.leaveGroup(_group);
+ } catch (SocketException exception) {
+ //
}
-
- startServiceResolver(loType, queryInterval);
+ _socket.close();
+ } catch (final Exception exception) {
+ logger.warn("closeMulticastSocket() Close socket exception ", exception);
+ }
+ _socket = null;
}
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void registerService(ServiceInfo infoAbstract) throws IOException {
- final ServiceInfoImpl info = (ServiceInfoImpl) infoAbstract;
-
- info.setServer(_localHost.getName());
-
- _services.putIfAbsent(info.getKey(), info);
-
- logger.debug("registerService() JmDNS registered service as {}", info);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getName() {
+ return _name;
+ }
+
+ /**
+ * Returns the local host info
+ *
+ * @return local host info
+ */
+ public HostInfo getLocalHost() {
+ return _localHost;
+ }
+
+ void handleServiceAnswers(List answers) {
+ DNSRecord ptr = answers.get(0);
+ if (!DNSRecordType.TYPE_PTR.equals(ptr.getRecordType())) return;
+ List list = _answerListeners.get(ptr.getKey());
+
+ if ((list != null) && (!list.isEmpty())) {
+ final List listCopy;
+ synchronized (list) {
+ listCopy = new ArrayList<>(list);
+ }
+ for (final AnswerListener listener : listCopy) {
+ _executor.submit(
+ new Runnable() {
+ @Override
+ public void run() {
+ listener.answersReceived(answers);
+ }
+ });
+ }
}
-
- /**
- * Handle an incoming response. Cache answers, and pass them on to the appropriate questions.
- *
- * @throws IOException
- */
- void handleResponse(DNSIncoming msg) throws IOException {
- List allAnswers = msg.getAllAnswers();
- allAnswers = aRecordsLast(allAnswers);
-
- handleServiceAnswers(allAnswers);
+ }
+
+ @Override
+ public void addAnswerListener(String type, int queryInterval, AnswerListener listener) {
+ final String loType = type.toLowerCase();
+ List list = _answerListeners.get(loType);
+ if (list == null) {
+ _answerListeners.putIfAbsent(loType, new LinkedList<>());
+ list = _answerListeners.get(loType);
}
-
- /**
- * In case the a record is received before the srv record the ip address would not be set.
- *
- * Multicast Domain Name System (response)
- * Transaction ID: 0x0000
- * Flags: 0x8400 Standard query response, No error
- * Questions: 0
- * Answer RRs: 2
- * Authority RRs: 0
- * Additional RRs: 8
- * Answers
- * _ibisip_http._tcp.local: type PTR, class IN, DeviceManagementService._ibisip_http._tcp.local
- * _ibisip_http._tcp.local: type PTR, class IN, PassengerCountingService._ibisip_http._tcp.local
- * Additional records
- * DeviceManagementService._ibisip_http._tcp.local: type TXT, class IN, cache flush
- * PassengerCountingService._ibisip_http._tcp.local: type TXT, class IN, cache flush
- * DIST500_7-F07_OC030_05_03941.local: type A, class IN, cache flush, addr 192.168.88.236
- * DeviceManagementService._ibisip_http._tcp.local: type SRV, class IN, cache flush, priority 0, weight 0, port 5000, target DIST500_7-F07_OC030_05_03941.local
- * PassengerCountingService._ibisip_http._tcp.local: type SRV, class IN, cache flush, priority 0, weight 0, port 5001, target DIST500_7-F07_OC030_05_03941.local
- * DeviceManagementService._ibisip_http._tcp.local: type NSEC, class IN, cache flush, next domain name DeviceManagementService._ibisip_http._tcp.local
- * PassengerCountingService._ibisip_http._tcp.local: type NSEC, class IN, cache flush, next domain name PassengerCountingService._ibisip_http._tcp.local
- * DIST500_7-F07_OC030_05_03941.local: type NSEC, class IN, cache flush, next domain name DIST500_7-F07_OC030_05_03941.local
- */
- private List aRecordsLast(List allAnswers) {
- ArrayList ret = new ArrayList(allAnswers.size());
- ArrayList arecords = new ArrayList();
-
- for (DNSRecord answer : allAnswers) {
- DNSRecordType type = answer.getRecordType();
- if (type.equals(DNSRecordType.TYPE_A) || type.equals(DNSRecordType.TYPE_AAAA)) {
- arecords.add(answer);
- } else if (type.equals(DNSRecordType.TYPE_PTR)) {
- ret.add(0, answer);
- } else {
- ret.add(answer);
- }
+ if (list != null) {
+ synchronized (list) {
+ if (!list.contains(listener)) {
+ list.add(listener);
}
- ret.addAll(arecords);
- return ret;
+ }
}
-
- /**
- * Handle an incoming query. See if we can answer any part of it given our service infos.
- *
- * @param in
- * @param addr
- * @param port
- * @throws IOException
- */
- void handleQuery(DNSIncoming in, InetAddress addr, int port) throws IOException {
- logger.debug("{} handle query: {}", this.getName(), in);
- this.ioLock();
- try {
- DNSIncoming plannedAnswer = in.clone();
- this.startResponder(plannedAnswer, addr, port);
- } finally {
- this.ioUnlock();
- }
+ startServiceResolver(loType, queryInterval);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void registerService(ServiceInfo infoAbstract) throws IOException {
+ final ServiceInfoImpl info = (ServiceInfoImpl) infoAbstract;
+
+ info.setServer(_localHost.getName());
+
+ _services.putIfAbsent(info.getKey(), info);
+
+ logger.debug("registerService() JmDNS registered service as {}", info);
+ }
+
+ /**
+ * Handle an incoming response. Cache answers, and pass them on to the appropriate questions.
+ *
+ * @throws IOException
+ */
+ void handleResponse(DNSIncoming msg) throws IOException {
+ List allAnswers = msg.getAllAnswers();
+ allAnswers = aRecordsLast(allAnswers);
+
+ handleServiceAnswers(allAnswers);
+ }
+
+ /**
+ * In case the a record is received before the srv record the ip address would not be set.
+ *
+ * Multicast Domain Name System (response) Transaction ID: 0x0000 Flags: 0x8400 Standard query
+ * response, No error Questions: 0 Answer RRs: 2 Authority RRs: 0 Additional RRs: 8 Answers
+ * _ibisip_http._tcp.local: type PTR, class IN, DeviceManagementService._ibisip_http._tcp.local
+ * _ibisip_http._tcp.local: type PTR, class IN, PassengerCountingService._ibisip_http._tcp.local
+ * Additional records DeviceManagementService._ibisip_http._tcp.local: type TXT, class IN, cache
+ * flush PassengerCountingService._ibisip_http._tcp.local: type TXT, class IN, cache flush
+ * DIST500_7-F07_OC030_05_03941.local: type A, class IN, cache flush, addr 192.168.88.236
+ * DeviceManagementService._ibisip_http._tcp.local: type SRV, class IN, cache flush, priority 0,
+ * weight 0, port 5000, target DIST500_7-F07_OC030_05_03941.local
+ * PassengerCountingService._ibisip_http._tcp.local: type SRV, class IN, cache flush, priority 0,
+ * weight 0, port 5001, target DIST500_7-F07_OC030_05_03941.local
+ * DeviceManagementService._ibisip_http._tcp.local: type NSEC, class IN, cache flush, next domain
+ * name DeviceManagementService._ibisip_http._tcp.local
+ * PassengerCountingService._ibisip_http._tcp.local: type NSEC, class IN, cache flush, next domain
+ * name PassengerCountingService._ibisip_http._tcp.local DIST500_7-F07_OC030_05_03941.local: type
+ * NSEC, class IN, cache flush, next domain name DIST500_7-F07_OC030_05_03941.local
+ */
+ private List aRecordsLast(List allAnswers) {
+ ArrayList ret = new ArrayList(allAnswers.size());
+ ArrayList arecords = new ArrayList();
+
+ for (DNSRecord answer : allAnswers) {
+ DNSRecordType type = answer.getRecordType();
+ if (type.equals(DNSRecordType.TYPE_A) || type.equals(DNSRecordType.TYPE_AAAA)) {
+ arecords.add(answer);
+ } else if (type.equals(DNSRecordType.TYPE_PTR)) {
+ ret.add(0, answer);
+ } else {
+ ret.add(answer);
+ }
}
-
- /**
- * Send an outgoing multicast DNS message.
- *
- * @param out
- * @throws IOException
- */
- public void send(DNSOutgoing out) throws IOException {
- if (!out.isEmpty()) {
- final InetAddress addr;
- final int port;
-
- if (out.getDestination() != null) {
- addr = out.getDestination().getAddress();
- port = out.getDestination().getPort();
- } else {
- addr = _group;
- port = DNSConstants.MDNS_PORT;
- }
-
- byte[] message = out.data();
- final DatagramPacket packet = new DatagramPacket(message, message.length, addr, port);
-
- if (logger.isTraceEnabled()) {
- try {
- final DNSIncoming msg = new DNSIncoming(packet);
- if (logger.isTraceEnabled()) {
- logger.trace("send({}) JmDNS out:{}", this.getName(), msg.print(true));
- }
- } catch (final IOException e) {
- logger.debug(getClass().toString(), ".send(" + this.getName() + ") - JmDNS can not parse what it sends!!!", e);
- }
- }
- final MulticastSocket ms = _socket;
- if (ms != null && !ms.isClosed()) {
- ms.send(packet);
- }
- }
+ ret.addAll(arecords);
+ return ret;
+ }
+
+ /**
+ * Handle an incoming query. See if we can answer any part of it given our service infos.
+ *
+ * @param in
+ * @param addr
+ * @param port
+ * @throws IOException
+ */
+ void handleQuery(DNSIncoming in, InetAddress addr, int port) throws IOException {
+ logger.debug("{} handle query: {}", this.getName(), in);
+ this.ioLock();
+ try {
+ DNSIncoming plannedAnswer = in.clone();
+ this.startResponder(plannedAnswer, addr, port);
+ } finally {
+ this.ioUnlock();
}
-
- private void startServiceResolver(String type, int queryInterval) {
- if (_serviceResolvers.containsKey(type))
- return;
-
- ServiceResolver resolver = new ServiceResolver(this, type, queryInterval);
- if (_serviceResolvers.putIfAbsent(type, resolver) == null)
- resolver.start();
+ }
+
+ /**
+ * Send an outgoing multicast DNS message.
+ *
+ * @param out
+ * @throws IOException
+ */
+ public void send(DNSOutgoing out) throws IOException {
+ if (!out.isEmpty()) {
+ final InetAddress addr;
+ final int port;
+
+ if (out.getDestination() != null) {
+ addr = out.getDestination().getAddress();
+ port = out.getDestination().getPort();
+ } else {
+ addr = _group;
+ port = DNSConstants.MDNS_PORT;
+ }
+
+ byte[] message = out.data();
+ final DatagramPacket packet = new DatagramPacket(message, message.length, addr, port);
+
+ if (logger.isTraceEnabled()) {
+ try {
+ final DNSIncoming msg = new DNSIncoming(packet);
+ if (logger.isTraceEnabled()) {
+ logger.trace("send({}) JmDNS out:{}", this.getName(), msg.print(true));
+ }
+ } catch (final IOException e) {
+ logger.debug(
+ getClass().toString(),
+ ".send(" + this.getName() + ") - JmDNS can not parse what it sends!!!",
+ e);
+ }
+ }
+ final MulticastSocket ms = _socket;
+ if (ms != null && !ms.isClosed()) {
+ ms.send(packet);
+ }
}
+ }
- private void startResponder(DNSIncoming in, InetAddress addr, int port) {
- new Responder(this, in, addr, port).start();
- }
+ private void startServiceResolver(String type, int queryInterval) {
+ if (_serviceResolvers.containsKey(type)) return;
- public void stop() {
- logger.debug("Stopping JmDNS: {}", this);
+ ServiceResolver resolver = new ServiceResolver(this, type, queryInterval);
+ if (_serviceResolvers.putIfAbsent(type, resolver) == null) resolver.start();
+ }
- List> shutdowns = new ArrayList<>();
+ private void startResponder(DNSIncoming in, InetAddress addr, int port) {
+ new Responder(this, in, addr, port).start();
+ }
- shutdowns.add(_incomingListener.stop());
- _incomingListener = null;
+ public void stop() {
+ logger.debug("Stopping JmDNS: {}", this);
- for (ServiceResolver resolver : _serviceResolvers.values())
- shutdowns.add(resolver.stop());
+ List> shutdowns = new ArrayList<>();
- // close socket
- this.closeMulticastSocket();
+ shutdowns.add(_incomingListener.stop());
+ _incomingListener = null;
- logger.debug("JmDNS waiting for service stop...");
+ for (ServiceResolver resolver : _serviceResolvers.values()) shutdowns.add(resolver.stop());
- for (Future shutdown : shutdowns) {
- try {
- shutdown.get(10, TimeUnit.SECONDS);
- } catch (CancellationException e) {
- logger.trace("Task was already cancelled", e);
- } catch (InterruptedException e) {
- logger.trace("Stopping was interrupted", e);
- Thread.currentThread().interrupt();
- } catch (ExecutionException | TimeoutException e) {
- logger.debug("Exception when stopping JmDNS: ", e);
- throw new RuntimeException(e);
- }
- }
+ // close socket
+ this.closeMulticastSocket();
- _executor.shutdown();
+ logger.debug("JmDNS waiting for service stop...");
- logger.debug("JmDNS stopped.");
+ for (Future shutdown : shutdowns) {
+ try {
+ shutdown.get(10, TimeUnit.SECONDS);
+ } catch (CancellationException e) {
+ logger.trace("Task was already cancelled", e);
+ } catch (InterruptedException e) {
+ logger.trace("Stopping was interrupted", e);
+ Thread.currentThread().interrupt();
+ } catch (ExecutionException | TimeoutException e) {
+ logger.debug("Exception when stopping JmDNS: ", e);
+ throw new RuntimeException(e);
+ }
}
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder(2048);
- sb.append("\n");
- sb.append("\t---- Local Host -----");
- sb.append("\n\t");
- sb.append(_localHost);
- sb.append("\n\t---- Services -----");
- for (final Map.Entry entry : _services.entrySet()) {
- sb.append("\n\t\tService: ");
- sb.append(entry.getKey());
- sb.append(": ");
- sb.append(entry.getValue());
- }
- sb.append("\n");
- sb.append("\t---- Answer Listeners ----");
- for (final Map.Entry> entry : _answerListeners.entrySet()) {
- sb.append("\n\t\tAnswer Listener: ");
- sb.append(entry.getKey());
- sb.append(": ");
- sb.append(entry.getValue());
- }
- return sb.toString();
+ _executor.shutdown();
+
+ logger.debug("JmDNS stopped.");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder(2048);
+ sb.append("\n");
+ sb.append("\t---- Local Host -----");
+ sb.append("\n\t");
+ sb.append(_localHost);
+ sb.append("\n\t---- Services -----");
+ for (final Map.Entry entry : _services.entrySet()) {
+ sb.append("\n\t\tService: ");
+ sb.append(entry.getKey());
+ sb.append(": ");
+ sb.append(entry.getValue());
}
-
- public Map getServices() {
- return _services;
+ sb.append("\n");
+ sb.append("\t---- Answer Listeners ----");
+ for (final Map.Entry> entry : _answerListeners.entrySet()) {
+ sb.append("\n\t\tAnswer Listener: ");
+ sb.append(entry.getKey());
+ sb.append(": ");
+ sb.append(entry.getValue());
}
+ return sb.toString();
+ }
- public static Random getRandom() {
- return _random;
- }
+ public Map getServices() {
+ return _services;
+ }
- private void ioLock() {
- _ioLock.lock();
- }
+ public static Random getRandom() {
+ return _random;
+ }
- private void ioUnlock() {
- _ioLock.unlock();
- }
+ private void ioLock() {
+ _ioLock.lock();
+ }
- public MulticastSocket getSocket() {
- return _socket;
- }
+ private void ioUnlock() {
+ _ioLock.unlock();
+ }
- public InetAddress getGroup() {
- return _group;
- }
+ public MulticastSocket getSocket() {
+ return _socket;
+ }
+
+ public InetAddress getGroup() {
+ return _group;
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/ServiceInfoImpl.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/ServiceInfoImpl.java
index cc0c94dbf..54efc0ef7 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/ServiceInfoImpl.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/ServiceInfoImpl.java
@@ -7,9 +7,6 @@
import io.libp2p.discovery.mdns.ServiceInfo;
import io.libp2p.discovery.mdns.impl.constants.DNSRecordClass;
import io.libp2p.discovery.mdns.impl.util.ByteWrangler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.IOException;
import java.net.Inet4Address;
import java.net.Inet6Address;
@@ -23,6 +20,8 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* JmDNS service information.
@@ -30,435 +29,488 @@
* @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer, Victor Toni
*/
public class ServiceInfoImpl extends ServiceInfo {
- private static Logger logger = LoggerFactory.getLogger(ServiceInfoImpl.class.getName());
-
- private String _domain;
- private String _protocol;
- private String _application;
- private String _name;
- private String _subtype;
- private String _server;
- private int _port;
- private int _weight;
- private int _priority;
- private byte[] _text;
- private final Set _ipv4Addresses;
- private final Set _ipv6Addresses;
-
- private transient String _key;
-
- /**
- * @param type
- * @param name
- * @param subtype
- * @param port
- * @param weight
- * @param priority
- * @param text
- */
- public ServiceInfoImpl(String type, String name, String subtype, int port, int weight, int priority, String text) {
- this(ServiceInfoImpl.decodeQualifiedNameMap(type, name, subtype), port, weight, priority, (byte[]) null);
-
- try {
- this._text = ByteWrangler.encodeText(text);
- } catch (final IOException e) {
- throw new RuntimeException("Unexpected exception: " + e);
+ private static Logger logger = LoggerFactory.getLogger(ServiceInfoImpl.class.getName());
+
+ private String _domain;
+ private String _protocol;
+ private String _application;
+ private String _name;
+ private String _subtype;
+ private String _server;
+ private int _port;
+ private int _weight;
+ private int _priority;
+ private byte[] _text;
+ private final Set _ipv4Addresses;
+ private final Set _ipv6Addresses;
+
+ private transient String _key;
+
+ /**
+ * @param type
+ * @param name
+ * @param subtype
+ * @param port
+ * @param weight
+ * @param priority
+ * @param text
+ */
+ public ServiceInfoImpl(
+ String type, String name, String subtype, int port, int weight, int priority, String text) {
+ this(
+ ServiceInfoImpl.decodeQualifiedNameMap(type, name, subtype),
+ port,
+ weight,
+ priority,
+ (byte[]) null);
+
+ try {
+ this._text = ByteWrangler.encodeText(text);
+ } catch (final IOException e) {
+ throw new RuntimeException("Unexpected exception: " + e);
+ }
+
+ _server = text;
+ }
+
+ ServiceInfoImpl(
+ Map qualifiedNameMap, int port, int weight, int priority, byte text[]) {
+ Map map = ServiceInfoImpl.checkQualifiedNameMap(qualifiedNameMap);
+
+ this._domain = map.get(Fields.Domain);
+ this._protocol = map.get(Fields.Protocol);
+ this._application = map.get(Fields.Application);
+ this._name = map.get(Fields.Instance);
+ this._subtype = map.get(Fields.Subtype);
+
+ this._port = port;
+ this._weight = weight;
+ this._priority = priority;
+ this._text = text;
+ this._ipv4Addresses = Collections.synchronizedSet(new LinkedHashSet());
+ this._ipv6Addresses = Collections.synchronizedSet(new LinkedHashSet());
+ }
+
+ ServiceInfoImpl(ServiceInfo info) {
+ this._ipv4Addresses = Collections.synchronizedSet(new LinkedHashSet());
+ this._ipv6Addresses = Collections.synchronizedSet(new LinkedHashSet());
+ if (info != null) {
+ this._domain = info.getDomain();
+ this._protocol = info.getProtocol();
+ this._application = info.getApplication();
+ this._name = info.getName();
+ this._subtype = info.getSubtype();
+ this._port = info.getPort();
+ this._weight = info.getWeight();
+ this._priority = info.getPriority();
+ this._text = info.getTextBytes();
+ Inet6Address[] ipv6Addresses = info.getInet6Addresses();
+ for (Inet6Address address : ipv6Addresses) {
+ this._ipv6Addresses.add(address);
+ }
+ Inet4Address[] ipv4Addresses = info.getInet4Addresses();
+ for (Inet4Address address : ipv4Addresses) {
+ this._ipv4Addresses.add(address);
+ }
+ }
+ }
+
+ public static Map decodeQualifiedNameMap(
+ String type, String name, String subtype) {
+ Map qualifiedNameMap = decodeQualifiedNameMapForType(type);
+
+ qualifiedNameMap.put(Fields.Instance, name);
+ qualifiedNameMap.put(Fields.Subtype, subtype);
+
+ return checkQualifiedNameMap(qualifiedNameMap);
+ }
+
+ public static Map decodeQualifiedNameMapForType(String type) {
+ int index;
+
+ String casePreservedType = type;
+
+ String aType = type.toLowerCase();
+ String application = aType;
+ String protocol = "";
+ String subtype = "";
+ String name = "";
+ String domain = "";
+
+ if (aType.contains("in-addr.arpa") || aType.contains("ip6.arpa")) {
+ index =
+ (aType.contains("in-addr.arpa")
+ ? aType.indexOf("in-addr.arpa")
+ : aType.indexOf("ip6.arpa"));
+ name = removeSeparators(casePreservedType.substring(0, index));
+ domain = casePreservedType.substring(index);
+ application = "";
+ } else if ((!aType.contains("_")) && aType.contains(".")) {
+ index = aType.indexOf('.');
+ name = removeSeparators(casePreservedType.substring(0, index));
+ domain = removeSeparators(casePreservedType.substring(index));
+ application = "";
+ } else {
+ // First remove the name if it there.
+ if (!aType.startsWith("_") || aType.startsWith("_services")) {
+ index = aType.indexOf("._");
+ if (index > 0) {
+ // We need to preserve the case for the user readable name.
+ name = casePreservedType.substring(0, index);
+ if (index + 1 < aType.length()) {
+ aType = aType.substring(index + 1);
+ casePreservedType = casePreservedType.substring(index + 1);
+ }
}
-
- _server = text;
- }
-
- ServiceInfoImpl(Map qualifiedNameMap, int port, int weight, int priority, byte text[]) {
- Map map = ServiceInfoImpl.checkQualifiedNameMap(qualifiedNameMap);
-
- this._domain = map.get(Fields.Domain);
- this._protocol = map.get(Fields.Protocol);
- this._application = map.get(Fields.Application);
- this._name = map.get(Fields.Instance);
- this._subtype = map.get(Fields.Subtype);
-
- this._port = port;
- this._weight = weight;
- this._priority = priority;
- this._text = text;
- this._ipv4Addresses = Collections.synchronizedSet(new LinkedHashSet());
- this._ipv6Addresses = Collections.synchronizedSet(new LinkedHashSet());
- }
-
- ServiceInfoImpl(ServiceInfo info) {
- this._ipv4Addresses = Collections.synchronizedSet(new LinkedHashSet());
- this._ipv6Addresses = Collections.synchronizedSet(new LinkedHashSet());
- if (info != null) {
- this._domain = info.getDomain();
- this._protocol = info.getProtocol();
- this._application = info.getApplication();
- this._name = info.getName();
- this._subtype = info.getSubtype();
- this._port = info.getPort();
- this._weight = info.getWeight();
- this._priority = info.getPriority();
- this._text = info.getTextBytes();
- Inet6Address[] ipv6Addresses = info.getInet6Addresses();
- for (Inet6Address address : ipv6Addresses) {
- this._ipv6Addresses.add(address);
- }
- Inet4Address[] ipv4Addresses = info.getInet4Addresses();
- for (Inet4Address address : ipv4Addresses) {
- this._ipv4Addresses.add(address);
- }
+ }
+
+ index = aType.lastIndexOf("._");
+ if (index > 0) {
+ int start = index + 2;
+ int end = aType.indexOf('.', start);
+ protocol = casePreservedType.substring(start, end);
+ }
+ if (protocol.length() > 0) {
+ index = aType.indexOf("_" + protocol.toLowerCase() + ".");
+ int start = index + protocol.length() + 2;
+ int end = aType.length() - (aType.endsWith(".") ? 1 : 0);
+ if (end > start) {
+ domain = casePreservedType.substring(start, end);
}
- }
-
- public static Map decodeQualifiedNameMap(String type, String name, String subtype) {
- Map qualifiedNameMap = decodeQualifiedNameMapForType(type);
-
- qualifiedNameMap.put(Fields.Instance, name);
- qualifiedNameMap.put(Fields.Subtype, subtype);
-
- return checkQualifiedNameMap(qualifiedNameMap);
- }
-
- public static Map decodeQualifiedNameMapForType(String type) {
- int index;
-
- String casePreservedType = type;
-
- String aType = type.toLowerCase();
- String application = aType;
- String protocol = "";
- String subtype = "";
- String name = "";
- String domain = "";
-
- if (aType.contains("in-addr.arpa") || aType.contains("ip6.arpa")) {
- index = (aType.contains("in-addr.arpa") ? aType.indexOf("in-addr.arpa") : aType.indexOf("ip6.arpa"));
- name = removeSeparators(casePreservedType.substring(0, index));
- domain = casePreservedType.substring(index);
- application = "";
- } else if ((!aType.contains("_")) && aType.contains(".")) {
- index = aType.indexOf('.');
- name = removeSeparators(casePreservedType.substring(0, index));
- domain = removeSeparators(casePreservedType.substring(index));
- application = "";
+ if (index > 0) {
+ application = casePreservedType.substring(0, index - 1);
} else {
- // First remove the name if it there.
- if (!aType.startsWith("_") || aType.startsWith("_services")) {
- index = aType.indexOf("._");
- if (index > 0) {
- // We need to preserve the case for the user readable name.
- name = casePreservedType.substring(0, index);
- if (index + 1 < aType.length()) {
- aType = aType.substring(index + 1);
- casePreservedType = casePreservedType.substring(index + 1);
- }
- }
- }
-
- index = aType.lastIndexOf("._");
- if (index > 0) {
- int start = index + 2;
- int end = aType.indexOf('.', start);
- protocol = casePreservedType.substring(start, end);
- }
- if (protocol.length() > 0) {
- index = aType.indexOf("_" + protocol.toLowerCase() + ".");
- int start = index + protocol.length() + 2;
- int end = aType.length() - (aType.endsWith(".") ? 1 : 0);
- if (end > start) {
- domain = casePreservedType.substring(start, end);
- }
- if (index > 0) {
- application = casePreservedType.substring(0, index - 1);
- } else {
- application = "";
- }
- }
- index = application.toLowerCase().indexOf("._sub");
- if (index > 0) {
- int start = index + 5;
- subtype = removeSeparators(application.substring(0, index));
- application = application.substring(start);
- }
- }
-
- final Map qualifiedNameMap = new HashMap(5);
- qualifiedNameMap.put(Fields.Domain, removeSeparators(domain));
- qualifiedNameMap.put(Fields.Protocol, protocol);
- qualifiedNameMap.put(Fields.Application, removeSeparators(application));
- qualifiedNameMap.put(Fields.Instance, name);
- qualifiedNameMap.put(Fields.Subtype, subtype);
-
- return qualifiedNameMap;
- }
-
- protected static Map checkQualifiedNameMap(Map qualifiedNameMap) {
- Map checkedQualifiedNameMap = new HashMap(5);
-
- // Optional domain
- String domain = (qualifiedNameMap.containsKey(Fields.Domain) ? qualifiedNameMap.get(Fields.Domain) : "local");
- if ((domain == null) || (domain.length() == 0)) {
- domain = "local";
- }
- domain = removeSeparators(domain);
- checkedQualifiedNameMap.put(Fields.Domain, domain);
- // Optional protocol
- String protocol = (qualifiedNameMap.containsKey(Fields.Protocol) ? qualifiedNameMap.get(Fields.Protocol) : "tcp");
- if ((protocol == null) || (protocol.length() == 0)) {
- protocol = "tcp";
- }
- protocol = removeSeparators(protocol);
- checkedQualifiedNameMap.put(Fields.Protocol, protocol);
- // Application
- String application = (qualifiedNameMap.containsKey(Fields.Application) ? qualifiedNameMap.get(Fields.Application) : "");
- if ((application == null) || (application.length() == 0)) {
- application = "";
+ application = "";
}
- application = removeSeparators(application);
- checkedQualifiedNameMap.put(Fields.Application, application);
- // Instance
- String instance = (qualifiedNameMap.containsKey(Fields.Instance) ? qualifiedNameMap.get(Fields.Instance) : "");
- if ((instance == null) || (instance.length() == 0)) {
- instance = "";
- // throw new IllegalArgumentException("The instance name component of a fully qualified service cannot be empty.");
- }
- instance = removeSeparators(instance);
- checkedQualifiedNameMap.put(Fields.Instance, instance);
- // Optional Subtype
- String subtype = (qualifiedNameMap.containsKey(Fields.Subtype) ? qualifiedNameMap.get(Fields.Subtype) : "");
- if ((subtype == null) || (subtype.length() == 0)) {
- subtype = "";
- }
- subtype = removeSeparators(subtype);
- checkedQualifiedNameMap.put(Fields.Subtype, subtype);
-
- return checkedQualifiedNameMap;
- }
-
- private static String removeSeparators(String name) {
- if (name == null) {
- return "";
- }
- String newName = name.trim();
- if (newName.startsWith(".")) {
- newName = newName.substring(1);
- }
- if (newName.startsWith("_")) {
- newName = newName.substring(1);
- }
- if (newName.endsWith(".")) {
- newName = newName.substring(0, newName.length() - 1);
- }
- return newName;
- }
-
- @Override
- public String getType() {
- String domain = this.getDomain();
- String protocol = this.getProtocol();
- String application = this.getApplication();
- return (application.length() > 0 ? "_" + application + "." : "") + (protocol.length() > 0 ? "_" + protocol + "." : "") + domain + ".";
- }
-
- @Override
- public String getTypeWithSubtype() {
- String subtype = this.getSubtype();
- return (subtype.length() > 0 ? "_" + subtype + "._sub." : "") + this.getType();
- }
-
- @Override
- public String getName() {
- return (_name != null ? _name : "");
- }
-
- @Override
- public String getKey() {
- if (this._key == null) {
- this._key = this.getQualifiedName().toLowerCase();
- }
- return this._key;
- }
-
- @Override
- public String getQualifiedName() {
- String domain = this.getDomain();
- String protocol = this.getProtocol();
- String application = this.getApplication();
- String instance = this.getName();
- return (instance.length() > 0 ? instance + "." : "") + (application.length() > 0 ? "_" + application + "." : "") + (protocol.length() > 0 ? "_" + protocol + "." : "") + domain + ".";
- }
-
- @Override
- public String getServer() {
- return (_server != null ? _server : "");
- }
- void setServer(String server) {
- this._server = server;
- }
-
- public void addAddress(Inet4Address addr) {
- _ipv4Addresses.add(addr);
- }
- public void addAddress(Inet6Address addr) {
- _ipv6Addresses.add(addr);
- }
-
- @Override
- public Inet4Address[] getInet4Addresses() {
- return _ipv4Addresses.toArray(new Inet4Address[_ipv4Addresses.size()]);
- }
-
- @Override
- public Inet6Address[] getInet6Addresses() {
- return _ipv6Addresses.toArray(new Inet6Address[_ipv6Addresses.size()]);
- }
-
- @Override
- public int getPort() {
- return _port;
- }
-
- @Override
- public int getPriority() {
- return _priority;
- }
-
- @Override
- public int getWeight() {
- return _weight;
- }
-
- @Override
- public byte[] getTextBytes() {
- return (this._text != null && this._text.length > 0 ? this._text : ByteWrangler.EMPTY_TXT);
- }
-
- @Override
- public String getApplication() {
- return (_application != null ? _application : "");
- }
-
- @Override
- public String getDomain() {
- return (_domain != null ? _domain : "local");
- }
-
- @Override
- public String getProtocol() {
- return (_protocol != null ? _protocol : "tcp");
- }
-
- @Override
- public String getSubtype() {
- return (_subtype != null ? _subtype : "");
- }
-
- @Override
- public Map getQualifiedNameMap() {
- Map map = new HashMap(5);
-
- map.put(Fields.Domain, this.getDomain());
- map.put(Fields.Protocol, this.getProtocol());
- map.put(Fields.Application, this.getApplication());
- map.put(Fields.Instance, this.getName());
- map.put(Fields.Subtype, this.getSubtype());
- return map;
- }
-
- @Override
- public synchronized boolean hasData() {
- return this.getServer() != null && this.hasInetAddress() && this.getTextBytes() != null && this.getTextBytes().length > 0;
- }
-
- private boolean hasInetAddress() {
- return _ipv4Addresses.size() > 0 || _ipv6Addresses.size() > 0;
- }
-
- @Override
- public int hashCode() {
- return getQualifiedName().hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- return (obj instanceof ServiceInfoImpl) && getQualifiedName().equals(((ServiceInfoImpl) obj).getQualifiedName());
- }
-
- @Override
- public ServiceInfoImpl clone() {
- ServiceInfoImpl serviceInfo = new ServiceInfoImpl(this.getQualifiedNameMap(), _port, _weight, _priority, _text);
- serviceInfo._ipv6Addresses.addAll(Arrays.asList(getInet6Addresses()));
- serviceInfo._ipv4Addresses.addAll(Arrays.asList(getInet4Addresses()));
- serviceInfo._server = _server;
- return serviceInfo;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append('[').append(this.getClass().getSimpleName()).append('@').append(System.identityHashCode(this));
- sb.append(" name: '");
- if (0 < this.getName().length()) {
- sb.append(this.getName()).append('.');
- }
- sb.append(this.getTypeWithSubtype());
- sb.append("' address: '");
- Inet4Address[] addresses4 = this.getInet4Addresses();
- for (InetAddress address : addresses4) {
- sb.append(address).append(':').append(this.getPort()).append(' ');
- }
- Inet6Address[] addresses6 = this.getInet6Addresses();
- for (InetAddress address : addresses6) {
- sb.append(address).append(':').append(this.getPort()).append(' ');
- }
-
- sb.append(this.hasData() ? " has data" : " has NO data");
- sb.append(']');
-
- return sb.toString();
- }
-
- /**
- * Create a series of answer that correspond with the give service info.
- *
- * @param recordClass
- * record class of the query
- * @param unique
- * @param ttl
- * @param localHost
- * @return collection of answers
- */
- public Collection answers(DNSRecordClass recordClass, boolean unique, int ttl, HostInfo localHost) {
- List list = new ArrayList();
-
- if ((recordClass == DNSRecordClass.CLASS_ANY) || (recordClass == DNSRecordClass.CLASS_IN)) {
- if (this.getSubtype().length() > 0) {
- list.add(new DNSRecord.Pointer(this.getTypeWithSubtype(), DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE, ttl, this.getQualifiedName()));
- }
- list.add(new DNSRecord.Pointer(this.getType(), DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE, ttl, this.getQualifiedName()));
- list.add(new DNSRecord.Service(this.getQualifiedName(), DNSRecordClass.CLASS_IN, unique, ttl, _priority, _weight, _port, localHost.getName()));
- list.add(new DNSRecord.Text(this.getQualifiedName(), DNSRecordClass.CLASS_IN, unique, ttl, this.getTextBytes()));
- for (InetAddress address : _ipv4Addresses)
- list.add(
- new DNSRecord.IPv4Address(
- this.getQualifiedName(),
- DNSRecordClass.CLASS_IN,
- unique,
- ttl,
- address
- )
- );
- for (InetAddress address : _ipv6Addresses)
- list.add(
- new DNSRecord.IPv6Address(
- this.getQualifiedName(),
- DNSRecordClass.CLASS_IN,
- unique,
- ttl,
- address
- )
- );
- }
-
- return list;
- }
+ }
+ index = application.toLowerCase().indexOf("._sub");
+ if (index > 0) {
+ int start = index + 5;
+ subtype = removeSeparators(application.substring(0, index));
+ application = application.substring(start);
+ }
+ }
+
+ final Map qualifiedNameMap = new HashMap(5);
+ qualifiedNameMap.put(Fields.Domain, removeSeparators(domain));
+ qualifiedNameMap.put(Fields.Protocol, protocol);
+ qualifiedNameMap.put(Fields.Application, removeSeparators(application));
+ qualifiedNameMap.put(Fields.Instance, name);
+ qualifiedNameMap.put(Fields.Subtype, subtype);
+
+ return qualifiedNameMap;
+ }
+
+ protected static Map checkQualifiedNameMap(Map qualifiedNameMap) {
+ Map checkedQualifiedNameMap = new HashMap(5);
+
+ // Optional domain
+ String domain =
+ (qualifiedNameMap.containsKey(Fields.Domain)
+ ? qualifiedNameMap.get(Fields.Domain)
+ : "local");
+ if ((domain == null) || (domain.length() == 0)) {
+ domain = "local";
+ }
+ domain = removeSeparators(domain);
+ checkedQualifiedNameMap.put(Fields.Domain, domain);
+ // Optional protocol
+ String protocol =
+ (qualifiedNameMap.containsKey(Fields.Protocol)
+ ? qualifiedNameMap.get(Fields.Protocol)
+ : "tcp");
+ if ((protocol == null) || (protocol.length() == 0)) {
+ protocol = "tcp";
+ }
+ protocol = removeSeparators(protocol);
+ checkedQualifiedNameMap.put(Fields.Protocol, protocol);
+ // Application
+ String application =
+ (qualifiedNameMap.containsKey(Fields.Application)
+ ? qualifiedNameMap.get(Fields.Application)
+ : "");
+ if ((application == null) || (application.length() == 0)) {
+ application = "";
+ }
+ application = removeSeparators(application);
+ checkedQualifiedNameMap.put(Fields.Application, application);
+ // Instance
+ String instance =
+ (qualifiedNameMap.containsKey(Fields.Instance)
+ ? qualifiedNameMap.get(Fields.Instance)
+ : "");
+ if ((instance == null) || (instance.length() == 0)) {
+ instance = "";
+ // throw new IllegalArgumentException("The instance name component of a fully qualified
+ // service cannot be empty.");
+ }
+ instance = removeSeparators(instance);
+ checkedQualifiedNameMap.put(Fields.Instance, instance);
+ // Optional Subtype
+ String subtype =
+ (qualifiedNameMap.containsKey(Fields.Subtype) ? qualifiedNameMap.get(Fields.Subtype) : "");
+ if ((subtype == null) || (subtype.length() == 0)) {
+ subtype = "";
+ }
+ subtype = removeSeparators(subtype);
+ checkedQualifiedNameMap.put(Fields.Subtype, subtype);
+
+ return checkedQualifiedNameMap;
+ }
+
+ private static String removeSeparators(String name) {
+ if (name == null) {
+ return "";
+ }
+ String newName = name.trim();
+ if (newName.startsWith(".")) {
+ newName = newName.substring(1);
+ }
+ if (newName.startsWith("_")) {
+ newName = newName.substring(1);
+ }
+ if (newName.endsWith(".")) {
+ newName = newName.substring(0, newName.length() - 1);
+ }
+ return newName;
+ }
+
+ @Override
+ public String getType() {
+ String domain = this.getDomain();
+ String protocol = this.getProtocol();
+ String application = this.getApplication();
+ return (application.length() > 0 ? "_" + application + "." : "")
+ + (protocol.length() > 0 ? "_" + protocol + "." : "")
+ + domain
+ + ".";
+ }
+
+ @Override
+ public String getTypeWithSubtype() {
+ String subtype = this.getSubtype();
+ return (subtype.length() > 0 ? "_" + subtype + "._sub." : "") + this.getType();
+ }
+
+ @Override
+ public String getName() {
+ return (_name != null ? _name : "");
+ }
+
+ @Override
+ public String getKey() {
+ if (this._key == null) {
+ this._key = this.getQualifiedName().toLowerCase();
+ }
+ return this._key;
+ }
+
+ @Override
+ public String getQualifiedName() {
+ String domain = this.getDomain();
+ String protocol = this.getProtocol();
+ String application = this.getApplication();
+ String instance = this.getName();
+ return (instance.length() > 0 ? instance + "." : "")
+ + (application.length() > 0 ? "_" + application + "." : "")
+ + (protocol.length() > 0 ? "_" + protocol + "." : "")
+ + domain
+ + ".";
+ }
+
+ @Override
+ public String getServer() {
+ return (_server != null ? _server : "");
+ }
+
+ void setServer(String server) {
+ this._server = server;
+ }
+
+ public void addAddress(Inet4Address addr) {
+ _ipv4Addresses.add(addr);
+ }
+
+ public void addAddress(Inet6Address addr) {
+ _ipv6Addresses.add(addr);
+ }
+
+ @Override
+ public Inet4Address[] getInet4Addresses() {
+ return _ipv4Addresses.toArray(new Inet4Address[_ipv4Addresses.size()]);
+ }
+
+ @Override
+ public Inet6Address[] getInet6Addresses() {
+ return _ipv6Addresses.toArray(new Inet6Address[_ipv6Addresses.size()]);
+ }
+
+ @Override
+ public int getPort() {
+ return _port;
+ }
+
+ @Override
+ public int getPriority() {
+ return _priority;
+ }
+
+ @Override
+ public int getWeight() {
+ return _weight;
+ }
+
+ @Override
+ public byte[] getTextBytes() {
+ return (this._text != null && this._text.length > 0 ? this._text : ByteWrangler.EMPTY_TXT);
+ }
+
+ @Override
+ public String getApplication() {
+ return (_application != null ? _application : "");
+ }
+
+ @Override
+ public String getDomain() {
+ return (_domain != null ? _domain : "local");
+ }
+
+ @Override
+ public String getProtocol() {
+ return (_protocol != null ? _protocol : "tcp");
+ }
+
+ @Override
+ public String getSubtype() {
+ return (_subtype != null ? _subtype : "");
+ }
+
+ @Override
+ public Map getQualifiedNameMap() {
+ Map map = new HashMap(5);
+
+ map.put(Fields.Domain, this.getDomain());
+ map.put(Fields.Protocol, this.getProtocol());
+ map.put(Fields.Application, this.getApplication());
+ map.put(Fields.Instance, this.getName());
+ map.put(Fields.Subtype, this.getSubtype());
+ return map;
+ }
+
+ @Override
+ public synchronized boolean hasData() {
+ return this.getServer() != null
+ && this.hasInetAddress()
+ && this.getTextBytes() != null
+ && this.getTextBytes().length > 0;
+ }
+
+ private boolean hasInetAddress() {
+ return _ipv4Addresses.size() > 0 || _ipv6Addresses.size() > 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return getQualifiedName().hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return (obj instanceof ServiceInfoImpl)
+ && getQualifiedName().equals(((ServiceInfoImpl) obj).getQualifiedName());
+ }
+
+ @Override
+ public ServiceInfoImpl clone() {
+ ServiceInfoImpl serviceInfo =
+ new ServiceInfoImpl(this.getQualifiedNameMap(), _port, _weight, _priority, _text);
+ serviceInfo._ipv6Addresses.addAll(Arrays.asList(getInet6Addresses()));
+ serviceInfo._ipv4Addresses.addAll(Arrays.asList(getInet4Addresses()));
+ serviceInfo._server = _server;
+ return serviceInfo;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append('[')
+ .append(this.getClass().getSimpleName())
+ .append('@')
+ .append(System.identityHashCode(this));
+ sb.append(" name: '");
+ if (0 < this.getName().length()) {
+ sb.append(this.getName()).append('.');
+ }
+ sb.append(this.getTypeWithSubtype());
+ sb.append("' address: '");
+ Inet4Address[] addresses4 = this.getInet4Addresses();
+ for (InetAddress address : addresses4) {
+ sb.append(address).append(':').append(this.getPort()).append(' ');
+ }
+ Inet6Address[] addresses6 = this.getInet6Addresses();
+ for (InetAddress address : addresses6) {
+ sb.append(address).append(':').append(this.getPort()).append(' ');
+ }
+
+ sb.append(this.hasData() ? " has data" : " has NO data");
+ sb.append(']');
+
+ return sb.toString();
+ }
+
+ /**
+ * Create a series of answer that correspond with the give service info.
+ *
+ * @param recordClass record class of the query
+ * @param unique
+ * @param ttl
+ * @param localHost
+ * @return collection of answers
+ */
+ public Collection answers(
+ DNSRecordClass recordClass, boolean unique, int ttl, HostInfo localHost) {
+ List list = new ArrayList();
+
+ if ((recordClass == DNSRecordClass.CLASS_ANY) || (recordClass == DNSRecordClass.CLASS_IN)) {
+ if (this.getSubtype().length() > 0) {
+ list.add(
+ new DNSRecord.Pointer(
+ this.getTypeWithSubtype(),
+ DNSRecordClass.CLASS_IN,
+ DNSRecordClass.NOT_UNIQUE,
+ ttl,
+ this.getQualifiedName()));
+ }
+ list.add(
+ new DNSRecord.Pointer(
+ this.getType(),
+ DNSRecordClass.CLASS_IN,
+ DNSRecordClass.NOT_UNIQUE,
+ ttl,
+ this.getQualifiedName()));
+ list.add(
+ new DNSRecord.Service(
+ this.getQualifiedName(),
+ DNSRecordClass.CLASS_IN,
+ unique,
+ ttl,
+ _priority,
+ _weight,
+ _port,
+ localHost.getName()));
+ list.add(
+ new DNSRecord.Text(
+ this.getQualifiedName(), DNSRecordClass.CLASS_IN, unique, ttl, this.getTextBytes()));
+ for (InetAddress address : _ipv4Addresses)
+ list.add(
+ new DNSRecord.IPv4Address(
+ this.getQualifiedName(), DNSRecordClass.CLASS_IN, unique, ttl, address));
+ for (InetAddress address : _ipv6Addresses)
+ list.add(
+ new DNSRecord.IPv6Address(
+ this.getQualifiedName(), DNSRecordClass.CLASS_IN, unique, ttl, address));
+ }
+
+ return list;
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/SocketListener.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/SocketListener.java
index 3edbf9acc..17a3a97d6 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/SocketListener.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/SocketListener.java
@@ -4,85 +4,81 @@
package io.libp2p.discovery.mdns.impl;
+import io.libp2p.discovery.mdns.impl.constants.DNSConstants;
+import io.libp2p.discovery.mdns.impl.util.NamedThreadFactory;
import java.io.IOException;
import java.net.DatagramPacket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
-
-import io.libp2p.discovery.mdns.impl.util.NamedThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.libp2p.discovery.mdns.impl.constants.DNSConstants;
-
-/**
- * Listen for multicast packets.
- */
+/** Listen for multicast packets. */
class SocketListener implements Runnable {
- static Logger logger = LoggerFactory.getLogger(SocketListener.class.getName());
+ static Logger logger = LoggerFactory.getLogger(SocketListener.class.getName());
- private final JmDNSImpl _jmDNSImpl;
- private final String _name;
- private volatile boolean _closed;
- private final ExecutorService _executor = Executors.newSingleThreadExecutor(new NamedThreadFactory("JmDNS"));
- private Future _isShutdown;
+ private final JmDNSImpl _jmDNSImpl;
+ private final String _name;
+ private volatile boolean _closed;
+ private final ExecutorService _executor =
+ Executors.newSingleThreadExecutor(new NamedThreadFactory("JmDNS"));
+ private Future _isShutdown;
- SocketListener(JmDNSImpl jmDNSImpl) {
- _name = "SocketListener(" + (jmDNSImpl != null ? jmDNSImpl.getName() : "") + ")";
- this._jmDNSImpl = jmDNSImpl;
- }
+ SocketListener(JmDNSImpl jmDNSImpl) {
+ _name = "SocketListener(" + (jmDNSImpl != null ? jmDNSImpl.getName() : "") + ")";
+ this._jmDNSImpl = jmDNSImpl;
+ }
- public void start() {
- _isShutdown = _executor.submit(this, null);
- }
- public Future stop() {
- _closed = true;
- _executor.shutdown();
- return _isShutdown;
- }
+ public void start() {
+ _isShutdown = _executor.submit(this, null);
+ }
- @Override
- public void run() {
+ public Future stop() {
+ _closed = true;
+ _executor.shutdown();
+ return _isShutdown;
+ }
+
+ @Override
+ public void run() {
+ try {
+ byte buf[] = new byte[DNSConstants.MAX_MSG_ABSOLUTE];
+ DatagramPacket packet = new DatagramPacket(buf, buf.length);
+ while (!_closed) {
+ packet.setLength(buf.length);
+ this._jmDNSImpl.getSocket().receive(packet);
+ if (_closed) break;
try {
- byte buf[] = new byte[DNSConstants.MAX_MSG_ABSOLUTE];
- DatagramPacket packet = new DatagramPacket(buf, buf.length);
- while (!_closed) {
- packet.setLength(buf.length);
- this._jmDNSImpl.getSocket().receive(packet);
- if (_closed)
- break;
- try {
- if (this._jmDNSImpl.getLocalHost().shouldIgnorePacket(packet)) {
- continue;
- }
+ if (this._jmDNSImpl.getLocalHost().shouldIgnorePacket(packet)) {
+ continue;
+ }
- DNSIncoming msg = new DNSIncoming(packet);
- if (msg.isValidResponseCode()) {
- if (logger.isTraceEnabled()) {
- logger.trace("{}.run() JmDNS in:{}", _name, msg.print(true));
- }
- if (msg.isQuery()) {
- if (packet.getPort() != DNSConstants.MDNS_PORT) {
- this._jmDNSImpl.handleQuery(msg, packet.getAddress(), packet.getPort());
- }
- this._jmDNSImpl.handleQuery(msg, this._jmDNSImpl.getGroup(), DNSConstants.MDNS_PORT);
- } else {
- this._jmDNSImpl.handleResponse(msg);
- }
- } else {
- if (logger.isDebugEnabled()) {
- logger.debug("{}.run() JmDNS in message with error code: {}", _name, msg.print(true));
- }
- }
- } catch (IOException e) {
- logger.warn(_name + ".run() exception ", e);
- }
+ DNSIncoming msg = new DNSIncoming(packet);
+ if (msg.isValidResponseCode()) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("{}.run() JmDNS in:{}", _name, msg.print(true));
+ }
+ if (msg.isQuery()) {
+ if (packet.getPort() != DNSConstants.MDNS_PORT) {
+ this._jmDNSImpl.handleQuery(msg, packet.getAddress(), packet.getPort());
+ }
+ this._jmDNSImpl.handleQuery(msg, this._jmDNSImpl.getGroup(), DNSConstants.MDNS_PORT);
+ } else {
+ this._jmDNSImpl.handleResponse(msg);
+ }
+ } else {
+ if (logger.isDebugEnabled()) {
+ logger.debug("{}.run() JmDNS in message with error code: {}", _name, msg.print(true));
}
+ }
} catch (IOException e) {
- if (!_closed)
- logger.warn(_name + ".run() exception ", e);
+ logger.warn(_name + ".run() exception ", e);
}
- logger.trace("{}.run() exiting.", _name);
+ }
+ } catch (IOException e) {
+ if (!_closed) logger.warn(_name + ".run() exception ", e);
}
+ logger.trace("{}.run() exiting.", _name);
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSConstants.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSConstants.java
index 7def48772..4bcfcdfed 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSConstants.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSConstants.java
@@ -10,57 +10,63 @@
* @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Rick Blair
*/
public final class DNSConstants {
- // http://www.iana.org/assignments/dns-parameters
+ // http://www.iana.org/assignments/dns-parameters
- // changed to final class - jeffs
- public static final String MDNS_GROUP = "224.0.0.251";
- public static final String MDNS_GROUP_IPV6 = "FF02::FB";
- public static final int MDNS_PORT = Integer.getInteger("net.mdns.port", 5353);
- public static final int DNS_PORT = 53;
- public static final int DNS_TTL = Integer.getInteger("net.dns.ttl", 60 * 60); // default one hour TTL
- // public static final int DNS_TTL = 120 * 60; // two hour TTL (draft-cheshire-dnsext-multicastdns.txt ch 13)
+ // changed to final class - jeffs
+ public static final String MDNS_GROUP = "224.0.0.251";
+ public static final String MDNS_GROUP_IPV6 = "FF02::FB";
+ public static final int MDNS_PORT = Integer.getInteger("net.mdns.port", 5353);
+ public static final int DNS_PORT = 53;
+ public static final int DNS_TTL =
+ Integer.getInteger("net.dns.ttl", 60 * 60); // default one hour TTL
+ // public static final int DNS_TTL = 120 * 60; // two hour TTL
+ // (draft-cheshire-dnsext-multicastdns.txt ch 13)
- public static final int MAX_MSG_TYPICAL = 1460;
- public static final int MAX_MSG_ABSOLUTE = 8972;
+ public static final int MAX_MSG_TYPICAL = 1460;
+ public static final int MAX_MSG_ABSOLUTE = 8972;
- public static final int FLAGS_QR_MASK = 0x8000; // Query response mask
- public static final int FLAGS_QR_QUERY = 0x0000; // Query
- public static final int FLAGS_QR_RESPONSE = 0x8000; // Response
+ public static final int FLAGS_QR_MASK = 0x8000; // Query response mask
+ public static final int FLAGS_QR_QUERY = 0x0000; // Query
+ public static final int FLAGS_QR_RESPONSE = 0x8000; // Response
- public static final int FLAGS_OPCODE = 0x7800; // Operation code
- public static final int FLAGS_AA = 0x0400; // Authorative answer
- public static final int FLAGS_TC = 0x0200; // Truncated
- public static final int FLAGS_RD = 0x0100; // Recursion desired
- public static final int FLAGS_RA = 0x8000; // Recursion available
+ public static final int FLAGS_OPCODE = 0x7800; // Operation code
+ public static final int FLAGS_AA = 0x0400; // Authorative answer
+ public static final int FLAGS_TC = 0x0200; // Truncated
+ public static final int FLAGS_RD = 0x0100; // Recursion desired
+ public static final int FLAGS_RA = 0x8000; // Recursion available
- public static final int FLAGS_Z = 0x0040; // Zero
- public static final int FLAGS_AD = 0x0020; // Authentic data
- public static final int FLAGS_CD = 0x0010; // Checking disabled
- public static final int FLAGS_RCODE = 0x000F; // Response code
+ public static final int FLAGS_Z = 0x0040; // Zero
+ public static final int FLAGS_AD = 0x0020; // Authentic data
+ public static final int FLAGS_CD = 0x0010; // Checking disabled
+ public static final int FLAGS_RCODE = 0x000F; // Response code
- // Time Intervals for various functions
+ // Time Intervals for various functions
- public static final int SHARED_QUERY_TIME = 20; // milliseconds before send shared query
- public static final int QUERY_WAIT_INTERVAL = 225; // milliseconds between query loops.
- public static final int PROBE_WAIT_INTERVAL = 250; // milliseconds between probe loops.
- public static final int RESPONSE_MIN_WAIT_INTERVAL = 20; // minimal wait interval for response.
- public static final int RESPONSE_MAX_WAIT_INTERVAL = 115; // maximal wait interval for response
- public static final int PROBE_CONFLICT_INTERVAL = 1000; // milliseconds to wait after conflict.
- public static final int PROBE_THROTTLE_COUNT = 10; // After x tries go 1 time a sec. on probes.
- public static final int PROBE_THROTTLE_COUNT_INTERVAL = 5000; // We only increment the throttle count, if the previous increment is inside this interval.
- public static final int ANNOUNCE_WAIT_INTERVAL = 1000; // milliseconds between Announce loops.
- public static final int RECORD_REAPER_INTERVAL = 10000; // milliseconds between cache cleanups.
- public static final int RECORD_EXPIRY_DELAY = 1; // This is 1s delay used in ttl and therefore in seconds
- public static final int KNOWN_ANSWER_TTL = 120;
- public static final int ANNOUNCED_RENEWAL_TTL_INTERVAL = DNS_TTL * 500; // 50% of the TTL in milliseconds
- public static final int FLUSH_RECORD_OLDER_THAN_1_SECOND = 1; // rfc6762, section 10.2 Flush outdated cache (older than 1 second)
+ public static final int SHARED_QUERY_TIME = 20; // milliseconds before send shared query
+ public static final int QUERY_WAIT_INTERVAL = 225; // milliseconds between query loops.
+ public static final int PROBE_WAIT_INTERVAL = 250; // milliseconds between probe loops.
+ public static final int RESPONSE_MIN_WAIT_INTERVAL = 20; // minimal wait interval for response.
+ public static final int RESPONSE_MAX_WAIT_INTERVAL = 115; // maximal wait interval for response
+ public static final int PROBE_CONFLICT_INTERVAL = 1000; // milliseconds to wait after conflict.
+ public static final int PROBE_THROTTLE_COUNT = 10; // After x tries go 1 time a sec. on probes.
+ public static final int PROBE_THROTTLE_COUNT_INTERVAL =
+ 5000; // We only increment the throttle count, if the previous increment is inside this
+ // interval.
+ public static final int ANNOUNCE_WAIT_INTERVAL = 1000; // milliseconds between Announce loops.
+ public static final int RECORD_REAPER_INTERVAL = 10000; // milliseconds between cache cleanups.
+ public static final int RECORD_EXPIRY_DELAY =
+ 1; // This is 1s delay used in ttl and therefore in seconds
+ public static final int KNOWN_ANSWER_TTL = 120;
+ public static final int ANNOUNCED_RENEWAL_TTL_INTERVAL =
+ DNS_TTL * 500; // 50% of the TTL in milliseconds
+ public static final int FLUSH_RECORD_OLDER_THAN_1_SECOND =
+ 1; // rfc6762, section 10.2 Flush outdated cache (older than 1 second)
- public static final int STALE_REFRESH_INCREMENT = 5;
- public static final int STALE_REFRESH_STARTING_PERCENTAGE = 80;
+ public static final int STALE_REFRESH_INCREMENT = 5;
+ public static final int STALE_REFRESH_STARTING_PERCENTAGE = 80;
- public static final long CLOSE_TIMEOUT = ANNOUNCE_WAIT_INTERVAL * 5L;
- public static final long SERVICE_INFO_TIMEOUT = ANNOUNCE_WAIT_INTERVAL * 6L;
-
- public static final int NETWORK_CHECK_INTERVAL = 10 * 1000; // 10 secondes
+ public static final long CLOSE_TIMEOUT = ANNOUNCE_WAIT_INTERVAL * 5L;
+ public static final long SERVICE_INFO_TIMEOUT = ANNOUNCE_WAIT_INTERVAL * 6L;
+ public static final int NETWORK_CHECK_INTERVAL = 10 * 1000; // 10 secondes
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSLabel.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSLabel.java
index 86bf62a73..986c31efa 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSLabel.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSLabel.java
@@ -1,87 +1,75 @@
-/**
- *
- */
+/** */
package io.libp2p.discovery.mdns.impl.constants;
/**
* DNS label.
- *
+ *
* @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Rick Blair
*/
public enum DNSLabel {
- /**
- * This is unallocated.
- */
- Unknown("", 0x80),
- /**
- * Standard label [RFC 1035]
- */
- Standard("standard label", 0x00),
- /**
- * Compressed label [RFC 1035]
- */
- Compressed("compressed label", 0xC0),
- /**
- * Extended label [RFC 2671]
- */
- Extended("extended label", 0x40);
+ /** This is unallocated. */
+ Unknown("", 0x80),
+ /** Standard label [RFC 1035] */
+ Standard("standard label", 0x00),
+ /** Compressed label [RFC 1035] */
+ Compressed("compressed label", 0xC0),
+ /** Extended label [RFC 2671] */
+ Extended("extended label", 0x40);
- /**
- * DNS label types are encoded on the first 2 bits
- */
- static final int LABEL_MASK = 0xC0;
- static final int LABEL_NOT_MASK = 0x3F;
+ /** DNS label types are encoded on the first 2 bits */
+ static final int LABEL_MASK = 0xC0;
- private final String _externalName;
+ static final int LABEL_NOT_MASK = 0x3F;
- private final int _index;
+ private final String _externalName;
- DNSLabel(String name, int index) {
- _externalName = name;
- _index = index;
- }
+ private final int _index;
- /**
- * Return the string representation of this type
- *
- * @return String
- */
- public String externalName() {
- return _externalName;
- }
+ DNSLabel(String name, int index) {
+ _externalName = name;
+ _index = index;
+ }
- /**
- * Return the numeric value of this type
- *
- * @return String
- */
- public int indexValue() {
- return _index;
- }
+ /**
+ * Return the string representation of this type
+ *
+ * @return String
+ */
+ public String externalName() {
+ return _externalName;
+ }
- /**
- * @param index
- * @return label
- */
- public static DNSLabel labelForByte(int index) {
- int maskedIndex = index & LABEL_MASK;
- for (DNSLabel aLabel : DNSLabel.values()) {
- if (aLabel._index == maskedIndex) return aLabel;
- }
- return Unknown;
- }
+ /**
+ * Return the numeric value of this type
+ *
+ * @return String
+ */
+ public int indexValue() {
+ return _index;
+ }
- /**
- * @param index
- * @return masked value
- */
- public static int labelValue(int index) {
- return index & LABEL_NOT_MASK;
+ /**
+ * @param index
+ * @return label
+ */
+ public static DNSLabel labelForByte(int index) {
+ int maskedIndex = index & LABEL_MASK;
+ for (DNSLabel aLabel : DNSLabel.values()) {
+ if (aLabel._index == maskedIndex) return aLabel;
}
+ return Unknown;
+ }
- @Override
- public String toString() {
- return this.name() + " index " + this.indexValue();
- }
+ /**
+ * @param index
+ * @return masked value
+ */
+ public static int labelValue(int index) {
+ return index & LABEL_NOT_MASK;
+ }
+ @Override
+ public String toString() {
+ return this.name() + " index " + this.indexValue();
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSOperationCode.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSOperationCode.java
index 5045e0ea7..9c495fddb 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSOperationCode.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSOperationCode.java
@@ -1,86 +1,69 @@
-/**
- *
- */
+/** */
package io.libp2p.discovery.mdns.impl.constants;
/**
* DNS operation code.
- *
+ *
* @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Rick Blair
*/
public enum DNSOperationCode {
- /**
- * Query [RFC1035]
- */
- Query("Query", 0),
- /**
- * IQuery (Inverse Query, Obsolete) [RFC3425]
- */
- IQuery("Inverse Query", 1),
- /**
- * Status [RFC1035]
- */
- Status("Status", 2),
- /**
- * Unassigned
- */
- Unassigned("Unassigned", 3),
- /**
- * Notify [RFC1996]
- */
- Notify("Notify", 4),
- /**
- * Update [RFC2136]
- */
- Update("Update", 5);
+ /** Query [RFC1035] */
+ Query("Query", 0),
+ /** IQuery (Inverse Query, Obsolete) [RFC3425] */
+ IQuery("Inverse Query", 1),
+ /** Status [RFC1035] */
+ Status("Status", 2),
+ /** Unassigned */
+ Unassigned("Unassigned", 3),
+ /** Notify [RFC1996] */
+ Notify("Notify", 4),
+ /** Update [RFC2136] */
+ Update("Update", 5);
- /**
- * DNS RCode types are encoded on the last 4 bits
- */
- static final int OpCode_MASK = 0x7800;
+ /** DNS RCode types are encoded on the last 4 bits */
+ static final int OpCode_MASK = 0x7800;
- private final String _externalName;
+ private final String _externalName;
- private final int _index;
+ private final int _index;
- DNSOperationCode(String name, int index) {
- _externalName = name;
- _index = index;
- }
+ DNSOperationCode(String name, int index) {
+ _externalName = name;
+ _index = index;
+ }
- /**
- * Return the string representation of this type
- *
- * @return String
- */
- public String externalName() {
- return _externalName;
- }
-
- /**
- * Return the numeric value of this type
- *
- * @return String
- */
- public int indexValue() {
- return _index;
- }
+ /**
+ * Return the string representation of this type
+ *
+ * @return String
+ */
+ public String externalName() {
+ return _externalName;
+ }
- /**
- * @param flags
- * @return label
- */
- public static DNSOperationCode operationCodeForFlags(int flags) {
- int maskedIndex = (flags & OpCode_MASK) >> 11;
- for (DNSOperationCode aCode : DNSOperationCode.values()) {
- if (aCode._index == maskedIndex) return aCode;
- }
- return Unassigned;
- }
+ /**
+ * Return the numeric value of this type
+ *
+ * @return String
+ */
+ public int indexValue() {
+ return _index;
+ }
- @Override
- public String toString() {
- return this.name() + " index " + this.indexValue();
+ /**
+ * @param flags
+ * @return label
+ */
+ public static DNSOperationCode operationCodeForFlags(int flags) {
+ int maskedIndex = (flags & OpCode_MASK) >> 11;
+ for (DNSOperationCode aCode : DNSOperationCode.values()) {
+ if (aCode._index == maskedIndex) return aCode;
}
+ return Unassigned;
+ }
+ @Override
+ public String toString() {
+ return this.name() + " index " + this.indexValue();
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSOptionCode.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSOptionCode.java
index d254c2424..a30f437bf 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSOptionCode.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSOptionCode.java
@@ -1,78 +1,65 @@
-/**
- *
- */
+/** */
package io.libp2p.discovery.mdns.impl.constants;
/**
* DNS option code.
- *
+ *
* @author Arthur van Hoff, Pierre Frisch, Rick Blair
*/
public enum DNSOptionCode {
- /**
- * Token
- */
- Unknown("Unknown", 65535),
- /**
- * Long-Lived Queries Option [http://files.dns-sd.org/draft-sekar-dns-llq.txt]
- */
- LLQ("LLQ", 1),
- /**
- * Update Leases Option [http://files.dns-sd.org/draft-sekar-dns-ul.txt]
- */
- UL("UL", 2),
- /**
- * Name Server Identifier Option [RFC5001]
- */
- NSID("NSID", 3),
- /**
- * Owner Option [draft-cheshire-edns0-owner-option]
- */
- Owner("Owner", 4);
+ /** Token */
+ Unknown("Unknown", 65535),
+ /** Long-Lived Queries Option [http://files.dns-sd.org/draft-sekar-dns-llq.txt] */
+ LLQ("LLQ", 1),
+ /** Update Leases Option [http://files.dns-sd.org/draft-sekar-dns-ul.txt] */
+ UL("UL", 2),
+ /** Name Server Identifier Option [RFC5001] */
+ NSID("NSID", 3),
+ /** Owner Option [draft-cheshire-edns0-owner-option] */
+ Owner("Owner", 4);
- private final String _externalName;
+ private final String _externalName;
- private final int _index;
+ private final int _index;
- DNSOptionCode(String name, int index) {
- _externalName = name;
- _index = index;
- }
+ DNSOptionCode(String name, int index) {
+ _externalName = name;
+ _index = index;
+ }
- /**
- * Return the string representation of this type
- *
- * @return String
- */
- public String externalName() {
- return _externalName;
- }
-
- /**
- * Return the numeric value of this type
- *
- * @return String
- */
- public int indexValue() {
- return _index;
- }
+ /**
+ * Return the string representation of this type
+ *
+ * @return String
+ */
+ public String externalName() {
+ return _externalName;
+ }
- /**
- * @param optioncode
- * @return label
- */
- public static DNSOptionCode resultCodeForFlags(int optioncode) {
- int maskedIndex = optioncode;
- for (DNSOptionCode aCode : DNSOptionCode.values()) {
- if (aCode._index == maskedIndex) return aCode;
- }
- return Unknown;
- }
+ /**
+ * Return the numeric value of this type
+ *
+ * @return String
+ */
+ public int indexValue() {
+ return _index;
+ }
- @Override
- public String toString() {
- return this.name() + " index " + this.indexValue();
+ /**
+ * @param optioncode
+ * @return label
+ */
+ public static DNSOptionCode resultCodeForFlags(int optioncode) {
+ int maskedIndex = optioncode;
+ for (DNSOptionCode aCode : DNSOptionCode.values()) {
+ if (aCode._index == maskedIndex) return aCode;
}
+ return Unknown;
+ }
+ @Override
+ public String toString() {
+ return this.name() + " index " + this.indexValue();
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSRecordClass.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSRecordClass.java
index 359279f88..40bb610f4 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSRecordClass.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSRecordClass.java
@@ -1,6 +1,4 @@
-/**
- *
- */
+/** */
package io.libp2p.discovery.mdns.impl.constants;
import org.slf4j.Logger;
@@ -8,131 +6,112 @@
/**
* DNS Record Class
- *
+ *
* @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Rick Blair
*/
public enum DNSRecordClass {
- /**
- *
- */
- CLASS_UNKNOWN("?", 0),
- /**
- * static final Internet
- */
- CLASS_IN("in", 1),
- /**
- * CSNET
- */
- CLASS_CS("cs", 2),
- /**
- * CHAOS
- */
- CLASS_CH("ch", 3),
- /**
- * Hesiod
- */
- CLASS_HS("hs", 4),
- /**
- * Used in DNS UPDATE [RFC 2136]
- */
- CLASS_NONE("none", 254),
- /**
- * Not a DNS class, but a DNS query class, meaning "all classes"
- */
- CLASS_ANY("any", 255);
-
- private static Logger logger = LoggerFactory.getLogger(DNSRecordClass.class.getName());
-
- /**
- * Multicast DNS uses the bottom 15 bits to identify the record class...
- * Except for pseudo records like OPT.
- */
- public static final int CLASS_MASK = 0x7FFF;
-
- /**
- * For answers the top bit indicates that all other cached records are now invalid.
- * For questions it indicates that we should send a unicast response.
- */
- public static final int CLASS_UNIQUE = 0x8000;
-
- /**
- *
- */
- public static final boolean UNIQUE = true;
-
- /**
- *
- */
- public static final boolean NOT_UNIQUE = false;
-
- private final String _externalName;
-
- private final int _index;
-
- DNSRecordClass(String name, int index) {
- _externalName = name;
- _index = index;
- }
-
- /**
- * Return the string representation of this type
- *
- * @return String
- */
- public String externalName() {
- return _externalName;
- }
-
- /**
- * Return the numeric value of this type
- *
- * @return String
- */
- public int indexValue() {
- return _index;
+ /** */
+ CLASS_UNKNOWN("?", 0),
+ /** static final Internet */
+ CLASS_IN("in", 1),
+ /** CSNET */
+ CLASS_CS("cs", 2),
+ /** CHAOS */
+ CLASS_CH("ch", 3),
+ /** Hesiod */
+ CLASS_HS("hs", 4),
+ /** Used in DNS UPDATE [RFC 2136] */
+ CLASS_NONE("none", 254),
+ /** Not a DNS class, but a DNS query class, meaning "all classes" */
+ CLASS_ANY("any", 255);
+
+ private static Logger logger = LoggerFactory.getLogger(DNSRecordClass.class.getName());
+
+ /**
+ * Multicast DNS uses the bottom 15 bits to identify the record class...
+ * Except for pseudo records like OPT.
+ */
+ public static final int CLASS_MASK = 0x7FFF;
+
+ /**
+ * For answers the top bit indicates that all other cached records are now invalid.
+ * For questions it indicates that we should send a unicast response.
+ */
+ public static final int CLASS_UNIQUE = 0x8000;
+
+ /** */
+ public static final boolean UNIQUE = true;
+
+ /** */
+ public static final boolean NOT_UNIQUE = false;
+
+ private final String _externalName;
+
+ private final int _index;
+
+ DNSRecordClass(String name, int index) {
+ _externalName = name;
+ _index = index;
+ }
+
+ /**
+ * Return the string representation of this type
+ *
+ * @return String
+ */
+ public String externalName() {
+ return _externalName;
+ }
+
+ /**
+ * Return the numeric value of this type
+ *
+ * @return String
+ */
+ public int indexValue() {
+ return _index;
+ }
+
+ /**
+ * Checks if the class is unique
+ *
+ * @param index
+ * @return true
is the class is unique, false
otherwise.
+ */
+ public boolean isUnique(int index) {
+ return (this != CLASS_UNKNOWN) && ((index & CLASS_UNIQUE) != 0);
+ }
+
+ /**
+ * @param name
+ * @return class for name
+ */
+ public static DNSRecordClass classForName(String name) {
+ if (name != null) {
+ String aName = name.toLowerCase();
+ for (DNSRecordClass aClass : DNSRecordClass.values()) {
+ if (aClass._externalName.equals(aName)) return aClass;
+ }
}
-
- /**
- * Checks if the class is unique
- *
- * @param index
- * @return true
is the class is unique, false
otherwise.
- */
- public boolean isUnique(int index) {
- return (this != CLASS_UNKNOWN) && ((index & CLASS_UNIQUE) != 0);
- }
-
- /**
- * @param name
- * @return class for name
- */
- public static DNSRecordClass classForName(String name) {
- if (name != null) {
- String aName = name.toLowerCase();
- for (DNSRecordClass aClass : DNSRecordClass.values()) {
- if (aClass._externalName.equals(aName)) return aClass;
- }
- }
- logger.warn("Could not find record class for name: {}", name);
- return CLASS_UNKNOWN;
- }
-
- /**
- * @param index
- * @return class for name
- */
- public static DNSRecordClass classForIndex(int index) {
- int maskedIndex = index & CLASS_MASK;
- for (DNSRecordClass aClass : DNSRecordClass.values()) {
- if (aClass._index == maskedIndex) return aClass;
- }
- logger.warn("Could not find record class for index: {}", index);
- return CLASS_UNKNOWN;
- }
-
- @Override
- public String toString() {
- return this.name() + " index " + this.indexValue();
+ logger.warn("Could not find record class for name: {}", name);
+ return CLASS_UNKNOWN;
+ }
+
+ /**
+ * @param index
+ * @return class for name
+ */
+ public static DNSRecordClass classForIndex(int index) {
+ int maskedIndex = index & CLASS_MASK;
+ for (DNSRecordClass aClass : DNSRecordClass.values()) {
+ if (aClass._index == maskedIndex) return aClass;
}
-
+ logger.warn("Could not find record class for index: {}", index);
+ return CLASS_UNKNOWN;
+ }
+
+ @Override
+ public String toString() {
+ return this.name() + " index " + this.indexValue();
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSRecordType.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSRecordType.java
index 0ad1e8e9f..9ff8754ac 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSRecordType.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSRecordType.java
@@ -1,6 +1,4 @@
-/**
- *
- */
+/** */
package io.libp2p.discovery.mdns.impl.constants;
import org.slf4j.Logger;
@@ -8,306 +6,187 @@
/**
* DNS Record Type
- *
+ *
* @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Rick Blair
*/
public enum DNSRecordType {
- /**
- * Address
- */
- TYPE_IGNORE("ignore", 0),
- /**
- * Address
- */
- TYPE_A("a", 1),
- /**
- * Name Server
- */
- TYPE_NS("ns", 2),
- /**
- * Mail Destination
- */
- TYPE_MD("md", 3),
- /**
- * Mail Forwarder
- */
- TYPE_MF("mf", 4),
- /**
- * Canonical Name
- */
- TYPE_CNAME("cname", 5),
- /**
- * Start of Authority
- */
- TYPE_SOA("soa", 6),
- /**
- * Mailbox
- */
- TYPE_MB("mb", 7),
- /**
- * Mail Group
- */
- TYPE_MG("mg", 8),
- /**
- * Mail Rename
- */
- TYPE_MR("mr", 9),
- /**
- * NULL RR
- */
- TYPE_NULL("null", 10),
- /**
- * Well-known-service
- */
- TYPE_WKS("wks", 11),
- /**
- * Domain Name pointer
- */
- TYPE_PTR("ptr", 12),
- /**
- * Host information
- */
- TYPE_HINFO("hinfo", 13),
- /**
- * Mailbox information
- */
- TYPE_MINFO("minfo", 14),
- /**
- * Mail exchanger
- */
- TYPE_MX("mx", 15),
- /**
- * Arbitrary text string
- */
- TYPE_TXT("txt", 16),
- /**
- * for Responsible Person [RFC1183]
- */
- TYPE_RP("rp", 17),
- /**
- * for AFS Data Base location [RFC1183]
- */
- TYPE_AFSDB("afsdb", 18),
- /**
- * for X.25 PSDN address [RFC1183]
- */
- TYPE_X25("x25", 19),
- /**
- * for ISDN address [RFC1183]
- */
- TYPE_ISDN("isdn", 20),
- /**
- * for Route Through [RFC1183]
- */
- TYPE_RT("rt", 21),
- /**
- * for NSAP address, NSAP style A record [RFC1706]
- */
- TYPE_NSAP("nsap", 22),
- /**
- *
- */
- TYPE_NSAP_PTR("nsap-otr", 23),
- /**
- * for security signature [RFC2931]
- */
- TYPE_SIG("sig", 24),
- /**
- * for security key [RFC2535]
- */
- TYPE_KEY("key", 25),
- /**
- * X.400 mail mapping information [RFC2163]
- */
- TYPE_PX("px", 26),
- /**
- * Geographical Position [RFC1712]
- */
- TYPE_GPOS("gpos", 27),
- /**
- * IP6 Address [Thomson]
- */
- TYPE_AAAA("aaaa", 28),
- /**
- * Location Information [Vixie]
- */
- TYPE_LOC("loc", 29),
- /**
- * Next Domain - OBSOLETE [RFC2535, RFC3755]
- */
- TYPE_NXT("nxt", 30),
- /**
- * Endpoint Identifier [Patton]
- */
- TYPE_EID("eid", 31),
- /**
- * Nimrod Locator [Patton]
- */
- TYPE_NIMLOC("nimloc", 32),
- /**
- * Server Selection [RFC2782]
- */
- TYPE_SRV("srv", 33),
- /**
- * ATM Address [Dobrowski]
- */
- TYPE_ATMA("atma", 34),
- /**
- * Naming Authority Pointer [RFC2168, RFC2915]
- */
- TYPE_NAPTR("naptr", 35),
- /**
- * Key Exchanger [RFC2230]
- */
- TYPE_KX("kx", 36),
- /**
- * CERT [RFC2538]
- */
- TYPE_CERT("cert", 37),
- /**
- * A6 [RFC2874]
- */
- TYPE_A6("a6", 38),
- /**
- * DNAME [RFC2672]
- */
- TYPE_DNAME("dname", 39),
- /**
- * SINK [Eastlake]
- */
- TYPE_SINK("sink", 40),
- /**
- * OPT [RFC2671]
- */
- TYPE_OPT("opt", 41),
- /**
- * APL [RFC3123]
- */
- TYPE_APL("apl", 42),
- /**
- * Delegation Signer [RFC3658]
- */
- TYPE_DS("ds", 43),
- /**
- * SSH Key Fingerprint [RFC-ietf-secsh-dns-05.txt]
- */
- TYPE_SSHFP("sshfp", 44),
- /**
- * RRSIG [RFC3755]
- */
- TYPE_RRSIG("rrsig", 46),
- /**
- * NSEC [RFC3755]
- */
- TYPE_NSEC("nsec", 47),
- /**
- * DNSKEY [RFC3755]
- */
- TYPE_DNSKEY("dnskey", 48),
- /**
- * [IANA-Reserved]
- */
- TYPE_UINFO("uinfo", 100),
- /**
- * [IANA-Reserved]
- */
- TYPE_UID("uid", 101),
- /**
- * [IANA-Reserved]
- */
- TYPE_GID("gid", 102),
- /**
- * [IANA-Reserved]
- */
- TYPE_UNSPEC("unspec", 103),
- /**
- * Transaction Key [RFC2930]
- */
- TYPE_TKEY("tkey", 249),
- /**
- * Transaction Signature [RFC2845]
- */
- TYPE_TSIG("tsig", 250),
- /**
- * Incremental transfer [RFC1995]
- */
- TYPE_IXFR("ixfr", 251),
- /**
- * Transfer of an entire zone [RFC1035]
- */
- TYPE_AXFR("axfr", 252),
- /**
- * Mailbox-related records (MB, MG or MR) [RFC1035]
- */
- TYPE_MAILA("mails", 253),
- /**
- * Mail agent RRs (Obsolete - see MX) [RFC1035]
- */
- TYPE_MAILB("mailb", 254),
- /**
- * Request for all records [RFC1035]
- */
- TYPE_ANY("any", 255);
+ /** Address */
+ TYPE_IGNORE("ignore", 0),
+ /** Address */
+ TYPE_A("a", 1),
+ /** Name Server */
+ TYPE_NS("ns", 2),
+ /** Mail Destination */
+ TYPE_MD("md", 3),
+ /** Mail Forwarder */
+ TYPE_MF("mf", 4),
+ /** Canonical Name */
+ TYPE_CNAME("cname", 5),
+ /** Start of Authority */
+ TYPE_SOA("soa", 6),
+ /** Mailbox */
+ TYPE_MB("mb", 7),
+ /** Mail Group */
+ TYPE_MG("mg", 8),
+ /** Mail Rename */
+ TYPE_MR("mr", 9),
+ /** NULL RR */
+ TYPE_NULL("null", 10),
+ /** Well-known-service */
+ TYPE_WKS("wks", 11),
+ /** Domain Name pointer */
+ TYPE_PTR("ptr", 12),
+ /** Host information */
+ TYPE_HINFO("hinfo", 13),
+ /** Mailbox information */
+ TYPE_MINFO("minfo", 14),
+ /** Mail exchanger */
+ TYPE_MX("mx", 15),
+ /** Arbitrary text string */
+ TYPE_TXT("txt", 16),
+ /** for Responsible Person [RFC1183] */
+ TYPE_RP("rp", 17),
+ /** for AFS Data Base location [RFC1183] */
+ TYPE_AFSDB("afsdb", 18),
+ /** for X.25 PSDN address [RFC1183] */
+ TYPE_X25("x25", 19),
+ /** for ISDN address [RFC1183] */
+ TYPE_ISDN("isdn", 20),
+ /** for Route Through [RFC1183] */
+ TYPE_RT("rt", 21),
+ /** for NSAP address, NSAP style A record [RFC1706] */
+ TYPE_NSAP("nsap", 22),
+ /** */
+ TYPE_NSAP_PTR("nsap-otr", 23),
+ /** for security signature [RFC2931] */
+ TYPE_SIG("sig", 24),
+ /** for security key [RFC2535] */
+ TYPE_KEY("key", 25),
+ /** X.400 mail mapping information [RFC2163] */
+ TYPE_PX("px", 26),
+ /** Geographical Position [RFC1712] */
+ TYPE_GPOS("gpos", 27),
+ /** IP6 Address [Thomson] */
+ TYPE_AAAA("aaaa", 28),
+ /** Location Information [Vixie] */
+ TYPE_LOC("loc", 29),
+ /** Next Domain - OBSOLETE [RFC2535, RFC3755] */
+ TYPE_NXT("nxt", 30),
+ /** Endpoint Identifier [Patton] */
+ TYPE_EID("eid", 31),
+ /** Nimrod Locator [Patton] */
+ TYPE_NIMLOC("nimloc", 32),
+ /** Server Selection [RFC2782] */
+ TYPE_SRV("srv", 33),
+ /** ATM Address [Dobrowski] */
+ TYPE_ATMA("atma", 34),
+ /** Naming Authority Pointer [RFC2168, RFC2915] */
+ TYPE_NAPTR("naptr", 35),
+ /** Key Exchanger [RFC2230] */
+ TYPE_KX("kx", 36),
+ /** CERT [RFC2538] */
+ TYPE_CERT("cert", 37),
+ /** A6 [RFC2874] */
+ TYPE_A6("a6", 38),
+ /** DNAME [RFC2672] */
+ TYPE_DNAME("dname", 39),
+ /** SINK [Eastlake] */
+ TYPE_SINK("sink", 40),
+ /** OPT [RFC2671] */
+ TYPE_OPT("opt", 41),
+ /** APL [RFC3123] */
+ TYPE_APL("apl", 42),
+ /** Delegation Signer [RFC3658] */
+ TYPE_DS("ds", 43),
+ /** SSH Key Fingerprint [RFC-ietf-secsh-dns-05.txt] */
+ TYPE_SSHFP("sshfp", 44),
+ /** RRSIG [RFC3755] */
+ TYPE_RRSIG("rrsig", 46),
+ /** NSEC [RFC3755] */
+ TYPE_NSEC("nsec", 47),
+ /** DNSKEY [RFC3755] */
+ TYPE_DNSKEY("dnskey", 48),
+ /** [IANA-Reserved] */
+ TYPE_UINFO("uinfo", 100),
+ /** [IANA-Reserved] */
+ TYPE_UID("uid", 101),
+ /** [IANA-Reserved] */
+ TYPE_GID("gid", 102),
+ /** [IANA-Reserved] */
+ TYPE_UNSPEC("unspec", 103),
+ /** Transaction Key [RFC2930] */
+ TYPE_TKEY("tkey", 249),
+ /** Transaction Signature [RFC2845] */
+ TYPE_TSIG("tsig", 250),
+ /** Incremental transfer [RFC1995] */
+ TYPE_IXFR("ixfr", 251),
+ /** Transfer of an entire zone [RFC1035] */
+ TYPE_AXFR("axfr", 252),
+ /** Mailbox-related records (MB, MG or MR) [RFC1035] */
+ TYPE_MAILA("mails", 253),
+ /** Mail agent RRs (Obsolete - see MX) [RFC1035] */
+ TYPE_MAILB("mailb", 254),
+ /** Request for all records [RFC1035] */
+ TYPE_ANY("any", 255);
- private static Logger logger = LoggerFactory.getLogger(DNSRecordType.class.getName());
+ private static Logger logger = LoggerFactory.getLogger(DNSRecordType.class.getName());
- private final String _externalName;
+ private final String _externalName;
- private final int _index;
+ private final int _index;
- DNSRecordType(String name, int index) {
- _externalName = name;
- _index = index;
- }
+ DNSRecordType(String name, int index) {
+ _externalName = name;
+ _index = index;
+ }
- /**
- * Return the string representation of this type
- *
- * @return String
- */
- public String externalName() {
- return _externalName;
- }
-
- /**
- * Return the numeric value of this type
- *
- * @return String
- */
- public int indexValue() {
- return _index;
- }
+ /**
+ * Return the string representation of this type
+ *
+ * @return String
+ */
+ public String externalName() {
+ return _externalName;
+ }
- /**
- * @param name
- * @return type for name
- */
- public static DNSRecordType typeForName(String name) {
- if (name != null) {
- String aName = name.toLowerCase();
- for (DNSRecordType aType : DNSRecordType.values()) {
- if (aType._externalName.equals(aName)) return aType;
- }
- }
- logger.warn("Could not find record type for name: {}", name);
- return TYPE_IGNORE;
- }
+ /**
+ * Return the numeric value of this type
+ *
+ * @return String
+ */
+ public int indexValue() {
+ return _index;
+ }
- /**
- * @param index
- * @return type for name
- */
- public static DNSRecordType typeForIndex(int index) {
- for (DNSRecordType aType : DNSRecordType.values()) {
- if (aType._index == index) return aType;
- }
- logger.warn("Could not find record type for index: {}", index);
- return TYPE_IGNORE;
+ /**
+ * @param name
+ * @return type for name
+ */
+ public static DNSRecordType typeForName(String name) {
+ if (name != null) {
+ String aName = name.toLowerCase();
+ for (DNSRecordType aType : DNSRecordType.values()) {
+ if (aType._externalName.equals(aName)) return aType;
+ }
}
+ logger.warn("Could not find record type for name: {}", name);
+ return TYPE_IGNORE;
+ }
- @Override
- public String toString() {
- return this.name() + " index " + this.indexValue();
+ /**
+ * @param index
+ * @return type for name
+ */
+ public static DNSRecordType typeForIndex(int index) {
+ for (DNSRecordType aType : DNSRecordType.values()) {
+ if (aType._index == index) return aType;
}
+ logger.warn("Could not find record type for index: {}", index);
+ return TYPE_IGNORE;
+ }
+ @Override
+ public String toString() {
+ return this.name() + " index " + this.indexValue();
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSResultCode.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSResultCode.java
index 9b73ba628..7175e599c 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSResultCode.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSResultCode.java
@@ -1,149 +1,118 @@
-/**
- *
- */
+/** */
package io.libp2p.discovery.mdns.impl.constants;
/**
* DNS result code.
- *
+ *
* @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Rick Blair
*/
public enum DNSResultCode {
- /**
- * Token
- */
- Unknown("Unknown", 65535),
- /**
- * No Error [RFC1035]
- */
- NoError("No Error", 0),
- /**
- * Format Error [RFC1035]
- */
- FormErr("Format Error", 1),
- /**
- * Server Failure [RFC1035]
- */
- ServFail("Server Failure", 2),
- /**
- * Non-Existent Domain [RFC1035]
- */
- NXDomain("Non-Existent Domain", 3),
- /**
- * Not Implemented [RFC1035]
- */
- NotImp("Not Implemented", 4),
- /**
- * Query Refused [RFC1035]
- */
- Refused("Query Refused", 5),
- /**
- * Name Exists when it should not [RFC2136]
- */
- YXDomain("Name Exists when it should not", 6),
- /**
- * RR Set Exists when it should not [RFC2136]
- */
- YXRRSet("RR Set Exists when it should not", 7),
- /**
- * RR Set that should exist does not [RFC2136]
- */
- NXRRSet("RR Set that should exist does not", 8),
- /**
- * Server Not Authoritative for zone [RFC2136]]
- */
- NotAuth("Server Not Authoritative for zone", 9),
- /**
- * Name not contained in zone [RFC2136]
- */
- NotZone("NotZone Name not contained in zone", 10),
+ /** Token */
+ Unknown("Unknown", 65535),
+ /** No Error [RFC1035] */
+ NoError("No Error", 0),
+ /** Format Error [RFC1035] */
+ FormErr("Format Error", 1),
+ /** Server Failure [RFC1035] */
+ ServFail("Server Failure", 2),
+ /** Non-Existent Domain [RFC1035] */
+ NXDomain("Non-Existent Domain", 3),
+ /** Not Implemented [RFC1035] */
+ NotImp("Not Implemented", 4),
+ /** Query Refused [RFC1035] */
+ Refused("Query Refused", 5),
+ /** Name Exists when it should not [RFC2136] */
+ YXDomain("Name Exists when it should not", 6),
+ /** RR Set Exists when it should not [RFC2136] */
+ YXRRSet("RR Set Exists when it should not", 7),
+ /** RR Set that should exist does not [RFC2136] */
+ NXRRSet("RR Set that should exist does not", 8),
+ /** Server Not Authoritative for zone [RFC2136]] */
+ NotAuth("Server Not Authoritative for zone", 9),
+ /** Name not contained in zone [RFC2136] */
+ NotZone("NotZone Name not contained in zone", 10),
+ ;
- ;
+ // 0 NoError No Error [RFC1035]
+ // 1 FormErr Format Error [RFC1035]
+ // 2 ServFail Server Failure [RFC1035]
+ // 3 NXDomain Non-Existent Domain [RFC1035]
+ // 4 NotImp Not Implemented [RFC1035]
+ // 5 Refused Query Refused [RFC1035]
+ // 6 YXDomain Name Exists when it should not [RFC2136]
+ // 7 YXRRSet RR Set Exists when it should not [RFC2136]
+ // 8 NXRRSet RR Set that should exist does not [RFC2136]
+ // 9 NotAuth Server Not Authoritative for zone [RFC2136]
+ // 10 NotZone Name not contained in zone [RFC2136]
+ // 11-15 Unassigned
+ // 16 BADVERS Bad OPT Version [RFC2671]
+ // 16 BADSIG TSIG Signature Failure [RFC2845]
+ // 17 BADKEY Key not recognized [RFC2845]
+ // 18 BADTIME Signature out of time window [RFC2845]
+ // 19 BADMODE Bad TKEY Mode [RFC2930]
+ // 20 BADNAME Duplicate key name [RFC2930]
+ // 21 BADALG Algorithm not supported [RFC2930]
+ // 22 BADTRUNC Bad Truncation [RFC4635]
+ // 23-3840 Unassigned
+ // 3841-4095 Reserved for Private Use [RFC5395]
+ // 4096-65534 Unassigned
+ // 65535 Reserved, can be allocated by Standards Action [RFC5395]
- // 0 NoError No Error [RFC1035]
- // 1 FormErr Format Error [RFC1035]
- // 2 ServFail Server Failure [RFC1035]
- // 3 NXDomain Non-Existent Domain [RFC1035]
- // 4 NotImp Not Implemented [RFC1035]
- // 5 Refused Query Refused [RFC1035]
- // 6 YXDomain Name Exists when it should not [RFC2136]
- // 7 YXRRSet RR Set Exists when it should not [RFC2136]
- // 8 NXRRSet RR Set that should exist does not [RFC2136]
- // 9 NotAuth Server Not Authoritative for zone [RFC2136]
- // 10 NotZone Name not contained in zone [RFC2136]
- // 11-15 Unassigned
- // 16 BADVERS Bad OPT Version [RFC2671]
- // 16 BADSIG TSIG Signature Failure [RFC2845]
- // 17 BADKEY Key not recognized [RFC2845]
- // 18 BADTIME Signature out of time window [RFC2845]
- // 19 BADMODE Bad TKEY Mode [RFC2930]
- // 20 BADNAME Duplicate key name [RFC2930]
- // 21 BADALG Algorithm not supported [RFC2930]
- // 22 BADTRUNC Bad Truncation [RFC4635]
- // 23-3840 Unassigned
- // 3841-4095 Reserved for Private Use [RFC5395]
- // 4096-65534 Unassigned
- // 65535 Reserved, can be allocated by Standards Action [RFC5395]
+ /** DNS Result Code types are encoded on the last 4 bits */
+ static final int RCode_MASK = 0x0F;
- /**
- * DNS Result Code types are encoded on the last 4 bits
- */
- final static int RCode_MASK = 0x0F;
- /**
- * DNS Extended Result Code types are encoded on the first 8 bits
- */
- final static int ExtendedRCode_MASK = 0xFF;
+ /** DNS Extended Result Code types are encoded on the first 8 bits */
+ static final int ExtendedRCode_MASK = 0xFF;
- private final String _externalName;
+ private final String _externalName;
- private final int _index;
+ private final int _index;
- DNSResultCode(String name, int index) {
- _externalName = name;
- _index = index;
- }
+ DNSResultCode(String name, int index) {
+ _externalName = name;
+ _index = index;
+ }
- /**
- * Return the string representation of this type
- *
- * @return String
- */
- public String externalName() {
- return _externalName;
- }
-
- /**
- * Return the numeric value of this type
- *
- * @return String
- */
- public int indexValue() {
- return _index;
- }
+ /**
+ * Return the string representation of this type
+ *
+ * @return String
+ */
+ public String externalName() {
+ return _externalName;
+ }
- /**
- * @param flags
- * @return label
- */
- public static DNSResultCode resultCodeForFlags(int flags) {
- int maskedIndex = flags & RCode_MASK;
- for (DNSResultCode aCode : DNSResultCode.values()) {
- if (aCode._index == maskedIndex) return aCode;
- }
- return Unknown;
- }
+ /**
+ * Return the numeric value of this type
+ *
+ * @return String
+ */
+ public int indexValue() {
+ return _index;
+ }
- public static DNSResultCode resultCodeForFlags(int flags, int extendedRCode) {
- int maskedIndex = ((extendedRCode >> 28) & ExtendedRCode_MASK) | (flags & RCode_MASK);
- for (DNSResultCode aCode : DNSResultCode.values()) {
- if (aCode._index == maskedIndex) return aCode;
- }
- return Unknown;
+ /**
+ * @param flags
+ * @return label
+ */
+ public static DNSResultCode resultCodeForFlags(int flags) {
+ int maskedIndex = flags & RCode_MASK;
+ for (DNSResultCode aCode : DNSResultCode.values()) {
+ if (aCode._index == maskedIndex) return aCode;
}
+ return Unknown;
+ }
- @Override
- public String toString() {
- return this.name() + " index " + this.indexValue();
+ public static DNSResultCode resultCodeForFlags(int flags, int extendedRCode) {
+ int maskedIndex = ((extendedRCode >> 28) & ExtendedRCode_MASK) | (flags & RCode_MASK);
+ for (DNSResultCode aCode : DNSResultCode.values()) {
+ if (aCode._index == maskedIndex) return aCode;
}
+ return Unknown;
+ }
+ @Override
+ public String toString() {
+ return this.name() + " index " + this.indexValue();
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSState.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSState.java
index 9b1b99995..9b7578ea9 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSState.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/DNSState.java
@@ -11,205 +11,189 @@
*/
public enum DNSState {
- /**
- *
- */
- PROBING_1("probing 1", StateClass.probing),
- /**
- *
- */
- PROBING_2("probing 2", StateClass.probing),
- /**
- *
- */
- PROBING_3("probing 3", StateClass.probing),
- /**
- *
- */
- ANNOUNCING_1("announcing 1", StateClass.announcing),
- /**
- *
- */
- ANNOUNCING_2("announcing 2", StateClass.announcing),
- /**
- *
- */
- ANNOUNCED("announced", StateClass.announced),
- /**
- *
- */
- CANCELING_1("canceling 1", StateClass.canceling),
- /**
- *
- */
- CANCELING_2("canceling 2", StateClass.canceling),
- /**
- *
- */
- CANCELING_3("canceling 3", StateClass.canceling),
- /**
- *
- */
- CANCELED("canceled", StateClass.canceled),
- /**
- *
- */
- CLOSING("closing", StateClass.closing),
- /**
- *
- */
- CLOSED("closed", StateClass.closed);
-
- private enum StateClass {
- probing, announcing, announced, canceling, canceled, closing, closed
+ /** */
+ PROBING_1("probing 1", StateClass.probing),
+ /** */
+ PROBING_2("probing 2", StateClass.probing),
+ /** */
+ PROBING_3("probing 3", StateClass.probing),
+ /** */
+ ANNOUNCING_1("announcing 1", StateClass.announcing),
+ /** */
+ ANNOUNCING_2("announcing 2", StateClass.announcing),
+ /** */
+ ANNOUNCED("announced", StateClass.announced),
+ /** */
+ CANCELING_1("canceling 1", StateClass.canceling),
+ /** */
+ CANCELING_2("canceling 2", StateClass.canceling),
+ /** */
+ CANCELING_3("canceling 3", StateClass.canceling),
+ /** */
+ CANCELED("canceled", StateClass.canceled),
+ /** */
+ CLOSING("closing", StateClass.closing),
+ /** */
+ CLOSED("closed", StateClass.closed);
+
+ private enum StateClass {
+ probing,
+ announcing,
+ announced,
+ canceling,
+ canceled,
+ closing,
+ closed
+ }
+
+ // private static Logger logger = LoggerFactory.getLogger(DNSState.class.getName());
+
+ private final String _name;
+
+ private final StateClass _state;
+
+ private DNSState(String name, StateClass state) {
+ _name = name;
+ _state = state;
+ }
+
+ @Override
+ public final String toString() {
+ return _name;
+ }
+
+ /**
+ * Returns the next advanced state.
+ * In general, this advances one step in the following sequence: PROBING_1, PROBING_2, PROBING_3,
+ * ANNOUNCING_1, ANNOUNCING_2, ANNOUNCED.
+ * or CANCELING_1, CANCELING_2, CANCELING_3, CANCELED Does not advance for ANNOUNCED and CANCELED
+ * state.
+ *
+ * @return next state
+ */
+ public final DNSState advance() {
+ switch (this) {
+ case PROBING_1:
+ return PROBING_2;
+ case PROBING_2:
+ return PROBING_3;
+ case PROBING_3:
+ return ANNOUNCING_1;
+ case ANNOUNCING_1:
+ return ANNOUNCING_2;
+ case ANNOUNCING_2:
+ return ANNOUNCED;
+ case ANNOUNCED:
+ return ANNOUNCED;
+ case CANCELING_1:
+ return CANCELING_2;
+ case CANCELING_2:
+ return CANCELING_3;
+ case CANCELING_3:
+ return CANCELED;
+ case CANCELED:
+ return CANCELED;
+ case CLOSING:
+ return CLOSED;
+ case CLOSED:
+ return CLOSED;
+ default:
+ // This is just to keep the compiler happy as we have covered all cases before.
+ return this;
}
-
- // private static Logger logger = LoggerFactory.getLogger(DNSState.class.getName());
-
- private final String _name;
-
- private final StateClass _state;
-
- private DNSState(String name, StateClass state) {
- _name = name;
- _state = state;
+ }
+
+ /**
+ * Returns to the next reverted state. All states except CANCELED revert to PROBING_1. Status
+ * CANCELED does not revert.
+ *
+ * @return reverted state
+ */
+ public final DNSState revert() {
+ switch (this) {
+ case PROBING_1:
+ case PROBING_2:
+ case PROBING_3:
+ case ANNOUNCING_1:
+ case ANNOUNCING_2:
+ case ANNOUNCED:
+ return PROBING_1;
+ case CANCELING_1:
+ case CANCELING_2:
+ case CANCELING_3:
+ return CANCELING_1;
+ case CANCELED:
+ return CANCELED;
+ case CLOSING:
+ return CLOSING;
+ case CLOSED:
+ return CLOSED;
+ default:
+ // This is just to keep the compiler happy as we have covered all cases before.
+ return this;
}
-
- @Override
- public final String toString() {
- return _name;
- }
-
- /**
- * Returns the next advanced state.
- * In general, this advances one step in the following sequence: PROBING_1, PROBING_2, PROBING_3, ANNOUNCING_1, ANNOUNCING_2, ANNOUNCED.
- * or CANCELING_1, CANCELING_2, CANCELING_3, CANCELED Does not advance for ANNOUNCED and CANCELED state.
- *
- * @return next state
- */
- public final DNSState advance() {
- switch (this) {
- case PROBING_1:
- return PROBING_2;
- case PROBING_2:
- return PROBING_3;
- case PROBING_3:
- return ANNOUNCING_1;
- case ANNOUNCING_1:
- return ANNOUNCING_2;
- case ANNOUNCING_2:
- return ANNOUNCED;
- case ANNOUNCED:
- return ANNOUNCED;
- case CANCELING_1:
- return CANCELING_2;
- case CANCELING_2:
- return CANCELING_3;
- case CANCELING_3:
- return CANCELED;
- case CANCELED:
- return CANCELED;
- case CLOSING:
- return CLOSED;
- case CLOSED:
- return CLOSED;
- default:
- // This is just to keep the compiler happy as we have covered all cases before.
- return this;
- }
- }
-
- /**
- * Returns to the next reverted state. All states except CANCELED revert to PROBING_1. Status CANCELED does not revert.
- *
- * @return reverted state
- */
- public final DNSState revert() {
- switch (this) {
- case PROBING_1:
- case PROBING_2:
- case PROBING_3:
- case ANNOUNCING_1:
- case ANNOUNCING_2:
- case ANNOUNCED:
- return PROBING_1;
- case CANCELING_1:
- case CANCELING_2:
- case CANCELING_3:
- return CANCELING_1;
- case CANCELED:
- return CANCELED;
- case CLOSING:
- return CLOSING;
- case CLOSED:
- return CLOSED;
- default:
- // This is just to keep the compiler happy as we have covered all cases before.
- return this;
- }
- }
-
- /**
- * Returns true, if this is a probing state.
- *
- * @return true
if probing state, false
otherwise
- */
- public final boolean isProbing() {
- return _state == StateClass.probing;
- }
-
- /**
- * Returns true, if this is an announcing state.
- *
- * @return true
if announcing state, false
otherwise
- */
- public final boolean isAnnouncing() {
- return _state == StateClass.announcing;
- }
-
- /**
- * Returns true, if this is an announced state.
- *
- * @return true
if announced state, false
otherwise
- */
- public final boolean isAnnounced() {
- return _state == StateClass.announced;
- }
-
- /**
- * Returns true, if this is a canceling state.
- *
- * @return true
if canceling state, false
otherwise
- */
- public final boolean isCanceling() {
- return _state == StateClass.canceling;
- }
-
- /**
- * Returns true, if this is a canceled state.
- *
- * @return true
if canceled state, false
otherwise
- */
- public final boolean isCanceled() {
- return _state == StateClass.canceled;
- }
-
- /**
- * Returns true, if this is a closing state.
- *
- * @return true
if closing state, false
otherwise
- */
- public final boolean isClosing() {
- return _state == StateClass.closing;
- }
-
- /**
- * Returns true, if this is a closing state.
- *
- * @return true
if closed state, false
otherwise
- */
- public final boolean isClosed() {
- return _state == StateClass.closed;
- }
-
+ }
+
+ /**
+ * Returns true, if this is a probing state.
+ *
+ * @return true
if probing state, false
otherwise
+ */
+ public final boolean isProbing() {
+ return _state == StateClass.probing;
+ }
+
+ /**
+ * Returns true, if this is an announcing state.
+ *
+ * @return true
if announcing state, false
otherwise
+ */
+ public final boolean isAnnouncing() {
+ return _state == StateClass.announcing;
+ }
+
+ /**
+ * Returns true, if this is an announced state.
+ *
+ * @return true
if announced state, false
otherwise
+ */
+ public final boolean isAnnounced() {
+ return _state == StateClass.announced;
+ }
+
+ /**
+ * Returns true, if this is a canceling state.
+ *
+ * @return true
if canceling state, false
otherwise
+ */
+ public final boolean isCanceling() {
+ return _state == StateClass.canceling;
+ }
+
+ /**
+ * Returns true, if this is a canceled state.
+ *
+ * @return true
if canceled state, false
otherwise
+ */
+ public final boolean isCanceled() {
+ return _state == StateClass.canceled;
+ }
+
+ /**
+ * Returns true, if this is a closing state.
+ *
+ * @return true
if closing state, false
otherwise
+ */
+ public final boolean isClosing() {
+ return _state == StateClass.closing;
+ }
+
+ /**
+ * Returns true, if this is a closing state.
+ *
+ * @return true
if closed state, false
otherwise
+ */
+ public final boolean isClosed() {
+ return _state == StateClass.closed;
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/package-info.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/package-info.java
index 829cb4144..41316a160 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/package-info.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/constants/package-info.java
@@ -1,2 +1 @@
package io.libp2p.discovery.mdns.impl.constants;
-
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/package-info.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/package-info.java
index cc0bfbe66..effecf1ed 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/package-info.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/package-info.java
@@ -1,2 +1 @@
package io.libp2p.discovery.mdns.impl;
-
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/tasks/DNSTask.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/tasks/DNSTask.java
index 7b4595a83..880c87cc2 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/tasks/DNSTask.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/tasks/DNSTask.java
@@ -4,53 +4,50 @@
import io.libp2p.discovery.mdns.impl.DNSOutgoing;
import io.libp2p.discovery.mdns.impl.DNSQuestion;
import io.libp2p.discovery.mdns.impl.JmDNSImpl;
-
+import io.libp2p.discovery.mdns.impl.constants.DNSConstants;
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
-import io.libp2p.discovery.mdns.impl.constants.DNSConstants;
-
public abstract class DNSTask implements Runnable {
- private final JmDNSImpl _jmDNSImpl;
- protected final ScheduledExecutorService _scheduler =
- Executors.newScheduledThreadPool(1);
-
- protected DNSTask(JmDNSImpl jmDNSImpl) {
- super();
- this._jmDNSImpl = jmDNSImpl;
- }
-
- protected JmDNSImpl dns() {
- return _jmDNSImpl;
- }
-
- public abstract void start();
-
- protected abstract String getName();
-
- @Override
- public String toString() {
- return this.getName();
- }
-
- protected DNSOutgoing addQuestion(DNSOutgoing out, DNSQuestion rec) throws IOException {
- DNSOutgoing newOut = out;
- try {
- newOut.addQuestion(rec);
- } catch (final IOException e) {
- int flags = newOut.getFlags();
- boolean multicast = newOut.isMulticast();
- int maxUDPPayload = newOut.getMaxUDPPayload();
- int id = newOut.getId();
-
- newOut.setFlags(flags | DNSConstants.FLAGS_TC);
- newOut.setId(id);
- this._jmDNSImpl.send(newOut);
-
- newOut = new DNSOutgoing(flags, multicast, maxUDPPayload);
- newOut.addQuestion(rec);
- }
- return newOut;
+ private final JmDNSImpl _jmDNSImpl;
+ protected final ScheduledExecutorService _scheduler = Executors.newScheduledThreadPool(1);
+
+ protected DNSTask(JmDNSImpl jmDNSImpl) {
+ super();
+ this._jmDNSImpl = jmDNSImpl;
+ }
+
+ protected JmDNSImpl dns() {
+ return _jmDNSImpl;
+ }
+
+ public abstract void start();
+
+ protected abstract String getName();
+
+ @Override
+ public String toString() {
+ return this.getName();
+ }
+
+ protected DNSOutgoing addQuestion(DNSOutgoing out, DNSQuestion rec) throws IOException {
+ DNSOutgoing newOut = out;
+ try {
+ newOut.addQuestion(rec);
+ } catch (final IOException e) {
+ int flags = newOut.getFlags();
+ boolean multicast = newOut.isMulticast();
+ int maxUDPPayload = newOut.getMaxUDPPayload();
+ int id = newOut.getId();
+
+ newOut.setFlags(flags | DNSConstants.FLAGS_TC);
+ newOut.setId(id);
+ this._jmDNSImpl.send(newOut);
+
+ newOut = new DNSOutgoing(flags, multicast, maxUDPPayload);
+ newOut.addQuestion(rec);
}
+ return newOut;
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/tasks/Responder.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/tasks/Responder.java
index 77dab738e..cd62930b1 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/tasks/Responder.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/tasks/Responder.java
@@ -4,131 +4,131 @@
package io.libp2p.discovery.mdns.impl.tasks;
+import io.libp2p.discovery.mdns.impl.DNSIncoming;
+import io.libp2p.discovery.mdns.impl.DNSOutgoing;
+import io.libp2p.discovery.mdns.impl.DNSQuestion;
+import io.libp2p.discovery.mdns.impl.DNSRecord;
+import io.libp2p.discovery.mdns.impl.JmDNSImpl;
+import io.libp2p.discovery.mdns.impl.constants.DNSConstants;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.libp2p.discovery.mdns.impl.DNSIncoming;
-import io.libp2p.discovery.mdns.impl.DNSOutgoing;
-import io.libp2p.discovery.mdns.impl.DNSQuestion;
-import io.libp2p.discovery.mdns.impl.DNSRecord;
-import io.libp2p.discovery.mdns.impl.JmDNSImpl;
-import io.libp2p.discovery.mdns.impl.constants.DNSConstants;
-
-/**
- * The Responder sends a single answer for the specified service infos and for the host name.
- */
+/** The Responder sends a single answer for the specified service infos and for the host name. */
public class Responder extends DNSTask {
- static Logger logger = LoggerFactory.getLogger(Responder.class.getName());
+ static Logger logger = LoggerFactory.getLogger(Responder.class.getName());
+
+ private final DNSIncoming _in;
+
+ private final InetAddress _addr;
+ private final int _port;
+
+ private final boolean _unicast;
+
+ public Responder(JmDNSImpl jmDNSImpl, DNSIncoming in, InetAddress addr, int port) {
+ super(jmDNSImpl);
+ this._in = in;
+ this._addr = addr;
+ this._port = port;
+ this._unicast = (port != DNSConstants.MDNS_PORT);
+ }
+
+ @Override
+ protected String getName() {
+ return "Responder(" + (this.dns() != null ? this.dns().getName() : "") + ")";
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + " incoming: " + _in;
+ }
+
+ @Override
+ public void start() {
+ int delay =
+ DNSConstants.RESPONSE_MIN_WAIT_INTERVAL
+ + JmDNSImpl.getRandom()
+ .nextInt(
+ DNSConstants.RESPONSE_MAX_WAIT_INTERVAL
+ - DNSConstants.RESPONSE_MIN_WAIT_INTERVAL
+ + 1)
+ - _in.elapseSinceArrival();
+ if (delay < 0) {
+ delay = 0;
+ }
+ logger.trace("{}.start() Responder chosen delay={}", this.getName(), delay);
- private final DNSIncoming _in;
+ _scheduler.schedule(this, delay, TimeUnit.MILLISECONDS);
+ }
- private final InetAddress _addr;
- private final int _port;
+ @Override
+ public void run() {
+ // We use these sets to prevent duplicate records
+ Set questions = new HashSet();
+ Set answers = new HashSet();
- private final boolean _unicast;
+ try {
+ // Answer questions
+ for (DNSQuestion question : _in.getQuestions()) {
+ logger.debug("{}.run() JmDNS responding to: {}", this.getName(), question);
- public Responder(JmDNSImpl jmDNSImpl, DNSIncoming in, InetAddress addr, int port) {
- super(jmDNSImpl);
- this._in = in;
- this._addr = addr;
- this._port = port;
- this._unicast = (port != DNSConstants.MDNS_PORT);
- }
+ // for unicast responses the question must be included
+ if (_unicast) {
+ questions.add(question);
+ }
- @Override
- protected String getName() {
- return "Responder(" + (this.dns() != null ? this.dns().getName() : "") + ")";
- }
+ question.addAnswers(this.dns(), answers);
+ }
- @Override
- public String toString() {
- return super.toString() + " incoming: " + _in;
- }
+ // respond if we have answers
+ if (!answers.isEmpty()) {
+ logger.debug("{}.run() JmDNS responding", this.getName());
- @Override
- public void start() {
- int delay =
- DNSConstants.RESPONSE_MIN_WAIT_INTERVAL +
- JmDNSImpl.getRandom().nextInt(
- DNSConstants.RESPONSE_MAX_WAIT_INTERVAL -
- DNSConstants.RESPONSE_MIN_WAIT_INTERVAL + 1
- ) -
- _in.elapseSinceArrival();
- if (delay < 0) {
- delay = 0;
+ DNSOutgoing out =
+ new DNSOutgoing(
+ DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA,
+ !_unicast,
+ _in.getSenderUDPPayload());
+ if (_unicast) {
+ out.setDestination(new InetSocketAddress(_addr, _port));
}
- logger.trace("{}.start() Responder chosen delay={}", this.getName(), delay);
-
- _scheduler.schedule(this, delay, TimeUnit.MILLISECONDS);
- }
-
- @Override
- public void run() {
- // We use these sets to prevent duplicate records
- Set questions = new HashSet();
- Set answers = new HashSet();
-
- try {
- // Answer questions
- for (DNSQuestion question : _in.getQuestions()) {
- logger.debug("{}.run() JmDNS responding to: {}", this.getName(), question);
-
- // for unicast responses the question must be included
- if (_unicast) {
- questions.add(question);
- }
-
- question.addAnswers(this.dns(), answers);
- }
-
- // respond if we have answers
- if (!answers.isEmpty()) {
- logger.debug("{}.run() JmDNS responding", this.getName());
-
- DNSOutgoing out = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA, !_unicast, _in.getSenderUDPPayload());
- if (_unicast) {
- out.setDestination(new InetSocketAddress(_addr, _port));
- }
- out.setId(_in.getId());
- for (DNSQuestion question : questions) {
- out = this.addQuestion(out, question);
- }
- for (DNSRecord answer : answers) {
- out = this.addAnswer(out, answer);
- }
- if (!out.isEmpty())
- this.dns().send(out);
- }
- } catch (Throwable e) {
- logger.warn(this.getName() + "run() exception ", e);
+ out.setId(_in.getId());
+ for (DNSQuestion question : questions) {
+ out = this.addQuestion(out, question);
}
- _scheduler.shutdown();
- }
-
- private DNSOutgoing addAnswer(DNSOutgoing out, DNSRecord rec) throws IOException {
- DNSOutgoing newOut = out;
- try {
- newOut.addAnswer(rec);
- } catch (final IOException e) {
- int flags = newOut.getFlags();
- boolean multicast = newOut.isMulticast();
- int maxUDPPayload = newOut.getMaxUDPPayload();
- int id = newOut.getId();
-
- newOut.setFlags(flags | DNSConstants.FLAGS_TC);
- newOut.setId(id);
- this.dns().send(newOut);
-
- newOut = new DNSOutgoing(flags, multicast, maxUDPPayload);
- newOut.addAnswer(rec);
+ for (DNSRecord answer : answers) {
+ out = this.addAnswer(out, answer);
}
- return newOut;
+ if (!out.isEmpty()) this.dns().send(out);
+ }
+ } catch (Throwable e) {
+ logger.warn(this.getName() + "run() exception ", e);
+ }
+ _scheduler.shutdown();
+ }
+
+ private DNSOutgoing addAnswer(DNSOutgoing out, DNSRecord rec) throws IOException {
+ DNSOutgoing newOut = out;
+ try {
+ newOut.addAnswer(rec);
+ } catch (final IOException e) {
+ int flags = newOut.getFlags();
+ boolean multicast = newOut.isMulticast();
+ int maxUDPPayload = newOut.getMaxUDPPayload();
+ int id = newOut.getId();
+
+ newOut.setFlags(flags | DNSConstants.FLAGS_TC);
+ newOut.setId(id);
+ this.dns().send(newOut);
+
+ newOut = new DNSOutgoing(flags, multicast, maxUDPPayload);
+ newOut.addAnswer(rec);
}
-}
\ No newline at end of file
+ return newOut;
+ }
+}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/tasks/ServiceResolver.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/tasks/ServiceResolver.java
index 4b15a5544..71c34a244 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/tasks/ServiceResolver.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/tasks/ServiceResolver.java
@@ -10,72 +10,73 @@
import io.libp2p.discovery.mdns.impl.constants.DNSConstants;
import io.libp2p.discovery.mdns.impl.constants.DNSRecordClass;
import io.libp2p.discovery.mdns.impl.constants.DNSRecordType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.IOException;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
- * The ServiceResolver queries three times consecutively for services of a given type, and then removes itself from the timer.
+ * The ServiceResolver queries three times consecutively for services of a given type, and then
+ * removes itself from the timer.
*/
public class ServiceResolver extends DNSTask {
- private static Logger logger = LoggerFactory.getLogger(ServiceResolver.class.getName());
+ private static Logger logger = LoggerFactory.getLogger(ServiceResolver.class.getName());
- private final String _type;
- private final int _queryInterval;
- private ScheduledFuture> _isShutdown;
+ private final String _type;
+ private final int _queryInterval;
+ private ScheduledFuture> _isShutdown;
- public ServiceResolver(JmDNSImpl jmDNSImpl, String type, int queryInterval) {
- super(jmDNSImpl);
- this._type = type;
- this._queryInterval = queryInterval;
- }
+ public ServiceResolver(JmDNSImpl jmDNSImpl, String type, int queryInterval) {
+ super(jmDNSImpl);
+ this._type = type;
+ this._queryInterval = queryInterval;
+ }
- @Override
- protected String getName() {
- return "ServiceResolver(" + (this.dns() != null ? this.dns().getName() : "") + ")";
- }
+ @Override
+ protected String getName() {
+ return "ServiceResolver(" + (this.dns() != null ? this.dns().getName() : "") + ")";
+ }
- @Override
- public void start() {
- _isShutdown = _scheduler.scheduleAtFixedRate(
- this,
- DNSConstants.QUERY_WAIT_INTERVAL,
- _queryInterval * 1000,
- TimeUnit.MILLISECONDS
- );
- }
+ @Override
+ public void start() {
+ _isShutdown =
+ _scheduler.scheduleAtFixedRate(
+ this, DNSConstants.QUERY_WAIT_INTERVAL, _queryInterval * 1000, TimeUnit.MILLISECONDS);
+ }
- @SuppressWarnings("unchecked")
- public Future stop() {
- _scheduler.shutdown();
- return (Future)_isShutdown;
- }
+ @SuppressWarnings("unchecked")
+ public Future stop() {
+ _scheduler.shutdown();
+ return (Future) _isShutdown;
+ }
- @Override
- public void run() {
- try {
- logger.debug("{}.run() JmDNS {}",this.getName(), this.description());
- DNSOutgoing out = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY);
- out = this.addQuestions(out);
- if (!out.isEmpty()) {
- this.dns().send(out);
- }
- } catch (Throwable e) {
- logger.warn(this.getName() + ".run() exception ", e);
- }
+ @Override
+ public void run() {
+ try {
+ logger.debug("{}.run() JmDNS {}", this.getName(), this.description());
+ DNSOutgoing out = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY);
+ out = this.addQuestions(out);
+ if (!out.isEmpty()) {
+ this.dns().send(out);
+ }
+ } catch (Throwable e) {
+ logger.warn(this.getName() + ".run() exception ", e);
}
+ }
- private DNSOutgoing addQuestions(DNSOutgoing out) throws IOException {
- DNSOutgoing newOut = out;
- newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_type, DNSRecordType.TYPE_PTR, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
- return newOut;
- }
+ private DNSOutgoing addQuestions(DNSOutgoing out) throws IOException {
+ DNSOutgoing newOut = out;
+ newOut =
+ this.addQuestion(
+ newOut,
+ DNSQuestion.newQuestion(
+ _type, DNSRecordType.TYPE_PTR, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
+ return newOut;
+ }
- private String description() {
- return "querying service";
- }
-}
\ No newline at end of file
+ private String description() {
+ return "querying service";
+ }
+}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/tasks/package-info.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/tasks/package-info.java
index 0262d1c57..6e2ee0569 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/tasks/package-info.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/tasks/package-info.java
@@ -1,2 +1 @@
package io.libp2p.discovery.mdns.impl.tasks;
-
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/util/ByteWrangler.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/util/ByteWrangler.java
index a628f7217..baf198486 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/util/ByteWrangler.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/util/ByteWrangler.java
@@ -5,57 +5,48 @@
import java.nio.charset.Charset;
/**
- * This class contains all the byte shifting
- *
- * @author Victor Toni
+ * This class contains all the byte shifting
*
+ * @author Victor Toni
*/
public class ByteWrangler {
- /**
- * Maximum number of bytes a value can consist of.
- */
- public static final int MAX_VALUE_LENGTH = 255;
-
- /**
- * Maximum number of bytes record data can consist of.
- * It is {@link #MAX_VALUE_LENGTH} + 1 because the first byte contains the number of the following bytes.
- */
- public static final int MAX_DATA_LENGTH = MAX_VALUE_LENGTH + 1;
-
- /**
- * Representation of no value. A zero length array of bytes.
- */
- public static final byte[] NO_VALUE = new byte[0];
-
- /**
- * Representation of empty text.
- * The first byte denotes the length of the following character bytes (in this case zero.)
- *
- * FIXME: Should this be exported as a method since it could change externally???
- */
- public final static byte[] EMPTY_TXT = new byte[] { 0 };
-
- /**
- * Name for charset used to convert Strings to/from wire bytes: {@value #CHARSET_NAME}.
- */
- public final static String CHARSET_NAME = "UTF-8";
-
- /**
- * Charset used to convert Strings to/from wire bytes: {@value #CHARSET_NAME}.
- */
- private final static Charset CHARSET_UTF_8 = Charset.forName(CHARSET_NAME);
-
- public static byte[] encodeText(final String text) throws IOException {
- final byte data[] = text.getBytes(CHARSET_UTF_8);
- if (data.length > MAX_VALUE_LENGTH) {
- return EMPTY_TXT;
- }
-
- final ByteArrayOutputStream out = new ByteArrayOutputStream(MAX_DATA_LENGTH);
- out.write((byte) data.length);
- out.write(data, 0, data.length);
-
- final byte[] encodedText = out.toByteArray();
- return encodedText;
+ /** Maximum number of bytes a value can consist of. */
+ public static final int MAX_VALUE_LENGTH = 255;
+
+ /**
+ * Maximum number of bytes record data can consist of. It is {@link #MAX_VALUE_LENGTH} + 1 because
+ * the first byte contains the number of the following bytes.
+ */
+ public static final int MAX_DATA_LENGTH = MAX_VALUE_LENGTH + 1;
+
+ /** Representation of no value. A zero length array of bytes. */
+ public static final byte[] NO_VALUE = new byte[0];
+
+ /**
+ * Representation of empty text. The first byte denotes the length of the following character
+ * bytes (in this case zero.)
+ *
+ * FIXME: Should this be exported as a method since it could change externally???
+ */
+ public static final byte[] EMPTY_TXT = new byte[] {0};
+
+ /** Name for charset used to convert Strings to/from wire bytes: {@value #CHARSET_NAME}. */
+ public static final String CHARSET_NAME = "UTF-8";
+
+ /** Charset used to convert Strings to/from wire bytes: {@value #CHARSET_NAME}. */
+ private static final Charset CHARSET_UTF_8 = Charset.forName(CHARSET_NAME);
+
+ public static byte[] encodeText(final String text) throws IOException {
+ final byte data[] = text.getBytes(CHARSET_UTF_8);
+ if (data.length > MAX_VALUE_LENGTH) {
+ return EMPTY_TXT;
}
+
+ final ByteArrayOutputStream out = new ByteArrayOutputStream(MAX_DATA_LENGTH);
+ out.write((byte) data.length);
+ out.write(data, 0, data.length);
+
+ final byte[] encodedText = out.toByteArray();
+ return encodedText;
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/util/NamedThreadFactory.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/util/NamedThreadFactory.java
index 7906a63ee..e5f0d1765 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/util/NamedThreadFactory.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/impl/util/NamedThreadFactory.java
@@ -8,28 +8,30 @@
import java.util.concurrent.ThreadFactory;
/**
- * Custom thread factory which sets the name to make it easier to identify where the pooled threads were created.
+ * Custom thread factory which sets the name to make it easier to identify where the pooled threads
+ * were created.
*
* @author Trejkaz, Pierre Frisch
*/
public class NamedThreadFactory implements ThreadFactory {
- private final ThreadFactory _delegate;
- private final String _namePrefix;
+ private final ThreadFactory _delegate;
+ private final String _namePrefix;
- /**
- * Constructs the thread factory.
- *
- * @param namePrefix a prefix to append to thread names (will be separated from the default thread name by a space.)
- */
- public NamedThreadFactory(String namePrefix) {
- this._namePrefix = namePrefix;
- _delegate = Executors.defaultThreadFactory();
- }
+ /**
+ * Constructs the thread factory.
+ *
+ * @param namePrefix a prefix to append to thread names (will be separated from the default thread
+ * name by a space.)
+ */
+ public NamedThreadFactory(String namePrefix) {
+ this._namePrefix = namePrefix;
+ _delegate = Executors.defaultThreadFactory();
+ }
- @Override
- public Thread newThread(Runnable runnable) {
- Thread thread = _delegate.newThread(runnable);
- thread.setName(_namePrefix + ' ' + thread.getName());
- return thread;
- }
+ @Override
+ public Thread newThread(Runnable runnable) {
+ Thread thread = _delegate.newThread(runnable);
+ thread.setName(_namePrefix + ' ' + thread.getName());
+ return thread;
+ }
}
diff --git a/libp2p/src/main/java/io/libp2p/discovery/mdns/package-info.java b/libp2p/src/main/java/io/libp2p/discovery/mdns/package-info.java
index a93d49ef7..ed16fce56 100644
--- a/libp2p/src/main/java/io/libp2p/discovery/mdns/package-info.java
+++ b/libp2p/src/main/java/io/libp2p/discovery/mdns/package-info.java
@@ -3,24 +3,19 @@
/**
* Java code in this package is derived from the JmDNS project.
*
- * JmDNS is a Java implementation of multi-cast DNS and can be used for
- * service registration and discovery in local area networks. JmDNS is
- * fully compatible with Apple's Bonjour. The project was originally
- * started in December 2002 by Arthur van Hoff at Strangeberry. In
- * November 2003 the project was moved to SourceForge, and the name
- * was changed from JRendezvous to JmDNS for legal reasons. Many
- * thanks to Stuart Cheshire for help and moral support. In 2014, it was
- * been moved from Sourceforge to Github by Kai Kreuzer with the kind
- * approval from Arthur and Rick.
- *
- * https://github.com/jmdns/jmdns/
- *
+ * JmDNS is a Java implementation of multi-cast DNS and can be used for service registration and
+ * discovery in local area networks. JmDNS is fully compatible with Apple's Bonjour. The project was
+ * originally started in December 2002 by Arthur van Hoff at Strangeberry. In November 2003 the
+ * project was moved to SourceForge, and the name was changed from JRendezvous to JmDNS for legal
+ * reasons. Many thanks to Stuart Cheshire for help and moral support. In 2014, it was been moved
+ * from Sourceforge to Github by Kai Kreuzer with the kind approval from Arthur and Rick.
*
- * JmDNS was originally licensed under the GNU Lesser General Public
- * License as jRendevous. It was re-released under the
- * Apache License, Version 2.0 in 2005. It is under those terms it is reused here.
- *
- * JmDNS License Notice
- * JmDNS Changelog
- *
- **/
+ * https://github.com/jmdns/jmdns/ JmDNS was
+ * originally licensed under the GNU Lesser General Public License as jRendevous. It was re-released
+ * under the Apache License, Version 2.0 in 2005. It is under those terms it is reused here.
+ *
+ *
JmDNS License Notice
+ * JmDNS
+ * Changelog
+ */
diff --git a/libp2p/src/main/kotlin/io/libp2p/core/Connection.kt b/libp2p/src/main/kotlin/io/libp2p/core/Connection.kt
index 579b9a1a0..64eb52b64 100644
--- a/libp2p/src/main/kotlin/io/libp2p/core/Connection.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/core/Connection.kt
@@ -27,6 +27,7 @@ interface Connection : P2PChannel {
* Returns the local [Multiaddr] of this [Connection]
*/
fun localAddress(): Multiaddr
+
/**
* Returns the remote [Multiaddr] of this [Connection]
*/
diff --git a/libp2p/src/main/kotlin/io/libp2p/core/Host.kt b/libp2p/src/main/kotlin/io/libp2p/core/Host.kt
index f419787ad..1ba4685b0 100644
--- a/libp2p/src/main/kotlin/io/libp2p/core/Host.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/core/Host.kt
@@ -15,14 +15,17 @@ interface Host {
* Our private key which can be used by different protocols to sign messages
*/
val privKey: PrivKey
+
/**
* Our [PeerId] which is normally derived from [privKey]
*/
val peerId: PeerId
+
/**
* [Network] implementation
*/
val network: Network
+
/**
* [AddressBook] implementation
*/
diff --git a/libp2p/src/main/kotlin/io/libp2p/core/Libp2pException.kt b/libp2p/src/main/kotlin/io/libp2p/core/Libp2pException.kt
index 31bab6068..b25269f7c 100644
--- a/libp2p/src/main/kotlin/io/libp2p/core/Libp2pException.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/core/Libp2pException.kt
@@ -50,6 +50,7 @@ open class NoSuchProtocolException(message: String) : Libp2pException(message)
* Indicates that the protocol is not registered at local configuration
*/
class NoSuchLocalProtocolException(message: String) : NoSuchProtocolException(message)
+
/**
* Indicates that the protocol is not known by the remote party
*/
diff --git a/libp2p/src/main/kotlin/io/libp2p/core/crypto/Key.kt b/libp2p/src/main/kotlin/io/libp2p/core/crypto/Key.kt
index 3324c510c..7d394966d 100644
--- a/libp2p/src/main/kotlin/io/libp2p/core/crypto/Key.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/core/crypto/Key.kt
@@ -31,7 +31,7 @@ import java.security.SecureRandom
import crypto.pb.Crypto.PrivateKey as PbPrivateKey
import crypto.pb.Crypto.PublicKey as PbPublicKey
-enum class KEY_TYPE {
+enum class KeyType {
/**
* RSA is an enum for the supported RSA key type
@@ -56,7 +56,7 @@ enum class KEY_TYPE {
interface Key {
- val keyType: crypto.pb.Crypto.KeyType
+ val keyType: Crypto.KeyType
/**
* Bytes returns a serialized, storeable representation of this key.
@@ -124,12 +124,12 @@ abstract class PubKey(override val keyType: Crypto.KeyType) : Key {
* @param bits the number of bits desired for the key (only applicable for RSA).
*/
@JvmOverloads
-fun generateKeyPair(type: KEY_TYPE, bits: Int = 2048, random: SecureRandom = SecureRandom()): Pair {
+fun generateKeyPair(type: KeyType, bits: Int = 2048, random: SecureRandom = SecureRandom()): Pair {
return when (type) {
- KEY_TYPE.RSA -> generateRsaKeyPair(bits, random)
- KEY_TYPE.ED25519 -> generateEd25519KeyPair(random)
- KEY_TYPE.SECP256K1 -> generateSecp256k1KeyPair(random)
- KEY_TYPE.ECDSA -> generateEcdsaKeyPair(random)
+ KeyType.RSA -> generateRsaKeyPair(bits, random)
+ KeyType.ED25519 -> generateEd25519KeyPair(random)
+ KeyType.SECP256K1 -> generateSecp256k1KeyPair(random)
+ KeyType.ECDSA -> generateEcdsaKeyPair(random)
}
}
diff --git a/libp2p/src/main/kotlin/io/libp2p/core/dsl/Builders.kt b/libp2p/src/main/kotlin/io/libp2p/core/dsl/Builders.kt
index 67dd02fcd..971d35b07 100644
--- a/libp2p/src/main/kotlin/io/libp2p/core/dsl/Builders.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/core/dsl/Builders.kt
@@ -8,7 +8,7 @@ import io.libp2p.core.ConnectionHandler
import io.libp2p.core.Host
import io.libp2p.core.P2PChannel
import io.libp2p.core.Stream
-import io.libp2p.core.crypto.KEY_TYPE
+import io.libp2p.core.crypto.KeyType
import io.libp2p.core.crypto.PrivKey
import io.libp2p.core.crypto.generateKeyPair
import io.libp2p.core.multiformats.Multiaddr
@@ -219,8 +219,8 @@ class NetworkConfigBuilder {
class IdentityBuilder {
var factory: IdentityFactory? = null
- fun random() = random(KEY_TYPE.ECDSA)
- fun random(keyType: KEY_TYPE): IdentityBuilder = apply { factory = { generateKeyPair(keyType).first } }
+ fun random() = random(KeyType.ECDSA)
+ fun random(keyType: KeyType): IdentityBuilder = apply { factory = { generateKeyPair(keyType).first } }
}
class AddressBookBuilder {
@@ -241,11 +241,13 @@ class DebugBuilder {
* Could be primarily useful for security handshake debugging/monitoring
*/
val beforeSecureHandler = DebugHandlerBuilder("wire.sec.before")
+
/**
* Injects the [ChannelHandler] right after the connection cipher
* to handle plain wire messages
*/
val afterSecureHandler = DebugHandlerBuilder("wire.sec.after")
+
/**
* Injects the [ChannelHandler] right after the [StreamMuxer] pipeline handler
* It intercepts [io.libp2p.mux.MuxFrame] instances
diff --git a/libp2p/src/main/kotlin/io/libp2p/core/multiformats/MultiaddrDns.kt b/libp2p/src/main/kotlin/io/libp2p/core/multiformats/MultiaddrDns.kt
index 294fc5a8a..2fe118b27 100644
--- a/libp2p/src/main/kotlin/io/libp2p/core/multiformats/MultiaddrDns.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/core/multiformats/MultiaddrDns.kt
@@ -17,18 +17,20 @@ class MultiaddrDns {
private val dnsProtocols = arrayOf(Protocol.DNS4, Protocol.DNS6, Protocol.DNSADDR)
fun resolve(addr: Multiaddr, resolver: Resolver = DefaultResolver): List {
- if (!addr.hasAny(*dnsProtocols))
+ if (!addr.hasAny(*dnsProtocols)) {
return listOf(addr)
+ }
val addressesToResolve = addr.split { isDnsProtocol(it) }
val resolvedAddresses = mutableListOf>()
for (address in addressesToResolve) {
val toResolve = address.filterComponents(*dnsProtocols).firstOrNull()
- val resolved = if (toResolve != null)
+ val resolved = if (toResolve != null) {
resolve(toResolve.protocol, toResolve.stringValue!!, address, resolver)
- else
+ } else {
listOf(address)
+ }
resolvedAddresses.add(resolved)
}
@@ -70,13 +72,14 @@ class MultiaddrDns {
// * /ip4/1.1.1.2/p2p-circuit/ip4/2.1.1.1
// * /ip4/1.1.1.2/p2p-circuit/ip4/2.1.1.2
private fun crossProduct(addressMatrix: List>): List {
- return if (addressMatrix.size == 1)
+ return if (addressMatrix.size == 1) {
addressMatrix[0]
- else
+ } else {
addressMatrix[0].flatMap { parent ->
crossProduct(addressMatrix.subList(1, addressMatrix.size))
.map { child -> parent.concatenated(child) }
}
+ }
}
private fun isDnsProtocol(proto: Protocol): Boolean {
diff --git a/libp2p/src/main/kotlin/io/libp2p/core/multiformats/Multihash.kt b/libp2p/src/main/kotlin/io/libp2p/core/multiformats/Multihash.kt
index ad3645506..b09c5fa88 100644
--- a/libp2p/src/main/kotlin/io/libp2p/core/multiformats/Multihash.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/core/multiformats/Multihash.kt
@@ -112,6 +112,7 @@ class Multihash(val bytes: ByteBuf, val desc: Descriptor, val lengthBits: Int, v
return Multihash(this, desc, lengthBits, digest)
}
}
+
@JvmStatic
fun digest(desc: Descriptor, content: ByteBuf, lengthBits: Int? = null): Multihash {
val entry = REGISTRY[desc] ?: throw InvalidMultihashException("Unrecognised multihash descriptor")
diff --git a/libp2p/src/main/kotlin/io/libp2p/core/multiformats/Protocol.kt b/libp2p/src/main/kotlin/io/libp2p/core/multiformats/Protocol.kt
index f097591a1..5d171b811 100644
--- a/libp2p/src/main/kotlin/io/libp2p/core/multiformats/Protocol.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/core/multiformats/Protocol.kt
@@ -115,8 +115,9 @@ enum class Protocol(
private const val LENGTH_PREFIXED_VAR_SIZE = -1
private val SIZE_VALIDATOR: (Protocol, ByteArray?) -> Unit = { protocol, bytes ->
- if (!protocol.hasValue && bytes != null)
+ if (!protocol.hasValue && bytes != null) {
throw IllegalArgumentException("No value expected for protocol $protocol, but got ${bytes.contentToString()}")
+ }
if (protocol.hasValue) {
requireNotNull(bytes) { "Non-null value expected for protocol $protocol" }
if (protocol.sizeBits != LENGTH_PREFIXED_VAR_SIZE && bytes.size * 8 != protocol.sizeBits) {
diff --git a/libp2p/src/main/kotlin/io/libp2p/core/multistream/ProtocolMatcher.kt b/libp2p/src/main/kotlin/io/libp2p/core/multistream/ProtocolMatcher.kt
index 7e8448c38..8f46d6144 100644
--- a/libp2p/src/main/kotlin/io/libp2p/core/multistream/ProtocolMatcher.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/core/multistream/ProtocolMatcher.kt
@@ -15,10 +15,12 @@ interface ProtocolMatcher {
fun strict(protocol: ProtocolId) = object : ProtocolMatcher {
override fun matches(proposed: ProtocolId) = protocol == proposed
}
+
@JvmStatic
fun prefix(protocolPrefix: String) = object : ProtocolMatcher {
override fun matches(proposed: ProtocolId) = proposed.startsWith(protocolPrefix)
}
+
@JvmStatic
fun list(protocols: Collection) = object : ProtocolMatcher {
override fun matches(proposed: ProtocolId) = proposed in protocols
diff --git a/libp2p/src/main/kotlin/io/libp2p/core/pubsub/PubsubApi.kt b/libp2p/src/main/kotlin/io/libp2p/core/pubsub/PubsubApi.kt
index 0ecb451d4..21b8dbffe 100644
--- a/libp2p/src/main/kotlin/io/libp2p/core/pubsub/PubsubApi.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/core/pubsub/PubsubApi.kt
@@ -173,14 +173,17 @@ interface MessageApi {
* Message body
*/
val data: ByteBuf
+
/**
* Sender identity. Usually it a [PeerId] derived from the sender's public key
*/
val from: ByteArray?
+
/**
* Sequence id for the sender. A pair [from]` + `[seqId] should be globally unique
*/
val seqId: Long?
+
/**
* A set of message topics
*/
diff --git a/libp2p/src/main/kotlin/io/libp2p/discovery/MDnsDiscovery.kt b/libp2p/src/main/kotlin/io/libp2p/discovery/MDnsDiscovery.kt
index 585135a58..658103db3 100644
--- a/libp2p/src/main/kotlin/io/libp2p/discovery/MDnsDiscovery.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/discovery/MDnsDiscovery.kt
@@ -105,8 +105,9 @@ class MDnsDiscovery(
val aRecords = answers.filter { DNSRecordType.TYPE_A.equals(it.recordType) }
val aaaaRecords = answers.filter { DNSRecordType.TYPE_AAAA.equals(it.recordType) }
- if (txtRecord == null || srvRecord == null || aRecords.isEmpty())
+ if (txtRecord == null || srvRecord == null || aRecords.isEmpty()) {
return // incomplete answers
+ }
txtRecord as DNSRecord.Text
srvRecord as DNSRecord.Service
diff --git a/libp2p/src/main/kotlin/io/libp2p/etc/types/AsyncExt.kt b/libp2p/src/main/kotlin/io/libp2p/etc/types/AsyncExt.kt
index 0e24eb4d4..7dcbf57c9 100644
--- a/libp2p/src/main/kotlin/io/libp2p/etc/types/AsyncExt.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/etc/types/AsyncExt.kt
@@ -61,16 +61,19 @@ fun anyComplete(all: List>): CompletableFuture =
anyComplete(*all.toTypedArray())
fun anyComplete(vararg all: CompletableFuture): CompletableFuture {
- return if (all.isEmpty()) completedExceptionally(NothingToCompleteException())
- else object : CompletableFuture() {
- init {
- val counter = AtomicInteger(all.size)
- all.forEach {
- it.whenComplete { v, t ->
- if (t == null) {
- complete(v)
- } else if (counter.decrementAndGet() == 0) {
- completeExceptionally(NonCompleteException(t))
+ return if (all.isEmpty()) {
+ completedExceptionally(NothingToCompleteException())
+ } else {
+ object : CompletableFuture() {
+ init {
+ val counter = AtomicInteger(all.size)
+ all.forEach {
+ it.whenComplete { v, t ->
+ if (t == null) {
+ complete(v)
+ } else if (counter.decrementAndGet() == 0) {
+ completeExceptionally(NonCompleteException(t))
+ }
}
}
}
diff --git a/libp2p/src/main/kotlin/io/libp2p/etc/types/Delegates.kt b/libp2p/src/main/kotlin/io/libp2p/etc/types/Delegates.kt
index 9c9e3a77a..ea44d904a 100644
--- a/libp2p/src/main/kotlin/io/libp2p/etc/types/Delegates.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/etc/types/Delegates.kt
@@ -39,18 +39,20 @@ fun cappedDouble(
// thanks to https://stackoverflow.com/a/47948047/9630725
class LazyMutable(val initializer: () -> T, val rejectSetAfterGet: Boolean = false) : ReadWriteProperty {
- private object UNINITIALIZED_VALUE
- private var prop: Any? = UNINITIALIZED_VALUE
+ private object UninitializedValue
+ private var prop: Any? = UninitializedValue
private var readAccessed = false
@Suppress("UNCHECKED_CAST")
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
- return if (prop == UNINITIALIZED_VALUE) {
+ return if (prop == UninitializedValue) {
synchronized(this) {
readAccessed = true
- return if (prop == UNINITIALIZED_VALUE) initializer().also { prop = it } else prop as T
+ return if (prop == UninitializedValue) initializer().also { prop = it } else prop as T
}
- } else prop as T
+ } else {
+ prop as T
+ }
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
diff --git a/libp2p/src/main/kotlin/io/libp2p/etc/types/MutableBiMultiMap.kt b/libp2p/src/main/kotlin/io/libp2p/etc/types/MutableBiMultiMap.kt
index 59d86193b..0d34d0f75 100644
--- a/libp2p/src/main/kotlin/io/libp2p/etc/types/MutableBiMultiMap.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/etc/types/MutableBiMultiMap.kt
@@ -55,6 +55,7 @@ operator fun MutableBiMultiMap.minusAssign(key: K) = removeKey(key)
internal class MutableBiMultiMapImpl : MutableBiMultiMap {
@VisibleForTesting
internal val keyToValue: MutableMap = mutableMapOf()
+
@VisibleForTesting
internal val valueToKeys: MutableMap> = mutableMapOf()
diff --git a/libp2p/src/main/kotlin/io/libp2p/etc/util/P2PService.kt b/libp2p/src/main/kotlin/io/libp2p/etc/util/P2PService.kt
index 13c2d3f38..9ad2bdd71 100644
--- a/libp2p/src/main/kotlin/io/libp2p/etc/util/P2PService.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/etc/util/P2PService.kt
@@ -34,6 +34,7 @@ abstract class P2PService(
) {
private val peersMutable = mutableListOf()
+
/**
* List of connected peers.
* Note that connected peer could not be ready for writing yet, so consider [activePeers]
@@ -42,6 +43,7 @@ abstract class P2PService(
val peers: List = peersMutable
private val activePeersMutable = mutableListOf()
+
/**
* List of active peers to which data could be written
*/
@@ -241,6 +243,7 @@ abstract class P2PService(
* Executes the code on the service event thread
*/
fun submitOnEventThread(run: () -> C): CompletableFuture = CompletableFuture.supplyAsync({ run() }, executor)
+
/**
* Executes the code on the service event thread
*/
diff --git a/libp2p/src/main/kotlin/io/libp2p/multistream/Negotiator.kt b/libp2p/src/main/kotlin/io/libp2p/multistream/Negotiator.kt
index 988725dd3..49d4cbd3b 100644
--- a/libp2p/src/main/kotlin/io/libp2p/multistream/Negotiator.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/multistream/Negotiator.kt
@@ -94,8 +94,11 @@ object Negotiator {
override fun channelRead0(ctx: ChannelHandlerContext, msg: String) {
if (msg == MULTISTREAM_PROTO) {
- if (!headerRead) headerRead = true else
+ if (!headerRead) {
+ headerRead = true
+ } else {
throw ProtocolNegotiationException("Received multistream header more than once")
+ }
} else {
processMsg(ctx, msg)?.also { completeEvent ->
// first fire event to setup a handler for selected protocol
diff --git a/libp2p/src/main/kotlin/io/libp2p/multistream/ProtocolSelect.kt b/libp2p/src/main/kotlin/io/libp2p/multistream/ProtocolSelect.kt
index 332d8f2b6..9fef1f3f2 100644
--- a/libp2p/src/main/kotlin/io/libp2p/multistream/ProtocolSelect.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/multistream/ProtocolSelect.kt
@@ -48,7 +48,8 @@ class ProtocolSelect(val protocols: List(Lon
{
requests.remove(dataS)?.second?.completeExceptionally(PingTimeoutException())
},
- pingTimeout.toMillis(), TimeUnit.MILLISECONDS
+ pingTimeout.toMillis(),
+ TimeUnit.MILLISECONDS
)
}
diff --git a/libp2p/src/main/kotlin/io/libp2p/protocol/ProtocolMessageHandlerAdapter.kt b/libp2p/src/main/kotlin/io/libp2p/protocol/ProtocolMessageHandlerAdapter.kt
index 4a3dd52ab..a86dd2cce 100644
--- a/libp2p/src/main/kotlin/io/libp2p/protocol/ProtocolMessageHandlerAdapter.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/protocol/ProtocolMessageHandlerAdapter.kt
@@ -54,10 +54,12 @@ class ProtocolMessageHandlerAdapter(
}
private fun checkedRelease(count: Int, obj: Any) {
- if (count == -1)
+ if (count == -1) {
return
+ }
val rc = obj as ReferenceCounted
- if (count == rc.refCnt())
+ if (count == rc.refCnt()) {
rc.release()
+ }
}
}
diff --git a/libp2p/src/main/kotlin/io/libp2p/pubsub/PubsubApiImpl.kt b/libp2p/src/main/kotlin/io/libp2p/pubsub/PubsubApiImpl.kt
index dc4bfdf19..fddc263f2 100644
--- a/libp2p/src/main/kotlin/io/libp2p/pubsub/PubsubApiImpl.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/pubsub/PubsubApiImpl.kt
@@ -81,8 +81,11 @@ open class PubsubApiImpl(val router: PubsubRouter) : PubsubApi {
it.receiver.apply(rpc2Msg(msg))
}
return validationFuts.thenApplyAll {
- if (it.isEmpty()) ValidationResult.Ignore
- else it.reduce(validationResultReduce)
+ if (it.isEmpty()) {
+ ValidationResult.Ignore
+ } else {
+ it.reduce(validationResultReduce)
+ }
}
}
@@ -139,8 +142,10 @@ class MessageImpl(override val originalMessage: PubsubMessage) : MessageApi {
private val msg = originalMessage.protobufMessage
override val data = msg.data.toByteArray().toByteBuf()
override val from = if (msg.hasFrom()) msg.from.toByteArray() else null
- override val seqId = if (msg.hasSeqno() && msg.seqno.size() >= 8)
+ override val seqId = if (msg.hasSeqno() && msg.seqno.size() >= 8) {
msg.seqno.toByteArray().copyOfRange(0, 8).toLongBigEndian()
- else null
+ } else {
+ null
+ }
override val topics = msg.topicIDsList.map { Topic(it) }
}
diff --git a/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/Gossip.kt b/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/Gossip.kt
index 0645ddf46..b413c03df 100644
--- a/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/Gossip.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/Gossip.kt
@@ -30,13 +30,14 @@ class Gossip @JvmOverloads constructor(
}
override val protocolDescriptor =
- if (router.protocol == PubsubProtocol.Gossip_V_1_1)
+ if (router.protocol == PubsubProtocol.Gossip_V_1_1) {
ProtocolDescriptor(
PubsubProtocol.Gossip_V_1_1.announceStr,
PubsubProtocol.Gossip_V_1_0.announceStr
)
- else
+ } else {
ProtocolDescriptor(PubsubProtocol.Gossip_V_1_0.announceStr)
+ }
override fun handleConnection(conn: Connection) {
conn.muxerSession().createStream(listOf(this))
diff --git a/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/GossipParams.kt b/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/GossipParams.kt
index fb7fa6180..6823ecc4e 100644
--- a/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/GossipParams.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/GossipParams.kt
@@ -485,7 +485,7 @@ data class GossipTopicScoreParams(
* The penalty is only activated after [meshMessageDeliveriesActivation] time in the mesh.
* The weight of the parameter MUST be negative (or zero to disable).
*/
- val meshMessageDeliveriesWeight: Weight = 0.0 /*-1.0*/, // TODO temporarily exclude this parameter
+ val meshMessageDeliveriesWeight: Weight = 0.0, // TODO temporarily exclude this parameter
/** @see meshMessageDeliveriesWeight */
val meshMessageDeliveriesDecay: Double = 0.0,
/** @see meshMessageDeliveriesWeight */
diff --git a/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/GossipRouter.kt b/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/GossipRouter.kt
index 2d3b21625..c09f0a67e 100644
--- a/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/GossipRouter.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/GossipRouter.kt
@@ -234,7 +234,6 @@ open class GossipRouter(
curTime <= whitelistEntry.whitelistedTill &&
whitelistEntry.messagesAccepted < acceptRequestsWhitelistMaxMessages
) {
-
acceptRequestsWhitelist[peer] = whitelistEntry.incrementMessageCount()
return true
}
diff --git a/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/GossipRpcPartsQueue.kt b/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/GossipRpcPartsQueue.kt
index bfe86339e..cc5fe7893 100644
--- a/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/GossipRpcPartsQueue.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/GossipRpcPartsQueue.kt
@@ -21,6 +21,7 @@ interface GossipRpcPartsQueue : RpcPartsQueue {
* Gossip 1.0 variant
*/
fun addPrune(topic: Topic)
+
/**
* Gossip 1.1 variant
*/
@@ -118,7 +119,6 @@ open class DefaultGossipRpcPartsQueue(
publishCount > 0 && subscriptionCount > 0 && iHaveCount > 0 &&
iWantCount > 0 && graftCount > 0 && pruneCount > 0
) {
-
val part = parts[partIdx++]
when (part) {
is PublishPart -> publishCount--
diff --git a/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/GossipScore.kt b/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/GossipScore.kt
index a8f41deb4..c244e0c08 100644
--- a/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/GossipScore.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/pubsub/gossip/GossipScore.kt
@@ -91,9 +91,11 @@ class DefaultGossipScore(
inMesh() && ((curTimeMillis() - joinedMeshTimeMillis).millis > params.meshMessageDeliveriesActivation)
private fun meshMessageDeliveriesDeficit() =
- if (isMeshMessageDeliveriesActive())
+ if (isMeshMessageDeliveriesActive()) {
max(0.0, params.meshMessageDeliveriesThreshold - meshMessageDeliveries)
- else 0.0
+ } else {
+ 0.0
+ }
fun meshMessageDeliveriesDeficitSqr() = meshMessageDeliveriesDeficit().pow(2)
@@ -142,8 +144,11 @@ class DefaultGossipScore(
fun isConnected() = connectedTimeMillis > 0 && disconnectedTimeMillis == 0L
fun isDisconnected() = disconnectedTimeMillis > 0
fun getDisconnectDuration() =
- if (isDisconnected()) (curTimeMillis() - disconnectedTimeMillis).millis
- else throw IllegalStateException("Peer is not disconnected")
+ if (isDisconnected()) {
+ (curTimeMillis() - disconnectedTimeMillis).millis
+ } else {
+ throw IllegalStateException("Peer is not disconnected")
+ }
}
val peerParams = params.peerScoreParams
@@ -197,8 +202,11 @@ class DefaultGossipScore(
val behaviorExcess = peerScore.behaviorPenalty - peerParams.behaviourPenaltyThreshold
val routerPenalty =
- if (behaviorExcess < 0) 0.0
- else behaviorExcess.pow(2) * peerParams.behaviourPenaltyWeight
+ if (behaviorExcess < 0) {
+ 0.0
+ } else {
+ behaviorExcess.pow(2) * peerParams.behaviourPenaltyWeight
+ }
val computedScore = topicsScore + appScore + ipColocationPenalty + routerPenalty
peerScore.cachedScore = computedScore
diff --git a/libp2p/src/main/kotlin/io/libp2p/security/noise/NoiseXXSecureChannel.kt b/libp2p/src/main/kotlin/io/libp2p/security/noise/NoiseXXSecureChannel.kt
index 9bb407ef6..8ab7bcb14 100644
--- a/libp2p/src/main/kotlin/io/libp2p/security/noise/NoiseXXSecureChannel.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/security/noise/NoiseXXSecureChannel.kt
@@ -226,7 +226,6 @@ class NoiseIoHandshake(
} // sendNoiseStaticKeyAsPayload
private fun sendNoiseMessage(ctx: ChannelHandlerContext, msg: ByteArray? = null) {
-
val lenMsg = if (!NoiseXXSecureChannel.rustInteroperability) {
msg
} else if (msg != null) {
diff --git a/libp2p/src/main/kotlin/io/libp2p/security/plaintext/PlaintextInsecureChannel.kt b/libp2p/src/main/kotlin/io/libp2p/security/plaintext/PlaintextInsecureChannel.kt
index a75c71ce3..7b2c00d71 100644
--- a/libp2p/src/main/kotlin/io/libp2p/security/plaintext/PlaintextInsecureChannel.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/security/plaintext/PlaintextInsecureChannel.kt
@@ -84,14 +84,16 @@ class PlaintextHandshakeHandler(
val exchangeRecv = Plaintext.Exchange.parser().parseFrom(msg.nioBuffer())
?: throw InvalidInitialPacket()
- if (!exchangeRecv.hasPubkey())
+ if (!exchangeRecv.hasPubkey()) {
throw InvalidRemotePubKey()
+ }
remotePeerId = PeerId(exchangeRecv.id.toByteArray())
remotePubKey = unmarshalPublicKey(exchangeRecv.pubkey.toByteArray())
val calculatedPeerId = PeerId.fromPubKey(remotePubKey)
- if (remotePeerId != calculatedPeerId)
+ if (remotePeerId != calculatedPeerId) {
throw InvalidRemotePubKey()
+ }
handshakeCompleted(ctx)
} // channelRead0
diff --git a/libp2p/src/main/kotlin/io/libp2p/security/secio/SecIoCodec.kt b/libp2p/src/main/kotlin/io/libp2p/security/secio/SecIoCodec.kt
index dfdbbb3d5..097b77f19 100644
--- a/libp2p/src/main/kotlin/io/libp2p/security/secio/SecIoCodec.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/security/secio/SecIoCodec.kt
@@ -58,8 +58,9 @@ class SecIoCodec(val local: SecioParams, val remote: SecioParams) : MessageToMes
val macArr = updateMac(remote, cipherBytes)
- if (!macBytes.contentEquals(macArr))
+ if (!macBytes.contentEquals(macArr)) {
throw InvalidMacException()
+ }
val clearText = processBytes(remoteCipher, cipherBytes)
out.add(clearText.toByteBuf())
diff --git a/libp2p/src/main/kotlin/io/libp2p/security/secio/SecIoNegotiator.kt b/libp2p/src/main/kotlin/io/libp2p/security/secio/SecIoNegotiator.kt
index 837a9b8e2..c55a0ac19 100644
--- a/libp2p/src/main/kotlin/io/libp2p/security/secio/SecIoNegotiator.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/security/secio/SecIoNegotiator.kt
@@ -140,8 +140,9 @@ class SecIoNegotiator(
val pubKey = unmarshalPublicKey(remotePubKeyBytes)
val calcedPeerId = PeerId.fromPubKey(pubKey)
- if (remotePeerId != null && calcedPeerId != remotePeerId)
+ if (remotePeerId != null && calcedPeerId != remotePeerId) {
throw InvalidRemotePubKey()
+ }
return pubKey
} // validateRemoteKey
@@ -151,8 +152,9 @@ class SecIoNegotiator(
val h2 = sha256(localPubKeyBytes + remoteNonce)
val keyOrder = h1.compareTo(h2)
- if (keyOrder == 0)
+ if (keyOrder == 0) {
throw SelfConnecting()
+ }
return keyOrder
} // orderKeys
@@ -203,8 +205,9 @@ class SecIoNegotiator(
exchangeMsg.signature.toByteArray()
)
- if (!signatureIsOk)
+ if (!signatureIsOk) {
throw InvalidSignature()
+ }
} // validateExchangeMessage
private fun calcHMac(macKey: ByteArray): HMac {
@@ -241,8 +244,9 @@ class SecIoNegotiator(
} // generateSharedSecret
private fun verifyNonceResponse(buf: ByteBuf) {
- if (!nonce.contentEquals(buf.toByteArray()))
+ if (!nonce.contentEquals(buf.toByteArray())) {
throw InvalidInitialPacket()
+ }
state = State.FinalValidated
} // verifyNonceResponse
diff --git a/libp2p/src/main/kotlin/io/libp2p/security/tls/TLSSecureChannel.kt b/libp2p/src/main/kotlin/io/libp2p/security/tls/TLSSecureChannel.kt
index ad4d229f5..f555418c7 100644
--- a/libp2p/src/main/kotlin/io/libp2p/security/tls/TLSSecureChannel.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/security/tls/TLSSecureChannel.kt
@@ -109,10 +109,11 @@ fun buildTlsHandler(
val connectionKeys = if (certAlgorithm.equals("ECDSA")) generateEcdsaKeyPair() else generateEd25519KeyPair()
val javaPrivateKey = getJavaKey(connectionKeys.first)
val sslContext = (
- if (ch.isInitiator)
+ if (ch.isInitiator) {
SslContextBuilder.forClient().keyManager(javaPrivateKey, listOf(buildCert(localKey, connectionKeys.first)))
- else
+ } else {
SslContextBuilder.forServer(javaPrivateKey, listOf(buildCert(localKey, connectionKeys.first)))
+ }
)
.protocols(listOf("TLSv1.3"))
.ciphers(listOf("TLS_AES_128_GCM_SHA256", "TLS_AES_256_GCM_SHA384", "TLS_CHACHA20_POLY1305_SHA256"))
@@ -133,10 +134,11 @@ fun buildTlsHandler(
val handshake = handler.handshakeFuture()
val engine = handler.engine()
handshake.addListener { fut ->
- if (! fut.isSuccess) {
+ if (!fut.isSuccess) {
var cause = fut.cause()
- if (cause != null && cause.cause != null)
+ if (cause != null && cause.cause != null) {
cause = cause.cause
+ }
handshakeComplete.completeExceptionally(cause)
} else {
val nextProtocol = handler.applicationProtocol()
@@ -175,7 +177,7 @@ private class ChannelSetup(
private var activated = false
override fun channelActive(ctx: ChannelHandlerContext) {
- if (! activated) {
+ if (!activated) {
activated = true
val expectedRemotePeerId = ctx.channel().attr(REMOTE_PEER_ID).get()
ctx.channel().pipeline().addLast(
@@ -214,11 +216,13 @@ private class ChannelSetup(
class Libp2pTrustManager(private val expectedRemotePeer: Optional) : X509TrustManager {
override fun checkClientTrusted(certs: Array?, authType: String?) {
- if (certs?.size != 1)
+ if (certs?.size != 1) {
throw CertificateException()
+ }
val claimedPeerId = verifyAndExtractPeerId(arrayOf(certs.get(0)))
- if (expectedRemotePeer.map { ex -> ! ex.equals(claimedPeerId) }.orElse(false))
+ if (expectedRemotePeer.map { ex -> !ex.equals(claimedPeerId) }.orElse(false)) {
throw InvalidRemotePubKey()
+ }
}
override fun checkServerTrusted(certs: Array?, authType: String?) {
@@ -268,14 +272,16 @@ fun getPubKey(pub: PublicKey): PubKey {
if (pub.algorithm.equals("EC")) {
return EcdsaPublicKey(pub as ECPublicKey)
}
- if (pub.algorithm.equals("RSA"))
+ if (pub.algorithm.equals("RSA")) {
throw IllegalStateException("Unimplemented RSA public key support for TLS")
+ }
throw IllegalStateException("Unsupported key type: " + pub.algorithm)
}
fun verifyAndExtractPeerId(chain: Array): PeerId {
- if (chain.size != 1)
+ if (chain.size != 1) {
throw java.lang.IllegalStateException("Cert chain must have exactly 1 element!")
+ }
val cert = chain.get(0)
// peerid is in the certificate extension
val bcCert = org.bouncycastle.asn1.x509.Certificate
@@ -283,29 +289,34 @@ fun verifyAndExtractPeerId(chain: Array): PeerId {
val bcX509Cert = X509CertificateHolder(bcCert)
val libp2pOid = ASN1ObjectIdentifier("1.3.6.1.4.1.53594.1.1")
val extension = bcX509Cert.extensions.getExtension(libp2pOid)
- if (extension == null)
+ if (extension == null) {
throw IllegalStateException("Certificate extension not present!")
+ }
val input = ASN1InputStream(extension.extnValue.encoded)
val wrapper = input.readObject() as DEROctetString
val seq = ASN1InputStream(wrapper.octets).readObject() as DLSequence
val pubKeyProto = (seq.getObjectAt(0) as DEROctetString).octets
val signature = (seq.getObjectAt(1) as DEROctetString).octets
val pubKey = unmarshalPublicKey(pubKeyProto)
- if (! pubKey.verify(certificatePrefix.plus(cert.publicKey.encoded), signature))
+ if (!pubKey.verify(certificatePrefix.plus(cert.publicKey.encoded), signature)) {
throw IllegalStateException("Invalid signature on TLS certificate extension!")
+ }
cert.verify(cert.publicKey)
val now = Date()
- if (bcCert.endDate.date.before(now))
+ if (bcCert.endDate.date.before(now)) {
throw IllegalStateException("TLS certificate has expired!")
- if (bcCert.startDate.date.after(now))
+ }
+ if (bcCert.startDate.date.after(now)) {
throw IllegalStateException("TLS certificate is not valid yet!")
+ }
return PeerId.fromPubKey(pubKey)
}
fun getPublicKeyFromCert(chain: Array): PubKey {
- if (chain.size != 1)
+ if (chain.size != 1) {
throw java.lang.IllegalStateException("Cert chain must have exactly 1 element!")
+ }
val cert = chain.get(0)
return getPubKey(cert.publicKey)
}
diff --git a/libp2p/src/main/kotlin/io/libp2p/transport/implementation/ConnectionOverNetty.kt b/libp2p/src/main/kotlin/io/libp2p/transport/implementation/ConnectionOverNetty.kt
index fee796146..f6617cc03 100644
--- a/libp2p/src/main/kotlin/io/libp2p/transport/implementation/ConnectionOverNetty.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/transport/implementation/ConnectionOverNetty.kt
@@ -43,10 +43,11 @@ open class ConnectionOverNetty(
toMultiaddr(nettyChannel.remoteAddress() as InetSocketAddress)
private fun toMultiaddr(addr: InetSocketAddress): Multiaddr {
- if (transport is NettyTransport)
+ if (transport is NettyTransport) {
return transport.toMultiaddr(addr)
- else
+ } else {
return toMultiaddrDefault(addr)
+ }
}
fun toMultiaddrDefault(addr: InetSocketAddress): Multiaddr {
diff --git a/libp2p/src/main/kotlin/io/libp2p/transport/implementation/NettyTransport.kt b/libp2p/src/main/kotlin/io/libp2p/transport/implementation/NettyTransport.kt
index 2a078266d..f29c2bfa6 100644
--- a/libp2p/src/main/kotlin/io/libp2p/transport/implementation/NettyTransport.kt
+++ b/libp2p/src/main/kotlin/io/libp2p/transport/implementation/NettyTransport.kt
@@ -129,8 +129,7 @@ abstract class NettyTransport(
?: throw Libp2pException("No listeners on address $addr")
} // unlisten
- override fun dial(addr: Multiaddr, connHandler: ConnectionHandler, preHandler: ChannelVisitor?):
- CompletableFuture {
+ override fun dial(addr: Multiaddr, connHandler: ConnectionHandler, preHandler: ChannelVisitor?): CompletableFuture {
if (closed) throw Libp2pException("Transport is closed")
val remotePeerId = addr.getPeerId()
@@ -186,8 +185,9 @@ abstract class NettyTransport(
protected fun hostFromMultiaddr(addr: Multiaddr): String {
val resolvedAddresses = MultiaddrDns.resolve(addr)
- if (resolvedAddresses.isEmpty())
+ if (resolvedAddresses.isEmpty()) {
throw Libp2pException("Could not resolve $addr to an IP address")
+ }
return resolvedAddresses[0].components.find {
it.protocol in arrayOf(Protocol.IP4, Protocol.IP6)
diff --git a/libp2p/src/test/java/io/libp2p/core/HostTestJava.java b/libp2p/src/test/java/io/libp2p/core/HostTestJava.java
index f5e63059e..1f943159c 100644
--- a/libp2p/src/test/java/io/libp2p/core/HostTestJava.java
+++ b/libp2p/src/test/java/io/libp2p/core/HostTestJava.java
@@ -1,7 +1,7 @@
package io.libp2p.core;
-import io.libp2p.core.crypto.KEY_TYPE;
import io.libp2p.core.crypto.KeyKt;
+import io.libp2p.core.crypto.KeyType;
import io.libp2p.core.crypto.PrivKey;
import io.libp2p.core.crypto.PubKey;
import io.libp2p.core.dsl.HostBuilder;
@@ -11,218 +11,214 @@
import io.libp2p.protocol.PingController;
import io.libp2p.security.tls.*;
import io.libp2p.transport.tcp.TcpTransport;
-import kotlin.Pair;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
+import kotlin.Pair;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
public class HostTestJava {
- @Test
- void ping() throws Exception {
-/* HostImpl clientHost = BuildersJKt.hostJ(b -> {
- b.getIdentity().random();
- b.getTransports().add(TcpTransport::new);
- b.getSecureChannels().add(SecIoSecureChannel::new);
- b.getMuxers().add(MplexStreamMuxer::new);
- b.getProtocols().add(new Ping());
- b.getDebug().getMuxFramesHandler().setLogger(LogLevel.ERROR, "host-1-MUX");
- b.getDebug().getBeforeSecureHandler().setLogger(LogLevel.ERROR, "host-1-BS");
- b.getDebug().getAfterSecureHandler().setLogger(LogLevel.ERROR, "host-1-AS");
- });
-*/
- String localListenAddress = "/ip4/127.0.0.1/tcp/40002";
-
- Host clientHost = new HostBuilder()
- .transport(TcpTransport::new)
- .secureChannel((k, m) -> new TlsSecureChannel(k, m, "ECDSA"))
- .muxer(StreamMuxerProtocol::getYamux)
- .build();
-
- Host serverHost = new HostBuilder()
- .transport(TcpTransport::new)
- .secureChannel(TlsSecureChannel::new)
- .muxer(StreamMuxerProtocol::getYamux)
- .protocol(new Ping())
- .listen(localListenAddress)
- .build();
-
- CompletableFuture clientStarted = clientHost.start();
- CompletableFuture serverStarted = serverHost.start();
- clientStarted.get(5, TimeUnit.SECONDS);
- System.out.println("Client started");
- serverStarted.get(5, TimeUnit.SECONDS);
- System.out.println("Server started");
-
- Assertions.assertEquals(0, clientHost.listenAddresses().size());
- Assertions.assertEquals(1, serverHost.listenAddresses().size());
- Assertions.assertEquals(
- localListenAddress + "/p2p/" + serverHost.getPeerId(),
- serverHost.listenAddresses().get(0).toString()
- );
-
- StreamPromise ping =
- clientHost.getNetwork().connect(
- serverHost.getPeerId(),
- new Multiaddr(localListenAddress)
- ).thenApply(
- it -> it.muxerSession().createStream(new Ping())
- )
- .get(5, TimeUnit.SECONDS);
-
- Stream pingStream = ping.getStream().get(5, TimeUnit.SECONDS);
- System.out.println("Ping stream created");
- PingController pingCtr = ping.getController().get(5, TimeUnit.SECONDS);
- System.out.println("Ping controller created");
-
- for (int i = 0; i < 10; i++) {
- long latency = pingCtr.ping().get(1, TimeUnit.SECONDS);
- System.out.println("Ping is " + latency);
- }
- pingStream.close().get(5, TimeUnit.SECONDS);
- System.out.println("Ping stream closed");
-
- Assertions.assertThrows(ExecutionException.class, () ->
- pingCtr.ping().get(5, TimeUnit.SECONDS));
-
- clientHost.stop().get(5, TimeUnit.SECONDS);
- System.out.println("Client stopped");
- serverHost.stop().get(5, TimeUnit.SECONDS);
- System.out.println("Server stopped");
+ @Test
+ void ping() throws Exception {
+ /* HostImpl clientHost = BuildersJKt.hostJ(b -> {
+ b.getIdentity().random();
+ b.getTransports().add(TcpTransport::new);
+ b.getSecureChannels().add(SecIoSecureChannel::new);
+ b.getMuxers().add(MplexStreamMuxer::new);
+ b.getProtocols().add(new Ping());
+ b.getDebug().getMuxFramesHandler().setLogger(LogLevel.ERROR, "host-1-MUX");
+ b.getDebug().getBeforeSecureHandler().setLogger(LogLevel.ERROR, "host-1-BS");
+ b.getDebug().getAfterSecureHandler().setLogger(LogLevel.ERROR, "host-1-AS");
+ });
+ */
+ String localListenAddress = "/ip4/127.0.0.1/tcp/40002";
+
+ Host clientHost =
+ new HostBuilder()
+ .transport(TcpTransport::new)
+ .secureChannel((k, m) -> new TlsSecureChannel(k, m, "ECDSA"))
+ .muxer(StreamMuxerProtocol::getYamux)
+ .build();
+
+ Host serverHost =
+ new HostBuilder()
+ .transport(TcpTransport::new)
+ .secureChannel(TlsSecureChannel::new)
+ .muxer(StreamMuxerProtocol::getYamux)
+ .protocol(new Ping())
+ .listen(localListenAddress)
+ .build();
+
+ CompletableFuture clientStarted = clientHost.start();
+ CompletableFuture serverStarted = serverHost.start();
+ clientStarted.get(5, TimeUnit.SECONDS);
+ System.out.println("Client started");
+ serverStarted.get(5, TimeUnit.SECONDS);
+ System.out.println("Server started");
+
+ Assertions.assertEquals(0, clientHost.listenAddresses().size());
+ Assertions.assertEquals(1, serverHost.listenAddresses().size());
+ Assertions.assertEquals(
+ localListenAddress + "/p2p/" + serverHost.getPeerId(),
+ serverHost.listenAddresses().get(0).toString());
+
+ StreamPromise ping =
+ clientHost
+ .getNetwork()
+ .connect(serverHost.getPeerId(), new Multiaddr(localListenAddress))
+ .thenApply(it -> it.muxerSession().createStream(new Ping()))
+ .get(5, TimeUnit.SECONDS);
+
+ Stream pingStream = ping.getStream().get(5, TimeUnit.SECONDS);
+ System.out.println("Ping stream created");
+ PingController pingCtr = ping.getController().get(5, TimeUnit.SECONDS);
+ System.out.println("Ping controller created");
+
+ for (int i = 0; i < 10; i++) {
+ long latency = pingCtr.ping().get(1, TimeUnit.SECONDS);
+ System.out.println("Ping is " + latency);
}
-
- @Test
- void largePing() throws Exception {
- int pingSize = 200 * 1024;
- String localListenAddress = "/ip4/127.0.0.1/tcp/40002";
-
- Host clientHost = new HostBuilder()
- .transport(TcpTransport::new)
- .secureChannel((k, m) -> new TlsSecureChannel(k, m, "ECDSA"))
- .muxer(StreamMuxerProtocol::getYamux)
- .build();
-
- Host serverHost = new HostBuilder()
- .transport(TcpTransport::new)
- .secureChannel(TlsSecureChannel::new)
- .muxer(StreamMuxerProtocol::getYamux)
- .protocol(new Ping(pingSize))
- .listen(localListenAddress)
- .build();
-
- CompletableFuture clientStarted = clientHost.start();
- CompletableFuture serverStarted = serverHost.start();
- clientStarted.get(5, TimeUnit.SECONDS);
- System.out.println("Client started");
- serverStarted.get(5, TimeUnit.SECONDS);
- System.out.println("Server started");
-
- Assertions.assertEquals(0, clientHost.listenAddresses().size());
- Assertions.assertEquals(1, serverHost.listenAddresses().size());
- Assertions.assertEquals(
- localListenAddress + "/p2p/" + serverHost.getPeerId(),
- serverHost.listenAddresses().get(0).toString()
- );
-
- StreamPromise ping =
- clientHost.getNetwork().connect(
- serverHost.getPeerId(),
- new Multiaddr(localListenAddress)
- ).thenApply(
- it -> it.muxerSession().createStream(new Ping(pingSize))
- )
- .join();
-
- Stream pingStream = ping.getStream().get(5, TimeUnit.SECONDS);
- System.out.println("Ping stream created");
- PingController pingCtr = ping.getController().get(5, TimeUnit.SECONDS);
- System.out.println("Ping controller created");
-
- for (int i = 0; i < 10; i++) {
- long latency = pingCtr.ping().join();//get(5, TimeUnit.SECONDS);
- System.out.println("Ping is " + latency);
- }
- pingStream.close().get(5, TimeUnit.SECONDS);
- System.out.println("Ping stream closed");
-
- Assertions.assertThrows(ExecutionException.class, () ->
- pingCtr.ping().get(5, TimeUnit.SECONDS));
-
- clientHost.stop().get(5, TimeUnit.SECONDS);
- System.out.println("Client stopped");
- serverHost.stop().get(5, TimeUnit.SECONDS);
- System.out.println("Server stopped");
+ pingStream.close().get(5, TimeUnit.SECONDS);
+ System.out.println("Ping stream closed");
+
+ Assertions.assertThrows(
+ ExecutionException.class, () -> pingCtr.ping().get(5, TimeUnit.SECONDS));
+
+ clientHost.stop().get(5, TimeUnit.SECONDS);
+ System.out.println("Client stopped");
+ serverHost.stop().get(5, TimeUnit.SECONDS);
+ System.out.println("Server stopped");
+ }
+
+ @Test
+ void largePing() throws Exception {
+ int pingSize = 200 * 1024;
+ String localListenAddress = "/ip4/127.0.0.1/tcp/40002";
+
+ Host clientHost =
+ new HostBuilder()
+ .transport(TcpTransport::new)
+ .secureChannel((k, m) -> new TlsSecureChannel(k, m, "ECDSA"))
+ .muxer(StreamMuxerProtocol::getYamux)
+ .build();
+
+ Host serverHost =
+ new HostBuilder()
+ .transport(TcpTransport::new)
+ .secureChannel(TlsSecureChannel::new)
+ .muxer(StreamMuxerProtocol::getYamux)
+ .protocol(new Ping(pingSize))
+ .listen(localListenAddress)
+ .build();
+
+ CompletableFuture clientStarted = clientHost.start();
+ CompletableFuture serverStarted = serverHost.start();
+ clientStarted.get(5, TimeUnit.SECONDS);
+ System.out.println("Client started");
+ serverStarted.get(5, TimeUnit.SECONDS);
+ System.out.println("Server started");
+
+ Assertions.assertEquals(0, clientHost.listenAddresses().size());
+ Assertions.assertEquals(1, serverHost.listenAddresses().size());
+ Assertions.assertEquals(
+ localListenAddress + "/p2p/" + serverHost.getPeerId(),
+ serverHost.listenAddresses().get(0).toString());
+
+ StreamPromise ping =
+ clientHost
+ .getNetwork()
+ .connect(serverHost.getPeerId(), new Multiaddr(localListenAddress))
+ .thenApply(it -> it.muxerSession().createStream(new Ping(pingSize)))
+ .join();
+
+ Stream pingStream = ping.getStream().get(5, TimeUnit.SECONDS);
+ System.out.println("Ping stream created");
+ PingController pingCtr = ping.getController().get(5, TimeUnit.SECONDS);
+ System.out.println("Ping controller created");
+
+ for (int i = 0; i < 10; i++) {
+ long latency = pingCtr.ping().join(); // get(5, TimeUnit.SECONDS);
+ System.out.println("Ping is " + latency);
}
-
- @Test
- void addPingAfterHostStart() throws Exception {
- String localListenAddress = "/ip4/127.0.0.1/tcp/40002";
-
- Host clientHost = new HostBuilder()
- .transport(TcpTransport::new)
- .secureChannel((k, m) -> new TlsSecureChannel(k, m, "ECDSA"))
- .muxer(StreamMuxerProtocol::getYamux)
- .build();
-
- Host serverHost = new HostBuilder()
- .transport(TcpTransport::new)
- .secureChannel(TlsSecureChannel::new)
- .muxer(StreamMuxerProtocol::getYamux)
- .listen(localListenAddress)
- .build();
-
- CompletableFuture clientStarted = clientHost.start();
- CompletableFuture serverStarted = serverHost.start();
- clientStarted.get(5, TimeUnit.SECONDS);
- System.out.println("Client started");
- serverStarted.get(5, TimeUnit.SECONDS);
- System.out.println("Server started");
-
- Assertions.assertEquals(0, clientHost.listenAddresses().size());
- Assertions.assertEquals(1, serverHost.listenAddresses().size());
- Assertions.assertEquals(
- localListenAddress + "/p2p/" + serverHost.getPeerId(),
- serverHost.listenAddresses().get(0).toString()
- );
-
- serverHost.addProtocolHandler(new Ping());
-
- StreamPromise ping =
- clientHost.getNetwork().connect(
- serverHost.getPeerId(),
- new Multiaddr(localListenAddress)
- ).thenApply(
- it -> it.muxerSession().createStream(new Ping())
- )
- .get(5, TimeUnit.SECONDS);
-
- Stream pingStream = ping.getStream().get(5, TimeUnit.SECONDS);
- System.out.println("Ping stream created");
- PingController pingCtr = ping.getController().get(5, TimeUnit.SECONDS);
- System.out.println("Ping controller created");
-
- for (int i = 0; i < 10; i++) {
- long latency = pingCtr.ping().get(1, TimeUnit.SECONDS);
- System.out.println("Ping is " + latency);
- }
- pingStream.close().get(5, TimeUnit.SECONDS);
- System.out.println("Ping stream closed");
-
- Assertions.assertThrows(ExecutionException.class, () ->
- pingCtr.ping().get(5, TimeUnit.SECONDS));
-
- clientHost.stop().get(5, TimeUnit.SECONDS);
- System.out.println("Client stopped");
- serverHost.stop().get(5, TimeUnit.SECONDS);
- System.out.println("Server stopped");
- }
-
- @Test
- void keyPairGeneration() {
- Pair pair = KeyKt.generateKeyPair(KEY_TYPE.SECP256K1);
- PeerId peerId = PeerId.fromPubKey(pair.component2());
- System.out.println("PeerId: " + peerId.toHex());
+ pingStream.close().get(5, TimeUnit.SECONDS);
+ System.out.println("Ping stream closed");
+
+ Assertions.assertThrows(
+ ExecutionException.class, () -> pingCtr.ping().get(5, TimeUnit.SECONDS));
+
+ clientHost.stop().get(5, TimeUnit.SECONDS);
+ System.out.println("Client stopped");
+ serverHost.stop().get(5, TimeUnit.SECONDS);
+ System.out.println("Server stopped");
+ }
+
+ @Test
+ void addPingAfterHostStart() throws Exception {
+ String localListenAddress = "/ip4/127.0.0.1/tcp/40002";
+
+ Host clientHost =
+ new HostBuilder()
+ .transport(TcpTransport::new)
+ .secureChannel((k, m) -> new TlsSecureChannel(k, m, "ECDSA"))
+ .muxer(StreamMuxerProtocol::getYamux)
+ .build();
+
+ Host serverHost =
+ new HostBuilder()
+ .transport(TcpTransport::new)
+ .secureChannel(TlsSecureChannel::new)
+ .muxer(StreamMuxerProtocol::getYamux)
+ .listen(localListenAddress)
+ .build();
+
+ CompletableFuture clientStarted = clientHost.start();
+ CompletableFuture serverStarted = serverHost.start();
+ clientStarted.get(5, TimeUnit.SECONDS);
+ System.out.println("Client started");
+ serverStarted.get(5, TimeUnit.SECONDS);
+ System.out.println("Server started");
+
+ Assertions.assertEquals(0, clientHost.listenAddresses().size());
+ Assertions.assertEquals(1, serverHost.listenAddresses().size());
+ Assertions.assertEquals(
+ localListenAddress + "/p2p/" + serverHost.getPeerId(),
+ serverHost.listenAddresses().get(0).toString());
+
+ serverHost.addProtocolHandler(new Ping());
+
+ StreamPromise ping =
+ clientHost
+ .getNetwork()
+ .connect(serverHost.getPeerId(), new Multiaddr(localListenAddress))
+ .thenApply(it -> it.muxerSession().createStream(new Ping()))
+ .get(5, TimeUnit.SECONDS);
+
+ Stream pingStream = ping.getStream().get(5, TimeUnit.SECONDS);
+ System.out.println("Ping stream created");
+ PingController pingCtr = ping.getController().get(5, TimeUnit.SECONDS);
+ System.out.println("Ping controller created");
+
+ for (int i = 0; i < 10; i++) {
+ long latency = pingCtr.ping().get(1, TimeUnit.SECONDS);
+ System.out.println("Ping is " + latency);
}
+ pingStream.close().get(5, TimeUnit.SECONDS);
+ System.out.println("Ping stream closed");
+
+ Assertions.assertThrows(
+ ExecutionException.class, () -> pingCtr.ping().get(5, TimeUnit.SECONDS));
+
+ clientHost.stop().get(5, TimeUnit.SECONDS);
+ System.out.println("Client stopped");
+ serverHost.stop().get(5, TimeUnit.SECONDS);
+ System.out.println("Server stopped");
+ }
+
+ @Test
+ void keyPairGeneration() {
+ Pair pair = KeyKt.generateKeyPair(KeyType.SECP256K1);
+ PeerId peerId = PeerId.fromPubKey(pair.component2());
+ System.out.println("PeerId: " + peerId.toHex());
+ }
}
diff --git a/libp2p/src/test/java/io/libp2p/pubsub/GossipApiTest.java b/libp2p/src/test/java/io/libp2p/pubsub/GossipApiTest.java
index 7f7de2bdf..d95485103 100644
--- a/libp2p/src/test/java/io/libp2p/pubsub/GossipApiTest.java
+++ b/libp2p/src/test/java/io/libp2p/pubsub/GossipApiTest.java
@@ -1,5 +1,8 @@
package io.libp2p.pubsub;
+import static io.libp2p.tools.StubsKt.peerHandlerStub;
+import static org.assertj.core.api.Assertions.assertThat;
+
import com.google.protobuf.ByteString;
import io.libp2p.core.pubsub.ValidationResult;
import io.libp2p.etc.types.WBytes;
@@ -8,123 +11,120 @@
import io.libp2p.pubsub.gossip.GossipParamsKt;
import io.libp2p.pubsub.gossip.GossipRouter;
import io.libp2p.pubsub.gossip.builders.GossipRouterBuilder;
-import org.jetbrains.annotations.NotNull;
-import org.junit.jupiter.api.Test;
-import pubsub.pb.Rpc;
-
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
-import java.util.Optional;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
-
-import static io.libp2p.tools.StubsKt.peerHandlerStub;
-import static org.assertj.core.api.Assertions.assertThat;
+import org.jetbrains.annotations.NotNull;
+import org.junit.jupiter.api.Test;
+import pubsub.pb.Rpc;
public class GossipApiTest {
- @Test
- public void createGossipTest() {
- GossipParams gossipParams = GossipParams.builder()
- .D(10)
- .DHigh(20)
- .build();
- GossipRouterBuilder routerBuilder = new GossipRouterBuilder();
- routerBuilder.setParams(gossipParams);
- GossipRouter router = routerBuilder.build();
- assertThat(router.getParams().getD()).isEqualTo(10);
- assertThat(router.getParams().getDHigh()).isEqualTo(20);
- assertThat(router.getParams().getDScore()).isEqualTo(GossipParamsKt.defaultDScore(10));
- }
-
- @Test
- public void testFastMessageId() throws Exception {
- List createdMessages = new ArrayList<>();
-
- GossipRouterBuilder routerBuilder = new GossipRouterBuilder();
- routerBuilder.setSeenCache(new FastIdSeenCache<>(msg -> msg.getProtobufMessage().getData()));
- routerBuilder.setMessageFactory(m -> {
- TestPubsubMessage message = new TestPubsubMessage(m);
- createdMessages.add(message);
- return message;
+ @Test
+ public void createGossipTest() {
+ GossipParams gossipParams = GossipParams.builder().D(10).DHigh(20).build();
+ GossipRouterBuilder routerBuilder = new GossipRouterBuilder();
+ routerBuilder.setParams(gossipParams);
+ GossipRouter router = routerBuilder.build();
+ assertThat(router.getParams().getD()).isEqualTo(10);
+ assertThat(router.getParams().getDHigh()).isEqualTo(20);
+ assertThat(router.getParams().getDScore()).isEqualTo(GossipParamsKt.defaultDScore(10));
+ }
+
+ @Test
+ public void testFastMessageId() throws Exception {
+ List createdMessages = new ArrayList<>();
+
+ GossipRouterBuilder routerBuilder = new GossipRouterBuilder();
+ routerBuilder.setSeenCache(new FastIdSeenCache<>(msg -> msg.getProtobufMessage().getData()));
+ routerBuilder.setMessageFactory(
+ m -> {
+ TestPubsubMessage message = new TestPubsubMessage(m);
+ createdMessages.add(message);
+ return message;
});
- GossipRouter router = routerBuilder.build();
- router.subscribe("topic");
-
- BlockingQueue messages = new LinkedBlockingQueue<>();
- router.initHandler(m -> {
- messages.add(m);
- return CompletableFuture.completedFuture(ValidationResult.Valid);
+ GossipRouter router = routerBuilder.build();
+ router.subscribe("topic");
+
+ BlockingQueue messages = new LinkedBlockingQueue<>();
+ router.initHandler(
+ m -> {
+ messages.add(m);
+ return CompletableFuture.completedFuture(ValidationResult.Valid);
});
- P2PService.PeerHandler peerHandler = peerHandlerStub(router);
-
- router.runOnEventThread(() -> router.onInbound(peerHandler, newMessage("Hello-1")));
- TestPubsubMessage message1 = (TestPubsubMessage) messages.poll(1, TimeUnit.SECONDS);
-
- assertThat(message1).isNotNull();
- assertThat(message1.canonicalId).isNotNull();
- assertThat(createdMessages.size()).isEqualTo(1);
- createdMessages.clear();
-
- router.runOnEventThread(() -> router.onInbound(peerHandler, newMessage("Hello-1")));
- TestPubsubMessage message2 = (TestPubsubMessage) messages.poll(100, TimeUnit.MILLISECONDS);
+ P2PService.PeerHandler peerHandler = peerHandlerStub(router);
+
+ router.runOnEventThread(() -> router.onInbound(peerHandler, newMessage("Hello-1")));
+ TestPubsubMessage message1 = (TestPubsubMessage) messages.poll(1, TimeUnit.SECONDS);
+
+ assertThat(message1).isNotNull();
+ assertThat(message1.canonicalId).isNotNull();
+ assertThat(createdMessages.size()).isEqualTo(1);
+ createdMessages.clear();
+
+ router.runOnEventThread(() -> router.onInbound(peerHandler, newMessage("Hello-1")));
+ TestPubsubMessage message2 = (TestPubsubMessage) messages.poll(100, TimeUnit.MILLISECONDS);
+
+ assertThat(message2).isNull();
+ assertThat(createdMessages.size()).isEqualTo(1);
+ // assert that 'slow' canonicalId was not calculated and the message was filtered as seen by
+ // fastId
+ assertThat(createdMessages.get(0).canonicalId).isNull();
+ createdMessages.clear();
+ }
+
+ private static Rpc.RPC newMessage(String msg) {
+ return Rpc.RPC
+ .newBuilder()
+ .addPublish(
+ Rpc.Message.newBuilder()
+ .addTopicIDs("topic")
+ .setData(ByteString.copyFrom(msg, StandardCharsets.US_ASCII)))
+ .build();
+ }
+
+ private static class TestPubsubMessage implements PubsubMessage {
+ final Rpc.Message message;
+ Function canonicalIdCalculator =
+ m -> new WBytes(("canon-" + m.getData().toString()).getBytes());
+ WBytes canonicalId = null;
+
+ public TestPubsubMessage(Rpc.Message message) {
+ this.message = message;
+ }
- assertThat(message2).isNull();
- assertThat(createdMessages.size()).isEqualTo(1);
- // assert that 'slow' canonicalId was not calculated and the message was filtered as seen by fastId
- assertThat(createdMessages.get(0).canonicalId).isNull();
- createdMessages.clear();
+ @NotNull
+ @Override
+ public Rpc.Message getProtobufMessage() {
+ return message;
}
- private static Rpc.RPC newMessage(String msg) {
- return Rpc.RPC.newBuilder().addPublish(
- Rpc.Message.newBuilder()
- .addTopicIDs("topic")
- .setData(ByteString.copyFrom(msg, StandardCharsets.US_ASCII))
- ).build();
+ @NotNull
+ @Override
+ public WBytes getMessageId() {
+ if (canonicalId == null) {
+ canonicalId = canonicalIdCalculator.apply(getProtobufMessage());
+ }
+ return canonicalId;
}
- private static class TestPubsubMessage implements PubsubMessage {
- final Rpc.Message message;
- Function canonicalIdCalculator = m -> new WBytes(("canon-" + m.getData().toString()).getBytes());
- WBytes canonicalId = null;
-
- public TestPubsubMessage(Rpc.Message message) {
- this.message = message;
- }
-
- @NotNull
- @Override
- public Rpc.Message getProtobufMessage() {
- return message;
- }
-
- @NotNull
- @Override
- public WBytes getMessageId() {
- if (canonicalId == null) {
- canonicalId = canonicalIdCalculator.apply(getProtobufMessage());
- }
- return canonicalId;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- TestPubsubMessage that = (TestPubsubMessage) o;
- return message.equals(that.message);
- }
-
- @Override
- public int hashCode() {
- return message.hashCode();
- }
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ TestPubsubMessage that = (TestPubsubMessage) o;
+ return message.equals(that.message);
}
+ @Override
+ public int hashCode() {
+ return message.hashCode();
+ }
+ }
}
diff --git a/libp2p/src/test/kotlin/io/libp2p/core/HostTest.kt b/libp2p/src/test/kotlin/io/libp2p/core/HostTest.kt
index eb4513f99..09720736e 100644
--- a/libp2p/src/test/kotlin/io/libp2p/core/HostTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/core/HostTest.kt
@@ -75,13 +75,17 @@ class HostTest {
var interceptRead = false
var interceptWrite = false
override fun interceptRead(buf: ByteBuf) =
- if (interceptRead)
+ if (interceptRead) {
Unpooled.wrappedBuffer("RRR".toByteArray(Charsets.UTF_8))
- else buf
+ } else {
+ buf
+ }
override fun interceptWrite(buf: ByteBuf) =
- if (interceptWrite)
+ if (interceptWrite) {
Unpooled.wrappedBuffer("WWW".toByteArray(Charsets.UTF_8))
- else buf
+ } else {
+ buf
+ }
}
val interceptor = TestInterceptor()
diff --git a/libp2p/src/test/kotlin/io/libp2p/core/HostTranportsTest.kt b/libp2p/src/test/kotlin/io/libp2p/core/HostTranportsTest.kt
index 3768d39ca..522ce91a4 100644
--- a/libp2p/src/test/kotlin/io/libp2p/core/HostTranportsTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/core/HostTranportsTest.kt
@@ -32,17 +32,20 @@ import java.util.concurrent.TimeUnit
@Tag("secure-channel")
class PlaintextTcpTest : TcpTransportHostTest(::PlaintextInsecureChannel)
+
@Tag("secure-channel")
class PlaintextWsTest : WsTransportHostTest(::PlaintextInsecureChannel)
@Tag("secure-channel")
class SecioTcpTest : TcpTransportHostTest(::SecIoSecureChannel)
+
@Tag("secure-channel")
class SecioWsTest : WsTransportHostTest(::SecIoSecureChannel)
@DisabledIfEnvironmentVariable(named = "TRAVIS", matches = "true")
@Tag("secure-channel")
class NoiseXXTcpTest : TcpTransportHostTest(::NoiseXXSecureChannel)
+
@DisabledIfEnvironmentVariable(named = "TRAVIS", matches = "true")
@Tag("secure-channel")
class NoiseXXWsTest : WsTransportHostTest(::NoiseXXSecureChannel)
@@ -96,7 +99,7 @@ abstract class HostTransportsTest(
add(secureChannelCtor)
}
muxers {
- + StreamMuxerProtocol.Mplex
+ +StreamMuxerProtocol.Mplex
}
protocols {
+Ping()
@@ -121,7 +124,7 @@ abstract class HostTransportsTest(
add(secureChannelCtor)
}
muxers {
- + StreamMuxerProtocol.Mplex
+ +StreamMuxerProtocol.Mplex
}
network {
listen(listenAddress)
diff --git a/libp2p/src/test/kotlin/io/libp2p/core/RpcHandlerTest.kt b/libp2p/src/test/kotlin/io/libp2p/core/RpcHandlerTest.kt
index 3f43d040e..da8a6b056 100644
--- a/libp2p/src/test/kotlin/io/libp2p/core/RpcHandlerTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/core/RpcHandlerTest.kt
@@ -106,7 +106,7 @@ class RpcHandlerTest {
add(::SecIoSecureChannel)
}
muxers {
- + StreamMuxerProtocol.Mplex
+ +StreamMuxerProtocol.Mplex
}
protocols {
+RpcProtocol()
@@ -127,7 +127,7 @@ class RpcHandlerTest {
add(::SecIoSecureChannel)
}
muxers {
- + StreamMuxerProtocol.Mplex
+ +StreamMuxerProtocol.Mplex
}
protocols {
+RpcProtocol()
@@ -166,8 +166,11 @@ class RpcHandlerTest {
Assertions.assertEquals(1, streamCounter2)
Assertions.assertEquals(1, streamCounter1)
for (i in 1..100) {
- if (host1.streams.isNotEmpty() || host2.streams.isNotEmpty()) Thread.sleep(10)
- else break
+ if (host1.streams.isNotEmpty() || host2.streams.isNotEmpty()) {
+ Thread.sleep(10)
+ } else {
+ break
+ }
}
Assertions.assertEquals(0, host1.streams.size)
Assertions.assertEquals(0, host2.streams.size)
@@ -188,8 +191,11 @@ class RpcHandlerTest {
Assertions.assertEquals(2, streamCounter1)
Assertions.assertEquals(2, streamCounter2)
for (i in 1..100) {
- if (host1.streams.isNotEmpty() || host2.streams.isNotEmpty()) Thread.sleep(10)
- else break
+ if (host1.streams.isNotEmpty() || host2.streams.isNotEmpty()) {
+ Thread.sleep(10)
+ } else {
+ break
+ }
}
Assertions.assertEquals(0, host1.streams.size)
Assertions.assertEquals(0, host2.streams.size)
diff --git a/libp2p/src/test/kotlin/io/libp2p/core/dsl/BuilderDefaultsTest.kt b/libp2p/src/test/kotlin/io/libp2p/core/dsl/BuilderDefaultsTest.kt
index f7bc79b7a..b3bafc9d7 100644
--- a/libp2p/src/test/kotlin/io/libp2p/core/dsl/BuilderDefaultsTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/core/dsl/BuilderDefaultsTest.kt
@@ -57,7 +57,7 @@ class BuilderDefaultsTest {
identity { random() }
transports { +::TcpTransport }
secureChannels { add(::SecIoSecureChannel) }
- muxers { + StreamMuxerProtocol.Mplex }
+ muxers { +StreamMuxerProtocol.Mplex }
}
host.start().get(5, SECONDS)
diff --git a/libp2p/src/test/kotlin/io/libp2p/core/multiformats/MultiaddrDnsTest.kt b/libp2p/src/test/kotlin/io/libp2p/core/multiformats/MultiaddrDnsTest.kt
index f0dbaf617..9e28b8b6a 100644
--- a/libp2p/src/test/kotlin/io/libp2p/core/multiformats/MultiaddrDnsTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/core/multiformats/MultiaddrDnsTest.kt
@@ -164,12 +164,13 @@ class MultiaddrDnsTest {
val TestResolver = object : MultiaddrDns.Resolver {
override fun resolveDns4(hostname: String): List {
- val address = if ("pig.com".equals(hostname))
+ val address = if ("pig.com".equals(hostname)) {
listOf("/ip4/1.1.1.1", "/ip4/1.1.1.2")
- else if ("localhost".equals(hostname))
+ } else if ("localhost".equals(hostname)) {
listOf("/ip4/127.0.0.1")
- else
+ } else {
listOf("/ip4/2.2.2.1", "/ip4/2.2.2.2")
+ }
return address.map { Multiaddr(it) }
}
diff --git a/libp2p/src/test/kotlin/io/libp2p/core/multiformats/ProtocolTest.kt b/libp2p/src/test/kotlin/io/libp2p/core/multiformats/ProtocolTest.kt
index e78c13bd6..8fcd1f075 100644
--- a/libp2p/src/test/kotlin/io/libp2p/core/multiformats/ProtocolTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/core/multiformats/ProtocolTest.kt
@@ -21,6 +21,7 @@ class ProtocolTest {
assertEquals(protocol, roundTrippedProtocol)
}
}
+
@Test
fun tcpProtocolProperties() {
assertEquals(Protocol.TCP, Protocol.get("tcp"))
diff --git a/libp2p/src/test/kotlin/io/libp2p/mux/mplex/MplexFrameCodecTest.kt b/libp2p/src/test/kotlin/io/libp2p/mux/mplex/MplexFrameCodecTest.kt
index 6ba816250..0f8645f3a 100644
--- a/libp2p/src/test/kotlin/io/libp2p/mux/mplex/MplexFrameCodecTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/mux/mplex/MplexFrameCodecTest.kt
@@ -36,7 +36,8 @@ class MplexFrameCodecTest {
@Test
fun `check max frame size limit`() {
val mplexFrame = MplexFrame(
- MuxId(dummyId, 777, true), MplexFlag.MessageInitiator,
+ MuxId(dummyId, 777, true),
+ MplexFlag.MessageInitiator,
ByteArray(maxFrameDataLength).toByteBuf()
)
diff --git a/libp2p/src/test/kotlin/io/libp2p/mux/mplex/MplexHandlerTest.kt b/libp2p/src/test/kotlin/io/libp2p/mux/mplex/MplexHandlerTest.kt
index bd9fd88fd..0026a0aa6 100644
--- a/libp2p/src/test/kotlin/io/libp2p/mux/mplex/MplexHandlerTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/mux/mplex/MplexHandlerTest.kt
@@ -17,7 +17,10 @@ class MplexHandlerTest : MuxHandlerAbstractTest() {
override fun createMuxHandler(streamHandler: StreamHandler<*>): MuxHandler =
object : MplexHandler(
- MultistreamProtocolV1, maxFrameDataLength, null, streamHandler
+ MultistreamProtocolV1,
+ maxFrameDataLength,
+ null,
+ streamHandler
) {
// MuxHandler consumes the exception. Override this behaviour for testing
@Deprecated("Deprecated in Java")
diff --git a/libp2p/src/test/kotlin/io/libp2p/pubsub/MaxCountTopicSubscriptionFilterTest.kt b/libp2p/src/test/kotlin/io/libp2p/pubsub/MaxCountTopicSubscriptionFilterTest.kt
index 0cc30b190..f3483fed7 100644
--- a/libp2p/src/test/kotlin/io/libp2p/pubsub/MaxCountTopicSubscriptionFilterTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/pubsub/MaxCountTopicSubscriptionFilterTest.kt
@@ -134,7 +134,8 @@ internal class MaxCountTopicSubscriptionFilterTest {
PubsubSubscription("allow_10", true),
)
val result = filter.filterIncomingSubscriptions(
- subscriptions, listOf("allow_1", "allow_2", "allow_3", "allow_4", "allow_5", "allow_6", "allow_7")
+ subscriptions,
+ listOf("allow_1", "allow_2", "allow_3", "allow_4", "allow_5", "allow_6", "allow_7")
)
assertThat(result).isEqualTo(subscriptions)
}
diff --git a/libp2p/src/test/kotlin/io/libp2p/pubsub/PubsubRouterTest.kt b/libp2p/src/test/kotlin/io/libp2p/pubsub/PubsubRouterTest.kt
index af08bca7c..b06f713bc 100644
--- a/libp2p/src/test/kotlin/io/libp2p/pubsub/PubsubRouterTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/pubsub/PubsubRouterTest.kt
@@ -296,7 +296,7 @@ abstract class PubsubRouterTest(val routerFactory: DeterministicFuzzRouterFactor
}
for (i in 0 until nodesCount) {
for (j in 1..neighboursCount / 2)
- allConnections += allRouters[i].connectSemiDuplex(allRouters[(i + j) % 21]/*, pubsubLogs = LogLevel.ERROR*/)
+ allConnections += allRouters[i].connectSemiDuplex(allRouters[(i + j) % 21])
.connections
}
@@ -409,7 +409,10 @@ abstract class PubsubRouterTest(val routerFactory: DeterministicFuzzRouterFactor
val subs2 = topics
.map { it to RecordingSubscriber() }
- .map { apis[2].subscribe(it.second, it.first); it.second }
+ .map {
+ apis[2].subscribe(it.second, it.first)
+ it.second
+ }
val scheduler = fuzz.createControlledExecutor()
val delayed = { result: ValidationResult, delayMs: Long ->
diff --git a/libp2p/src/test/kotlin/io/libp2p/pubsub/gossip/DefaultGossipScoreTest.kt b/libp2p/src/test/kotlin/io/libp2p/pubsub/gossip/DefaultGossipScoreTest.kt
index ffeceeb3f..7f5056199 100644
--- a/libp2p/src/test/kotlin/io/libp2p/pubsub/gossip/DefaultGossipScoreTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/pubsub/gossip/DefaultGossipScoreTest.kt
@@ -732,7 +732,6 @@ class DefaultGossipScoreTest {
@Test
fun `test IP colocation penalty`() {
-
val addr1 = Multiaddr.fromString("/ip4/0.0.0.1")
val addr2 = Multiaddr.fromString("/ip4/0.0.0.2")
val peer1 = PeerId.random()
diff --git a/libp2p/src/test/kotlin/io/libp2p/pubsub/gossip/GossipV1_1Tests.kt b/libp2p/src/test/kotlin/io/libp2p/pubsub/gossip/GossipV1_1Tests.kt
index 6dbd3fa88..6518d07fd 100644
--- a/libp2p/src/test/kotlin/io/libp2p/pubsub/gossip/GossipV1_1Tests.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/pubsub/gossip/GossipV1_1Tests.kt
@@ -1,3 +1,5 @@
+@file:Suppress("ktlint:standard:class-naming")
+
package io.libp2p.pubsub.gossip
import com.google.common.util.concurrent.AtomicDouble
@@ -74,8 +76,11 @@ class GossipV1_1Tests {
fun connect(routerIndexes: IntRange, outbound: Boolean = true): List {
val list =
routers.slice(routerIndexes).map {
- if (outbound) router0.connectSemiDuplex(it, null, LogLevel.ERROR)
- else it.connectSemiDuplex(router0, null, LogLevel.ERROR)
+ if (outbound) {
+ router0.connectSemiDuplex(it, null, LogLevel.ERROR)
+ } else {
+ it.connectSemiDuplex(router0, null, LogLevel.ERROR)
+ }
}
connections += list
return list
@@ -696,8 +701,12 @@ class GossipV1_1Tests {
fun testAdaptiveGossip() {
val appScore = mutableMapOf().withDefault { 0.0 }
val coreParams = GossipParams(
- 3, 3, 3, DLazy = 3,
- floodPublish = false, gossipFactor = 0.5
+ 3,
+ 3,
+ 3,
+ DLazy = 3,
+ floodPublish = false,
+ gossipFactor = 0.5
)
val peerScoreParams = GossipPeerScoreParams(
appSpecificScore = { appScore.getValue(it) },
@@ -806,8 +815,13 @@ class GossipV1_1Tests {
fun testOpportunisticGraft() {
val appScore = mutableMapOf().withDefault { 0.0 }
val coreParams = GossipParams(
- 3, 3, 10, DLazy = 3, DOut = 1,
- opportunisticGraftPeers = 2, opportunisticGraftTicks = 60
+ 3,
+ 3,
+ 10,
+ DLazy = 3,
+ DOut = 1,
+ opportunisticGraftPeers = 2,
+ opportunisticGraftTicks = 60
)
val peerScoreParams = GossipPeerScoreParams(
appSpecificScore = { appScore.getValue(it) },
@@ -970,7 +984,10 @@ class GossipV1_1Tests {
val validationResult = CompletableFuture()
val receivedMessages = LinkedBlockingQueue()
- val slowValidator = Validator { receivedMessages += it; validationResult }
+ val slowValidator = Validator {
+ receivedMessages += it
+ validationResult
+ }
api.subscribe(slowValidator, io.libp2p.core.pubsub.Topic("topic1"))
test.mockRouters.forEach { it.subscribe("topic1") }
diff --git a/libp2p/src/test/kotlin/io/libp2p/security/CipherSecureChannelTest.kt b/libp2p/src/test/kotlin/io/libp2p/security/CipherSecureChannelTest.kt
index b466f04e6..bfb68a36e 100644
--- a/libp2p/src/test/kotlin/io/libp2p/security/CipherSecureChannelTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/security/CipherSecureChannelTest.kt
@@ -1,7 +1,7 @@
package io.libp2p.security
import io.libp2p.core.PeerId
-import io.libp2p.core.crypto.KEY_TYPE
+import io.libp2p.core.crypto.KeyType
import io.libp2p.core.crypto.generateKeyPair
import io.libp2p.core.mux.StreamMuxer
import io.libp2p.tools.TestChannel
@@ -18,9 +18,9 @@ abstract class CipherSecureChannelTest(secureChannelCtor: SecureChannelCtor, mux
@Test
fun `incorrect initiator remote PeerId should throw`() {
- val (privKey1, _) = generateKeyPair(KEY_TYPE.ECDSA)
- val (privKey2, _) = generateKeyPair(KEY_TYPE.ECDSA)
- val (_, wrongPubKey) = generateKeyPair(KEY_TYPE.ECDSA)
+ val (privKey1, _) = generateKeyPair(KeyType.ECDSA)
+ val (privKey2, _) = generateKeyPair(KeyType.ECDSA)
+ val (_, wrongPubKey) = generateKeyPair(KeyType.ECDSA)
val protocolSelect1 = makeSelector(privKey1, muxerIds)
val protocolSelect2 = makeSelector(privKey2, muxerIds)
@@ -37,8 +37,8 @@ abstract class CipherSecureChannelTest(secureChannelCtor: SecureChannelCtor, mux
@Test
fun `test that on malformed message from remote the connection closes and no log noise`() {
- val (privKey1, _) = generateKeyPair(KEY_TYPE.ECDSA)
- val (privKey2, pubKey2) = generateKeyPair(KEY_TYPE.ECDSA)
+ val (privKey1, _) = generateKeyPair(KeyType.ECDSA)
+ val (privKey2, pubKey2) = generateKeyPair(KeyType.ECDSA)
val protocolSelect1 = makeSelector(privKey1, muxerIds)
val protocolSelect2 = makeSelector(privKey2, muxerIds)
diff --git a/libp2p/src/test/kotlin/io/libp2p/security/SecureChannelTestBase.kt b/libp2p/src/test/kotlin/io/libp2p/security/SecureChannelTestBase.kt
index a91651a75..a4a899d81 100644
--- a/libp2p/src/test/kotlin/io/libp2p/security/SecureChannelTestBase.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/security/SecureChannelTestBase.kt
@@ -1,7 +1,7 @@
package io.libp2p.security
import io.libp2p.core.PeerId
-import io.libp2p.core.crypto.KEY_TYPE
+import io.libp2p.core.crypto.KeyType
import io.libp2p.core.crypto.PrivKey
import io.libp2p.core.crypto.generateKeyPair
import io.libp2p.core.multistream.ProtocolMatcher
@@ -55,8 +55,8 @@ abstract class SecureChannelTestBase(
@ParameterizedTest
@MethodSource("plainDataSizes")
fun secureInterconnect(dataSize: Int) {
- val (privKey1, _) = generateKeyPair(KEY_TYPE.ECDSA)
- val (privKey2, pubKey2) = generateKeyPair(KEY_TYPE.ECDSA)
+ val (privKey1, _) = generateKeyPair(KeyType.ECDSA)
+ val (privKey2, pubKey2) = generateKeyPair(KeyType.ECDSA)
val protocolSelect1 = makeSelector(privKey1, muxerIds)
val protocolSelect2 = makeSelector(privKey2, muxerIds)
diff --git a/libp2p/src/test/kotlin/io/libp2p/security/noise/NoiseHandshakeTest.kt b/libp2p/src/test/kotlin/io/libp2p/security/noise/NoiseHandshakeTest.kt
index a6f6454b2..5489a6e94 100644
--- a/libp2p/src/test/kotlin/io/libp2p/security/noise/NoiseHandshakeTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/security/noise/NoiseHandshakeTest.kt
@@ -2,7 +2,7 @@ package io.libp2p.security.noise
import com.google.protobuf.ByteString
import com.southernstorm.noise.protocol.HandshakeState
-import io.libp2p.core.crypto.KEY_TYPE
+import io.libp2p.core.crypto.KeyType
import io.libp2p.core.crypto.generateKeyPair
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation
@@ -120,7 +120,7 @@ class NoiseHandshakeTest {
// generate a Peer Identity protobuf object
// use it for encoding and decoding peer identities from the wire
// this identity is intended to be sent as a Noise transport payload
- val (privKey, pubKey) = generateKeyPair(KEY_TYPE.ECDSA)
+ val (privKey, pubKey) = generateKeyPair(KeyType.ECDSA)
assert(pubKey.bytes().maxOrNull()?.compareTo(0) != 0)
// sign the identity using the identity's private key
@@ -144,7 +144,7 @@ class NoiseHandshakeTest {
@Test
fun testAnnounceAndMatch() {
- val (privKey1, _) = generateKeyPair(KEY_TYPE.ECDSA)
+ val (privKey1, _) = generateKeyPair(KeyType.ECDSA)
val ch1 = NoiseXXSecureChannel(privKey1, listOf())
@@ -155,11 +155,11 @@ class NoiseHandshakeTest {
@Test
fun testStaticNoiseKeyPerProcess() {
- val (privKey1, _) = generateKeyPair(KEY_TYPE.ECDSA)
+ val (privKey1, _) = generateKeyPair(KeyType.ECDSA)
NoiseXXSecureChannel(privKey1, listOf())
val b1 = NoiseXXSecureChannel.localStaticPrivateKey25519.copyOf()
- val (privKey2, _) = generateKeyPair(KEY_TYPE.ECDSA)
+ val (privKey2, _) = generateKeyPair(KeyType.ECDSA)
NoiseXXSecureChannel(privKey2, listOf())
val b2 = NoiseXXSecureChannel.localStaticPrivateKey25519.copyOf()
diff --git a/libp2p/src/test/kotlin/io/libp2p/security/secio/EchoSampleTest.kt b/libp2p/src/test/kotlin/io/libp2p/security/secio/EchoSampleTest.kt
index f1c8b097c..4948a0022 100644
--- a/libp2p/src/test/kotlin/io/libp2p/security/secio/EchoSampleTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/security/secio/EchoSampleTest.kt
@@ -4,7 +4,7 @@ import io.libp2p.core.ChannelVisitor
import io.libp2p.core.Connection
import io.libp2p.core.P2PChannel
import io.libp2p.core.P2PChannelHandler
-import io.libp2p.core.crypto.KEY_TYPE
+import io.libp2p.core.crypto.KeyType
import io.libp2p.core.crypto.generateKeyPair
import io.libp2p.core.multiformats.Multiaddr
import io.libp2p.core.multistream.MultistreamProtocolV1
@@ -53,7 +53,7 @@ class EchoSampleTest {
fun connect1() {
val logger = LoggerFactory.getLogger("test")
- val (privKey1, _) = generateKeyPair(KEY_TYPE.ECDSA)
+ val (privKey1, _) = generateKeyPair(KeyType.ECDSA)
val applicationProtocols = listOf(createSimpleBinding("/echo/1.0.0") { EchoProtocol() })
val muxer = StreamMuxerProtocol.Mplex.createMuxer(MultistreamProtocolV1, applicationProtocols).also {
it as MplexStreamMuxer
diff --git a/libp2p/src/test/kotlin/io/libp2p/security/secio/SecIoNegotiatorTest.kt b/libp2p/src/test/kotlin/io/libp2p/security/secio/SecIoNegotiatorTest.kt
index e0c119768..45309c119 100644
--- a/libp2p/src/test/kotlin/io/libp2p/security/secio/SecIoNegotiatorTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/security/secio/SecIoNegotiatorTest.kt
@@ -1,7 +1,7 @@
package io.libp2p.security.secio
import io.libp2p.core.PeerId
-import io.libp2p.core.crypto.KEY_TYPE
+import io.libp2p.core.crypto.KeyType
import io.libp2p.core.crypto.generateKeyPair
import io.libp2p.core.crypto.unmarshalPrivateKey
import io.libp2p.crypto.keys.secp256k1PublicKeyFromCoordinates
@@ -19,8 +19,8 @@ import java.math.BigInteger
class SecIoNegotiatorTest {
@Test
fun handshake() {
- val (privKey1, pubKey1) = generateKeyPair(KEY_TYPE.ECDSA)
- val (privKey2, pubKey2) = generateKeyPair(KEY_TYPE.ECDSA)
+ val (privKey1, pubKey1) = generateKeyPair(KeyType.ECDSA)
+ val (privKey2, pubKey2) = generateKeyPair(KeyType.ECDSA)
var bb1: ByteBuf? = null
var bb2: ByteBuf? = null
diff --git a/libp2p/src/test/kotlin/io/libp2p/security/tls/TlsSecureChannelTest.kt b/libp2p/src/test/kotlin/io/libp2p/security/tls/TlsSecureChannelTest.kt
index 1d5fe5ed5..99bbda1de 100644
--- a/libp2p/src/test/kotlin/io/libp2p/security/tls/TlsSecureChannelTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/security/tls/TlsSecureChannelTest.kt
@@ -1,7 +1,7 @@
package io.libp2p.security.tls
import io.libp2p.core.PeerId
-import io.libp2p.core.crypto.KEY_TYPE
+import io.libp2p.core.crypto.KeyType
import io.libp2p.core.crypto.generateKeyPair
import io.libp2p.core.multistream.MultistreamProtocolDebug
import io.libp2p.core.mux.StreamMuxerProtocol
@@ -24,9 +24,9 @@ class TlsSecureChannelTest : SecureChannelTestBase(
) {
@Test
fun `incorrect initiator remote PeerId should throw`() {
- val (privKey1, _) = generateKeyPair(KEY_TYPE.ECDSA)
- val (privKey2, _) = generateKeyPair(KEY_TYPE.ECDSA)
- val (_, wrongPubKey) = generateKeyPair(KEY_TYPE.ECDSA)
+ val (privKey1, _) = generateKeyPair(KeyType.ECDSA)
+ val (privKey2, _) = generateKeyPair(KeyType.ECDSA)
+ val (_, wrongPubKey) = generateKeyPair(KeyType.ECDSA)
val protocolSelect1 = makeSelector(privKey1, muxerIds)
val protocolSelect2 = makeSelector(privKey2, muxerIds)
diff --git a/libp2p/src/test/kotlin/io/libp2p/transport/tcp/TcpTransportTest.kt b/libp2p/src/test/kotlin/io/libp2p/transport/tcp/TcpTransportTest.kt
index e73577448..167092911 100644
--- a/libp2p/src/test/kotlin/io/libp2p/transport/tcp/TcpTransportTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/transport/tcp/TcpTransportTest.kt
@@ -16,10 +16,11 @@ class TcpTransportTest : TransportTests() {
}
override fun localAddress(portNumber: Int): Multiaddr {
- return if (ip4DnsAvailable && (portNumber % 2 == 0))
+ return if (ip4DnsAvailable && (portNumber % 2 == 0)) {
Multiaddr("/dns4/localhost/tcp/$portNumber")
- else
+ } else {
Multiaddr("/ip4/127.0.0.1/tcp/$portNumber")
+ }
}
override fun badAddress(): Multiaddr =
diff --git a/libp2p/src/test/kotlin/io/libp2p/transport/ws/WsTransportTest.kt b/libp2p/src/test/kotlin/io/libp2p/transport/ws/WsTransportTest.kt
index a3f067610..9c7d42bd5 100644
--- a/libp2p/src/test/kotlin/io/libp2p/transport/ws/WsTransportTest.kt
+++ b/libp2p/src/test/kotlin/io/libp2p/transport/ws/WsTransportTest.kt
@@ -15,10 +15,11 @@ class WsTransportTest : TransportTests() {
} // makeTransport
override fun localAddress(portNumber: Int): Multiaddr {
- return if (ip4DnsAvailable && (portNumber % 2 == 0))
+ return if (ip4DnsAvailable && (portNumber % 2 == 0)) {
Multiaddr("/dns4/localhost/tcp/$portNumber/ws")
- else
+ } else {
Multiaddr("/ip4/127.0.0.1/tcp/$portNumber/ws")
+ }
} // localAddress
override fun badAddress(): Multiaddr =
diff --git a/libp2p/src/testFixtures/java/io/libp2p/tools/p2pd/AsyncDaemonExecutor.java b/libp2p/src/testFixtures/java/io/libp2p/tools/p2pd/AsyncDaemonExecutor.java
index db9973351..7dbe50fb3 100644
--- a/libp2p/src/testFixtures/java/io/libp2p/tools/p2pd/AsyncDaemonExecutor.java
+++ b/libp2p/src/testFixtures/java/io/libp2p/tools/p2pd/AsyncDaemonExecutor.java
@@ -1,50 +1,49 @@
package io.libp2p.tools.p2pd;
import io.netty.channel.unix.DomainSocketAddress;
-
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
-/**
- * Created by Anton Nashatyrev on 20.12.2018.
- */
+/** Created by Anton Nashatyrev on 20.12.2018. */
public class AsyncDaemonExecutor {
- private final SocketAddress address;
-
- public AsyncDaemonExecutor(SocketAddress address) {
- this.address = address;
- }
-
- public CompletableFuture executeWithDaemon(
- Function> executor) {
- CompletableFuture daemonFut = getDaemon();
- return daemonFut
- .thenCompose(executor)
- .whenComplete((r, t) -> {
- if (!daemonFut.isCompletedExceptionally()) {
- try {
- daemonFut.get().close();
- } catch (Exception e) {}
- }
- });
+ private final SocketAddress address;
+
+ public AsyncDaemonExecutor(SocketAddress address) {
+ this.address = address;
+ }
+
+ public CompletableFuture executeWithDaemon(
+ Function> executor) {
+ CompletableFuture daemonFut = getDaemon();
+ return daemonFut
+ .thenCompose(executor)
+ .whenComplete(
+ (r, t) -> {
+ if (!daemonFut.isCompletedExceptionally()) {
+ try {
+ daemonFut.get().close();
+ } catch (Exception e) {
+ }
+ }
+ });
+ }
+
+ public CompletableFuture getDaemon() {
+ ControlConnector connector;
+ if (address instanceof InetSocketAddress) {
+ connector = new TCPControlConnector();
+ } else if (address instanceof DomainSocketAddress) {
+ connector = new UnixSocketControlConnector();
+ } else {
+ throw new IllegalArgumentException();
}
- public CompletableFuture getDaemon() {
- ControlConnector connector;
- if (address instanceof InetSocketAddress) {
- connector = new TCPControlConnector();
- } else if (address instanceof DomainSocketAddress) {
- connector = new UnixSocketControlConnector();
- } else {
- throw new IllegalArgumentException();
- }
+ return connector.connect(address);
+ }
- return connector.connect(address);
- }
-
- public SocketAddress getAddress() {
- return address;
- }
+ public SocketAddress getAddress() {
+ return address;
+ }
}
diff --git a/libp2p/src/testFixtures/java/io/libp2p/tools/p2pd/ControlConnector.java b/libp2p/src/testFixtures/java/io/libp2p/tools/p2pd/ControlConnector.java
index 0f2e12209..fadf1ffa0 100644
--- a/libp2p/src/testFixtures/java/io/libp2p/tools/p2pd/ControlConnector.java
+++ b/libp2p/src/testFixtures/java/io/libp2p/tools/p2pd/ControlConnector.java
@@ -6,50 +6,52 @@
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.SimpleChannelInboundHandler;
-
import java.net.SocketAddress;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
-/**
- * Created by Anton Nashatyrev on 13.12.2018.
- */
+/** Created by Anton Nashatyrev on 13.12.2018. */
public abstract class ControlConnector {
- protected final int connectTimeoutSec = 5;
+ protected final int connectTimeoutSec = 5;
- public abstract CompletableFuture connect(SocketAddress addr);
+ public abstract CompletableFuture connect(SocketAddress addr);
- public abstract ChannelFuture listen(SocketAddress addr, Consumer handlersConsumer);
+ public abstract ChannelFuture listen(
+ SocketAddress addr, Consumer handlersConsumer);
- protected static class ChannelInit extends ChannelInitializer {
- private final Consumer handlersConsumer;
- private final boolean initiator;
+ protected static class ChannelInit extends ChannelInitializer