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 &lt; PROBING_2 &lt; PROBING_3 &lt; ANNOUNCING_1 &lt;
+     * ANNOUNCING_2 &lt; RESPONDING &lt; ANNOUNCED &lt; 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