001: // $Id: IpAddress.java,v 1.36 2006/09/11 13:57:57 belaban Exp $
002:
003: package org.jgroups.stack;
004:
005: import org.apache.commons.logging.Log;
006: import org.apache.commons.logging.LogFactory;
007: import org.jgroups.Address;
008: import org.jgroups.Global;
009: import org.jgroups.util.Util;
010:
011: import java.io.*;
012: import java.net.InetAddress;
013: import java.net.UnknownHostException;
014:
015: /**
016: * Network-dependent address (Internet). Generated by the bottommost layer of the protocol
017: * stack (UDP). Contains an InetAddress and port.
018: * @author Bela Ban
019: */
020: public class IpAddress implements Address {
021: private InetAddress ip_addr = null;
022: private int port = 0;
023: private byte[] additional_data;
024: protected static final Log log = LogFactory.getLog(IpAddress.class);
025: static boolean resolve_dns = false;
026: transient int size = -1;
027:
028: static {
029: /* Trying to get value of resolve_dns. PropertyPermission not granted if
030: * running in an untrusted environment with JNLP */
031: try {
032: String tmp = Util.getProperty(new String[] {
033: Global.RESOLVE_DNS, "resolve.dns" }, null, null,
034: false, "false");
035: resolve_dns = Boolean.valueOf(tmp).booleanValue();
036: } catch (SecurityException ex) {
037: resolve_dns = false;
038: }
039: }
040:
041: // Used only by Externalization
042: public IpAddress() {
043: }
044:
045: public IpAddress(String i, int p) throws UnknownHostException {
046: port = p;
047: ip_addr = InetAddress.getByName(i);
048: }
049:
050: public IpAddress(InetAddress i, int p) {
051: ip_addr = i;
052: port = p;
053: if (this .ip_addr == null)
054: setAddressToLocalHost();
055: }
056:
057: private void setAddressToLocalHost() {
058: try {
059: ip_addr = InetAddress.getLocalHost(); // get first NIC found (on multi-homed systems)
060: // size=size();
061: } catch (Exception e) {
062: if (log.isWarnEnabled())
063: log.warn("exception: " + e);
064: }
065: }
066:
067: public IpAddress(int port) {
068: this (port, true);
069: }
070:
071: public IpAddress(int port, boolean set_default_host) {
072: this .port = port;
073: if (set_default_host)
074: setAddressToLocalHost();
075: }
076:
077: public final InetAddress getIpAddress() {
078: return ip_addr;
079: }
080:
081: public final int getPort() {
082: return port;
083: }
084:
085: public final boolean isMulticastAddress() {
086: return ip_addr != null && ip_addr.isMulticastAddress();
087: }
088:
089: /**
090: * Returns the additional_data.
091: * @return byte[]
092: */
093: public final byte[] getAdditionalData() {
094: return additional_data;
095: }
096:
097: /**
098: * Sets the additional_data.
099: * @param additional_data The additional_data to set
100: */
101: public final void setAdditionalData(byte[] additional_data) {
102: this .additional_data = additional_data;
103: size = -1; // changed May 13 2006 bela (suggested by Bruce Schuchardt)
104: size = size();
105: }
106:
107: /**
108: * Establishes an order between 2 addresses. Assumes other contains non-null IpAddress.
109: * Excludes channel_name from comparison.
110: * @return 0 for equality, value less than 0 if smaller, greater than 0 if greater.
111: */
112: public final int compare(IpAddress other) {
113: return compareTo(other);
114: }
115:
116: /**
117: * implements the java.lang.Comparable interface
118: * @see java.lang.Comparable
119: * @param o - the Object to be compared
120: * @return a negative integer, zero, or a positive integer as this object is less than,
121: * equal to, or greater than the specified object.
122: * @exception java.lang.ClassCastException - if the specified object's type prevents it
123: * from being compared to this Object.
124: */
125: public final int compareTo(Object o) {
126: int h1, h2, rc; // added Nov 7 2005, makes sense with canonical addresses
127:
128: if (this == o)
129: return 0;
130: if ((o == null) || !(o instanceof IpAddress))
131: throw new ClassCastException(
132: "comparison between different classes: the other object is "
133: + (o != null ? o.getClass() : o));
134: IpAddress other = (IpAddress) o;
135: if (ip_addr == null)
136: if (other.ip_addr == null)
137: return port < other.port ? -1 : (port > other.port ? 1
138: : 0);
139: else
140: return -1;
141:
142: h1 = ip_addr.hashCode();
143: h2 = other.ip_addr.hashCode();
144: rc = h1 < h2 ? -1 : h1 > h2 ? 1 : 0;
145: return rc != 0 ? rc : port < other.port ? -1
146: : (port > other.port ? 1 : 0);
147: }
148:
149: public final boolean equals(Object obj) {
150: if (this == obj)
151: return true; // added Nov 7 2005, makes sense with canonical addresses
152: if (obj == null)
153: return false;
154: return compareTo(obj) == 0;
155: }
156:
157: public final int hashCode() {
158: return ip_addr != null ? ip_addr.hashCode() + port : port;
159: }
160:
161: public String toString() {
162: StringBuffer sb = new StringBuffer();
163:
164: if (ip_addr == null)
165: sb.append("<null>");
166: else {
167: if (ip_addr.isMulticastAddress())
168: sb.append(ip_addr.getHostAddress());
169: else {
170: String host_name = null;
171: if (resolve_dns) {
172: host_name = ip_addr.getHostName();
173: // appendShortName(host_name, sb);
174: } else {
175: host_name = ip_addr.getHostAddress();
176: }
177: sb.append(host_name);
178: }
179: }
180: sb.append(":").append(port);
181: return sb.toString();
182: }
183:
184: public void writeExternal(ObjectOutput out) throws IOException {
185: if (ip_addr != null) {
186: byte[] address = ip_addr.getAddress();
187: out.writeByte(address.length); // 1 byte
188: out.write(address, 0, address.length);
189: } else {
190: out.writeByte(0);
191: }
192: out.writeInt(port);
193: if (additional_data != null) {
194: out.writeBoolean(true);
195: out.writeShort(additional_data.length);
196: out.write(additional_data, 0, additional_data.length);
197: } else
198: out.writeBoolean(false);
199: }
200:
201: public void readExternal(ObjectInput in) throws IOException,
202: ClassNotFoundException {
203: int len = in.readByte();
204: if (len > 0) {
205: //read the four bytes
206: byte[] a = new byte[len];
207: //in theory readFully(byte[]) should be faster
208: //than read(byte[]) since latter reads
209: // 4 bytes one at a time
210: in.readFully(a);
211: //look up an instance in the cache
212: this .ip_addr = InetAddress.getByAddress(a);
213: }
214: //then read the port
215: port = in.readInt();
216:
217: if (in.readBoolean() == false)
218: return;
219: len = in.readShort();
220: if (len > 0) {
221: additional_data = new byte[len];
222: in.readFully(additional_data, 0, additional_data.length);
223: }
224: }
225:
226: public void writeTo(DataOutputStream out) throws IOException {
227: if (ip_addr != null) {
228: byte[] address = ip_addr.getAddress(); // 4 bytes (IPv4) or 16 bytes (IPv6)
229: out.writeByte(address.length); // 1 byte
230: out.write(address, 0, address.length);
231: } else {
232: out.writeByte(0);
233: }
234: out.writeInt(port);
235: if (additional_data != null) {
236: out.writeBoolean(true); // 1 byte
237: out.writeShort(additional_data.length);
238: out.write(additional_data, 0, additional_data.length);
239: } else {
240: out.writeBoolean(false);
241: }
242: }
243:
244: public void readFrom(DataInputStream in) throws IOException {
245: int len = in.readByte();
246: if (len > 0) {
247: byte[] a = new byte[len]; // 4 bytes (IPv4) or 16 bytes (IPv6)
248: in.readFully(a);
249: this .ip_addr = InetAddress.getByAddress(a);
250: }
251: port = in.readInt();
252:
253: if (in.readBoolean() == false)
254: return;
255: len = in.readShort();
256: if (len > 0) {
257: additional_data = new byte[len];
258: in.readFully(additional_data, 0, additional_data.length);
259: }
260: }
261:
262: public int size() {
263: if (size >= 0)
264: return size;
265: // length (1 bytes) + 4 bytes for port + 1 for additional_data available
266: int tmp_size = Global.BYTE_SIZE + Global.INT_SIZE
267: + Global.BYTE_SIZE;
268: if (ip_addr != null)
269: tmp_size += ip_addr.getAddress().length; // 4 bytes for IPv4
270: if (additional_data != null)
271: tmp_size += additional_data.length + Global.SHORT_SIZE;
272: size = tmp_size;
273: return tmp_size;
274: }
275:
276: public Object clone() throws CloneNotSupportedException {
277: IpAddress ret = new IpAddress(ip_addr, port);
278: if (additional_data != null) {
279: ret.additional_data = new byte[additional_data.length];
280: System.arraycopy(additional_data, 0, ret.additional_data,
281: 0, additional_data.length);
282: }
283: return ret;
284: }
285:
286: }
|