KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jgroups > stack > IpAddress


1 // $Id: IpAddress.java,v 1.23 2005/04/20 13:55:14 belaban Exp $
2

3 package org.jgroups.stack;
4
5 import org.apache.commons.logging.Log;
6 import org.apache.commons.logging.LogFactory;
7 import org.jgroups.Address;
8 import org.jgroups.Global;
9 import org.jgroups.util.Util;
10
11 import java.io.*;
12 import java.net.InetAddress JavaDoc;
13 import java.util.HashMap JavaDoc;
14
15
16
17 /**
18  * Network-dependent address (Internet). Generated by the bottommost layer of the protocol
19  * stack (UDP). Contains an InetAddress and port.
20  * @author Bela Ban
21  */

22 public class IpAddress implements Address {
23     private InetAddress JavaDoc ip_addr=null;
24     private int port=0;
25     private byte[] additional_data=null;
26     protected static final HashMap JavaDoc sAddrCache=new HashMap JavaDoc();
27     protected static final Log log=LogFactory.getLog(IpAddress.class);
28
29     static boolean resolve_dns=false;
30     static final char[] digits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
31     static final boolean jdk_14=Util.getJavaVersion() >= 14;
32
33
34     static {
35         /* Trying to get value of resolve_dns. PropertyPermission not granted if
36         * running in an untrusted environment with JNLP */

37         try {
38             resolve_dns=Boolean.valueOf(System.getProperty("resolve.dns", "false")).booleanValue();
39         }
40         catch (SecurityException JavaDoc ex){
41             resolve_dns=false;
42         }
43     }
44
45
46
47     // Used only by Externalization
48
public IpAddress() {
49     }
50     
51     public IpAddress(String JavaDoc i, int p) {
52         port=p;
53         try {
54             ip_addr=InetAddress.getByName(i);
55         }
56         catch(Exception JavaDoc e) {
57             if(log.isWarnEnabled()) log.warn("failed to get " + i + ": " + e);
58         }
59         if(this.ip_addr == null)
60             setAddressToLocalHost();
61     }
62
63
64
65     public IpAddress(InetAddress JavaDoc i, int p) {
66         ip_addr=i; port=p;
67         if(this.ip_addr == null)
68             setAddressToLocalHost();
69     }
70
71
72     private void setAddressToLocalHost() {
73         try {
74             ip_addr=InetAddress.getLocalHost(); // get first NIC found (on multi-homed systems)
75
}
76         catch(Exception JavaDoc e) {
77             if(log.isWarnEnabled()) log.warn("exception: " + e);
78         }
79     }
80
81     public IpAddress(int port) {
82         this(port, true);
83     }
84
85     public IpAddress(int port, boolean set_default_host) {
86         this.port=port;
87         if(set_default_host)
88             setAddressToLocalHost();
89     }
90
91
92
93     public InetAddress JavaDoc getIpAddress() {return ip_addr;}
94     public int getPort() {return port;}
95
96     public boolean isMulticastAddress() {
97         return ip_addr != null ? ip_addr.isMulticastAddress() : false;
98     }
99
100     /**
101      * Returns the additional_data.
102      * @return byte[]
103      */

104     public byte[] getAdditionalData() {
105         return additional_data;
106     }
107
108     /**
109      * Sets the additional_data.
110      * @param additional_data The additional_data to set
111      */

112     public void setAdditionalData(byte[] additional_data) {
113         this.additional_data = additional_data;
114     }
115
116
117     /**
118      * Establishes an order between 2 addresses. Assumes other contains non-null IpAddress.
119      * Excludes channel_name from comparison.
120      * @return 0 for equality, value less than 0 if smaller, greater than 0 if greater.
121      */

122     public int compare(IpAddress other) {
123         return compareTo(other);
124     }
125
126
127     /**
128      * implements the java.lang.Comparable interface
129      * @see java.lang.Comparable
130      * @param o - the Object to be compared
131      * @return a negative integer, zero, or a positive integer as this object is less than,
132      * equal to, or greater than the specified object.
133      * @exception java.lang.ClassCastException - if the specified object's type prevents it
134      * from being compared to this Object.
135      */

136     public int compareTo(Object JavaDoc o) {
137       int h1, h2, rc;
138
139       if ((o == null) || !(o instanceof IpAddress))
140           throw new ClassCastException JavaDoc("comparison between different classes: the other object is " +
141                                        (o != null? o.getClass() : o));
142       IpAddress other = (IpAddress) o;
143       if(ip_addr == null)
144           if (other.ip_addr == null) return port < other.port ? -1 : (port > other.port ? 1 : 0);
145           else return -1;
146       
147       h1=ip_addr.hashCode();
148       h2=other.ip_addr.hashCode();
149       rc=h1 < h2? -1 : h1 > h2? 1 : 0;
150       return rc != 0 ? rc : port < other.port ? -1 : (port > other.port ? 1 : 0);
151     }
152
153
154
155     public boolean equals(Object JavaDoc obj) {
156         if(obj == null) return false;
157         return compareTo(obj) == 0 ? true : false;
158     }
159
160
161
162
163     public int hashCode() {
164         int retval=ip_addr != null ? ip_addr.hashCode() + port : port;
165         return retval;
166     }
167
168
169
170
171     public String JavaDoc toString() {
172         StringBuffer JavaDoc sb=new StringBuffer JavaDoc();
173
174         if(ip_addr == null)
175             sb.append("<null>");
176         else {
177             if(ip_addr.isMulticastAddress())
178                 sb.append(ip_addr.getHostAddress());
179             else {
180                 String JavaDoc host_name=null;
181                 if(resolve_dns)
182                     host_name=ip_addr.getHostName();
183                 else
184                     host_name=ip_addr.getHostAddress();
185                 appendShortName(host_name, sb);
186             }
187         }
188         sb.append(":" + port);
189         if(additional_data != null)
190             sb.append(" (additional data: ").append(additional_data.length).append(" bytes)");
191         return sb.toString();
192     }
193
194
195
196
197
198     /**
199      * Input: "daddy.nms.fnc.fujitsu.com", output: "daddy". Appends result to string buffer 'sb'.
200      * @param hostname The hostname in long form. Guaranteed not to be null
201      * @param sb The string buffer to which the result is to be appended
202      */

203     private void appendShortName(String JavaDoc hostname, StringBuffer JavaDoc sb) {
204         if(hostname == null) return;
205         int index=hostname.indexOf('.');
206         if(index > 0 && !Character.isDigit(hostname.charAt(0)))
207             sb.append(hostname.substring(0, index));
208         else
209             sb.append(hostname);
210     }
211
212
213     /**
214      * Converts 4 byte address representation into a char array
215      * of length 7-15, depending on the actual address, i.e XXX.XXX.XXX.XXX
216      * and returns a String representation of that address.
217      *
218      * @param address 4 byte array representing address
219      *
220      */

221     private static final String JavaDoc addressToString(byte[] address) {
222         int q,r = 0;
223         int charPos = 15;
224         char[] buf = new char[15];
225         char dot = '.';
226         
227         int i = address[3] & 0xFF;
228         for(;;) {
229             q = (i * 52429) >>> (19);
230             r = i - ((q << 3) + (q << 1));
231             buf[--charPos] = digits[r];
232             i = q;
233             if (i == 0) break;
234         }
235         buf[--charPos] = dot;
236         i = address[2] & 0xFF;
237         for (;;) {
238             q = (i * 52429) >>> (19);
239             r = i - ((q << 3) + (q << 1));
240             buf[--charPos] = digits[r];
241             i = q;
242             if (i == 0) break;
243         }
244         buf[--charPos] = dot;
245         
246         i = address[1] & 0xFF;
247         for (;;) {
248             q = (i * 52429) >>> (19);
249             r = i - ((q << 3) + (q << 1));
250             buf[--charPos] = digits[r];
251             i = q;
252             if (i == 0) break;
253         }
254         
255         buf[--charPos] = dot;
256         i = address[0] & 0xFF;
257         
258         for (;;) {
259             q = (i * 52429) >>> (19);
260             r = i - ((q << 3) + (q << 1));
261             buf[--charPos] = digits[r];
262             i = q;
263             if (i == 0) break;
264         }
265         return new String JavaDoc(buf, charPos, 15 - charPos);
266     }
267     
268
269     public void writeExternal(ObjectOutput out) throws IOException {
270         byte[] address = ip_addr.getAddress();
271         out.write(address);
272         out.writeInt(port);
273         if(additional_data != null) {
274             out.writeInt(additional_data.length);
275             out.write(additional_data, 0, additional_data.length);
276         }
277         else
278             out.writeInt(0);
279     }
280     
281     
282     
283     
284     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException JavaDoc {
285         int len=0;
286         //read the four bytes
287
byte[] a = new byte[4];
288         //in theory readFully(byte[]) should be faster
289
//than read(byte[]) since latter reads
290
// 4 bytes one at a time
291
in.readFully(a);
292         //then read the port
293
port = in.readInt();
294         //look up an instance in the cache
295
if(jdk_14)
296             this.ip_addr=InetAddress.getByAddress(a);
297         else
298             this.ip_addr = getIpAddress(a);
299         len=in.readInt();
300         if(len > 0) {
301             additional_data=new byte[len];
302             in.readFully(additional_data, 0, additional_data.length);
303         }
304     }
305
306     public void writeTo(DataOutputStream out) throws IOException {
307         byte[] address;
308
309         if(ip_addr != null) {
310             address=ip_addr.getAddress();
311             out.writeShort(address.length); // 2 bytes
312
out.write(address, 0, address.length);
313         }
314         else {
315             out.writeShort(0);
316         }
317         out.writeInt(port);
318         if(additional_data != null) {
319             out.writeBoolean(true); // 1 byte
320
out.writeInt(additional_data.length);
321             out.write(additional_data, 0, additional_data.length);
322         }
323         else {
324             out.writeBoolean(false);
325         }
326     }
327
328     public void readFrom(DataInputStream in) throws IOException {
329         int len;
330
331         len=in.readShort();
332         if(len > 0) {
333             //read the four bytes
334
byte[] a = new byte[len];
335             //in theory readFully(byte[]) should be faster
336
//than read(byte[]) since latter reads
337
// 4 bytes one at a time
338
in.readFully(a);
339             //look up an instance in the cache
340
if(jdk_14)
341                 this.ip_addr=InetAddress.getByAddress(a);
342             else
343                 this.ip_addr = getIpAddress(a);
344         }
345         //then read the port
346
port=in.readInt();
347
348         if(in.readBoolean() == false)
349             return;
350         len=in.readInt();
351         if(len > 0) {
352             additional_data=new byte[len];
353             in.readFully(additional_data, 0, additional_data.length);
354         }
355     }
356
357     public int size() {
358         // length + 4 bytes for IPv4 address + 4 bytes for port + 1 for additional_data available
359
int size=Global.SHORT_SIZE + (2*Global.INT_SIZE) + Global.BYTE_SIZE;
360         if(additional_data != null)
361             size+=additional_data.length+Global.INT_SIZE;
362         return size;
363     }
364
365     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
366         IpAddress ret=new IpAddress(ip_addr, port);
367         if(additional_data != null) {
368             ret.additional_data=new byte[additional_data.length];
369             System.arraycopy(additional_data, 0, ret.additional_data, 0, additional_data.length);
370         }
371
372         return ret;
373     }
374
375
376     protected static InetAddress JavaDoc getIpAddress(byte[] addr) {
377         try {
378             HashKey key = new HashKey(addr);
379             InetAddress JavaDoc result;
380
381             synchronized(sAddrCache) {
382                 result=(InetAddress JavaDoc)sAddrCache.get(key);
383                 if(result == null) {
384                     result = java.net.InetAddress.getByName(addressToString(addr));
385                     sAddrCache.put(key,result);
386                 }
387             }
388             return result;
389         }
390         catch (Exception JavaDoc x) {
391             x.printStackTrace();
392             if(log.isErrorEnabled()) log.error(x.getMessage());
393         }
394         return null;
395         
396     }
397     
398     static class HashKey {
399         private final byte[] mIpAddress;
400
401         public HashKey(byte[] ipaddress) {
402             if (ipaddress == null)
403                 mIpAddress = new byte[0];
404             else
405                 mIpAddress = ipaddress;
406         }
407         
408         public int hashCode() {
409             if(mIpAddress.length > 0)
410                 return (int)mIpAddress[0];
411             else
412                 return 0;
413         }
414         
415         public byte[] getIpBytes() {
416             return mIpAddress;
417         }
418         
419         public boolean equals(Object JavaDoc o) {
420             if (o != null && o instanceof HashKey) {
421                 byte[] other = ((HashKey)o).getIpBytes();
422                 if ( other.length != mIpAddress.length )
423                     return false;
424                 boolean result = true;
425                 for ( int i=0; i<other.length && result; i++ )
426                     result = result & (other[i] == mIpAddress[i]);
427                 return result;
428             }
429             else
430                 return false;
431         }
432     }
433
434
435
436 }
437
Popular Tags