View Javadoc

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 }