You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by dj...@apache.org on 2008/04/06 21:21:24 UTC
svn commit: r645288 [2/7] - in /activemq/branches/activemq-4.1: ./
activemq-console/src/main/resources/META-INF/ activemq-core/
activemq-core/src/main/java/org/apache/activemq/transport/discovery/rendezvous/
activemq-core/src/main/resources/META-INF/ a...
Added: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSConstants.java
URL: http://svn.apache.org/viewvc/activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSConstants.java?rev=645288&view=auto
==============================================================================
--- activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSConstants.java (added)
+++ activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSConstants.java Sun Apr 6 12:21:18 2008
@@ -0,0 +1,125 @@
+//Copyright 2003-2005 Arthur van Hoff, Rick Blair
+//Licensed under Apache License version 2.0
+//Original license LGPL
+
+
+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
+}
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSConstants.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSConstants.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSConstants.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSEntry.java
URL: http://svn.apache.org/viewvc/activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSEntry.java?rev=645288&view=auto
==============================================================================
--- activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSEntry.java (added)
+++ activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSEntry.java Sun Apr 6 12:21:18 2008
@@ -0,0 +1,148 @@
+//Copyright 2003-2005 Arthur van Hoff, Rick Blair
+//Licensed under Apache License version 2.0
+//Original license LGPL
+
+
+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 + "]" : "]");
+ }
+}
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSEntry.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSEntry.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSEntry.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSIncoming.java
URL: http://svn.apache.org/viewvc/activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSIncoming.java?rev=645288&view=auto
==============================================================================
--- activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSIncoming.java (added)
+++ activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSIncoming.java Sun Apr 6 12:21:18 2008
@@ -0,0 +1,466 @@
+///Copyright 2003-2005 Arthur van Hoff, Rick Blair
+//Licensed under Apache License version 2.0
+//Original license LGPL
+
+
+
+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);
+ }
+}
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSIncoming.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSIncoming.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSIncoming.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSListener.java
URL: http://svn.apache.org/viewvc/activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSListener.java?rev=645288&view=auto
==============================================================================
--- activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSListener.java (added)
+++ activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSListener.java Sun Apr 6 12:21:18 2008
@@ -0,0 +1,24 @@
+//Copyright 2003-2005 Arthur van Hoff, Rick Blair
+//Licensed under Apache License version 2.0
+//Original license LGPL
+
+
+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.
+ */
+interface DNSListener
+{
+ /**
+ * Update a DNS record.
+ */
+ void updateRecord(JmDNS jmdns, long now, DNSRecord record);
+}
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSListener.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSListener.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSOutgoing.java
URL: http://svn.apache.org/viewvc/activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSOutgoing.java?rev=645288&view=auto
==============================================================================
--- activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSOutgoing.java (added)
+++ activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSOutgoing.java Sun Apr 6 12:21:18 2008
@@ -0,0 +1,381 @@
+//Copyright 2003-2005 Arthur van Hoff, Rick Blair
+//Licensed under Apache License version 2.0
+//Original license LGPL
+
+
+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();
+ }
+
+}
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSOutgoing.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSOutgoing.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSOutgoing.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSQuestion.java
URL: http://svn.apache.org/viewvc/activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSQuestion.java?rev=645288&view=auto
==============================================================================
--- activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSQuestion.java (added)
+++ activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSQuestion.java Sun Apr 6 12:21:18 2008
@@ -0,0 +1,44 @@
+//Copyright 2003-2005 Arthur van Hoff, Rick Blair
+//Licensed under Apache License version 2.0
+//Original license LGPL
+
+
+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);
+ }
+}
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSQuestion.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSQuestion.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSQuestion.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSRecord.java
URL: http://svn.apache.org/viewvc/activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSRecord.java?rev=645288&view=auto
==============================================================================
--- activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSRecord.java (added)
+++ activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSRecord.java Sun Apr 6 12:21:18 2008
@@ -0,0 +1,673 @@
+//Copyright 2003-2005 Arthur van Hoff, Rick Blair
+//Licensed under Apache License version 2.0
+//Original license LGPL
+
+
+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
+ */
+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.
+ */
+ 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.
+ */
+ 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.
+ */
+ 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);
+ }
+ }
+
+ static class Text extends DNSRecord
+ {
+ private static Logger logger = Logger.getLogger(Text.class.toString());
+ 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.
+ */
+ 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);
+ }
+}
+
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSRecord.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSRecord.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSRecord.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSState.java
URL: http://svn.apache.org/viewvc/activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSState.java?rev=645288&view=auto
==============================================================================
--- activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSState.java (added)
+++ activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSState.java Sun Apr 6 12:21:18 2008
@@ -0,0 +1,111 @@
+//Copyright 2003-2005 Arthur van Hoff, Rick Blair
+//Licensed under Apache License version 2.0
+//Original license LGPL
+
+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
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSState.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSState.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/DNSState.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/HostInfo.java
URL: http://svn.apache.org/viewvc/activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/HostInfo.java?rev=645288&view=auto
==============================================================================
--- activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/HostInfo.java (added)
+++ activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/HostInfo.java Sun Apr 6 12:21:18 2008
@@ -0,0 +1,138 @@
+//Copyright 2003-2005 Arthur van Hoff, Rick Blair
+//Licensed under Apache License version 2.0
+//Original license LGPL
+
+
+
+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();
+ }
+
+}
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/HostInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/HostInfo.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: activemq/branches/activemq-4.1/activemq-jmdns_1.0/src/main/java/org/apache/activemq/jmdns/HostInfo.java
------------------------------------------------------------------------------
svn:mime-type = text/plain