Home | History | Annotate | Download | only in impl
      1 /**
      2  *
      3  */
      4 package javax.jmdns.impl;
      5 
      6 import java.util.ArrayList;
      7 import java.util.Collection;
      8 import java.util.Collections;
      9 import java.util.LinkedList;
     10 import java.util.List;
     11 
     12 import javax.jmdns.impl.constants.DNSConstants;
     13 
     14 /**
     15  * DNSMessage define a DNS message either incoming or outgoing.
     16  *
     17  * @author Werner Randelshofer, Rick Blair, Pierre Frisch
     18  */
     19 public abstract class DNSMessage {
     20 
     21     /**
     22      *
     23      */
     24     public static final boolean       MULTICAST = true;
     25 
     26     /**
     27      *
     28      */
     29     public static final boolean       UNICAST   = false;
     30 
     31     // protected DatagramPacket _packet;
     32     // protected int _off;
     33     // protected int _len;
     34     // protected byte[] _data;
     35 
     36     private int                       _id;
     37 
     38     boolean                           _multicast;
     39 
     40     private int                       _flags;
     41 
     42     protected final List<DNSQuestion> _questions;
     43 
     44     protected final List<DNSRecord>   _answers;
     45 
     46     protected final List<DNSRecord>   _authoritativeAnswers;
     47 
     48     protected final List<DNSRecord>   _additionals;
     49 
     50     /**
     51      * @param flags
     52      * @param id
     53      * @param multicast
     54      */
     55     protected DNSMessage(int flags, int id, boolean multicast) {
     56         super();
     57         _flags = flags;
     58         _id = id;
     59         _multicast = multicast;
     60         _questions = Collections.synchronizedList(new LinkedList<DNSQuestion>());
     61         _answers = Collections.synchronizedList(new LinkedList<DNSRecord>());
     62         _authoritativeAnswers = Collections.synchronizedList(new LinkedList<DNSRecord>());
     63         _additionals = Collections.synchronizedList(new LinkedList<DNSRecord>());
     64     }
     65 
     66     // public DatagramPacket getPacket() {
     67     // return _packet;
     68     // }
     69     //
     70     // public int getOffset() {
     71     // return _off;
     72     // }
     73     //
     74     // public int getLength() {
     75     // return _len;
     76     // }
     77     //
     78     // public byte[] getData() {
     79     // if ( _data == null ) _data = new byte[DNSConstants.MAX_MSG_TYPICAL];
     80     // return _data;
     81     // }
     82 
     83     /**
     84      * @return message id
     85      */
     86     public int getId() {
     87         return (_multicast ? 0 : _id);
     88     }
     89 
     90     /**
     91      * @param id
     92      *            the id to set
     93      */
     94     public void setId(int id) {
     95         this._id = id;
     96     }
     97 
     98     /**
     99      * @return message flags
    100      */
    101     public int getFlags() {
    102         return _flags;
    103     }
    104 
    105     /**
    106      * @param flags
    107      *            the flags to set
    108      */
    109     public void setFlags(int flags) {
    110         this._flags = flags;
    111     }
    112 
    113     /**
    114      * @return true if multicast
    115      */
    116     public boolean isMulticast() {
    117         return _multicast;
    118     }
    119 
    120     /**
    121      * @return list of questions
    122      */
    123     public Collection<? extends DNSQuestion> getQuestions() {
    124         return _questions;
    125     }
    126 
    127     /**
    128      * @return number of questions in the message
    129      */
    130     public int getNumberOfQuestions() {
    131         return this.getQuestions().size();
    132     }
    133 
    134     public Collection<? extends DNSRecord> getAllAnswers() {
    135         List<DNSRecord> aList = new ArrayList<DNSRecord>(_answers.size() + _authoritativeAnswers.size() + _additionals.size());
    136         aList.addAll(_answers);
    137         aList.addAll(_authoritativeAnswers);
    138         aList.addAll(_additionals);
    139         return aList;
    140     }
    141 
    142     /**
    143      * @return list of answers
    144      */
    145     public Collection<? extends DNSRecord> getAnswers() {
    146         return _answers;
    147     }
    148 
    149     /**
    150      * @return number of answers in the message
    151      */
    152     public int getNumberOfAnswers() {
    153         return this.getAnswers().size();
    154     }
    155 
    156     /**
    157      * @return list of authorities
    158      */
    159     public Collection<? extends DNSRecord> getAuthorities() {
    160         return _authoritativeAnswers;
    161     }
    162 
    163     /**
    164      * @return number of authorities in the message
    165      */
    166     public int getNumberOfAuthorities() {
    167         return this.getAuthorities().size();
    168     }
    169 
    170     /**
    171      * @return list of additional answers
    172      */
    173     public Collection<? extends DNSRecord> getAdditionals() {
    174         return _additionals;
    175     }
    176 
    177     /**
    178      * @return number of additional in the message
    179      */
    180     public int getNumberOfAdditionals() {
    181         return this.getAdditionals().size();
    182     }
    183 
    184     /**
    185      * Check if the message is truncated.
    186      *
    187      * @return true if the message was truncated
    188      */
    189     public boolean isTruncated() {
    190         return (_flags & DNSConstants.FLAGS_TC) != 0;
    191     }
    192 
    193     /**
    194      * Check if the message is a query.
    195      *
    196      * @return true is the message is a query
    197      */
    198     public boolean isQuery() {
    199         return (_flags & DNSConstants.FLAGS_QR_MASK) == DNSConstants.FLAGS_QR_QUERY;
    200     }
    201 
    202     /**
    203      * Check if the message is a response.
    204      *
    205      * @return true is the message is a response
    206      */
    207     public boolean isResponse() {
    208         return (_flags & DNSConstants.FLAGS_QR_MASK) == DNSConstants.FLAGS_QR_RESPONSE;
    209     }
    210 
    211     /**
    212      * Check if the message is empty
    213      *
    214      * @return true is the message is empty
    215      */
    216     public boolean isEmpty() {
    217         return (this.getNumberOfQuestions() + this.getNumberOfAnswers() + this.getNumberOfAuthorities() + this.getNumberOfAdditionals()) == 0;
    218     }
    219 
    220     /**
    221      * Debugging.
    222      */
    223     String print() {
    224         StringBuffer buf = new StringBuffer(200);
    225         buf.append(this.toString());
    226         buf.append("\n");
    227         for (DNSQuestion question : _questions) {
    228             buf.append("\tquestion:      ");
    229             buf.append(question);
    230             buf.append("\n");
    231         }
    232         for (DNSRecord answer : _answers) {
    233             buf.append("\tanswer:        ");
    234             buf.append(answer);
    235             buf.append("\n");
    236         }
    237         for (DNSRecord answer : _authoritativeAnswers) {
    238             buf.append("\tauthoritative: ");
    239             buf.append(answer);
    240             buf.append("\n");
    241         }
    242         for (DNSRecord answer : _additionals) {
    243             buf.append("\tadditional:    ");
    244             buf.append(answer);
    245             buf.append("\n");
    246         }
    247         return buf.toString();
    248     }
    249 
    250     /**
    251      * Debugging.
    252      *
    253      * @param data
    254      * @return data dump
    255      */
    256     protected String print(byte[] data) {
    257         StringBuilder buf = new StringBuilder(4000);
    258         for (int off = 0, len = data.length; off < len; off += 32) {
    259             int n = Math.min(32, len - off);
    260             if (off < 0x10) {
    261                 buf.append(' ');
    262             }
    263             if (off < 0x100) {
    264                 buf.append(' ');
    265             }
    266             if (off < 0x1000) {
    267                 buf.append(' ');
    268             }
    269             buf.append(Integer.toHexString(off));
    270             buf.append(':');
    271             int index = 0;
    272             for (index = 0; index < n; index++) {
    273                 if ((index % 8) == 0) {
    274                     buf.append(' ');
    275                 }
    276                 buf.append(Integer.toHexString((data[off + index] & 0xF0) >> 4));
    277                 buf.append(Integer.toHexString((data[off + index] & 0x0F) >> 0));
    278             }
    279             // for incomplete lines
    280             if (index < 32) {
    281                 for (int i = index; i < 32; i++) {
    282                     if ((i % 8) == 0) {
    283                         buf.append(' ');
    284                     }
    285                     buf.append("  ");
    286                 }
    287             }
    288             buf.append("    ");
    289             for (index = 0; index < n; index++) {
    290                 if ((index % 8) == 0) {
    291                     buf.append(' ');
    292                 }
    293                 int ch = data[off + index] & 0xFF;
    294                 buf.append(((ch > ' ') && (ch < 127)) ? (char) ch : '.');
    295             }
    296             buf.append("\n");
    297 
    298             // limit message size
    299             if (off + 32 >= 2048) {
    300                 buf.append("....\n");
    301                 break;
    302             }
    303         }
    304         return buf.toString();
    305     }
    306 
    307 }
    308