diff --git a/activemq-core/src/main/java/org/apache/activemq/transport/discovery/zeroconf/JmDNSFactory.java b/activemq-core/src/main/java/org/apache/activemq/transport/discovery/zeroconf/JmDNSFactory.java
index 6b2a369be9..08f61bca29 100644
--- a/activemq-core/src/main/java/org/apache/activemq/transport/discovery/zeroconf/JmDNSFactory.java
+++ b/activemq-core/src/main/java/org/apache/activemq/transport/discovery/zeroconf/JmDNSFactory.java
@@ -21,7 +21,7 @@ import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.activemq.jmdns.JmDNS;
+import javax.jmdns.JmDNS;
public final class JmDNSFactory {
@@ -39,20 +39,14 @@ public final class JmDNSFactory {
UsageTracker tracker = registry.get(address);
if (tracker == null) {
tracker = new UsageTracker();
- tracker.jmDNS = new JmDNS(address) {
- public void close() {
- if (onClose(address)) {
- super.close();
- }
- }
- };
+ tracker.jmDNS = JmDNS.create(address);
registry.put(address, tracker);
}
tracker.count.incrementAndGet();
return tracker.jmDNS;
}
- static synchronized boolean onClose(InetAddress address) {
+ static synchronized boolean onClose(InetAddress address, JmDNS dns) {
UsageTracker tracker = registry.get(address);
if (tracker != null) {
if (tracker.count.decrementAndGet() == 0) {
diff --git a/activemq-core/src/main/java/org/apache/activemq/transport/discovery/zeroconf/ZeroconfDiscoveryAgent.java b/activemq-core/src/main/java/org/apache/activemq/transport/discovery/zeroconf/ZeroconfDiscoveryAgent.java
index ad032a1f4d..77fc9f3f9c 100755
--- a/activemq-core/src/main/java/org/apache/activemq/transport/discovery/zeroconf/ZeroconfDiscoveryAgent.java
+++ b/activemq-core/src/main/java/org/apache/activemq/transport/discovery/zeroconf/ZeroconfDiscoveryAgent.java
@@ -23,11 +23,10 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.apache.activemq.jmdns.JmDNS;
-import org.apache.activemq.jmdns.ServiceEvent;
-import org.apache.activemq.jmdns.ServiceInfo;
-import org.apache.activemq.jmdns.ServiceListener;
+import javax.jmdns.JmDNS;
+import javax.jmdns.ServiceEvent;
+import javax.jmdns.ServiceInfo;
+import javax.jmdns.ServiceListener;
import org.apache.activemq.command.DiscoveryEvent;
import org.apache.activemq.transport.discovery.DiscoveryAgent;
@@ -46,7 +45,7 @@ import org.slf4j.LoggerFactory;
public class ZeroconfDiscoveryAgent implements DiscoveryAgent, ServiceListener {
private static final Logger LOG = LoggerFactory.getLogger(ZeroconfDiscoveryAgent.class);
- private static final String TYPE_SUFFIX = "ActiveMQ-4.";
+ private static final String TYPE_SUFFIX = "ActiveMQ-5.";
private JmDNS jmdns;
private InetAddress localAddress;
@@ -92,7 +91,11 @@ public class ZeroconfDiscoveryAgent implements DiscoveryAgent, ServiceListener {
final JmDNS closeTarget = jmdns;
Thread thread = new Thread() {
public void run() {
- closeTarget.close();
+ try {
+ JmDNSFactory.onClose(getLocalAddress(), closeTarget);
+ } catch (IOException e) {
+ LOG.debug("Error closing JmDNS " + getLocalhost() + ". This exception will be ignored.", e);
+ }
}
};
@@ -200,7 +203,7 @@ public class ZeroconfDiscoveryAgent implements DiscoveryAgent, ServiceListener {
if (LOG.isDebugEnabled()) {
LOG.debug("Registering service type: " + type + " name: " + name + " details: " + map);
}
- return new ServiceInfo(type, name + "." + type, port, weight, priority, "");
+ return ServiceInfo.create(type, name + "." + type, port, weight, priority, "");
}
protected JmDNS createJmDNS() throws IOException {
diff --git a/activemq-jmdns_1.0/pom.xml b/activemq-jmdns_1.0/pom.xml
deleted file mode 100644
index cff60795ed..0000000000
--- a/activemq-jmdns_1.0/pom.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
- activemq-parent
- org.apache.activemq
- 5.7-SNAPSHOT
-
- 4.0.0
- activemq-jmdns_1.0
- ActiveMQ :: jmdns 1.0
-
-
- The activemq-jmdns_1.0 source is derived from http://repo1.maven.org/maven2/jmdns/jmdns/1.0/jmdns-1.0-sources.jar
-
- Changes to apache activemq version:
- - renamed package javax.jmdns to org.apache.activemq.jmdns
- - removed classes with lgpl source headers, leaving only the org.apache.activemq.jmdns package.
-
-
-
-
-
- maven-surefire-plugin
-
- true
-
-
-
-
-
diff --git a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSCache.java b/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSCache.java
deleted file mode 100644
index 5b7cde07ca..0000000000
--- a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSCache.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/**
- * Copyright 2003-2005 Arthur van Hoff, Rick Blair
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.jmdns;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.logging.Logger;
-
-/**
- * A table of DNS entries. This is a hash table which
- * can handle multiple entries with the same name.
- *
- * Storing multiple entries with the same name is implemented using a
- * linked list of CacheNode
's.
- *
- * The current implementation of the API of DNSCache does expose the
- * cache nodes to clients. Clients must explicitly deal with the nodes
- * when iterating over entries in the cache. Here's how to iterate over
- * all entries in the cache:
- *
- * for (Iterator i=dnscache.iterator(); i.hasNext(); ) {
- * for (DNSCache.CacheNode n = (DNSCache.CacheNode) i.next(); n != null; n.next()) {
- * DNSEntry entry = n.getValue();
- * ...do something with entry...
- * }
- * }
- *
- *
- * And here's how to iterate over all entries having a given name:
- *
- * for (DNSCache.CacheNode n = (DNSCache.CacheNode) dnscache.find(name); n != null; n.next()) {
- * DNSEntry entry = n.getValue();
- * ...do something with entry...
- * }
- *
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Werner Randelshofer, Rick Blair
- */
-class DNSCache
-{
- private static Logger logger = Logger.getLogger(DNSCache.class.toString());
- // Implementation note:
- // We might completely hide the existence of CacheNode's in a future version
- // of DNSCache. But this will require to implement two (inner) classes for
- // the iterators that will be returned by method iterator()
and
- // method find(name)
.
- // Since DNSCache is not a public class, it does not seem worth the effort
- // to clean its API up that much.
-
- // [PJYF Oct 15 2004] This should implements Collections that would be amuch cleaner implementation
-
- /**
- * The number of DNSEntry's in the cache.
- */
- private int size;
-
- /**
- * The hashtable used internally to store the entries of the cache.
- * Keys are instances of String. The String contains an unqualified service
- * name.
- * Values are linked lists of CacheNode instances.
- */
- private HashMap hashtable;
-
- /**
- * Cache nodes are used to implement storage of multiple DNSEntry's of the
- * same name in the cache.
- */
- public static class CacheNode
- {
- private static Logger logger = Logger.getLogger(CacheNode.class.toString());
- private DNSEntry value;
- private CacheNode next;
-
- public CacheNode(DNSEntry value)
- {
- this.value = value;
- }
-
- public CacheNode next()
- {
- return next;
- }
-
- public DNSEntry getValue()
- {
- return value;
- }
- }
-
-
- /**
- * Create a table with a given initial size.
- */
- public DNSCache(final int size)
- {
- hashtable = new HashMap(size);
- }
-
- /**
- * Clears the cache.
- */
- public synchronized void clear()
- {
- hashtable.clear();
- size = 0;
- }
-
- /**
- * Adds an entry to the table.
- */
- public synchronized void add(final DNSEntry entry)
- {
- //logger.log("DNSCache.add("+entry.getName()+")");
- CacheNode newValue = new CacheNode(entry);
- CacheNode node = (CacheNode) hashtable.get(entry.getName());
- if (node == null)
- {
- hashtable.put(entry.getName(), newValue);
- }
- else
- {
- newValue.next = node.next;
- node.next = newValue;
- }
- size++;
- }
-
- /**
- * Remove a specific entry from the table. Returns true if the
- * entry was found.
- */
- public synchronized boolean remove(DNSEntry entry)
- {
- CacheNode node = (CacheNode) hashtable.get(entry.getName());
- if (node != null)
- {
- if (node.value == entry)
- {
- if (node.next == null)
- {
- hashtable.remove(entry.getName());
- }
- else
- {
- hashtable.put(entry.getName(), node.next);
- }
- size--;
- return true;
- }
-
- CacheNode previous = node;
- node = node.next;
- while (node != null)
- {
- if (node.value == entry)
- {
- previous.next = node.next;
- size--;
- return true;
- }
- previous = node;
- node = node.next;
- }
- ;
- }
- return false;
- }
-
- /**
- * Get a matching DNS entry from the table (using equals).
- * Returns the entry that was found.
- */
- public synchronized DNSEntry get(DNSEntry entry)
- {
- for (CacheNode node = find(entry.getName()); node != null; node = node.next)
- {
- if (node.value.equals(entry))
- {
- return node.value;
- }
- }
- return null;
- }
-
- /**
- * Get a matching DNS entry from the table.
- */
- public synchronized DNSEntry get(String name, int type, int clazz)
- {
- for (CacheNode node = find(name); node != null; node = node.next)
- {
- if (node.value.type == type && node.value.clazz == clazz)
- {
- return node.value;
- }
- }
- return null;
- }
-
- /**
- * Iterates over all cache nodes.
- * The iterator returns instances of DNSCache.CacheNode.
- * Each instance returned is the first node of a linked list.
- * To retrieve all entries, one must iterate over this linked list. See
- * code snippets in the header of the class.
- */
- public Iterator iterator()
- {
- return Collections.unmodifiableCollection(hashtable.values()).iterator();
- }
-
- /**
- * Iterate only over items with matching name.
- * Returns an instance of DNSCache.CacheNode or null.
- * If an instance is returned, it is the first node of a linked list.
- * To retrieve all entries, one must iterate over this linked list.
- */
- public synchronized CacheNode find(String name)
- {
- return (CacheNode) hashtable.get(name);
- }
-
- /**
- * List all entries for debugging.
- */
- public synchronized void print()
- {
- for (Iterator i = iterator(); i.hasNext();)
- {
- for (CacheNode n = (CacheNode) i.next(); n != null; n = n.next)
- {
- System.out.println(n.value);
- }
- }
- }
-
- public synchronized String toString()
- {
- StringBuffer aLog = new StringBuffer();
- aLog.append("\t---- cache ----");
- for (Iterator i = iterator(); i.hasNext();)
- {
- for (CacheNode n = (CacheNode) i.next(); n != null; n = n.next)
- {
- aLog.append("\n\t\t" + n.value);
- }
- }
- return aLog.toString();
- }
-
-}
diff --git a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSConstants.java b/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSConstants.java
deleted file mode 100644
index 21363e5d1b..0000000000
--- a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSConstants.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
- * Copyright 2003-2005 Arthur van Hoff, Rick Blair
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.jmdns;
-
-/**
- * DNS constants.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer, Pierre Frisch, Rick Blair
- */
-final class DNSConstants
-{
-
- // changed to final class - jeffs
- final static String MDNS_GROUP = "224.0.0.251";
- final static String MDNS_GROUP_IPV6 = "FF02::FB";
- final static int MDNS_PORT = 5353;
- final static int DNS_PORT = 53;
- final static int DNS_TTL = 60 * 60; // default one hour TTL
- // final static int DNS_TTL = 120 * 60; // two hour TTL (draft-cheshire-dnsext-multicastdns.txt ch 13)
-
- final static int MAX_MSG_TYPICAL = 1460;
- final static int MAX_MSG_ABSOLUTE = 8972;
-
- final static int FLAGS_QR_MASK = 0x8000; // Query response mask
- final static int FLAGS_QR_QUERY = 0x0000; // Query
- final static int FLAGS_QR_RESPONSE = 0x8000; // Response
-
- final static int FLAGS_AA = 0x0400; // Authorative answer
- final static int FLAGS_TC = 0x0200; // Truncated
- final static int FLAGS_RD = 0x0100; // Recursion desired
- final static int FLAGS_RA = 0x8000; // Recursion available
-
- final static int FLAGS_Z = 0x0040; // Zero
- final static int FLAGS_AD = 0x0020; // Authentic data
- final static int FLAGS_CD = 0x0010; // Checking disabled
-
- final static int CLASS_IN = 1; // Final Static Internet
- final static int CLASS_CS = 2; // CSNET
- final static int CLASS_CH = 3; // CHAOS
- final static int CLASS_HS = 4; // Hesiod
- final static int CLASS_NONE = 254; // Used in DNS UPDATE [RFC 2136]
- final static int CLASS_ANY = 255; // Not a DNS class, but a DNS query class, meaning "all classes"
- final static int CLASS_MASK = 0x7FFF; // Multicast DNS uses the bottom 15 bits to identify the record class...
- final static int CLASS_UNIQUE = 0x8000; // ... and the top bit indicates that all other cached records are now invalid
-
- final static int TYPE_IGNORE = 0; // This is a hack to stop further processing
- final static int TYPE_A = 1; // Address
- final static int TYPE_NS = 2; // Name Server
- final static int TYPE_MD = 3; // Mail Destination
- final static int TYPE_MF = 4; // Mail Forwarder
- final static int TYPE_CNAME = 5; // Canonical Name
- final static int TYPE_SOA = 6; // Start of Authority
- final static int TYPE_MB = 7; // Mailbox
- final static int TYPE_MG = 8; // Mail Group
- final static int TYPE_MR = 9; // Mail Rename
- final static int TYPE_NULL = 10; // NULL RR
- final static int TYPE_WKS = 11; // Well-known-service
- final static int TYPE_PTR = 12; // Domain Name pofinal static inter
- final static int TYPE_HINFO = 13; // Host information
- final static int TYPE_MINFO = 14; // Mailbox information
- final static int TYPE_MX = 15; // Mail exchanger
- final static int TYPE_TXT = 16; // Arbitrary text string
- final static int TYPE_RP = 17; // for Responsible Person [RFC1183]
- final static int TYPE_AFSDB = 18; // for AFS Data Base location [RFC1183]
- final static int TYPE_X25 = 19; // for X.25 PSDN address [RFC1183]
- final static int TYPE_ISDN = 20; // for ISDN address [RFC1183]
- final static int TYPE_RT = 21; // for Route Through [RFC1183]
- final static int TYPE_NSAP = 22; // for NSAP address, NSAP style A record [RFC1706]
- final static int TYPE_NSAP_PTR = 23; //
- final static int TYPE_SIG = 24; // for security signature [RFC2931]
- final static int TYPE_KEY = 25; // for security key [RFC2535]
- final static int TYPE_PX = 26; // X.400 mail mapping information [RFC2163]
- final static int TYPE_GPOS = 27; // Geographical Position [RFC1712]
- final static int TYPE_AAAA = 28; // IP6 Address [Thomson]
- final static int TYPE_LOC = 29; // Location Information [Vixie]
- final static int TYPE_NXT = 30; // Next Domain - OBSOLETE [RFC2535, RFC3755]
- final static int TYPE_EID = 31; // Endpoint Identifier [Patton]
- final static int TYPE_NIMLOC = 32; // Nimrod Locator [Patton]
- final static int TYPE_SRV = 33; // Server Selection [RFC2782]
- final static int TYPE_ATMA = 34; // ATM Address [Dobrowski]
- final static int TYPE_NAPTR = 35; // Naming Authority Pointer [RFC2168, RFC2915]
- final static int TYPE_KX = 36; // Key Exchanger [RFC2230]
- final static int TYPE_CERT = 37; // CERT [RFC2538]
- final static int TYPE_A6 = 38; // A6 [RFC2874]
- final static int TYPE_DNAME = 39; // DNAME [RFC2672]
- final static int TYPE_SINK = 40; // SINK [Eastlake]
- final static int TYPE_OPT = 41; // OPT [RFC2671]
- final static int TYPE_APL = 42; // APL [RFC3123]
- final static int TYPE_DS = 43; // Delegation Signer [RFC3658]
- final static int TYPE_SSHFP = 44; // SSH Key Fingerprint [RFC-ietf-secsh-dns-05.txt]
- final static int TYPE_RRSIG = 46; // RRSIG [RFC3755]
- final static int TYPE_NSEC = 47; // NSEC [RFC3755]
- final static int TYPE_DNSKEY = 48; // DNSKEY [RFC3755]
- final static int TYPE_UINFO = 100; // [IANA-Reserved]
- final static int TYPE_UID = 101; // [IANA-Reserved]
- final static int TYPE_GID = 102; // [IANA-Reserved]
- final static int TYPE_UNSPEC = 103; // [IANA-Reserved]
- final static int TYPE_TKEY = 249; // Transaction Key [RFC2930]
- final static int TYPE_TSIG = 250; // Transaction Signature [RFC2845]
- final static int TYPE_IXFR = 251; // Incremental transfer [RFC1995]
- final static int TYPE_AXFR = 252; // Transfer of an entire zone [RFC1035]
- final static int TYPE_MAILA = 253; // Mailbox-related records (MB, MG or MR) [RFC1035]
- final static int TYPE_MAILB = 254; // Mail agent RRs (Obsolete - see MX) [RFC1035]
- final static int TYPE_ANY = 255; // Request for all records [RFC1035]
-
- //Time Intervals for various functions
-
- final static int SHARED_QUERY_TIME = 20; //milliseconds before send shared query
- final static int QUERY_WAIT_INTERVAL = 225; //milliseconds between query loops.
- final static int PROBE_WAIT_INTERVAL = 250; //milliseconds between probe loops.
- final static int RESPONSE_MIN_WAIT_INTERVAL = 20; //minimal wait interval for response.
- final static int RESPONSE_MAX_WAIT_INTERVAL = 115; //maximal wait interval for response
- final static int PROBE_CONFLICT_INTERVAL = 1000; //milliseconds to wait after conflict.
- final static int PROBE_THROTTLE_COUNT = 10; //After x tries go 1 time a sec. on probes.
- final static int PROBE_THROTTLE_COUNT_INTERVAL = 5000; //We only increment the throttle count, if
- // the previous increment is inside this interval.
- final static int ANNOUNCE_WAIT_INTERVAL = 1000; //milliseconds between Announce loops.
- final static int RECORD_REAPER_INTERVAL = 10000; //milliseconds between cache cleanups.
- final static int KNOWN_ANSWER_TTL = 120;
- final static int ANNOUNCED_RENEWAL_TTL_INTERVAL = DNS_TTL * 500; // 50% of the TTL in milliseconds
-}
diff --git a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSEntry.java b/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSEntry.java
deleted file mode 100644
index b0bc06be72..0000000000
--- a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSEntry.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
- * Copyright 2003-2005 Arthur van Hoff, Rick Blair
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.jmdns;
-
-import java.util.logging.Logger;
-
-/**
- * DNS entry with a name, type, and class. This is the base
- * class for questions and records.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Pierre Frisch, Rick Blair
- */
-class DNSEntry
-{
- private static Logger logger = Logger.getLogger(DNSEntry.class.toString());
- String key;
- String name;
- int type;
- int clazz;
- boolean unique;
-
- /**
- * Create an entry.
- */
- DNSEntry(String name, int type, int clazz)
- {
- this.key = name.toLowerCase();
- this.name = name;
- this.type = type;
- this.clazz = clazz & DNSConstants.CLASS_MASK;
- this.unique = (clazz & DNSConstants.CLASS_UNIQUE) != 0;
- }
-
- /**
- * Check if two entries have exactly the same name, type, and class.
- */
- public boolean equals(Object obj)
- {
- if (obj instanceof DNSEntry)
- {
- DNSEntry other = (DNSEntry) obj;
- return name.equals(other.name) && type == other.type && clazz == other.clazz;
- }
- return false;
- }
-
- public String getName()
- {
- return name;
- }
-
- public int getType()
- {
- return type;
- }
-
- /**
- * Overriden, to return a value which is consistent with the value returned
- * by equals(Object).
- */
- public int hashCode()
- {
- return name.hashCode() + type + clazz;
- }
-
- /**
- * Get a string given a clazz.
- */
- static String getClazz(int clazz)
- {
- switch (clazz & DNSConstants.CLASS_MASK)
- {
- case DNSConstants.CLASS_IN:
- return "in";
- case DNSConstants.CLASS_CS:
- return "cs";
- case DNSConstants.CLASS_CH:
- return "ch";
- case DNSConstants.CLASS_HS:
- return "hs";
- case DNSConstants.CLASS_NONE:
- return "none";
- case DNSConstants.CLASS_ANY:
- return "any";
- default:
- return "?";
- }
- }
-
- /**
- * Get a string given a type.
- */
- static String getType(int type)
- {
- switch (type)
- {
- case DNSConstants.TYPE_A:
- return "a";
- case DNSConstants.TYPE_AAAA:
- return "aaaa";
- case DNSConstants.TYPE_NS:
- return "ns";
- case DNSConstants.TYPE_MD:
- return "md";
- case DNSConstants.TYPE_MF:
- return "mf";
- case DNSConstants.TYPE_CNAME:
- return "cname";
- case DNSConstants.TYPE_SOA:
- return "soa";
- case DNSConstants.TYPE_MB:
- return "mb";
- case DNSConstants.TYPE_MG:
- return "mg";
- case DNSConstants.TYPE_MR:
- return "mr";
- case DNSConstants.TYPE_NULL:
- return "null";
- case DNSConstants.TYPE_WKS:
- return "wks";
- case DNSConstants.TYPE_PTR:
- return "ptr";
- case DNSConstants.TYPE_HINFO:
- return "hinfo";
- case DNSConstants.TYPE_MINFO:
- return "minfo";
- case DNSConstants.TYPE_MX:
- return "mx";
- case DNSConstants.TYPE_TXT:
- return "txt";
- case DNSConstants.TYPE_SRV:
- return "srv";
- case DNSConstants.TYPE_ANY:
- return "any";
- default:
- return "?";
- }
- }
-
- public String toString(String hdr, String other)
- {
- return hdr + "[" + getType(type) + "," + getClazz(clazz) + (unique ? "-unique," : ",") + name + ((other != null) ? "," + other + "]" : "]");
- }
-}
diff --git a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSIncoming.java b/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSIncoming.java
deleted file mode 100644
index 90c18d90f4..0000000000
--- a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSIncoming.java
+++ /dev/null
@@ -1,478 +0,0 @@
-/**
- * Copyright 2003-2005 Arthur van Hoff, Rick Blair
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.jmdns;
-
-import java.io.IOException;
-import java.net.DatagramPacket;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Parse an incoming DNS message into its components.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Werner Randelshofer, Pierre Frisch
- */
-final class DNSIncoming
-{
- private static Logger logger = Logger.getLogger(DNSIncoming.class.toString());
- // Implementation note: This vector should be immutable.
- // If a client of DNSIncoming changes the contents of this vector,
- // we get undesired results. To fix this, we have to migrate to
- // the Collections API of Java 1.2. i.e we replace Vector by List.
- // final static Vector EMPTY = new Vector();
-
- private DatagramPacket packet;
- private int off;
- private int len;
- private byte data[];
-
- int id;
- private int flags;
- private int numQuestions;
- int numAnswers;
- private int numAuthorities;
- private int numAdditionals;
- private long receivedTime;
-
- List questions;
- List answers;
-
- /**
- * Parse a message from a datagram packet.
- */
- DNSIncoming(DatagramPacket packet) throws IOException
- {
- this.packet = packet;
- this.data = packet.getData();
- this.len = packet.getLength();
- this.off = packet.getOffset();
- this.questions = Collections.EMPTY_LIST;
- this.answers = Collections.EMPTY_LIST;
- this.receivedTime = System.currentTimeMillis();
-
- try
- {
- id = readUnsignedShort();
- flags = readUnsignedShort();
- numQuestions = readUnsignedShort();
- numAnswers = readUnsignedShort();
- numAuthorities = readUnsignedShort();
- numAdditionals = readUnsignedShort();
-
- // parse questions
- if (numQuestions > 0)
- {
- questions = Collections.synchronizedList(new ArrayList(numQuestions));
- for (int i = 0; i < numQuestions; i++)
- {
- DNSQuestion question = new DNSQuestion(readName(), readUnsignedShort(), readUnsignedShort());
- questions.add(question);
- }
- }
-
- // parse answers
- int n = numAnswers + numAuthorities + numAdditionals;
- if (n > 0)
- {
- answers = Collections.synchronizedList(new ArrayList(n));
- for (int i = 0; i < n; i++)
- {
- String domain = readName();
- int type = readUnsignedShort();
- int clazz = readUnsignedShort();
- int ttl = readInt();
- int len = readUnsignedShort();
- int end = off + len;
- DNSRecord rec = null;
-
- switch (type)
- {
- case DNSConstants.TYPE_A: // IPv4
- case DNSConstants.TYPE_AAAA: // IPv6 FIXME [PJYF Oct 14 2004] This has not been tested
- rec = new DNSRecord.Address(domain, type, clazz, ttl, readBytes(off, len));
- break;
- case DNSConstants.TYPE_CNAME:
- case DNSConstants.TYPE_PTR:
- rec = new DNSRecord.Pointer(domain, type, clazz, ttl, readName());
- break;
- case DNSConstants.TYPE_TXT:
- rec = new DNSRecord.Text(domain, type, clazz, ttl, readBytes(off, len));
- break;
- case DNSConstants.TYPE_SRV:
- rec = new DNSRecord.Service(domain, type, clazz, ttl,
- readUnsignedShort(), readUnsignedShort(), readUnsignedShort(), readName());
- break;
- case DNSConstants.TYPE_HINFO:
- // Maybe we should do something with those
- break;
- default :
- logger.finer("DNSIncoming() unknown type:" + type);
- break;
- }
-
- if (rec != null)
- {
- // Add a record, if we were able to create one.
- answers.add(rec);
- }
- else
- {
- // Addjust the numbers for the skipped record
- if (answers.size() < numAnswers)
- {
- numAnswers--;
- }
- else
- {
- if (answers.size() < numAnswers + numAuthorities)
- {
- numAuthorities--;
- }
- else
- {
- if (answers.size() < numAnswers + numAuthorities + numAdditionals)
- {
- numAdditionals--;
- }
- }
- }
- }
- off = end;
- }
- }
- }
- catch (IOException e)
- {
- logger.log(Level.WARNING, "DNSIncoming() dump " + print(true) + "\n exception ", e);
- throw e;
- }
- }
-
- /**
- * Check if the message is a query.
- */
- boolean isQuery()
- {
- return (flags & DNSConstants.FLAGS_QR_MASK) == DNSConstants.FLAGS_QR_QUERY;
- }
-
- /**
- * Check if the message is truncated.
- */
- boolean isTruncated()
- {
- return (flags & DNSConstants.FLAGS_TC) != 0;
- }
-
- /**
- * Check if the message is a response.
- */
- boolean isResponse()
- {
- return (flags & DNSConstants.FLAGS_QR_MASK) == DNSConstants.FLAGS_QR_RESPONSE;
- }
-
- private int get(int off) throws IOException
- {
- if ((off < 0) || (off >= len))
- {
- throw new IOException("parser error: offset=" + off);
- }
- return data[off] & 0xFF;
- }
-
- private int readUnsignedShort() throws IOException
- {
- return (get(off++) << 8) + get(off++);
- }
-
- private int readInt() throws IOException
- {
- return (readUnsignedShort() << 16) + readUnsignedShort();
- }
-
- private byte[] readBytes(int off, int len) throws IOException
- {
- byte bytes[] = new byte[len];
- System.arraycopy(data, off, bytes, 0, len);
- return bytes;
- }
-
- private void readUTF(StringBuffer buf, int off, int len) throws IOException
- {
- for (int end = off + len; off < end;)
- {
- int ch = get(off++);
- 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) | (get(off++) & 0x3F);
- break;
- case 14:
- // 1110 xxxx 10xx xxxx 10xx xxxx
- ch = ((ch & 0x0f) << 12) | ((get(off++) & 0x3F) << 6) | (get(off++) & 0x3F);
- break;
- default:
- // 10xx xxxx, 1111 xxxx
- ch = ((ch & 0x3F) << 4) | (get(off++) & 0x0f);
- break;
- }
- buf.append((char) ch);
- }
- }
-
- private String readName() throws IOException
- {
- StringBuffer buf = new StringBuffer();
- int off = this.off;
- int next = -1;
- int first = off;
-
- while (true)
- {
- int len = get(off++);
- if (len == 0)
- {
- break;
- }
- switch (len & 0xC0)
- {
- case 0x00:
- //buf.append("[" + off + "]");
- readUTF(buf, off, len);
- off += len;
- buf.append('.');
- break;
- case 0xC0:
- //buf.append("<" + (off - 1) + ">");
- if (next < 0)
- {
- next = off + 1;
- }
- off = ((len & 0x3F) << 8) | get(off++);
- if (off >= first)
- {
- throw new IOException("bad domain name: possible circular name detected");
- }
- first = off;
- break;
- default:
- throw new IOException("bad domain name: '" + buf + "' at " + off);
- }
- }
- this.off = (next >= 0) ? next : off;
- return buf.toString();
- }
-
- /**
- * Debugging.
- */
- String print(boolean dump)
- {
- StringBuffer buf = new StringBuffer();
- buf.append(toString() + "\n");
- for (Iterator iterator = questions.iterator(); iterator.hasNext();)
- {
- buf.append(" ques:" + iterator.next() + "\n");
- }
- int count = 0;
- for (Iterator iterator = answers.iterator(); iterator.hasNext(); count++)
- {
- if (count < numAnswers)
- {
- buf.append(" answ:");
- }
- else
- {
- if (count < numAnswers + numAuthorities)
- {
- buf.append(" auth:");
- }
- else
- {
- buf.append(" addi:");
- }
- }
- buf.append(iterator.next() + "\n");
- }
- if (dump)
- {
- for (int off = 0, len = packet.getLength(); off < len; off += 32)
- {
- int n = Math.min(32, len - off);
- if (off < 10)
- {
- buf.append(' ');
- }
- if (off < 100)
- {
- buf.append(' ');
- }
- buf.append(off);
- buf.append(':');
- for (int i = 0; i < n; i++)
- {
- if ((i % 8) == 0)
- {
- buf.append(' ');
- }
- buf.append(Integer.toHexString((data[off + i] & 0xF0) >> 4));
- buf.append(Integer.toHexString((data[off + i] & 0x0F) >> 0));
- }
- buf.append("\n");
- buf.append(" ");
- for (int i = 0; i < n; i++)
- {
- if ((i % 8) == 0)
- {
- buf.append(' ');
- }
- buf.append(' ');
- int ch = data[off + i] & 0xFF;
- buf.append(((ch > ' ') && (ch < 127)) ? (char) ch : '.');
- }
- buf.append("\n");
-
- // limit message size
- if (off + 32 >= 256)
- {
- buf.append("....\n");
- break;
- }
- }
- }
- return buf.toString();
- }
-
- public String toString()
- {
- StringBuffer buf = new StringBuffer();
- buf.append(isQuery() ? "dns[query," : "dns[response,");
- if (packet.getAddress() != null)
- {
- buf.append(packet.getAddress().getHostAddress());
- }
- buf.append(':');
- buf.append(packet.getPort());
- buf.append(",len=");
- buf.append(packet.getLength());
- buf.append(",id=0x");
- buf.append(Integer.toHexString(id));
- if (flags != 0)
- {
- buf.append(",flags=0x");
- buf.append(Integer.toHexString(flags));
- if ((flags & DNSConstants.FLAGS_QR_RESPONSE) != 0)
- {
- buf.append(":r");
- }
- if ((flags & DNSConstants.FLAGS_AA) != 0)
- {
- buf.append(":aa");
- }
- if ((flags & DNSConstants.FLAGS_TC) != 0)
- {
- buf.append(":tc");
- }
- }
- if (numQuestions > 0)
- {
- buf.append(",questions=");
- buf.append(numQuestions);
- }
- if (numAnswers > 0)
- {
- buf.append(",answers=");
- buf.append(numAnswers);
- }
- if (numAuthorities > 0)
- {
- buf.append(",authorities=");
- buf.append(numAuthorities);
- }
- if (numAdditionals > 0)
- {
- buf.append(",additionals=");
- buf.append(numAdditionals);
- }
- buf.append("]");
- return buf.toString();
- }
-
- /**
- * Appends answers to this Incoming.
- *
- * @throws IllegalArgumentException If not a query or if Truncated.
- */
- void append(DNSIncoming that)
- {
- if (this.isQuery() && this.isTruncated() && that.isQuery())
- {
- this.questions.addAll(that.questions);
- this.numQuestions += that.numQuestions;
-
- if (Collections.EMPTY_LIST.equals(answers))
- {
- answers = Collections.synchronizedList(new ArrayList());
- }
-
- if (that.numAnswers > 0)
- {
- this.answers.addAll(this.numAnswers, that.answers.subList(0, that.numAnswers));
- this.numAnswers += that.numAnswers;
- }
- if (that.numAuthorities > 0)
- {
- this.answers.addAll(this.numAnswers + this.numAuthorities, that.answers.subList(that.numAnswers, that.numAnswers + that.numAuthorities));
- this.numAuthorities += that.numAuthorities;
- }
- if (that.numAdditionals > 0)
- {
- this.answers.addAll(that.answers.subList(that.numAnswers + that.numAuthorities, that.numAnswers + that.numAuthorities + that.numAdditionals));
- this.numAdditionals += that.numAdditionals;
- }
- }
- else
- {
- throw new IllegalArgumentException();
- }
- }
-
- int elapseSinceArrival()
- {
- return (int) (System.currentTimeMillis() - receivedTime);
- }
-}
diff --git a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSListener.java b/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSListener.java
deleted file mode 100644
index 269a5f0b62..0000000000
--- a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Copyright 2003-2005 Arthur van Hoff, Rick Blair
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.jmdns;
-
-// REMIND: Listener should follow Java idiom for listener or have a different
-// name.
-
-/**
- * DNSListener.
- * Listener for record updates.
- *
- * @author Werner Randelshofer, Rick Blair
- * @version 1.0 May 22, 2004 Created.
- */
-public interface DNSListener
-{
- /**
- * Update a DNS record.
- */
- void updateRecord(JmDNS jmdns, long now, DNSRecord record);
-}
diff --git a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSOutgoing.java b/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSOutgoing.java
deleted file mode 100644
index a39dfec01a..0000000000
--- a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSOutgoing.java
+++ /dev/null
@@ -1,394 +0,0 @@
-/**
- * Copyright 2003-2005 Arthur van Hoff, Rick Blair
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.jmdns;
-
-import java.io.IOException;
-import java.util.Hashtable;
-import java.util.LinkedList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * An outgoing DNS message.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Rick Blair, Werner Randelshofer
- */
-final class DNSOutgoing
-{
- private static Logger logger = Logger.getLogger(DNSOutgoing.class.toString());
- int id;
- int flags;
- private boolean multicast;
- private int numQuestions;
- private int numAnswers;
- private int numAuthorities;
- private int numAdditionals;
- private Hashtable names;
-
- byte data[];
- int off;
- int len;
-
- /**
- * Create an outgoing multicast query or response.
- */
- DNSOutgoing(int flags)
- {
- this(flags, true);
- }
-
- /**
- * Create an outgoing query or response.
- */
- DNSOutgoing(int flags, boolean multicast)
- {
- this.flags = flags;
- this.multicast = multicast;
- names = new Hashtable();
- data = new byte[DNSConstants.MAX_MSG_TYPICAL];
- off = 12;
- }
-
- /**
- * Add a question to the message.
- */
- void addQuestion(DNSQuestion rec) throws IOException
- {
- if (numAnswers > 0 || numAuthorities > 0 || numAdditionals > 0)
- {
- throw new IllegalStateException("Questions must be added before answers");
- }
- numQuestions++;
- writeQuestion(rec);
- }
-
- /**
- * Add an answer if it is not suppressed.
- */
- void addAnswer(DNSIncoming in, DNSRecord rec) throws IOException
- {
- if (numAuthorities > 0 || numAdditionals > 0)
- {
- throw new IllegalStateException("Answers must be added before authorities and additionals");
- }
- if (!rec.suppressedBy(in))
- {
- addAnswer(rec, 0);
- }
- }
-
- /**
- * Add an additional answer to the record. Omit if there is no room.
- */
- void addAdditionalAnswer(DNSIncoming in, DNSRecord rec) throws IOException
- {
- if ((off < DNSConstants.MAX_MSG_TYPICAL - 200) && !rec.suppressedBy(in))
- {
- writeRecord(rec, 0);
- numAdditionals++;
- }
- }
-
- /**
- * Add an answer to the message.
- */
- void addAnswer(DNSRecord rec, long now) throws IOException
- {
- if (numAuthorities > 0 || numAdditionals > 0)
- {
- throw new IllegalStateException("Questions must be added before answers");
- }
- if (rec != null)
- {
- if ((now == 0) || !rec.isExpired(now))
- {
- writeRecord(rec, now);
- numAnswers++;
- }
- }
- }
-
- private LinkedList authorativeAnswers = new LinkedList();
-
- /**
- * Add an authorative answer to the message.
- */
- void addAuthorativeAnswer(DNSRecord rec) throws IOException
- {
- if (numAdditionals > 0)
- {
- throw new IllegalStateException("Authorative answers must be added before additional answers");
- }
- authorativeAnswers.add(rec);
- writeRecord(rec, 0);
- numAuthorities++;
-
- // VERIFY:
-
- }
-
- void writeByte(int value) throws IOException
- {
- if (off >= data.length)
- {
- throw new IOException("buffer full");
- }
- data[off++] = (byte) value;
- }
-
- void writeBytes(String str, int off, int len) throws IOException
- {
- for (int i = 0; i < len; i++)
- {
- writeByte(str.charAt(off + i));
- }
- }
-
- void writeBytes(byte data[]) throws IOException
- {
- if (data != null)
- {
- writeBytes(data, 0, data.length);
- }
- }
-
- void writeBytes(byte data[], int off, int len) throws IOException
- {
- for (int i = 0; i < len; i++)
- {
- writeByte(data[off + i]);
- }
- }
-
- void writeShort(int value) throws IOException
- {
- writeByte(value >> 8);
- writeByte(value);
- }
-
- void writeInt(int value) throws IOException
- {
- writeShort(value >> 16);
- writeShort(value);
- }
-
- void writeUTF(String str, int off, int len) throws IOException
- {
- // 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 writeName(String name) throws IOException
- {
- while (true)
- {
- int n = name.indexOf('.');
- if (n < 0)
- {
- n = name.length();
- }
- if (n <= 0)
- {
- writeByte(0);
- return;
- }
- Integer offset = (Integer) names.get(name);
- if (offset != null)
- {
- int val = offset.intValue();
-
- if (val > off)
- {
- logger.log(Level.WARNING, "DNSOutgoing writeName failed val=" + val + " name=" + name);
- }
-
- writeByte((val >> 8) | 0xC0);
- writeByte(val);
- return;
- }
- names.put(name, new Integer(off));
- writeUTF(name, 0, n);
- name = name.substring(n);
- if (name.startsWith("."))
- {
- name = name.substring(1);
- }
- }
- }
-
- void writeQuestion(DNSQuestion question) throws IOException
- {
- writeName(question.name);
- writeShort(question.type);
- writeShort(question.clazz);
- }
-
- void writeRecord(DNSRecord rec, long now) throws IOException
- {
- int save = off;
- try
- {
- writeName(rec.name);
- writeShort(rec.type);
- writeShort(rec.clazz | ((rec.unique && multicast) ? DNSConstants.CLASS_UNIQUE : 0));
- writeInt((now == 0) ? rec.ttl : rec.getRemainingTTL(now));
- writeShort(0);
- int start = off;
- rec.write(this);
- int len = off - start;
- data[start - 2] = (byte) (len >> 8);
- data[start - 1] = (byte) (len & 0xFF);
- }
- catch (IOException e)
- {
- off = save;
- throw e;
- }
- }
-
- /**
- * Finish the message before sending it off.
- */
- void finish() throws IOException
- {
- int save = off;
- off = 0;
-
- writeShort(multicast ? 0 : id);
- writeShort(flags);
- writeShort(numQuestions);
- writeShort(numAnswers);
- writeShort(numAuthorities);
- writeShort(numAdditionals);
- off = save;
- }
-
- boolean isQuery()
- {
- return (flags & DNSConstants.FLAGS_QR_MASK) == DNSConstants.FLAGS_QR_QUERY;
- }
-
- public boolean isEmpty()
- {
- return numQuestions == 0 && numAuthorities == 0
- && numAdditionals == 0 && numAnswers == 0;
- }
-
-
- public String toString()
- {
- StringBuffer buf = new StringBuffer();
- buf.append(isQuery() ? "dns[query," : "dns[response,");
- //buf.append(packet.getAddress().getHostAddress());
- buf.append(':');
- //buf.append(packet.getPort());
- //buf.append(",len=");
- //buf.append(packet.getLength());
- buf.append(",id=0x");
- buf.append(Integer.toHexString(id));
- if (flags != 0)
- {
- buf.append(",flags=0x");
- buf.append(Integer.toHexString(flags));
- if ((flags & DNSConstants.FLAGS_QR_RESPONSE) != 0)
- {
- buf.append(":r");
- }
- if ((flags & DNSConstants.FLAGS_AA) != 0)
- {
- buf.append(":aa");
- }
- if ((flags & DNSConstants.FLAGS_TC) != 0)
- {
- buf.append(":tc");
- }
- }
- if (numQuestions > 0)
- {
- buf.append(",questions=");
- buf.append(numQuestions);
- }
- if (numAnswers > 0)
- {
- buf.append(",answers=");
- buf.append(numAnswers);
- }
- if (numAuthorities > 0)
- {
- buf.append(",authorities=");
- buf.append(numAuthorities);
- }
- if (numAdditionals > 0)
- {
- buf.append(",additionals=");
- buf.append(numAdditionals);
- }
- buf.append(",\nnames=" + names);
- buf.append(",\nauthorativeAnswers=" + authorativeAnswers);
-
- buf.append("]");
- return buf.toString();
- }
-
-}
diff --git a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSQuestion.java b/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSQuestion.java
deleted file mode 100644
index a206d81704..0000000000
--- a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSQuestion.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * Copyright 2003-2005 Arthur van Hoff, Rick Blair
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.jmdns;
-
-import java.util.logging.Logger;
-
-/**
- * A DNS question.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff
- */
-final class DNSQuestion extends DNSEntry
-{
- private static Logger logger = Logger.getLogger(DNSQuestion.class.toString());
-
- /**
- * Create a question.
- */
- DNSQuestion(String name, int type, int clazz)
- {
- super(name, type, clazz);
- }
-
- /**
- * Check if this question is answered by a given DNS record.
- */
- boolean answeredBy(DNSRecord rec)
- {
- return (clazz == rec.clazz) && ((type == rec.type) || (type == DNSConstants.TYPE_ANY)) &&
- name.equals(rec.name);
- }
-
- /**
- * For debugging only.
- */
- public String toString()
- {
- return toString("question", null);
- }
-}
diff --git a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSRecord.java b/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSRecord.java
deleted file mode 100644
index 954b311c28..0000000000
--- a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSRecord.java
+++ /dev/null
@@ -1,686 +0,0 @@
-/**
- * Copyright 2003-2005 Arthur van Hoff, Rick Blair
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.jmdns;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Iterator;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * DNS record
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Rick Blair, Werner Randelshofer, Pierre Frisch
- */
-public abstract class DNSRecord extends DNSEntry
-{
- private static Logger logger = Logger.getLogger(DNSRecord.class.toString());
- int ttl;
- private long created;
-
- /**
- * Create a DNSRecord with a name, type, clazz, and ttl.
- */
- DNSRecord(String name, int type, int clazz, int ttl)
- {
- super(name, type, clazz);
- this.ttl = ttl;
- this.created = System.currentTimeMillis();
- }
-
- /**
- * True if this record is the same as some other record.
- */
- public boolean equals(Object other)
- {
- return (other instanceof DNSRecord) && sameAs((DNSRecord) other);
- }
-
- /**
- * True if this record is the same as some other record.
- */
- boolean sameAs(DNSRecord other)
- {
- return super.equals(other) && sameValue((DNSRecord) other);
- }
-
- /**
- * True if this record has the same value as some other record.
- */
- abstract boolean sameValue(DNSRecord other);
-
- /**
- * True if this record has the same type as some other record.
- */
- boolean sameType(DNSRecord other)
- {
- return type == other.type;
- }
-
- /**
- * Handles a query represented by this record.
- *
- * @return Returns true if a conflict with one of the services registered
- * with JmDNS or with the hostname occured.
- */
- abstract boolean handleQuery(JmDNS dns, long expirationTime);
-
- /**
- * Handles a responserepresented by this record.
- *
- * @return Returns true if a conflict with one of the services registered
- * with JmDNS or with the hostname occured.
- */
- abstract boolean handleResponse(JmDNS dns);
-
- /**
- * Adds this as an answer to the provided outgoing datagram.
- */
- abstract DNSOutgoing addAnswer(JmDNS dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException;
-
- /**
- * True if this record is suppressed by the answers in a message.
- */
- boolean suppressedBy(DNSIncoming msg)
- {
- try
- {
- for (int i = msg.numAnswers; i-- > 0;)
- {
- if (suppressedBy((DNSRecord) msg.answers.get(i)))
- {
- return true;
- }
- }
- return false;
- }
- catch (ArrayIndexOutOfBoundsException e)
- {
- logger.log(Level.WARNING, "suppressedBy() message " + msg + " exception ", e);
- // msg.print(true);
- return false;
- }
- }
-
- /**
- * True if this record would be supressed by an answer.
- * This is the case if this record would not have a
- * significantly longer TTL.
- */
- boolean suppressedBy(DNSRecord other)
- {
- if (sameAs(other) && (other.ttl > ttl / 2))
- {
- return true;
- }
- return false;
- }
-
- /**
- * Get the expiration time of this record.
- */
- long getExpirationTime(int percent)
- {
- return created + (percent * ttl * 10L);
- }
-
- /**
- * Get the remaining TTL for this record.
- */
- int getRemainingTTL(long now)
- {
- return (int) Math.max(0, (getExpirationTime(100) - now) / 1000);
- }
-
- /**
- * Check if the record is expired.
- */
- public boolean isExpired(long now)
- {
- return getExpirationTime(100) <= now;
- }
-
- /**
- * Check if the record is stale, ie it has outlived
- * more than half of its TTL.
- */
- boolean isStale(long now)
- {
- return getExpirationTime(50) <= now;
- }
-
- /**
- * Reset the TTL of a record. This avoids having to
- * update the entire record in the cache.
- */
- void resetTTL(DNSRecord other)
- {
- created = other.created;
- ttl = other.ttl;
- }
-
- /**
- * Write this record into an outgoing message.
- */
- abstract void write(DNSOutgoing out) throws IOException;
-
- /**
- * Address record.
- */
- public static class Address extends DNSRecord
- {
- private static Logger logger = Logger.getLogger(Address.class.toString());
- InetAddress addr;
-
- Address(String name, int type, int clazz, int ttl, InetAddress addr)
- {
- super(name, type, clazz, ttl);
- this.addr = addr;
- }
-
- Address(String name, int type, int clazz, int ttl, byte[] rawAddress)
- {
- super(name, type, clazz, ttl);
- try
- {
- this.addr = InetAddress.getByAddress(rawAddress);
- }
- catch (UnknownHostException exception)
- {
- logger.log(Level.WARNING, "Address() exception ", exception);
- }
- }
-
- void write(DNSOutgoing out) throws IOException
- {
- if (addr != null)
- {
- byte[] buffer = addr.getAddress();
- if (DNSConstants.TYPE_A == type)
- {
- // 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);
- }
- }
- else
- {
- // 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);
- }
- }
-
- boolean same(DNSRecord other)
- {
- return ((sameName(other)) && ((sameValue(other))));
- }
-
- boolean sameName(DNSRecord other)
- {
- return name.equalsIgnoreCase(((Address) other).name);
- }
-
- boolean sameValue(DNSRecord other)
- {
- return addr.equals(((Address) other).getAddress());
- }
-
- InetAddress getAddress()
- {
- return addr;
- }
-
- /**
- * 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.
- */
- private byte[] toByteArray()
- {
- try
- {
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- DataOutputStream dout = new DataOutputStream(bout);
- dout.write(name.getBytes("UTF8"));
- dout.writeShort(type);
- dout.writeShort(clazz);
- //dout.writeInt(len);
- byte[] buffer = addr.getAddress();
- for (int i = 0; i < buffer.length; i++)
- {
- dout.writeByte(buffer[i]);
- }
- dout.close();
- return bout.toByteArray();
- }
- catch (IOException e)
- {
- throw new InternalError();
- }
- }
-
- /**
- * Does a lexicographic comparison of the byte array representation
- * of this record and that record.
- * This is needed for tie-break tests according to
- * draft-cheshire-dnsext-multicastdns-04.txt chapter 9.2.
- */
- private int lexCompare(DNSRecord.Address that)
- {
- byte[] thisBytes = this.toByteArray();
- byte[] thatBytes = that.toByteArray();
- for (int i = 0, n = Math.min(thisBytes.length, thatBytes.length); i < n; i++)
- {
- if (thisBytes[i] > thatBytes[i])
- {
- return 1;
- }
- else
- {
- if (thisBytes[i] < thatBytes[i])
- {
- return -1;
- }
- }
- }
- return thisBytes.length - thatBytes.length;
- }
-
- /**
- * Does the necessary actions, when this as a query.
- */
- boolean handleQuery(JmDNS dns, long expirationTime)
- {
- DNSRecord.Address dnsAddress = dns.getLocalHost().getDNSAddressRecord(this);
- if (dnsAddress != null)
- {
- if (dnsAddress.sameType(this) && dnsAddress.sameName(this) && (!dnsAddress.sameValue(this)))
- {
- logger.finer("handleQuery() Conflicting probe detected. dns state " + dns.getState() + " lex compare " + lexCompare(dnsAddress));
- // Tie-breaker test
- if (dns.getState().isProbing() && lexCompare(dnsAddress) >= 0)
- {
- // We lost the tie-break. We have to choose a different name.
- dns.getLocalHost().incrementHostName();
- dns.getCache().clear();
- for (Iterator i = dns.services.values().iterator(); i.hasNext();)
- {
- ServiceInfo info = (ServiceInfo) i.next();
- info.revertState();
- }
- }
- dns.revertState();
- return true;
- }
- }
- return false;
- }
-
- /**
- * Does the necessary actions, when this as a response.
- */
- boolean handleResponse(JmDNS dns)
- {
- DNSRecord.Address dnsAddress = dns.getLocalHost().getDNSAddressRecord(this);
- if (dnsAddress != null)
- {
- if (dnsAddress.sameType(this) && dnsAddress.sameName(this) && (!dnsAddress.sameValue(this)))
- {
- logger.finer("handleResponse() Denial detected");
-
- if (dns.getState().isProbing())
- {
- dns.getLocalHost().incrementHostName();
- dns.getCache().clear();
- for (Iterator i = dns.services.values().iterator(); i.hasNext();)
- {
- ServiceInfo info = (ServiceInfo) i.next();
- info.revertState();
- }
- }
- dns.revertState();
- return true;
- }
- }
- return false;
- }
-
- DNSOutgoing addAnswer(JmDNS dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException
- {
- return out;
- }
-
- public String toString()
- {
- return toString(" address '" + (addr != null ? addr.getHostAddress() : "null") + "'");
- }
-
- }
-
- /**
- * Pointer record.
- */
- public static class Pointer extends DNSRecord
- {
- private static Logger logger = Logger.getLogger(Pointer.class.toString());
- String alias;
-
- Pointer(String name, int type, int clazz, int ttl, String alias)
- {
- super(name, type, clazz, ttl);
- this.alias = alias;
- }
-
- void write(DNSOutgoing out) throws IOException
- {
- out.writeName(alias);
- }
-
- boolean sameValue(DNSRecord other)
- {
- return alias.equals(((Pointer) other).alias);
- }
-
- boolean handleQuery(JmDNS dns, long expirationTime)
- {
- // Nothing to do (?)
- // I think there is no possibility for conflicts for this record type?
- return false;
- }
-
- boolean handleResponse(JmDNS dns)
- {
- // Nothing to do (?)
- // I think there is no possibility for conflicts for this record type?
- return false;
- }
-
- String getAlias()
- {
- return alias;
- }
-
- DNSOutgoing addAnswer(JmDNS dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException
- {
- return out;
- }
-
- public String toString()
- {
- return toString(alias);
- }
- }
-
- public static class Text extends DNSRecord
- {
- private static Logger logger = Logger.getLogger(Text.class.toString());
- final public byte text[];
-
- Text(String name, int type, int clazz, int ttl, byte text[])
- {
- super(name, type, clazz, ttl);
- this.text = text;
- }
-
- void write(DNSOutgoing out) throws IOException
- {
- out.writeBytes(text, 0, text.length);
- }
-
- boolean sameValue(DNSRecord other)
- {
- Text txt = (Text) other;
- 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;
- }
-
- boolean handleQuery(JmDNS dns, long expirationTime)
- {
- // Nothing to do (?)
- // I think there is no possibility for conflicts for this record type?
- return false;
- }
-
- boolean handleResponse(JmDNS dns)
- {
- // Nothing to do (?)
- // Shouldn't we care if we get a conflict at this level?
- /*
- ServiceInfo info = (ServiceInfo) dns.services.get(name.toLowerCase());
- if (info != null) {
- if (! Arrays.equals(text,info.text)) {
- info.revertState();
- return true;
- }
- }*/
- return false;
- }
-
- DNSOutgoing addAnswer(JmDNS dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException
- {
- return out;
- }
-
- public String toString()
- {
- return toString((text.length > 10) ? new String(text, 0, 7) + "..." : new String(text));
- }
- }
-
- /**
- * Service record.
- */
- public static class Service extends DNSRecord
- {
- private static Logger logger = Logger.getLogger(Service.class.toString());
- int priority;
- int weight;
- int port;
- String server;
-
- Service(String name, int type, int clazz, int ttl, int priority, int weight, int port, String server)
- {
- super(name, type, clazz, ttl);
- this.priority = priority;
- this.weight = weight;
- this.port = port;
- this.server = server;
- }
-
- void write(DNSOutgoing out) throws IOException
- {
- out.writeShort(priority);
- out.writeShort(weight);
- out.writeShort(port);
- out.writeName(server);
- }
-
- private byte[] toByteArray()
- {
- try
- {
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- DataOutputStream dout = new DataOutputStream(bout);
- dout.write(name.getBytes("UTF8"));
- dout.writeShort(type);
- dout.writeShort(clazz);
- //dout.writeInt(len);
- dout.writeShort(priority);
- dout.writeShort(weight);
- dout.writeShort(port);
- dout.write(server.getBytes("UTF8"));
- dout.close();
- return bout.toByteArray();
- }
- catch (IOException e)
- {
- throw new InternalError();
- }
- }
-
- private int lexCompare(DNSRecord.Service that)
- {
- byte[] thisBytes = this.toByteArray();
- byte[] thatBytes = that.toByteArray();
- for (int i = 0, n = Math.min(thisBytes.length, thatBytes.length); i < n; i++)
- {
- if (thisBytes[i] > thatBytes[i])
- {
- return 1;
- }
- else
- {
- if (thisBytes[i] < thatBytes[i])
- {
- return -1;
- }
- }
- }
- return thisBytes.length - thatBytes.length;
- }
-
- boolean sameValue(DNSRecord other)
- {
- Service s = (Service) other;
- return (priority == s.priority) && (weight == s.weight) && (port == s.port) && server.equals(s.server);
- }
-
- boolean handleQuery(JmDNS dns, long expirationTime)
- {
- ServiceInfo info = (ServiceInfo) dns.services.get(name.toLowerCase());
- if (info != null
- && (port != info.port || !server.equalsIgnoreCase(dns.getLocalHost().getName())))
- {
- logger.finer("handleQuery() Conflicting probe detected");
-
- // Tie breaker test
- if (info.getState().isProbing() && lexCompare(new DNSRecord.Service(info.getQualifiedName(), DNSConstants.TYPE_SRV,
- DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE,
- DNSConstants.DNS_TTL, info.priority,
- info.weight, info.port, dns.getLocalHost().getName())) >= 0)
- {
- // We lost the tie break
- String oldName = info.getQualifiedName().toLowerCase();
- info.setName(dns.incrementName(info.getName()));
- dns.services.remove(oldName);
- dns.services.put(info.getQualifiedName().toLowerCase(), info);
- logger.finer("handleQuery() Lost tie break: new unique name chosen:" + info.getName());
-
- }
- info.revertState();
- return true;
-
- }
- return false;
- }
-
- boolean handleResponse(JmDNS dns)
- {
- ServiceInfo info = (ServiceInfo) dns.services.get(name.toLowerCase());
- if (info != null
- && (port != info.port || !server.equalsIgnoreCase(dns.getLocalHost().getName())))
- {
- logger.finer("handleResponse() Denial detected");
-
- if (info.getState().isProbing())
- {
- String oldName = info.getQualifiedName().toLowerCase();
- info.setName(dns.incrementName(info.getName()));
- dns.services.remove(oldName);
- dns.services.put(info.getQualifiedName().toLowerCase(), info);
- logger.finer("handleResponse() New unique name chose:" + info.getName());
-
- }
- info.revertState();
- return true;
- }
- return false;
- }
-
- DNSOutgoing addAnswer(JmDNS dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException
- {
- ServiceInfo info = (ServiceInfo) dns.services.get(name.toLowerCase());
- if (info != null)
- {
- if (this.port == info.port != server.equals(dns.getLocalHost().getName()))
- {
- return dns.addAnswer(in, addr, port, out,
- new DNSRecord.Service(info.getQualifiedName(), DNSConstants.TYPE_SRV,
- DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE,
- DNSConstants.DNS_TTL, info.priority,
- info.weight, info.port, dns.getLocalHost().getName()));
- }
- }
- return out;
- }
-
- public String toString()
- {
- return toString(server + ":" + port);
- }
- }
-
- public String toString(String other)
- {
- return toString("record", ttl + "/" + getRemainingTTL(System.currentTimeMillis()) + "," + other);
- }
-}
-
diff --git a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSState.java b/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSState.java
deleted file mode 100644
index 3e26d354fd..0000000000
--- a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSState.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * Copyright 2003-2005 Arthur van Hoff, Rick Blair
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.jmdns;
-
-import java.util.ArrayList;
-import java.util.logging.Logger;
-
-/**
- * DNSState defines the possible states for services registered with JmDNS.
- *
- * @author Werner Randelshofer, Rick Blair
- * @version 1.0 May 23, 2004 Created.
- */
-public class DNSState implements Comparable
-{
- private static Logger logger = Logger.getLogger(DNSState.class.toString());
-
- private final String name;
-
- /**
- * Ordinal of next state to be created.
- */
- private static int nextOrdinal = 0;
- /**
- * Assign an ordinal to this state.
- */
- private final int ordinal = nextOrdinal++;
- /**
- * Logical sequence of states.
- * The sequence is consistent with the ordinal of a state.
- * This is used for advancing through states.
- */
- private final static ArrayList sequence = new ArrayList();
-
- private DNSState(String name)
- {
- this.name = name;
- sequence.add(this);
- }
-
- public final String toString()
- {
- return name;
- }
-
- public static final DNSState PROBING_1 = new DNSState("probing 1");
- public static final DNSState PROBING_2 = new DNSState("probing 2");
- public static final DNSState PROBING_3 = new DNSState("probing 3");
- public static final DNSState ANNOUNCING_1 = new DNSState("announcing 1");
- public static final DNSState ANNOUNCING_2 = new DNSState("announcing 2");
- public static final DNSState ANNOUNCED = new DNSState("announced");
- public static final DNSState CANCELED = new DNSState("canceled");
-
- /**
- * 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.
- * Does not advance for ANNOUNCED and CANCELED state.
- */
- public final DNSState advance()
- {
- return (isProbing() || isAnnouncing()) ? (DNSState) sequence.get(ordinal + 1) : this;
- }
-
- /**
- * Returns to the next reverted state.
- * All states except CANCELED revert to PROBING_1.
- * Status CANCELED does not revert.
- */
- public final DNSState revert()
- {
- return (this == CANCELED) ? this : PROBING_1;
- }
-
- /**
- * Returns true, if this is a probing state.
- */
- public boolean isProbing()
- {
- return compareTo(PROBING_1) >= 0 && compareTo(PROBING_3) <= 0;
- }
-
- /**
- * Returns true, if this is an announcing state.
- */
- public boolean isAnnouncing()
- {
- return compareTo(ANNOUNCING_1) >= 0 && compareTo(ANNOUNCING_2) <= 0;
- }
-
- /**
- * Returns true, if this is an announced state.
- */
- public boolean isAnnounced()
- {
- return compareTo(ANNOUNCED) == 0;
- }
-
- /**
- * Compares two states.
- * The states compare as follows:
- * PROBING_1 < PROBING_2 < PROBING_3 < ANNOUNCING_1 <
- * ANNOUNCING_2 < RESPONDING < ANNOUNCED < CANCELED.
- */
- public int compareTo(Object o)
- {
- return ordinal - ((DNSState) o).ordinal;
- }
-}
\ No newline at end of file
diff --git a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/HostInfo.java b/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/HostInfo.java
deleted file mode 100644
index b464888a6c..0000000000
--- a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/HostInfo.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/**
- * Copyright 2003-2005 Arthur van Hoff, Rick Blair
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.jmdns;
-
-import java.net.*;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * HostInfo information on the local host to be able to cope with change of addresses.
- *
- * @version %I%, %G%
- * @author Pierre Frisch, Werner Randelshofer
- */
-class HostInfo
-{
- private static Logger logger = Logger.getLogger(HostInfo.class.toString());
- protected String name;
- protected InetAddress address;
- protected NetworkInterface interfaze;
- /**
- * This is used to create a unique name for the host name.
- */
- private int hostNameCount;
-
- public HostInfo(InetAddress address, String name)
- {
- super();
- this.address = address;
- this.name = name;
- if (address != null)
- {
- try
- {
- interfaze = NetworkInterface.getByInetAddress(address);
- }
- catch (Exception exception)
- {
- // FIXME Shouldn't we take an action here?
- logger.log(Level.WARNING, "LocalHostInfo() exception ", exception);
- }
- }
- }
-
- public String getName()
- {
- return name;
- }
-
- public InetAddress getAddress()
- {
- return address;
- }
-
- public NetworkInterface getInterface()
- {
- return interfaze;
- }
-
- synchronized String incrementHostName()
- {
- hostNameCount++;
- int plocal = name.indexOf(".local.");
- int punder = name.lastIndexOf("-");
- name = name.substring(0, (punder == -1 ? plocal : punder)) + "-" + hostNameCount + ".local.";
- return name;
- }
-
- boolean shouldIgnorePacket(DatagramPacket packet)
- {
- boolean result = false;
- if (getAddress() != null)
- {
- InetAddress from = packet.getAddress();
- if (from != null)
- {
- if (from.isLinkLocalAddress() && (!getAddress().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() && (!getAddress().isLoopbackAddress()))
- {
- // Ignore loopback packets on a regular interface unless this is
- // also a loopback interface.
- result = true;
- }
- }
- }
- return result;
- }
-
- DNSRecord.Address getDNSAddressRecord(DNSRecord.Address address)
- {
- return (DNSConstants.TYPE_AAAA == address.type ? getDNS6AddressRecord() : getDNS4AddressRecord());
- }
-
- DNSRecord.Address getDNS4AddressRecord()
- {
- if ((getAddress() != null) &&
- ((getAddress() instanceof Inet4Address) ||
- ((getAddress() instanceof Inet6Address) && (((Inet6Address) getAddress()).isIPv4CompatibleAddress()))))
- {
- return new DNSRecord.Address(getName(), DNSConstants.TYPE_A, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, getAddress());
- }
- return null;
- }
-
- DNSRecord.Address getDNS6AddressRecord()
- {
- if ((getAddress() != null) && (getAddress() instanceof Inet6Address))
- {
- return new DNSRecord.Address(getName(), DNSConstants.TYPE_AAAA, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, getAddress());
- }
- return null;
- }
-
- public String toString()
- {
- StringBuffer buf = new StringBuffer();
- buf.append("local host info[");
- buf.append(getName() != null ? getName() : "no name");
- buf.append(", ");
- buf.append(getInterface() != null ? getInterface().getDisplayName() : "???");
- buf.append(":");
- buf.append(getAddress() != null ? getAddress().getHostAddress() : "no address");
- buf.append("]");
- return buf.toString();
- }
-
-}
diff --git a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/JmDNS.java b/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/JmDNS.java
deleted file mode 100644
index 8ab1c0e32b..0000000000
--- a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/JmDNS.java
+++ /dev/null
@@ -1,2132 +0,0 @@
-/**
- * Copyright 2003-2005 Arthur van Hoff, Rick Blair
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.jmdns;
-
-import java.io.IOException;
-import java.net.DatagramPacket;
-import java.net.InetAddress;
-import java.net.MulticastSocket;
-import java.util.*;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-// REMIND: multiple IP addresses
-
-/**
- * mDNS implementation in Java.
- *
- * @version %I%, %G%
- */
-public class JmDNS {
- private static Logger logger = Logger.getLogger(JmDNS.class.toString());
- /**
- * The version of JmDNS.
- */
- public static String VERSION = "2.0";
-
- /**
- * This is the multicast group, we are listening to for multicast DNS messages.
- */
- private InetAddress group;
- /**
- * This is our multicast socket.
- */
- private MulticastSocket socket;
-
- /**
- * Used to fix live lock problem on unregester.
- */
-
- protected boolean closed = false;
-
- /**
- * Holds instances of JmDNS.DNSListener.
- * Must by a synchronized collection, because it is updated from
- * concurrent threads.
- */
- private List listeners;
- /**
- * Holds instances of ServiceListener's.
- * Keys are Strings holding a fully qualified service type.
- * Values are LinkedList's of ServiceListener's.
- */
- private Map serviceListeners;
- /**
- * Holds instances of ServiceTypeListener's.
- */
- private List typeListeners;
-
-
- /**
- * Cache for DNSEntry's.
- */
- private DNSCache cache;
-
- /**
- * 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.
- */
- Map services;
-
- /**
- * This hashtable holds the service types that have been registered or
- * that have been received in an incoming datagram.
- * Keys are instances of String which hold an all lower-case version of the
- * fully qualified service type.
- * Values hold the fully qualified service type.
- */
- Map serviceTypes;
- /**
- * This is the shutdown hook, we registered with the java runtime.
- */
- private Thread shutdown;
-
- /**
- * Handle on the local host
- */
- HostInfo localHost;
-
- private Thread incomingListener = null;
-
- /**
- * Throttle count.
- * This is used to count the overall number of probes sent by JmDNS.
- * When the last throttle increment happened .
- */
- private int throttle;
- /**
- * Last throttle increment.
- */
- private long lastThrottleIncrement;
-
- /**
- * The timer is used to dispatch all outgoing messages of JmDNS.
- * It is also used to dispatch maintenance tasks for the DNS cache.
- */
- private Timer timer;
-
- /**
- * 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 Object ioLock = new Object();
-
- /**
- * If an incoming package which needs an answer is truncated, we store it
- * here. We add more incoming DNSRecords to it, until the JmDNS.Responder
- * timer picks it up.
- * Remind: This does not work well with multiple planned answers for packages
- * that came in from different clients.
- */
- private DNSIncoming plannedAnswer;
-
- // State machine
- /**
- * The state of JmDNS.
- *
- * For proper handling of concurrency, this variable must be
- * changed only using methods advanceState(), revertState() and cancel().
- */
- private DNSState state = DNSState.PROBING_1;
-
- /**
- * Timer task associated to the host name.
- * This is used to prevent from having multiple tasks associated to the host
- * name at the same time.
- */
- TimerTask task;
-
- /**
- * This hashtable is used to maintain a list of service types being collected
- * by this JmDNS instance.
- * The key of the hashtable is a service type name, the value is an instance
- * of JmDNS.ServiceCollector.
- *
- * @see #list
- */
- private HashMap serviceCollectors = new HashMap();
-
- /**
- * Create an instance of JmDNS.
- */
- public JmDNS() throws IOException {
- logger.finer("JmDNS instance created");
- try {
- InetAddress addr = InetAddress.getLocalHost();
- init(addr.isLoopbackAddress() ? null : addr, addr.getHostName()); // [PJYF Oct 14 2004] Why do we disallow the loopback address?
- } catch (IOException e) {
- init(null, "computer");
- }
- }
-
- /**
- * Create an instance of JmDNS and bind it to a
- * specific network interface given its IP-address.
- */
- public JmDNS(InetAddress addr) throws IOException {
- try {
- init(addr, addr.getHostName());
- } catch (IOException e) {
- init(null, "computer");
- }
- }
-
- /**
- * Initialize everything.
- *
- * @param address The interface to which JmDNS binds to.
- * @param name The host name of the interface.
- */
- private void init(InetAddress address, String name) throws IOException {
- // A host name with "." is illegal. so strip off everything and append .local.
- int idx = name.indexOf(".");
- if (idx > 0) {
- name = name.substring(0, idx);
- }
- name += ".local.";
- // localHost to IP address binding
- localHost = new HostInfo(address, name);
-
- cache = new DNSCache(100);
-
- listeners = Collections.synchronizedList(new ArrayList());
- serviceListeners = new HashMap();
- typeListeners = new ArrayList();
-
- services = new Hashtable(20);
- serviceTypes = new Hashtable(20);
-
- timer = new Timer("JmDNS.Timer");
- new RecordReaper().start();
- shutdown = new Thread(new Shutdown(), "JmDNS.Shutdown");
- Runtime.getRuntime().addShutdownHook(shutdown);
-
- incomingListener = new Thread(new SocketListener(), "JmDNS.SocketListener");
-
- // Bind to multicast socket
- openMulticastSocket(localHost);
- start(services.values());
- }
-
- private void start(Collection serviceInfos) {
- state = DNSState.PROBING_1;
- incomingListener.start();
- new Prober().start();
- for (Iterator iterator = serviceInfos.iterator(); iterator.hasNext(); ) {
- try {
- registerService(new ServiceInfo((ServiceInfo) iterator.next()));
- } catch (Exception exception) {
- logger.log(Level.WARNING, "start() Registration exception ", exception);
- }
- }
- }
-
- private void openMulticastSocket(HostInfo hostInfo) throws IOException {
- if (group == null) {
- group = InetAddress.getByName(DNSConstants.MDNS_GROUP);
- }
- if (socket != null) {
- this.closeMulticastSocket();
- }
- socket = new MulticastSocket(DNSConstants.MDNS_PORT);
- if ((hostInfo != null) && (localHost.getInterface() != null)) {
- socket.setNetworkInterface(hostInfo.getInterface());
- }
- socket.setTimeToLive(255);
- socket.joinGroup(group);
- }
-
- private void closeMulticastSocket() {
- logger.finer("closeMulticastSocket()");
- if (socket != null) {
- // close socket
- try {
- socket.leaveGroup(group);
- socket.close();
- if (incomingListener != null) {
- incomingListener.join();
- }
- } catch (Exception exception) {
- logger.log(Level.WARNING, "closeMulticastSocket() Close socket exception ", exception);
- }
- socket = null;
- }
- }
-
- // State machine
-
- /**
- * Sets the state and notifies all objects that wait on JmDNS.
- */
- synchronized void advanceState() {
- state = state.advance();
- notifyAll();
- }
-
- /**
- * Sets the state and notifies all objects that wait on JmDNS.
- */
- synchronized void revertState() {
- state = state.revert();
- notifyAll();
- }
-
- /**
- * Sets the state and notifies all objects that wait on JmDNS.
- */
- synchronized void cancel() {
- state = DNSState.CANCELED;
- notifyAll();
- }
-
- /**
- * Returns the current state of this info.
- */
- DNSState getState() {
- return state;
- }
-
-
- /**
- * Return the DNSCache associated with the cache variable
- */
- DNSCache getCache() {
- return cache;
- }
-
- /**
- * Return the HostName associated with this JmDNS instance.
- * Note: May not be the same as what started. The host name is subject to
- * negotiation.
- */
- public String getHostName() {
- return localHost.getName();
- }
-
- public HostInfo getLocalHost() {
- return localHost;
- }
-
- /**
- * Return the address of the interface to which this instance of JmDNS is
- * bound.
- */
- public InetAddress getInterface() throws IOException {
- return socket.getInterface();
- }
-
- /**
- * Get service information. If the information is not cached, the method
- * will block until updated information is received.
- *
- * Usage note: Do not call this method from the AWT event dispatcher thread.
- * You will make the user interface unresponsive.
- *
- * @param type fully qualified service type, such as _http._tcp.local.
.
- * @param name unqualified service name, such as foobar
.
- * @return null if the service information cannot be obtained
- */
- public ServiceInfo getServiceInfo(String type, String name) {
- return getServiceInfo(type, name, 3 * 1000);
- }
-
- /**
- * Get service information. If the information is not cached, the method
- * will block for the given timeout until updated information is received.
- *
- * Usage note: If you call this method from the AWT event dispatcher thread,
- * use a small timeout, or you will make the user interface unresponsive.
- *
- * @param type full qualified service type, such as _http._tcp.local.
.
- * @param name unqualified service name, such as foobar
.
- * @param timeout timeout in milliseconds
- * @return null if the service information cannot be obtained
- */
- public ServiceInfo getServiceInfo(String type, String name, int timeout) {
- ServiceInfo info = new ServiceInfo(type, name);
- new ServiceInfoResolver(info).start();
-
- try {
- long end = System.currentTimeMillis() + timeout;
- long delay;
- synchronized (info) {
- while (!info.hasData() && (delay = end - System.currentTimeMillis()) > 0) {
- info.wait(delay);
- }
- }
- } catch (InterruptedException e) {
- // empty
- }
-
- return (info.hasData()) ? info : null;
- }
-
- /**
- * Request service information. The information about the service is
- * requested and the ServiceListener.resolveService method is called as soon
- * as it is available.
- *
- * Usage note: Do not call this method from the AWT event dispatcher thread.
- * You will make the user interface unresponsive.
- *
- * @param type full qualified service type, such as _http._tcp.local.
.
- * @param name unqualified service name, such as foobar
.
- */
- public void requestServiceInfo(String type, String name) {
- requestServiceInfo(type, name, 3 * 1000);
- }
-
- /**
- * Request service information. The information about the service is requested
- * and the ServiceListener.resolveService method is called as soon as it is available.
- *
- * @param type full qualified service type, such as _http._tcp.local.
.
- * @param name unqualified service name, such as foobar
.
- * @param timeout timeout in milliseconds
- */
- public void requestServiceInfo(String type, String name, int timeout) {
- registerServiceType(type);
- ServiceInfo info = new ServiceInfo(type, name);
- new ServiceInfoResolver(info).start();
-
- try {
- long end = System.currentTimeMillis() + timeout;
- long delay;
- synchronized (info) {
- while (!info.hasData() && (delay = end - System.currentTimeMillis()) > 0) {
- info.wait(delay);
- }
- }
- } catch (InterruptedException e) {
- // empty
- }
- }
-
- void handleServiceResolved(ServiceInfo info) {
- List list = (List) serviceListeners.get(info.type.toLowerCase());
- if (list != null) {
- ServiceEvent event = new ServiceEvent(this, info.type, info.getName(), info);
- // Iterate on a copy in case listeners will modify it
- final ArrayList listCopy = new ArrayList(list);
- for (Iterator iterator = listCopy.iterator(); iterator.hasNext(); ) {
- ((ServiceListener) iterator.next()).serviceResolved(event);
- }
- }
- }
-
- /**
- * Listen for service types.
- *
- * @param listener listener for service types
- */
- public void addServiceTypeListener(ServiceTypeListener listener) throws IOException {
- synchronized (this) {
- typeListeners.remove(listener);
- typeListeners.add(listener);
- }
-
- // report cached service types
- for (Iterator iterator = serviceTypes.values().iterator(); iterator.hasNext(); ) {
- listener.serviceTypeAdded(new ServiceEvent(this, (String) iterator.next(), null, null));
- }
-
- new TypeResolver().start();
- }
-
- /**
- * Remove listener for service types.
- *
- * @param listener listener for service types
- */
- public void removeServiceTypeListener(ServiceTypeListener listener) {
- synchronized (this) {
- typeListeners.remove(listener);
- }
- }
-
- /**
- * Listen for services of a given type. The type has to be a fully qualified
- * type name such as _http._tcp.local.
.
- *
- * @param type full qualified service type, such as _http._tcp.local.
.
- * @param listener listener for service updates
- */
- public void addServiceListener(String type, ServiceListener listener) {
- String lotype = type.toLowerCase();
- removeServiceListener(lotype, listener);
- List list = null;
- synchronized (this) {
- list = (List) serviceListeners.get(lotype);
- if (list == null) {
- list = Collections.synchronizedList(new LinkedList());
- serviceListeners.put(lotype, list);
- }
- list.add(listener);
- }
-
- // report cached service types
- for (Iterator i = cache.iterator(); i.hasNext(); ) {
- for (DNSCache.CacheNode n = (DNSCache.CacheNode) i.next(); n != null; n = n.next()) {
- DNSRecord rec = (DNSRecord) n.getValue();
- if (rec.type == DNSConstants.TYPE_SRV) {
- if (rec.name.endsWith(type)) {
- listener.serviceAdded(new ServiceEvent(this, type, toUnqualifiedName(type, rec.name), null));
- }
- }
- }
- }
- new ServiceResolver(type).start();
- }
-
- /**
- * Remove listener for services of a given type.
- *
- * @param listener listener for service updates
- */
- public void removeServiceListener(String type, ServiceListener listener) {
- type = type.toLowerCase();
- List list = (List) serviceListeners.get(type);
- if (list != null) {
- synchronized (this) {
- list.remove(listener);
- if (list.size() == 0) {
- serviceListeners.remove(type);
- }
- }
- }
- }
-
- /**
- * Register a service. The service is registered for access by other jmdns clients.
- * The name of the service may be changed to make it unique.
- */
- public void registerService(ServiceInfo info) throws IOException {
- registerServiceType(info.type);
-
- // bind the service to this address
- info.server = localHost.getName();
- info.addr = localHost.getAddress();
-
- synchronized (this) {
- makeServiceNameUnique(info);
- services.put(info.getQualifiedName().toLowerCase(), info);
- }
-
- new /*Service*/Prober().start();
- try {
- synchronized (info) {
- while (info.getState().compareTo(DNSState.ANNOUNCED) < 0) {
- info.wait();
- }
- }
- } catch (InterruptedException e) {
- //empty
- }
- logger.fine("registerService() JmDNS registered service as " + info);
- }
-
- /**
- * Unregister a service. The service should have been registered.
- */
- public void unregisterService(ServiceInfo info) {
- synchronized (this) {
- services.remove(info.getQualifiedName().toLowerCase());
- }
- info.cancel();
-
- // Note: We use this lock object to synchronize on it.
- // Synchronizing on another object (e.g. the ServiceInfo) does
- // not make sense, because the sole purpose of the lock is to
- // wait until the canceler has finished. If we synchronized on
- // the ServiceInfo or on the Canceler, we would block all
- // accesses to synchronized methods on that object. This is not
- // what we want!
- Object lock = new Object();
- try {
- new Canceler(info, lock).start();
-
- // Remind: We get a deadlock here, if the Canceler does not run!
- try {
- synchronized (lock) {
- //don'r wait forever
- lock.wait(5000);
- }
- } catch (InterruptedException e) {
- // empty
- }
- } catch (Throwable e) {
- logger.info("Failed to properly unregister ");
- }
- }
-
- /**
- * Unregister all services.
- */
- public void unregisterAllServices() {
- logger.finer("unregisterAllServices()");
- if (services.size() == 0) {
- return;
- }
-
- Collection list;
- synchronized (this) {
- list = new LinkedList(services.values());
- services.clear();
- }
- for (Iterator iterator = list.iterator(); iterator.hasNext(); ) {
- ((ServiceInfo) iterator.next()).cancel();
- }
-
- try {
- Object lock = new Object();
- new Canceler(list, lock).start();
- // Remind: We get a livelock here, if the Canceler does not run!
- try {
- synchronized (lock) {
- if (!closed) {
- lock.wait(5000);
- }
- }
- } catch (InterruptedException e) {
- // empty
- }
- } catch (Throwable e) {
- logger.info("Failed to unregister");
- }
-
-
- }
-
- /**
- * Register a service type. If this service type was not already known,
- * all service listeners will be notified of the new service type. Service types
- * are automatically registered as they are discovered.
- */
- public void registerServiceType(String type) {
- String name = type.toLowerCase();
- if (serviceTypes.get(name) == null) {
- if ((type.indexOf("._mdns._udp.") < 0) && !type.endsWith(".in-addr.arpa.")) {
- Collection list;
- synchronized (this) {
- serviceTypes.put(name, type);
- list = new LinkedList(typeListeners);
- }
- for (Iterator iterator = list.iterator(); iterator.hasNext(); ) {
- ((ServiceTypeListener) iterator.next()).serviceTypeAdded(new ServiceEvent(this, type, null, null));
- }
- }
- }
- }
-
- /**
- * Generate a possibly unique name for a host using the information we
- * have in the cache.
- *
- * @return returns true, if the name of the host had to be changed.
- */
- private boolean makeHostNameUnique(DNSRecord.Address host) {
- String originalName = host.getName();
- long now = System.currentTimeMillis();
-
- boolean collision;
- do {
- collision = false;
-
- // Check for collision in cache
- for (DNSCache.CacheNode j = cache.find(host.getName().toLowerCase()); j != null; j = j.next()) {
- DNSRecord a = (DNSRecord) j.getValue();
- if (false) {
- host.name = incrementName(host.getName());
- collision = true;
- break;
- }
- }
- }
- while (collision);
-
- if (originalName.equals(host.getName())) {
- return false;
- } else {
- return true;
- }
- }
-
- /**
- * Generate a possibly unique name for a service using the information we
- * have in the cache.
- *
- * @return returns true, if the name of the service info had to be changed.
- */
- private boolean makeServiceNameUnique(ServiceInfo info) {
- String originalQualifiedName = info.getQualifiedName();
- long now = System.currentTimeMillis();
-
- boolean collision;
- do {
- collision = false;
-
- // Check for collision in cache
- for (DNSCache.CacheNode j = cache.find(info.getQualifiedName().toLowerCase()); j != null; j = j.next()) {
- DNSRecord a = (DNSRecord) j.getValue();
- if ((a.type == DNSConstants.TYPE_SRV) && !a.isExpired(now)) {
- DNSRecord.Service s = (DNSRecord.Service) a;
- if (s.port != info.port || !s.server.equals(localHost.getName())) {
- logger.finer("makeServiceNameUnique() JmDNS.makeServiceNameUnique srv collision:" + a + " s.server=" + s.server + " " + localHost.getName() + " equals:" + (s.server.equals(localHost.getName())));
- info.setName(incrementName(info.getName()));
- collision = true;
- break;
- }
- }
- }
-
- // Check for collision with other service infos published by JmDNS
- Object selfService = services.get(info.getQualifiedName().toLowerCase());
- if (selfService != null && selfService != info) {
- info.setName(incrementName(info.getName()));
- collision = true;
- }
- }
- while (collision);
-
- return !(originalQualifiedName.equals(info.getQualifiedName()));
- }
-
- String incrementName(String name) {
- try {
- int l = name.lastIndexOf('(');
- int r = name.lastIndexOf(')');
- if ((l >= 0) && (l < r)) {
- name = name.substring(0, l) + "(" + (Integer.parseInt(name.substring(l + 1, r)) + 1) + ")";
- } else {
- name += " (2)";
- }
- } catch (NumberFormatException e) {
- name += " (2)";
- }
- return name;
- }
-
- /**
- * Add a listener for a question. The listener will receive updates
- * of answers to the question as they arrive, or from the cache if they
- * are already available.
- */
- public void addListener(DNSListener listener, DNSQuestion question) {
- long now = System.currentTimeMillis();
-
- // add the new listener
- synchronized (this) {
- listeners.add(listener);
- }
-
- // report existing matched records
- if (question != null) {
- for (DNSCache.CacheNode i = cache.find(question.name); i != null; i = i.next()) {
- DNSRecord c = (DNSRecord) i.getValue();
- if (question.answeredBy(c) && !c.isExpired(now)) {
- listener.updateRecord(this, now, c);
- }
- }
- }
- }
-
- /**
- * Remove a listener from all outstanding questions. The listener will no longer
- * receive any updates.
- */
- public void removeListener(DNSListener listener) {
- synchronized (this) {
- listeners.remove(listener);
- }
- }
-
-
- // Remind: Method updateRecord should receive a better name.
-
- /**
- * Notify all listeners that a record was updated.
- */
- void updateRecord(long now, DNSRecord rec) {
- // We do not want to block the entire DNS while we are updating the record for each listener (service info)
- List listenerList = null;
- synchronized (this) {
- listenerList = new ArrayList(listeners);
- }
- for (Iterator iterator = listenerList.iterator(); iterator.hasNext(); ) {
- DNSListener listener = (DNSListener) iterator.next();
- listener.updateRecord(this, now, rec);
- }
- if (rec.type == DNSConstants.TYPE_PTR || rec.type == DNSConstants.TYPE_SRV) {
- List serviceListenerList = null;
- synchronized (this) {
- serviceListenerList = (List) serviceListeners.get(rec.name.toLowerCase());
- // Iterate on a copy in case listeners will modify it
- if (serviceListenerList != null) {
- serviceListenerList = new ArrayList(serviceListenerList);
- }
- }
- if (serviceListenerList != null) {
- boolean expired = rec.isExpired(now);
- String type = rec.getName();
- String name = ((DNSRecord.Pointer) rec).getAlias();
- // DNSRecord old = (DNSRecord)services.get(name.toLowerCase());
- if (!expired) {
- // new record
- ServiceEvent event = new ServiceEvent(this, type, toUnqualifiedName(type, name), null);
- for (Iterator iterator = serviceListenerList.iterator(); iterator.hasNext(); ) {
- ((ServiceListener) iterator.next()).serviceAdded(event);
- }
- } else {
- // expire record
- ServiceEvent event = new ServiceEvent(this, type, toUnqualifiedName(type, name), null);
- for (Iterator iterator = serviceListenerList.iterator(); iterator.hasNext(); ) {
- ((ServiceListener) iterator.next()).serviceRemoved(event);
- }
- }
- }
- }
- }
-
- /**
- * Handle an incoming response. Cache answers, and pass them on to
- * the appropriate questions.
- */
- private void handleResponse(DNSIncoming msg) throws IOException {
- long now = System.currentTimeMillis();
-
- boolean hostConflictDetected = false;
- boolean serviceConflictDetected = false;
-
- for (Iterator i = msg.answers.iterator(); i.hasNext(); ) {
- boolean isInformative = false;
- DNSRecord rec = (DNSRecord) i.next();
- boolean expired = rec.isExpired(now);
-
- // update the cache
- DNSRecord c = (DNSRecord) cache.get(rec);
- if (c != null) {
- if (expired) {
- isInformative = true;
- cache.remove(c);
- } else {
- c.resetTTL(rec);
- rec = c;
- }
- } else {
- if (!expired) {
- isInformative = true;
- cache.add(rec);
- }
- }
- switch (rec.type) {
- case DNSConstants.TYPE_PTR:
- // handle _mdns._udp records
- if (rec.getName().indexOf("._mdns._udp.") >= 0) {
- if (!expired && rec.name.startsWith("_services._mdns._udp.")) {
- isInformative = true;
- registerServiceType(((DNSRecord.Pointer) rec).alias);
- }
- continue;
- }
- registerServiceType(rec.name);
- break;
- }
-
- if ((rec.getType() == DNSConstants.TYPE_A) || (rec.getType() == DNSConstants.TYPE_AAAA)) {
- hostConflictDetected |= rec.handleResponse(this);
- } else {
- serviceConflictDetected |= rec.handleResponse(this);
- }
-
- // notify the listeners
- if (isInformative) {
- updateRecord(now, rec);
- }
- }
-
- if (hostConflictDetected || serviceConflictDetected) {
- new Prober().start();
- }
- }
-
- /**
- * Handle an incoming query. See if we can answer any part of it
- * given our service infos.
- */
- private void handleQuery(DNSIncoming in, InetAddress addr, int port) throws IOException {
- // Track known answers
- boolean hostConflictDetected = false;
- boolean serviceConflictDetected = false;
- long expirationTime = System.currentTimeMillis() + DNSConstants.KNOWN_ANSWER_TTL;
- for (Iterator i = in.answers.iterator(); i.hasNext(); ) {
- DNSRecord answer = (DNSRecord) i.next();
- if ((answer.getType() == DNSConstants.TYPE_A) || (answer.getType() == DNSConstants.TYPE_AAAA)) {
- hostConflictDetected |= answer.handleQuery(this, expirationTime);
- } else {
- serviceConflictDetected |= answer.handleQuery(this, expirationTime);
- }
- }
-
- if (plannedAnswer != null) {
- plannedAnswer.append(in);
- } else {
- if (in.isTruncated()) {
- plannedAnswer = in;
- }
-
- new Responder(in, addr, port).start();
- }
-
- if (hostConflictDetected || serviceConflictDetected) {
- new Prober().start();
- }
- }
-
- /**
- * Add an answer to a question. Deal with the case when the
- * outgoing packet overflows
- */
- DNSOutgoing addAnswer(DNSIncoming in, InetAddress addr, int port, DNSOutgoing out, DNSRecord rec) throws IOException {
- if (out == null) {
- out = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA);
- }
- try {
- out.addAnswer(in, rec);
- } catch (IOException e) {
- out.flags |= DNSConstants.FLAGS_TC;
- out.id = in.id;
- out.finish();
- send(out);
-
- out = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA);
- out.addAnswer(in, rec);
- }
- return out;
- }
-
-
- /**
- * Send an outgoing multicast DNS message.
- */
- private void send(DNSOutgoing out) throws IOException {
- out.finish();
- if (!out.isEmpty()) {
- DatagramPacket packet = new DatagramPacket(out.data, out.off, group, DNSConstants.MDNS_PORT);
-
- try {
- DNSIncoming msg = new DNSIncoming(packet);
- logger.finest("send() JmDNS out:" + msg.print(true));
- } catch (IOException e) {
- logger.throwing(getClass().toString(), "send(DNSOutgoing) - JmDNS can not parse what it sends!!!", e);
- }
- socket.send(packet);
- }
- }
-
- /**
- * Listen for multicast packets.
- */
- class SocketListener implements Runnable {
- public void run() {
- try {
- byte buf[] = new byte[DNSConstants.MAX_MSG_ABSOLUTE];
- DatagramPacket packet = new DatagramPacket(buf, buf.length);
- while (state != DNSState.CANCELED) {
- packet.setLength(buf.length);
- socket.receive(packet);
- if (state == DNSState.CANCELED) {
- break;
- }
- try {
- if (localHost.shouldIgnorePacket(packet)) {
- continue;
- }
-
- DNSIncoming msg = new DNSIncoming(packet);
- logger.finest("SocketListener.run() JmDNS in:" + msg.print(true));
-
- synchronized (ioLock) {
- if (msg.isQuery()) {
- if (packet.getPort() != DNSConstants.MDNS_PORT) {
- handleQuery(msg, packet.getAddress(), packet.getPort());
- }
- handleQuery(msg, group, DNSConstants.MDNS_PORT);
- } else {
- handleResponse(msg);
- }
- }
- } catch (IOException e) {
- logger.log(Level.WARNING, "run() exception ", e);
- }
- }
- } catch (IOException e) {
- if (state != DNSState.CANCELED) {
- logger.log(Level.WARNING, "run() exception ", e);
- recover();
- }
- }
- }
- }
-
-
- /**
- * Periodicaly removes expired entries from the cache.
- */
- private class RecordReaper extends TimerTask {
- public void start() {
- timer.schedule(this, DNSConstants.RECORD_REAPER_INTERVAL, DNSConstants.RECORD_REAPER_INTERVAL);
- }
-
- public void run() {
- synchronized (JmDNS.this) {
- if (state == DNSState.CANCELED) {
- return;
- }
- logger.finest("run() JmDNS reaping cache");
-
- // Remove expired answers from the cache
- // -------------------------------------
- // To prevent race conditions, we defensively copy all cache
- // entries into a list.
- List list = new ArrayList();
- synchronized (cache) {
- for (Iterator i = cache.iterator(); i.hasNext(); ) {
- for (DNSCache.CacheNode n = (DNSCache.CacheNode) i.next(); n != null; n = n.next()) {
- list.add(n.getValue());
- }
- }
- }
- // Now, we remove them.
- long now = System.currentTimeMillis();
- for (Iterator i = list.iterator(); i.hasNext(); ) {
- DNSRecord c = (DNSRecord) i.next();
- if (c.isExpired(now)) {
- updateRecord(now, c);
- cache.remove(c);
- }
- }
- }
- }
- }
-
-
- /**
- * The Prober sends three consecutive probes for all service infos
- * that needs probing as well as for the host name.
- * The state of each service info of the host name is advanced, when a probe has
- * been sent for it.
- * When the prober has run three times, it launches an Announcer.
- *
- * If a conflict during probes occurs, the affected service infos (and affected
- * host name) are taken away from the prober. This eventually causes the prober
- * tho cancel itself.
- */
- private class Prober extends TimerTask {
- /**
- * The state of the prober.
- */
- DNSState taskState = DNSState.PROBING_1;
-
- public Prober() {
- // Associate the host name to this, if it needs probing
- if (state == DNSState.PROBING_1) {
- task = this;
- }
- // Associate services to this, if they need probing
- synchronized (JmDNS.this) {
- for (Iterator iterator = services.values().iterator(); iterator.hasNext(); ) {
- ServiceInfo info = (ServiceInfo) iterator.next();
- if (info.getState() == DNSState.PROBING_1) {
- info.task = this;
- }
- }
- }
- }
-
-
- public void start() {
- long now = System.currentTimeMillis();
- if (now - lastThrottleIncrement < DNSConstants.PROBE_THROTTLE_COUNT_INTERVAL) {
- throttle++;
- } else {
- throttle = 1;
- }
- lastThrottleIncrement = now;
-
- if (state == DNSState.ANNOUNCED && throttle < DNSConstants.PROBE_THROTTLE_COUNT) {
- timer.schedule(this, random.nextInt(1 + DNSConstants.PROBE_WAIT_INTERVAL), DNSConstants.PROBE_WAIT_INTERVAL);
- } else {
- timer.schedule(this, DNSConstants.PROBE_CONFLICT_INTERVAL, DNSConstants.PROBE_CONFLICT_INTERVAL);
- }
- }
-
- public boolean cancel() {
- // Remove association from host name to this
- if (task == this) {
- task = null;
- }
-
- // Remove associations from services to this
- synchronized (JmDNS.this) {
- for (Iterator i = services.values().iterator(); i.hasNext(); ) {
- ServiceInfo info = (ServiceInfo) i.next();
- if (info.task == this) {
- info.task = null;
- }
- }
- }
-
- return super.cancel();
- }
-
- public void run() {
- synchronized (ioLock) {
- DNSOutgoing out = null;
- try {
- // send probes for JmDNS itself
- if (state == taskState && task == this) {
- if (out == null) {
- out = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY);
- }
- out.addQuestion(new DNSQuestion(localHost.getName(), DNSConstants.TYPE_ANY, DNSConstants.CLASS_IN));
- DNSRecord answer = localHost.getDNS4AddressRecord();
- if (answer != null) {
- out.addAuthorativeAnswer(answer);
- }
- answer = localHost.getDNS6AddressRecord();
- if (answer != null) {
- out.addAuthorativeAnswer(answer);
- }
- advanceState();
- }
- // send probes for services
- // Defensively copy the services into a local list,
- // to prevent race conditions with methods registerService
- // and unregisterService.
- List list;
- synchronized (JmDNS.this) {
- list = new LinkedList(services.values());
- }
- for (Iterator i = list.iterator(); i.hasNext(); ) {
- ServiceInfo info = (ServiceInfo) i.next();
-
- synchronized (info) {
- if (info.getState() == taskState && info.task == this) {
- info.advanceState();
- logger.fine("run() JmDNS probing " + info.getQualifiedName() + " state " + info.getState());
- if (out == null) {
- out = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY);
- out.addQuestion(new DNSQuestion(info.getQualifiedName(), DNSConstants.TYPE_ANY, DNSConstants.CLASS_IN));
- }
- out.addAuthorativeAnswer(new DNSRecord.Service(info.getQualifiedName(), DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, localHost.getName()));
- }
- }
- }
- if (out != null) {
- logger.finer("run() JmDNS probing #" + taskState);
- send(out);
- } else {
- // If we have nothing to send, another timer taskState ahead
- // of us has done the job for us. We can cancel.
- cancel();
- return;
- }
- } catch (Throwable e) {
- logger.log(Level.WARNING, "run() exception ", e);
- recover();
- }
-
- taskState = taskState.advance();
- if (!taskState.isProbing()) {
- cancel();
-
- new Announcer().start();
- }
- }
- }
-
- }
-
- /**
- * The Announcer sends an accumulated query of all announces, and advances
- * the state of all serviceInfos, for which it has sent an announce.
- * The Announcer also sends announcements and advances the state of JmDNS itself.
- *
- * When the announcer has run two times, it finishes.
- */
- private class Announcer extends TimerTask {
- /**
- * The state of the announcer.
- */
- DNSState taskState = DNSState.ANNOUNCING_1;
-
- public Announcer() {
- // Associate host to this, if it needs announcing
- if (state == DNSState.ANNOUNCING_1) {
- task = this;
- }
- // Associate services to this, if they need announcing
- synchronized (JmDNS.this) {
- for (Iterator s = services.values().iterator(); s.hasNext(); ) {
- ServiceInfo info = (ServiceInfo) s.next();
- if (info.getState() == DNSState.ANNOUNCING_1) {
- info.task = this;
- }
- }
- }
- }
-
- public void start() {
- timer.schedule(this, DNSConstants.ANNOUNCE_WAIT_INTERVAL, DNSConstants.ANNOUNCE_WAIT_INTERVAL);
- }
-
- public boolean cancel() {
- // Remove association from host to this
- if (task == this) {
- task = null;
- }
-
- // Remove associations from services to this
- synchronized (JmDNS.this) {
- for (Iterator i = services.values().iterator(); i.hasNext(); ) {
- ServiceInfo info = (ServiceInfo) i.next();
- if (info.task == this) {
- info.task = null;
- }
- }
- }
-
- return super.cancel();
- }
-
- public void run() {
- DNSOutgoing out = null;
- try {
- // send probes for JmDNS itself
- if (state == taskState) {
- if (out == null) {
- out = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA);
- }
- DNSRecord answer = localHost.getDNS4AddressRecord();
- if (answer != null) {
- out.addAnswer(answer, 0);
- }
- answer = localHost.getDNS6AddressRecord();
- if (answer != null) {
- out.addAnswer(answer, 0);
- }
- advanceState();
- }
- // send announces for services
- // Defensively copy the services into a local list,
- // to prevent race conditions with methods registerService
- // and unregisterService.
- List list;
- synchronized (JmDNS.this) {
- list = new ArrayList(services.values());
- }
- for (Iterator i = list.iterator(); i.hasNext(); ) {
- ServiceInfo info = (ServiceInfo) i.next();
- synchronized (info) {
- if (info.getState() == taskState && info.task == this) {
- info.advanceState();
- logger.finer("run() JmDNS announcing " + info.getQualifiedName() + " state " + info.getState());
- if (out == null) {
- out = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA);
- }
- out.addAnswer(new DNSRecord.Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.getQualifiedName()), 0);
- out.addAnswer(new DNSRecord.Service(info.getQualifiedName(), DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, localHost.getName()), 0);
- out.addAnswer(new DNSRecord.Text(info.getQualifiedName(), DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.text), 0);
- }
- }
- }
- if (out != null) {
- logger.finer("run() JmDNS announcing #" + taskState);
- send(out);
- } else {
- // If we have nothing to send, another timer taskState ahead
- // of us has done the job for us. We can cancel.
- cancel();
- }
- } catch (Throwable e) {
- logger.log(Level.WARNING, "run() exception ", e);
- recover();
- }
-
- taskState = taskState.advance();
- if (!taskState.isAnnouncing()) {
- cancel();
-
- new Renewer().start();
- }
- }
- }
-
- /**
- * The Renewer is there to send renewal announcment when the record expire for ours infos.
- */
- private class Renewer extends TimerTask {
- /**
- * The state of the announcer.
- */
- DNSState taskState = DNSState.ANNOUNCED;
-
- public Renewer() {
- // Associate host to this, if it needs renewal
- if (state == DNSState.ANNOUNCED) {
- task = this;
- }
- // Associate services to this, if they need renewal
- synchronized (JmDNS.this) {
- for (Iterator s = services.values().iterator(); s.hasNext(); ) {
- ServiceInfo info = (ServiceInfo) s.next();
- if (info.getState() == DNSState.ANNOUNCED) {
- info.task = this;
- }
- }
- }
- }
-
- public void start() {
- timer.schedule(this, DNSConstants.ANNOUNCED_RENEWAL_TTL_INTERVAL, DNSConstants.ANNOUNCED_RENEWAL_TTL_INTERVAL);
- }
-
- public boolean cancel() {
- // Remove association from host to this
- if (task == this) {
- task = null;
- }
-
- // Remove associations from services to this
- synchronized (JmDNS.this) {
- for (Iterator i = services.values().iterator(); i.hasNext(); ) {
- ServiceInfo info = (ServiceInfo) i.next();
- if (info.task == this) {
- info.task = null;
- }
- }
- }
-
- return super.cancel();
- }
-
- public void run() {
- DNSOutgoing out = null;
- try {
- // send probes for JmDNS itself
- if (state == taskState) {
- if (out == null) {
- out = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA);
- }
- DNSRecord answer = localHost.getDNS4AddressRecord();
- if (answer != null) {
- out.addAnswer(answer, 0);
- }
- answer = localHost.getDNS6AddressRecord();
- if (answer != null) {
- out.addAnswer(answer, 0);
- }
- advanceState();
- }
- // send announces for services
- // Defensively copy the services into a local list,
- // to prevent race conditions with methods registerService
- // and unregisterService.
- List list;
- synchronized (JmDNS.this) {
- list = new ArrayList(services.values());
- }
- for (Iterator i = list.iterator(); i.hasNext(); ) {
- ServiceInfo info = (ServiceInfo) i.next();
- synchronized (info) {
- if (info.getState() == taskState && info.task == this) {
- info.advanceState();
- logger.finer("run() JmDNS announced " + info.getQualifiedName() + " state " + info.getState());
- if (out == null) {
- out = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA);
- }
- out.addAnswer(new DNSRecord.Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.getQualifiedName()), 0);
- out.addAnswer(new DNSRecord.Service(info.getQualifiedName(), DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, localHost.getName()), 0);
- out.addAnswer(new DNSRecord.Text(info.getQualifiedName(), DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.text), 0);
- }
- }
- }
- if (out != null) {
- logger.finer("run() JmDNS announced");
- send(out);
- } else {
- // If we have nothing to send, another timer taskState ahead
- // of us has done the job for us. We can cancel.
- cancel();
- }
- } catch (Throwable e) {
- logger.log(Level.WARNING, "run() exception ", e);
- recover();
- }
-
- taskState = taskState.advance();
- if (!taskState.isAnnounced()) {
- cancel();
-
- }
- }
- }
-
- /**
- * The Responder sends a single answer for the specified service infos
- * and for the host name.
- */
- private class Responder extends TimerTask {
- private DNSIncoming in;
- private InetAddress addr;
- private int port;
-
- public Responder(DNSIncoming in, InetAddress addr, int port) {
- this.in = in;
- this.addr = addr;
- this.port = port;
- }
-
- public void start() {
- // According to draft-cheshire-dnsext-multicastdns.txt
- // chapter "8 Responding":
- // We respond immediately if we know for sure, that we are
- // the only one who can respond to the query.
- // In all other cases, we respond within 20-120 ms.
- //
- // According to draft-cheshire-dnsext-multicastdns.txt
- // chapter "7.2 Multi-Packet Known Answer Suppression":
- // We respond after 20-120 ms if the query is truncated.
-
- boolean iAmTheOnlyOne = true;
- for (Iterator i = in.questions.iterator(); i.hasNext(); ) {
- DNSEntry entry = (DNSEntry) i.next();
- if (entry instanceof DNSQuestion) {
- DNSQuestion q = (DNSQuestion) entry;
- logger.finest("start() question=" + q);
- iAmTheOnlyOne &= (q.type == DNSConstants.TYPE_SRV
- || q.type == DNSConstants.TYPE_TXT
- || q.type == DNSConstants.TYPE_A
- || q.type == DNSConstants.TYPE_AAAA
- || localHost.getName().equalsIgnoreCase(q.name)
- || services.containsKey(q.name.toLowerCase()));
- if (!iAmTheOnlyOne) {
- break;
- }
- }
- }
- int delay = (iAmTheOnlyOne && !in.isTruncated()) ? 0 : DNSConstants.RESPONSE_MIN_WAIT_INTERVAL + random.nextInt(DNSConstants.RESPONSE_MAX_WAIT_INTERVAL - DNSConstants.RESPONSE_MIN_WAIT_INTERVAL + 1) - in.elapseSinceArrival();
- if (delay < 0) {
- delay = 0;
- }
- logger.finest("start() Responder chosen delay=" + delay);
- timer.schedule(this, delay);
- }
-
- public void run() {
- synchronized (ioLock) {
- if (plannedAnswer == in) {
- plannedAnswer = null;
- }
-
- // We use these sets to prevent duplicate records
- // FIXME - This should be moved into DNSOutgoing
- HashSet questions = new HashSet();
- HashSet answers = new HashSet();
-
-
- if (state == DNSState.ANNOUNCED) {
- try {
- long now = System.currentTimeMillis();
- long expirationTime = now + 1; //=now+DNSConstants.KNOWN_ANSWER_TTL;
- boolean isUnicast = (port != DNSConstants.MDNS_PORT);
-
-
- // Answer questions
- for (Iterator iterator = in.questions.iterator(); iterator.hasNext(); ) {
- DNSEntry entry = (DNSEntry) iterator.next();
- if (entry instanceof DNSQuestion) {
- DNSQuestion q = (DNSQuestion) entry;
-
- // for unicast responses the question must be included
- if (isUnicast) {
- //out.addQuestion(q);
- questions.add(q);
- }
-
- int type = q.type;
- if (type == DNSConstants.TYPE_ANY || type == DNSConstants.TYPE_SRV) { // I ama not sure of why there is a special case here [PJYF Oct 15 2004]
- if (localHost.getName().equalsIgnoreCase(q.getName())) {
- // type = DNSConstants.TYPE_A;
- DNSRecord answer = localHost.getDNS4AddressRecord();
- if (answer != null) {
- answers.add(answer);
- }
- answer = localHost.getDNS6AddressRecord();
- if (answer != null) {
- answers.add(answer);
- }
- type = DNSConstants.TYPE_IGNORE;
- } else {
- if (serviceTypes.containsKey(q.getName().toLowerCase())) {
- type = DNSConstants.TYPE_PTR;
- }
- }
- }
-
- switch (type) {
- case DNSConstants.TYPE_A: {
- // Answer a query for a domain name
- //out = addAnswer( in, addr, port, out, host );
- DNSRecord answer = localHost.getDNS4AddressRecord();
- if (answer != null) {
- answers.add(answer);
- }
- break;
- }
- case DNSConstants.TYPE_AAAA: {
- // Answer a query for a domain name
- DNSRecord answer = localHost.getDNS6AddressRecord();
- if (answer != null) {
- answers.add(answer);
- }
- break;
- }
- case DNSConstants.TYPE_PTR: {
- // Answer a query for services of a given type
-
- // find matching services
- for (Iterator serviceIterator = services.values().iterator(); serviceIterator.hasNext(); ) {
- ServiceInfo info = (ServiceInfo) serviceIterator.next();
- if (info.getState() == DNSState.ANNOUNCED) {
- if (q.name.equalsIgnoreCase(info.type)) {
- DNSRecord answer = localHost.getDNS4AddressRecord();
- if (answer != null) {
- answers.add(answer);
- }
- answer = localHost.getDNS6AddressRecord();
- if (answer != null) {
- answers.add(answer);
- }
- answers.add(new DNSRecord.Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.getQualifiedName()));
- answers.add(new DNSRecord.Service(info.getQualifiedName(), DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, localHost.getName()));
- answers.add(new DNSRecord.Text(info.getQualifiedName(), DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.text));
- }
- }
- }
- if (q.name.equalsIgnoreCase("_services._mdns._udp.local.")) {
- for (Iterator serviceTypeIterator = serviceTypes.values().iterator(); serviceTypeIterator.hasNext(); ) {
- answers.add(new DNSRecord.Pointer("_services._mdns._udp.local.", DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, (String) serviceTypeIterator.next()));
- }
- }
- break;
- }
- case DNSConstants.TYPE_SRV:
- case DNSConstants.TYPE_ANY:
- case DNSConstants.TYPE_TXT: {
- ServiceInfo info = (ServiceInfo) services.get(q.name.toLowerCase());
- if (info != null && info.getState() == DNSState.ANNOUNCED) {
- DNSRecord answer = localHost.getDNS4AddressRecord();
- if (answer != null) {
- answers.add(answer);
- }
- answer = localHost.getDNS6AddressRecord();
- if (answer != null) {
- answers.add(answer);
- }
- answers.add(new DNSRecord.Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.getQualifiedName()));
- answers.add(new DNSRecord.Service(info.getQualifiedName(), DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, localHost.getName()));
- answers.add(new DNSRecord.Text(info.getQualifiedName(), DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.text));
- }
- break;
- }
- default: {
- //System.out.println("JmDNSResponder.unhandled query:"+q);
- break;
- }
- }
- }
- }
-
-
- // remove known answers, if the ttl is at least half of
- // the correct value. (See Draft Cheshire chapter 7.1.).
- for (Iterator i = in.answers.iterator(); i.hasNext(); ) {
- DNSRecord knownAnswer = (DNSRecord) i.next();
- if (knownAnswer.ttl > DNSConstants.DNS_TTL / 2 && answers.remove(knownAnswer)) {
- logger.log(Level.FINER, "JmDNS Responder Known Answer Removed");
- }
- }
-
-
- // responde if we have answers
- if (answers.size() != 0) {
- logger.finer("run() JmDNS responding");
- DNSOutgoing out = null;
- if (isUnicast) {
- out = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA, false);
- }
-
- for (Iterator i = questions.iterator(); i.hasNext(); ) {
- out.addQuestion((DNSQuestion) i.next());
- }
- for (Iterator i = answers.iterator(); i.hasNext(); ) {
- out = addAnswer(in, addr, port, out, (DNSRecord) i.next());
- }
- send(out);
- }
- cancel();
- } catch (Throwable e) {
- logger.log(Level.WARNING, "run() exception ", e);
- close();
- }
- }
- }
- }
- }
-
- /**
- * Helper class to resolve service types.
- *
- * The TypeResolver queries three times consecutively for service types, and then
- * removes itself from the timer.
- *
- * The TypeResolver will run only if JmDNS is in state ANNOUNCED.
- */
- private class TypeResolver extends TimerTask {
- public void start() {
- timer.schedule(this, DNSConstants.QUERY_WAIT_INTERVAL, DNSConstants.QUERY_WAIT_INTERVAL);
- }
-
- /**
- * Counts the number of queries that were sent.
- */
- int count = 0;
-
- public void run() {
- try {
- if (state == DNSState.ANNOUNCED) {
- if (++count < 3) {
- logger.finer("run() JmDNS querying type");
- DNSOutgoing out = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY);
- out.addQuestion(new DNSQuestion("_services._mdns._udp.local.", DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN));
- for (Iterator iterator = serviceTypes.values().iterator(); iterator.hasNext(); ) {
- out.addAnswer(new DNSRecord.Pointer("_services._mdns._udp.local.", DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, (String) iterator.next()), 0);
- }
- send(out);
- } else {
- // After three queries, we can quit.
- cancel();
- }
- ;
- } else {
- if (state == DNSState.CANCELED) {
- cancel();
- }
- }
- } catch (Throwable e) {
- logger.log(Level.WARNING, "run() exception ", e);
- recover();
- }
- }
- }
-
- /**
- * The ServiceResolver queries three times consecutively for services of
- * a given type, and then removes itself from the timer.
- *
- * The ServiceResolver will run only if JmDNS is in state ANNOUNCED.
- * REMIND: Prevent having multiple service resolvers for the same type in the
- * timer queue.
- */
- private class ServiceResolver extends TimerTask {
- /**
- * Counts the number of queries being sent.
- */
- int count = 0;
- private String type;
-
- public ServiceResolver(String type) {
- this.type = type;
- }
-
- public void start() {
- timer.schedule(this, DNSConstants.QUERY_WAIT_INTERVAL, DNSConstants.QUERY_WAIT_INTERVAL);
- }
-
- public void run() {
- try {
- if (state == DNSState.ANNOUNCED) {
- if (count++ < 3) {
- logger.finer("run() JmDNS querying service");
- long now = System.currentTimeMillis();
- DNSOutgoing out = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY);
- out.addQuestion(new DNSQuestion(type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN));
- for (Iterator s = services.values().iterator(); s.hasNext(); ) {
- final ServiceInfo info = (ServiceInfo) s.next();
- try {
- out.addAnswer(new DNSRecord.Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.getQualifiedName()), now);
- } catch (IOException ee) {
- break;
- }
- }
- send(out);
- } else {
- // After three queries, we can quit.
- cancel();
- }
- ;
- } else {
- if (state == DNSState.CANCELED) {
- cancel();
- }
- }
- } catch (Throwable e) {
- logger.log(Level.WARNING, "run() exception ", e);
- recover();
- }
- }
- }
-
- /**
- * The ServiceInfoResolver queries up to three times consecutively for
- * a service info, and then removes itself from the timer.
- *
- * The ServiceInfoResolver will run only if JmDNS is in state ANNOUNCED.
- * REMIND: Prevent having multiple service resolvers for the same info in the
- * timer queue.
- */
- private class ServiceInfoResolver extends TimerTask {
- /**
- * Counts the number of queries being sent.
- */
- int count = 0;
- private ServiceInfo info;
-
- public ServiceInfoResolver(ServiceInfo info) {
- this.info = info;
- info.dns = JmDNS.this;
- addListener(info, new DNSQuestion(info.getQualifiedName(), DNSConstants.TYPE_ANY, DNSConstants.CLASS_IN));
- }
-
- public void start() {
- timer.schedule(this, DNSConstants.QUERY_WAIT_INTERVAL, DNSConstants.QUERY_WAIT_INTERVAL);
- }
-
- public void run() {
- try {
- if (state == DNSState.ANNOUNCED) {
- if (count++ < 3 && !info.hasData()) {
- long now = System.currentTimeMillis();
- DNSOutgoing out = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY);
- out.addQuestion(new DNSQuestion(info.getQualifiedName(), DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN));
- out.addQuestion(new DNSQuestion(info.getQualifiedName(), DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN));
- if (info.server != null) {
- out.addQuestion(new DNSQuestion(info.server, DNSConstants.TYPE_A, DNSConstants.CLASS_IN));
- }
- out.addAnswer((DNSRecord) cache.get(info.getQualifiedName(), DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN), now);
- out.addAnswer((DNSRecord) cache.get(info.getQualifiedName(), DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN), now);
- if (info.server != null) {
- out.addAnswer((DNSRecord) cache.get(info.server, DNSConstants.TYPE_A, DNSConstants.CLASS_IN), now);
- }
- send(out);
- } else {
- // After three queries, we can quit.
- cancel();
- removeListener(info);
- }
- ;
- } else {
- if (state == DNSState.CANCELED) {
- cancel();
- removeListener(info);
- }
- }
- } catch (Throwable e) {
- logger.log(Level.WARNING, "run() exception ", e);
- recover();
- }
- }
- }
-
- /**
- * The Canceler sends two announces with TTL=0 for the specified services.
- */
- private class Canceler extends TimerTask {
- /**
- * Counts the number of announces being sent.
- */
- int count = 0;
- /**
- * The services that need cancelling.
- * Note: We have to use a local variable here, because the services
- * that are canceled, are removed immediately from variable JmDNS.services.
- */
- private ServiceInfo[] infos;
- /**
- * We call notifyAll() on the lock object, when we have canceled the
- * service infos.
- * This is used by method JmDNS.unregisterService() and
- * JmDNS.unregisterAllServices, to ensure that the JmDNS
- * socket stays open until the Canceler has canceled all services.
- *
- * Note: We need this lock, because ServiceInfos do the transition from
- * state ANNOUNCED to state CANCELED before we get here. We could get
- * rid of this lock, if we added a state named CANCELLING to DNSState.
- */
- private Object lock;
- int ttl = 0;
-
- public Canceler(ServiceInfo info, Object lock) {
- this.infos = new ServiceInfo[]{info};
- this.lock = lock;
- addListener(info, new DNSQuestion(info.getQualifiedName(), DNSConstants.TYPE_ANY, DNSConstants.CLASS_IN));
- }
-
- public Canceler(ServiceInfo[] infos, Object lock) {
- this.infos = infos;
- this.lock = lock;
- }
-
- public Canceler(Collection infos, Object lock) {
- this.infos = (ServiceInfo[]) infos.toArray(new ServiceInfo[infos.size()]);
- this.lock = lock;
- }
-
- public void start() {
- timer.schedule(this, 0, DNSConstants.ANNOUNCE_WAIT_INTERVAL);
- }
-
- public void run() {
- try {
- if (++count < 3) {
- logger.finer("run() JmDNS canceling service");
- // announce the service
- //long now = System.currentTimeMillis();
- DNSOutgoing out = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA);
- for (int i = 0; i < infos.length; i++) {
- ServiceInfo info = infos[i];
- out.addAnswer(new DNSRecord.Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, ttl, info.getQualifiedName()), 0);
- out.addAnswer(new DNSRecord.Service(info.getQualifiedName(), DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN, ttl, info.priority, info.weight, info.port, localHost.getName()), 0);
- out.addAnswer(new DNSRecord.Text(info.getQualifiedName(), DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN, ttl, info.text), 0);
- DNSRecord answer = localHost.getDNS4AddressRecord();
- if (answer != null) {
- out.addAnswer(answer, 0);
- }
- answer = localHost.getDNS6AddressRecord();
- if (answer != null) {
- out.addAnswer(answer, 0);
- }
- }
- send(out);
- } else {
- // After three successful announcements, we are finished.
- synchronized (lock) {
- closed = true;
- lock.notifyAll();
- }
- cancel();
- }
- } catch (Throwable e) {
- logger.log(Level.WARNING, "run() exception ", e);
- recover();
- }
- }
- }
-
- // REMIND: Why is this not an anonymous inner class?
-
- /**
- * Shutdown operations.
- */
- private class Shutdown implements Runnable {
- public void run() {
- shutdown = null;
- close();
- }
- }
-
- /**
- * Recover jmdns when there is an error.
- */
- protected void recover() {
- logger.finer("recover()");
- // We have an IO error so lets try to recover if anything happens lets close it.
- // This should cover the case of the IP address changing under our feet
- if (DNSState.CANCELED != state) {
- synchronized (this) { // Synchronize only if we are not already in process to prevent dead locks
- //
- logger.finer("recover() Cleanning up");
- // Stop JmDNS
- state = DNSState.CANCELED; // This protects against recursive calls
-
- // We need to keep a copy for reregistration
- Collection oldServiceInfos = new ArrayList(services.values());
-
- // Cancel all services
- unregisterAllServices();
- disposeServiceCollectors();
- //
- // close multicast socket
- closeMulticastSocket();
- //
- cache.clear();
- logger.finer("recover() All is clean");
- //
- // All is clear now start the services
- //
- try {
- openMulticastSocket(localHost);
- start(oldServiceInfos);
- } catch (Exception exception) {
- logger.log(Level.WARNING, "recover() Start services exception ", exception);
- }
- logger.log(Level.WARNING, "recover() We are back!");
- }
- }
- }
-
- /**
- * Close down jmdns. Release all resources and unregister all services.
- */
- public void close() {
- if (state != DNSState.CANCELED) {
- synchronized (this) { // Synchronize only if we are not already in process to prevent dead locks
- // Stop JmDNS
- state = DNSState.CANCELED; // This protects against recursive calls
-
- unregisterAllServices();
- disposeServiceCollectors();
-
- // close socket
- closeMulticastSocket();
-
- // Stop the timer
- timer.cancel();
-
- // remove the shutdown hook
- if (shutdown != null) {
- Runtime.getRuntime().removeShutdownHook(shutdown);
- }
-
- }
- }
- }
-
- /**
- * List cache entries, for debugging only.
- */
- void print() {
- System.out.println("---- cache ----");
- cache.print();
- System.out.println();
- }
-
- /**
- * List Services and serviceTypes.
- * Debugging Only
- */
-
- public void printServices() {
- System.err.println(toString());
- }
-
- public String toString() {
- StringBuffer aLog = new StringBuffer();
- aLog.append("\t---- Services -----");
- if (services != null) {
- for (Iterator k = services.keySet().iterator(); k.hasNext(); ) {
- Object key = k.next();
- aLog.append("\n\t\tService: " + key + ": " + services.get(key));
- }
- }
- aLog.append("\n");
- aLog.append("\t---- Types ----");
- if (serviceTypes != null) {
- for (Iterator k = serviceTypes.keySet().iterator(); k.hasNext(); ) {
- Object key = k.next();
- aLog.append("\n\t\tType: " + key + ": " + serviceTypes.get(key));
- }
- }
- aLog.append("\n");
- aLog.append(cache.toString());
- aLog.append("\n");
- aLog.append("\t---- Service Collectors ----");
- if (serviceCollectors != null) {
- synchronized (serviceCollectors) {
- for (Iterator k = serviceCollectors.keySet().iterator(); k.hasNext(); ) {
- Object key = k.next();
- aLog.append("\n\t\tService Collector: " + key + ": " + serviceCollectors.get(key));
- }
- serviceCollectors.clear();
- }
- }
- return aLog.toString();
- }
-
- /**
- * Returns a list of service infos of the specified type.
- *
- * @param type Service type name, such as _http._tcp.local.
.
- * @return An array of service instance names.
- */
- public ServiceInfo[] list(String type) {
- // Implementation note: The first time a list for a given type is
- // requested, a ServiceCollector is created which collects service
- // infos. This greatly speeds up the performance of subsequent calls
- // to this method. The caveats are, that 1) the first call to this method
- // for a given type is slow, and 2) we spawn a ServiceCollector
- // instance for each service type which increases network traffic a
- // little.
-
- ServiceCollector collector;
-
- boolean newCollectorCreated;
- synchronized (serviceCollectors) {
- collector = (ServiceCollector) serviceCollectors.get(type);
- if (collector == null) {
- collector = new ServiceCollector(type);
- serviceCollectors.put(type, collector);
- addServiceListener(type, collector);
- newCollectorCreated = true;
- } else {
- newCollectorCreated = false;
- }
- }
-
- // After creating a new ServiceCollector, we collect service infos for
- // 200 milliseconds. This should be enough time, to get some service
- // infos from the network.
- if (newCollectorCreated) {
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- }
- }
-
- return collector.list();
- }
-
- /**
- * This method disposes all ServiceCollector instances which have been
- * created by calls to method list(type)
.
- *
- * @see #list
- */
- private void disposeServiceCollectors() {
- logger.finer("disposeServiceCollectors()");
- synchronized (serviceCollectors) {
- for (Iterator i = serviceCollectors.values().iterator(); i.hasNext(); ) {
- ServiceCollector collector = (ServiceCollector) i.next();
- removeServiceListener(collector.type, collector);
- }
- serviceCollectors.clear();
- }
- }
-
- /**
- * Instances of ServiceCollector are used internally to speed up the
- * performance of method list(type)
.
- *
- * @see #list
- */
- private static class ServiceCollector implements ServiceListener {
- private static Logger logger = Logger.getLogger(ServiceCollector.class.toString());
- /**
- * A set of collected service instance names.
- */
- private Map infos = Collections.synchronizedMap(new HashMap());
-
- public String type;
-
- public ServiceCollector(String type) {
- this.type = type;
- }
-
- /**
- * A service has been added.
- */
- public void serviceAdded(ServiceEvent event) {
- synchronized (infos) {
- event.getDNS().requestServiceInfo(event.getType(), event.getName(), 0);
- }
- }
-
- /**
- * A service has been removed.
- */
- public void serviceRemoved(ServiceEvent event) {
- synchronized (infos) {
- infos.remove(event.getName());
- }
- }
-
- /**
- * A service hase been resolved. Its details are now available in the
- * ServiceInfo record.
- */
- public void serviceResolved(ServiceEvent event) {
- synchronized (infos) {
- infos.put(event.getName(), event.getInfo());
- }
- }
-
- /**
- * Returns an array of all service infos which have been collected by this
- * ServiceCollector.
- */
- public ServiceInfo[] list() {
- synchronized (infos) {
- return (ServiceInfo[]) infos.values().toArray(new ServiceInfo[infos.size()]);
- }
- }
-
- public String toString() {
- StringBuffer aLog = new StringBuffer();
- synchronized (infos) {
- for (Iterator k = infos.keySet().iterator(); k.hasNext(); ) {
- Object key = k.next();
- aLog.append("\n\t\tService: " + key + ": " + infos.get(key));
- }
- }
- return aLog.toString();
- }
- }
-
- ;
-
- private static String toUnqualifiedName(String type, String qualifiedName) {
- if (qualifiedName.endsWith(type)) {
- return qualifiedName.substring(0, qualifiedName.length() - type.length() - 1);
- } else {
- return qualifiedName;
- }
- }
-}
-
diff --git a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/ServiceEvent.java b/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/ServiceEvent.java
deleted file mode 100644
index a6df607230..0000000000
--- a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/ServiceEvent.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * Copyright 2003-2005 Arthur van Hoff, Rick Blair
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.jmdns;
-
-import java.util.EventObject;
-import java.util.logging.Logger;
-
-/**
- * ServiceEvent.
- *
- * @author Werner Randelshofer, Rick Blair
- * @version %I%, %G%
- */
-public class ServiceEvent extends EventObject
-{
- private static Logger logger = Logger.getLogger(ServiceEvent.class.toString());
- /**
- * The type name of the service.
- */
- private String type;
- /**
- * The instance name of the service. Or null, if the event was
- * fired to a service type listener.
- */
- private String name;
- /**
- * The service info record, or null if the service could be be resolved.
- * This is also null, if the event was fired to a service type listener.
- */
- private ServiceInfo info;
-
- /**
- * Creates a new instance.
- *
- * @param source the JmDNS instance which originated the event.
- * @param type the type name of the service.
- * @param name the instance name of the service.
- * @param info the service info record, or null if the service could be be resolved.
- */
- public ServiceEvent(JmDNS source, String type, String name, ServiceInfo info)
- {
- super(source);
- this.type = type;
- this.name = name;
- this.info = info;
- }
-
- /**
- * Returns the JmDNS instance which originated the event.
- */
- public JmDNS getDNS()
- {
- return (JmDNS) getSource();
- }
-
- /**
- * Returns the fully qualified type of the service.
- */
- public String getType()
- {
- return type;
- }
-
- /**
- * Returns the instance name of the service.
- * Always returns null, if the event is sent to a service type listener.
- */
- public String getName()
- {
- return name;
- }
-
- /**
- * Returns the service info record, or null if the service could not be
- * resolved.
- * Always returns null, if the event is sent to a service type listener.
- */
- public ServiceInfo getInfo()
- {
- return info;
- }
-
- public String toString()
- {
- StringBuffer buf = new StringBuffer();
- buf.append("<" + getClass().getName() + "> ");
- buf.append(super.toString());
- buf.append(" name ");
- buf.append(getName());
- buf.append(" type ");
- buf.append(getType());
- buf.append(" info ");
- buf.append(getInfo());
- return buf.toString();
- }
-
-}
diff --git a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/ServiceInfo.java b/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/ServiceInfo.java
deleted file mode 100644
index b91a9a2a36..0000000000
--- a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/ServiceInfo.java
+++ /dev/null
@@ -1,673 +0,0 @@
-/**
- * Copyright 2003-2005 Arthur van Hoff, Rick Blair
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.jmdns;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.TimerTask;
-import java.util.Vector;
-import java.util.logging.Logger;
-
-/**
- * JmDNS service information.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer
- */
-public class ServiceInfo implements DNSListener
-{
- private static Logger logger = Logger.getLogger(ServiceInfo.class.toString());
- public final static byte[] NO_VALUE = new byte[0];
- JmDNS dns;
-
- // State machine
- /**
- * The state of this service info.
- * This is used only for services announced by JmDNS.
- *
- * For proper handling of concurrency, this variable must be
- * changed only using methods advanceState(), revertState() and cancel().
- */
- private DNSState state = DNSState.PROBING_1;
-
- /**
- * Task associated to this service info.
- * Possible tasks are JmDNS.Prober, JmDNS.Announcer, JmDNS.Responder,
- * JmDNS.Canceler.
- */
- TimerTask task;
-
- String type;
- private String name;
- String server;
- int port;
- int weight;
- int priority;
- byte text[];
- Hashtable props;
- InetAddress addr;
-
-
- /**
- * Construct a service description for registrating with JmDNS.
- *
- * @param type fully qualified service type name, such as _http._tcp.local.
.
- * @param name unqualified service instance name, such as foobar
- * @param port the local port on which the service runs
- * @param text string describing the service
- */
- public ServiceInfo(String type, String name, int port, String text)
- {
- this(type, name, port, 0, 0, text);
- }
-
- /**
- * Construct a service description for registrating with JmDNS.
- *
- * @param type fully qualified service type name, such as _http._tcp.local.
.
- * @param name unqualified service instance name, such as foobar
- * @param port the local port on which the service runs
- * @param weight weight of the service
- * @param priority priority of the service
- * @param text string describing the service
- */
- public ServiceInfo(String type, String name, int port, int weight, int priority, String text)
- {
- this(type, name, port, weight, priority, (byte[]) null);
- try
- {
- ByteArrayOutputStream out = new ByteArrayOutputStream(text.length());
- writeUTF(out, text);
- this.text = out.toByteArray();
- }
- catch (IOException e)
- {
- throw new RuntimeException("unexpected exception: " + e);
- }
- }
-
- /**
- * Construct a service description for registrating with JmDNS. The properties hashtable must
- * map property names to either Strings or byte arrays describing the property values.
- *
- * @param type fully qualified service type name, such as _http._tcp.local.
.
- * @param name unqualified service instance name, such as foobar
- * @param port the local port on which the service runs
- * @param weight weight of the service
- * @param priority priority of the service
- * @param props properties describing the service
- */
- public ServiceInfo(String type, String name, int port, int weight, int priority, Hashtable props)
- {
- this(type, name, port, weight, priority, new byte[0]);
- if (props != null)
- {
- try
- {
- ByteArrayOutputStream out = new ByteArrayOutputStream(256);
- for (Enumeration e = props.keys(); e.hasMoreElements();)
- {
- String key = (String) e.nextElement();
- Object val = props.get(key);
- ByteArrayOutputStream out2 = new ByteArrayOutputStream(100);
- writeUTF(out2, key);
- if (val instanceof String)
- {
- out2.write('=');
- writeUTF(out2, (String) val);
- }
- else
- {
- if (val instanceof byte[])
- {
- out2.write('=');
- byte[] bval = (byte[]) val;
- out2.write(bval, 0, bval.length);
- }
- else
- {
- if (val != NO_VALUE)
- {
- throw new IllegalArgumentException("invalid property value: " + val);
- }
- }
- }
- byte data[] = out2.toByteArray();
- out.write(data.length);
- out.write(data, 0, data.length);
- }
- this.text = out.toByteArray();
- }
- catch (IOException e)
- {
- throw new RuntimeException("unexpected exception: " + e);
- }
- }
- }
-
- /**
- * Construct a service description for registrating with JmDNS.
- *
- * @param type fully qualified service type name, such as _http._tcp.local.
.
- * @param name unqualified service instance name, such as foobar
- * @param port the local port on which the service runs
- * @param weight weight of the service
- * @param priority priority of the service
- * @param text bytes describing the service
- */
- public ServiceInfo(String type, String name, int port, int weight, int priority, byte text[])
- {
- this.type = type;
- this.name = name;
- this.port = port;
- this.weight = weight;
- this.priority = priority;
- this.text = text;
- }
-
- /**
- * Construct a service record during service discovery.
- */
- ServiceInfo(String type, String name)
- {
- if (!type.endsWith("."))
- {
- throw new IllegalArgumentException("type must be fully qualified DNS name ending in '.': " + type);
- }
-
- this.type = type;
- this.name = name;
- }
-
- /**
- * During recovery we need to duplicate service info to reregister them
- */
- ServiceInfo(ServiceInfo info)
- {
- if (info != null)
- {
- this.type = info.type;
- this.name = info.name;
- this.port = info.port;
- this.weight = info.weight;
- this.priority = info.priority;
- this.text = info.text;
- }
- }
-
- /**
- * Fully qualified service type name, such as _http._tcp.local.
.
- */
- public String getType()
- {
- return type;
- }
-
- /**
- * Unqualified service instance name, such as foobar
.
- */
- public String getName()
- {
- return name;
- }
-
- /**
- * Sets the service instance name.
- *
- * @param name unqualified service instance name, such as foobar
- */
- void setName(String name)
- {
- this.name = name;
- }
-
- /**
- * Fully qualified service name, such as foobar._http._tcp.local.
.
- */
- public String getQualifiedName()
- {
- return name + "." + type;
- }
-
- /**
- * Get the name of the server.
- */
- public String getServer()
- {
- return server;
- }
-
- /**
- * Get the host address of the service (ie X.X.X.X).
- */
- public String getHostAddress()
- {
- return (addr != null ? addr.getHostAddress() : "");
- }
-
- public InetAddress getAddress()
- {
- return addr;
- }
-
- /**
- * Get the InetAddress of the service.
- */
- public InetAddress getInetAddress()
- {
- return addr;
- }
-
- /**
- * Get the port for the service.
- */
- public int getPort()
- {
- return port;
- }
-
- /**
- * Get the priority of the service.
- */
- public int getPriority()
- {
- return priority;
- }
-
- /**
- * Get the weight of the service.
- */
- public int getWeight()
- {
- return weight;
- }
-
- /**
- * Get the text for the serivce as raw bytes.
- */
- public byte[] getTextBytes()
- {
- return text;
- }
-
- /**
- * Get the text for the service. This will interpret the text bytes
- * as a UTF8 encoded string. Will return null if the bytes are not
- * a valid UTF8 encoded string.
- */
- public String getTextString()
- {
- if ((text == null) || (text.length == 0) || ((text.length == 1) && (text[0] == 0)))
- {
- return null;
- }
- return readUTF(text, 0, text.length);
- }
-
- /**
- * Get the URL for this service. An http URL is created by
- * combining the address, port, and path properties.
- */
- public String getURL()
- {
- return getURL("http");
- }
-
- /**
- * Get the URL for this service. An URL is created by
- * combining the protocol, address, port, and path properties.
- */
- public String getURL(String protocol)
- {
- String url = protocol + "://" + getAddress() + ":" + getPort();
- String path = getPropertyString("path");
- if (path != null)
- {
- if (path.indexOf("://") >= 0)
- {
- url = path;
- }
- else
- {
- url += path.startsWith("/") ? path : "/" + path;
- }
- }
- return url;
- }
-
- /**
- * Get a property of the service. This involves decoding the
- * text bytes into a property list. Returns null if the property
- * is not found or the text data could not be decoded correctly.
- */
- public synchronized byte[] getPropertyBytes(String name)
- {
- return (byte[]) getProperties().get(name);
- }
-
- /**
- * Get a property of the service. This involves decoding the
- * text bytes into a property list. Returns null if the property
- * is not found, the text data could not be decoded correctly, or
- * the resulting bytes are not a valid UTF8 string.
- */
- public synchronized String getPropertyString(String name)
- {
- byte data[] = (byte[]) getProperties().get(name);
- if (data == null)
- {
- return null;
- }
- if (data == NO_VALUE)
- {
- return "true";
- }
- return readUTF(data, 0, data.length);
- }
-
- /**
- * Enumeration of the property names.
- */
- public Enumeration getPropertyNames()
- {
- Hashtable props = getProperties();
- return (props != null) ? props.keys() : new Vector().elements();
- }
-
- /**
- * Write a UTF string with a length to a stream.
- */
- void writeUTF(OutputStream out, String str) throws IOException
- {
- for (int i = 0, len = str.length(); i < len; i++)
- {
- int c = str.charAt(i);
- if ((c >= 0x0001) && (c <= 0x007F))
- {
- out.write(c);
- }
- else
- {
- if (c > 0x07FF)
- {
- out.write(0xE0 | ((c >> 12) & 0x0F));
- out.write(0x80 | ((c >> 6) & 0x3F));
- out.write(0x80 | ((c >> 0) & 0x3F));
- }
- else
- {
- out.write(0xC0 | ((c >> 6) & 0x1F));
- out.write(0x80 | ((c >> 0) & 0x3F));
- }
- }
- }
- }
-
- /**
- * Read data bytes as a UTF stream.
- */
- String readUTF(byte data[], int off, int len)
- {
- StringBuffer buf = new StringBuffer();
- for (int end = off + len; off < end;)
- {
- int ch = data[off++] & 0xFF;
- 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:
- if (off >= len)
- {
- return null;
- }
- // 110x xxxx 10xx xxxx
- ch = ((ch & 0x1F) << 6) | (data[off++] & 0x3F);
- break;
- case 14:
- if (off + 2 >= len)
- {
- return null;
- }
- // 1110 xxxx 10xx xxxx 10xx xxxx
- ch = ((ch & 0x0f) << 12) | ((data[off++] & 0x3F) << 6) | (data[off++] & 0x3F);
- break;
- default:
- if (off + 1 >= len)
- {
- return null;
- }
- // 10xx xxxx, 1111 xxxx
- ch = ((ch & 0x3F) << 4) | (data[off++] & 0x0f);
- break;
- }
- buf.append((char) ch);
- }
- return buf.toString();
- }
-
- synchronized Hashtable getProperties()
- {
- if ((props == null) && (text != null))
- {
- Hashtable props = new Hashtable();
- int off = 0;
- while (off < text.length)
- {
- // length of the next key value pair
- int len = text[off++] & 0xFF;
- if ((len == 0) || (off + len > text.length))
- {
- props.clear();
- break;
- }
- // look for the '='
- int i = 0;
- for (; (i < len) && (text[off + i] != '='); i++)
- {
- ;
- }
-
- // get the property name
- String name = readUTF(text, off, i);
- if (name == null)
- {
- props.clear();
- break;
- }
- if (i == len)
- {
- props.put(name, NO_VALUE);
- }
- else
- {
- byte value[] = new byte[len - ++i];
- System.arraycopy(text, off + i, value, 0, len - i);
- props.put(name, value);
- off += len;
- }
- }
- this.props = props;
- }
- return props;
- }
-
- // REMIND: Oops, this shouldn't be public!
- /**
- * JmDNS callback to update a DNS record.
- */
- public void updateRecord(JmDNS jmdns, long now, DNSRecord rec)
- {
- if ((rec != null) && !rec.isExpired(now))
- {
- switch (rec.type)
- {
- case DNSConstants.TYPE_A: // IPv4
- case DNSConstants.TYPE_AAAA: // IPv6 FIXME [PJYF Oct 14 2004] This has not been tested
- if (rec.name.equals(server))
- {
- addr = ((DNSRecord.Address) rec).getAddress();
-
- }
- break;
- case DNSConstants.TYPE_SRV:
- if (rec.name.equals(getQualifiedName()))
- {
- DNSRecord.Service srv = (DNSRecord.Service) rec;
- server = srv.server;
- port = srv.port;
- weight = srv.weight;
- priority = srv.priority;
- addr = null;
- // changed to use getCache() instead - jeffs
- // updateRecord(jmdns, now, (DNSRecord)jmdns.cache.get(server, TYPE_A, CLASS_IN));
- updateRecord(jmdns, now, (DNSRecord) jmdns.getCache().get(server, DNSConstants.TYPE_A, DNSConstants.CLASS_IN));
- }
- break;
- case DNSConstants.TYPE_TXT:
- if (rec.name.equals(getQualifiedName()))
- {
- DNSRecord.Text txt = (DNSRecord.Text) rec;
- text = txt.text;
- }
- break;
- }
- // Future Design Pattern
- // This is done, to notify the wait loop in method
- // JmDNS.getServiceInfo(type, name, timeout);
- if (hasData() && dns != null)
- {
- dns.handleServiceResolved(this);
- dns = null;
- }
- synchronized (this)
- {
- notifyAll();
- }
- }
- }
-
- /**
- * Returns true if the service info is filled with data.
- */
- boolean hasData()
- {
- return server != null && addr != null && text != null;
- }
-
-
- // State machine
- /**
- * Sets the state and notifies all objects that wait on the ServiceInfo.
- */
- synchronized void advanceState()
- {
- state = state.advance();
- notifyAll();
- }
-
- /**
- * Sets the state and notifies all objects that wait on the ServiceInfo.
- */
- synchronized void revertState()
- {
- state = state.revert();
- notifyAll();
- }
-
- /**
- * Sets the state and notifies all objects that wait on the ServiceInfo.
- */
- synchronized void cancel()
- {
- state = DNSState.CANCELED;
- notifyAll();
- }
-
- /**
- * Returns the current state of this info.
- */
- DNSState getState()
- {
- return state;
- }
-
-
- public int hashCode()
- {
- return getQualifiedName().hashCode();
- }
-
- public boolean equals(Object obj)
- {
- return (obj instanceof ServiceInfo) && getQualifiedName().equals(((ServiceInfo) obj).getQualifiedName());
- }
-
- public String getNiceTextString()
- {
- StringBuffer buf = new StringBuffer();
- for (int i = 0, len = text.length; i < len; i++)
- {
- if (i >= 20)
- {
- buf.append("...");
- break;
- }
- int ch = text[i] & 0xFF;
- if ((ch < ' ') || (ch > 127))
- {
- buf.append("\\0");
- buf.append(Integer.toString(ch, 8));
- }
- else
- {
- buf.append((char) ch);
- }
- }
- return buf.toString();
- }
-
- public String toString()
- {
- StringBuffer buf = new StringBuffer();
- buf.append("service[");
- buf.append(getQualifiedName());
- buf.append(',');
- buf.append(getAddress());
- buf.append(':');
- buf.append(port);
- buf.append(',');
- buf.append(getNiceTextString());
- buf.append(']');
- return buf.toString();
- }
-}
diff --git a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/ServiceListener.java b/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/ServiceListener.java
deleted file mode 100644
index 0c529771d2..0000000000
--- a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/ServiceListener.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Copyright 2003-2005 Arthur van Hoff, Rick Blair
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.jmdns;
-
-import java.util.EventListener;
-
-/**
- * Listener for service updates.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Werner Randelshofer
- */
-public interface ServiceListener extends EventListener
-{
- /**
- * A service has been added.
- *
- * @param event The ServiceEvent providing the name and fully qualified type
- * of the service.
- */
- void serviceAdded(ServiceEvent event);
-
- /**
- * A service has been removed.
- *
- * @param event The ServiceEvent providing the name and fully qualified type
- * of the service.
- */
- void serviceRemoved(ServiceEvent event);
-
- /**
- * A service has been resolved. Its details are now available in the
- * ServiceInfo record.
- *
- * @param event The ServiceEvent providing the name, the fully qualified
- * type of the service, and the service info record, or null if the service
- * could not be resolved.
- */
- void serviceResolved(ServiceEvent event);
-}
diff --git a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/ServiceTypeListener.java b/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/ServiceTypeListener.java
deleted file mode 100644
index 2987abafcc..0000000000
--- a/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/ServiceTypeListener.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * Copyright 2003-2005 Arthur van Hoff, Rick Blair
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.jmdns;
-
-import java.util.EventListener;
-
-/**
- * Listener for service types.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff, Werner Randelshofer
- */
-public interface ServiceTypeListener extends EventListener
-{
- /**
- * A new service type was discovered.
- *
- * @param event The service event providing the fully qualified type of
- * the service.
- */
- void serviceTypeAdded(ServiceEvent event);
-}
diff --git a/activemq-jmdns_1.0/src/main/resources/META-INF/NOTICE b/activemq-jmdns_1.0/src/main/resources/META-INF/NOTICE
deleted file mode 100644
index 1495155864..0000000000
--- a/activemq-jmdns_1.0/src/main/resources/META-INF/NOTICE
+++ /dev/null
@@ -1,17 +0,0 @@
-===============================================================
-== NOTICE File for JmDNS ==
-===============================================================
-
-Java Multicast Domain Name Server (JmDNS)
-
-This project was originally developed by Arthur van Hoff under the GNU
-Lesser General Public License as jRendevous. It was moved to Sourceforge
-by Rick Blair and renamed to JmDNS with the Arthur's kind permission.
-
-Currently it has been re-released under the Apache License, Version 2.0.
-
-Details of the Apache License, Version 2.0 can be found at:
-http://www.apache.org/licenses/
-
-
-For other details please see the README.txt file.
diff --git a/activemq-jmdns_1.0/src/main/resources/META-INF/README.txt b/activemq-jmdns_1.0/src/main/resources/META-INF/README.txt
deleted file mode 100644
index e54a65e5a9..0000000000
--- a/activemq-jmdns_1.0/src/main/resources/META-INF/README.txt
+++ /dev/null
@@ -1,117 +0,0 @@
-// %Z%%M%, %I%, %G%
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
-//This library is now licensed under the Apache License Version 2.0 Please
-//see the file NOTICE.
-
-
-Arthur van Hoff
-avh@strangeberry.com
-
-Rick Blair
-rickblair@mac.com
-
-** JmDNS
-
-This is an implemenation of multi-cast DNS in Java. It currently
-supports service discovery and service registration. It is fully
-interoperable with Apple's Rendezvous.
-
-
-
-** Requirements
-
-jmdns has been tested using the JDK 1.3.1 and JDK 1.4.0
-on the following platforms:
-
-Windows 9x, XP, 2000
-Linux RedHat 7.3-9.0, Mandrake
-Mac OSX
-
-
-
-** Running jmdns from the Command Line
-
-GUI browser:
-
- java -jar lib/jmdns.jar -browse
-
-TTY browser for a particular service type:
-
- java -jar lib/jmdns.jar -bs _http._tcp local.
-
-Register a service:
-
- java -jar lib/jmdns.jar -rs foobar _http._tcp local. 1234 path=index.html
-
-List service types:
-
- java -jar lib/jmdns.jar -bt
-
-To print debugging output specify -d as the first argument.
-
-
-
-** Sample Code for Service Registration
-
- import javax.jmdns.*;
-
- JmDNS jmdns = new JmDNS();
- jmdns.registerService(
- new ServiceInfo("_http._tcp.local.", "foo._http._tcp.local.", 1234, 0, 0, "path=index.html")
- );
-
-
-** Sample code for Serivice Discovery
-
- import javax.jmdns.*;
-
- static class SampleListener implements ServiceListener
- {
- public void addService(JmDNS jmdns, String type, String name)
- {
- System.out.println("ADD: " + jmdns.getServiceInfo(type, name));
- }
- public void removeService(JmDNS jmdns, String type, String name)
- {
- System.out.println("REMOVE: " + name);
- }
- public void resolveService(JmDNS jmdns, String type, String name, ServiceInfo info)
- {
- System.out.println("RESOLVED: " + info);
- }
- }
-
- JmDNS jmdns = new JmDNS();
- jmdns.addServiceListener("_http._tcp.local.", new SampleListener());
-
-
-** Changes since October 2003
-
-- Renamed package com.strangeberry.rendezvous to javax.jmdns
-- fixed unicast queries
-- fixed property handling
-- use the hostname instead of the service name is address resolution
-- Added Apache License.
-
---------------------------------------------------------------------
-The activemq-jmdns_1.0 source is derived from http://repo1.maven.org/maven2/jmdns/jmdns/1.0/jmdns-1.0-sources.jar
-
-Changes to apache activemq version:
-- renamed package javax.jmdns to org.apache.activemq.jmdns
-- removed classes with lgpl source headers, leaving only the org.apache.activemq.jmdns package.
-
diff --git a/activemq-karaf/src/main/resources/features.xml b/activemq-karaf/src/main/resources/features.xml
index bff5b70797..97e0b0bcb1 100644
--- a/activemq-karaf/src/main/resources/features.xml
+++ b/activemq-karaf/src/main/resources/features.xml
@@ -75,6 +75,7 @@
mvn:org.apache.httpcomponents/httpcore-osgi/${httpclient-version}
mvn:org.apache.httpcomponents/httpclient-osgi/${httpclient-version}
mvn:org.springframework/spring-oxm/${spring-version}
+ mvn:javax.jmdns/jmdns/${jmdns-version}
diff --git a/assembly/pom.xml b/assembly/pom.xml
index b956b88c07..e39f296181 100755
--- a/assembly/pom.xml
+++ b/assembly/pom.xml
@@ -158,8 +158,8 @@
jaxp-api