Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/strangeberry/rendezvous/DNSRecord.java


1   // Copyright (C) 2002  Strangeberry Inc.
2   // @(#)DNSRecord.java, 1.24, 01/14/2003
3   //
4   // This library is free software; you can redistribute it and/or
5   // modify it under the terms of the GNU Lesser General Public
6   // License as published by the Free Software Foundation; either
7   // version 2.1 of the License, or (at your option) any later version.
8   // 
9   // This library is distributed in the hope that it will be useful,
10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  // Lesser General Public License for more details.
13  // 
14  // You should have received a copy of the GNU Lesser General Public
15  // License along with this library; if not, write to the Free Software
16  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  
18  package com.strangeberry.rendezvous;
19  
20  import java.io.*;
21  import java.net.*;
22  import java.util.*;
23  
24  /**
25   * DNS record
26   *
27   * @author  Arthur van Hoff
28   * @version   1.24, 01/14/2003
29   */
30  abstract class DNSRecord extends DNSEntry
31  {
32      int ttl;
33      long created;
34  
35      /**
36       * Create a DNSRecord with a name, type, clazz, and ttl.
37       */
38      DNSRecord(String name, int type, int clazz, int ttl)
39      {
40    super(name, type, clazz);
41    this.ttl = ttl;
42    this.created = System.currentTimeMillis();
43      }
44  
45      /**
46       * True if this record is the same as some other record.
47       */
48      public boolean equals(Object other)
49      {
50    return (other instanceof DNSRecord) && sameAs((DNSRecord)other);
51      }
52  
53      /**
54       * True if this record is the same as some other record.
55       */
56      boolean sameAs(DNSRecord other)
57      {
58    return super.equals(other) && sameValue((DNSRecord)other);
59      }
60  
61      /**
62       * True if this record has the same value as some other record.
63       */
64      abstract boolean sameValue(DNSRecord other);
65  
66      /**
67       * True if this record is suppressed by the answers in a message.
68       */
69      boolean suppressedBy(DNSIncoming msg)
70      {
71    for (int i = msg.numAnswers ; i-- > 0 ;) {
72        if (suppressedBy((DNSRecord)msg.answers.elementAt(i))) {
73      return true;
74        }
75    }
76    return false;
77      }
78  
79      /**
80       * True if this record would be supressed by an answer.
81       * This is the case if this record would not have a
82       * significantly longer TTL.
83       */
84      boolean suppressedBy(DNSRecord other)
85      {
86    if (sameAs(other) && (other.ttl > ttl / 2)) {
87        return true;
88    }
89    return false;
90      }
91  
92      /**
93       * Get the expiration time of this record.
94       */
95      long getExpirationTime(int percent)
96      {
97    return created + (percent * ttl * 10L);
98      }
99  
100     /**
101      * Get the remaining TTL for this record.
102      */
103     int getRemainingTTL(long now)
104     {
105   return (int)Math.max(0, (getExpirationTime(100) - now) / 1000);
106     }
107 
108     /**
109      * Check if the record is expired.
110      */
111     boolean isExpired(long now)
112     {
113   return getExpirationTime(100) <= now;
114     }
115 
116     /**
117      * Check if the record is stale, ie it has outlived
118      * more than half of its TTL.
119      */
120     boolean isStale(long now)
121     {
122   return getExpirationTime(50) <= now;
123     }
124 
125     /**
126      * Reset the TTL of a record. This avoids having to
127      * update the entire record in the cache.
128      */
129     void resetTTL(DNSRecord other)
130     {
131   created = other.created;
132   ttl = other.ttl;
133     }
134 
135     /**
136      * Write this record into an outgoing message.
137      */
138     abstract void write(DNSOutgoing out) throws IOException;
139 
140     /**
141      * Address record.
142      */
143     static class Address extends DNSRecord
144     {
145   int addr;
146 
147   Address(String name, int type, int clazz, int ttl, int addr)
148   {
149       super(name, type, clazz, ttl);
150       this.addr = addr;
151   }
152   void write(DNSOutgoing out) throws IOException
153   {
154       out.writeInt(addr);
155   }
156   boolean sameValue(DNSRecord other)
157   {
158       return (addr == ((Address)other).addr);
159   }
160   InetAddress getAddress()
161   {
162       try {
163     return InetAddress.getByName(getHostAddress());
164       } catch (UnknownHostException e) {
165     // should not happen
166     e.printStackTrace();
167     return null;
168       }
169   }
170   public String getHostAddress()
171   {
172       return ((addr >> 24) & 0xFF) + "." + ((addr >> 16) & 0xFF) + "." + ((addr >> 8) & 0xFF) + "." + (addr & 0xFF);
173   }
174   public String toString()
175   {
176       return toString(getHostAddress());
177   }
178     }
179 
180     /**
181      * Pointer record.
182      */
183     static class Pointer extends DNSRecord
184     {
185   String alias;
186 
187   Pointer(String name, int type, int clazz, int ttl, String alias)
188   {
189       super(name, type, clazz, ttl);
190       this.alias = alias;
191   }
192   void write(DNSOutgoing out) throws IOException
193   {
194       out.writeName(alias);
195   }
196   boolean sameValue(DNSRecord other)
197   {
198       return alias.equals(((Pointer)other).alias);
199   }
200   public String toString()
201   {
202       return toString(alias);
203   }
204     }
205 
206     static class Text extends DNSRecord
207     {
208   byte text[];
209 
210   Text(String name, int type, int clazz, int ttl, byte text[])
211   {
212       super(name, type, clazz, ttl);
213       this.text = text;
214   }
215   void write(DNSOutgoing out) throws IOException
216   {
217       out.writeBytes(text, 0, text.length);
218   }
219   boolean sameValue(DNSRecord other)
220   {
221       Text txt = (Text)other;
222       if (txt.text.length != text.length) {
223     return false;
224       }
225       for (int i = text.length ; i-- > 0 ;) {
226     if (txt.text[i] != text[i]) {
227         return false;
228     }
229       }
230       return true;
231   }
232   public String toString()
233   {
234       return toString((text.length > 10) ? new String(text, 0, 7) + "..." : new String(text));
235   }
236     }
237 
238     /**
239      * Service record.
240      */
241     static class Service extends DNSRecord
242     {
243   int priority;
244   int weight;
245   int port;
246   String server;
247 
248   Service(String name, int type, int clazz, int ttl, int priority, int weight, int port, String server)
249   {
250       super(name, type, clazz, ttl);
251       this.priority = priority;
252       this.weight = weight;
253       this.port = port;
254       this.server = server;
255   }
256   void write(DNSOutgoing out) throws IOException
257   {
258       out.writeShort(priority);
259       out.writeShort(weight);
260       out.writeShort(port);
261       out.writeName(server);
262   }
263   boolean sameValue(DNSRecord other)
264   {
265       Service s = (Service)other;
266       return (priority == s.priority) && (weight == s.weight) && (port == s.port) && server.equals(s.server);
267   }
268   public String toString()
269   {
270       return toString(server + ":" + port);
271   }
272     }
273 
274     public String toString(String other)
275     {
276   return toString("record", ttl + "/" + getRemainingTTL(System.currentTimeMillis())  + "," + other);
277     }
278 }
279