aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libjava/ChangeLog14
-rw-r--r--libjava/Makefile.in2
-rw-r--r--libjava/gnu/java/net/natPlainDatagramSocketImplPosix.cc6
-rw-r--r--libjava/gnu/java/net/natPlainSocketImplPosix.cc4
-rw-r--r--libjava/java/net/InetAddress.java627
-rw-r--r--libjava/java/net/VMInetAddress.java117
-rw-r--r--libjava/java/net/natVMNetworkInterfacePosix.cc5
-rw-r--r--libjava/sources.am2
8 files changed, 474 insertions, 303 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 222fc79..0afedde 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,17 @@
+2006-09-20 Gary Benson <gbenson@redhat.com>
+
+ * java/net/InetAddress.java: Mostly merged with Classpath.
+ * java/net/VMInetAddress.java: New file.
+ * sources.am, Makefile.in: Rebuilt.
+
+ * java/net/natVMNetworkInterfacePosix.cc
+ (getInterfaces): Create InetAddress objects using
+ InetAddress.getByAddress.
+ * gnu/java/net/natPlainSocketImplPosix.cc
+ (accept, getOption): Likewise.
+ * gnu/java/net/natPlainDatagramSocketImplPosix.cc
+ (peekData, receive, getLocalAddress): Likewise.
+
2006-09-19 Keith Seitz <keiths@redhat.com>
* testsuite/libjava.jvmti/jvmti.exp: New file.
diff --git a/libjava/Makefile.in b/libjava/Makefile.in
index cffe726..e81560c 100644
--- a/libjava/Makefile.in
+++ b/libjava/Makefile.in
@@ -4136,6 +4136,7 @@ classpath/java/net/NoRouteToHostException.java \
classpath/java/net/PasswordAuthentication.java \
classpath/java/net/PortUnreachableException.java \
classpath/java/net/ProtocolException.java \
+classpath/java/net/ResolverCache.java \
classpath/java/net/ServerSocket.java \
classpath/java/net/Socket.java \
classpath/java/net/SocketAddress.java \
@@ -4156,6 +4157,7 @@ classpath/java/net/URLStreamHandler.java \
classpath/java/net/URLStreamHandlerFactory.java \
classpath/java/net/UnknownHostException.java \
classpath/java/net/UnknownServiceException.java \
+java/net/VMInetAddress.java \
java/net/VMNetworkInterface.java \
java/net/VMURLConnection.java
diff --git a/libjava/gnu/java/net/natPlainDatagramSocketImplPosix.cc b/libjava/gnu/java/net/natPlainDatagramSocketImplPosix.cc
index 0a744c5..f7ffaa8 100644
--- a/libjava/gnu/java/net/natPlainDatagramSocketImplPosix.cc
+++ b/libjava/gnu/java/net/natPlainDatagramSocketImplPosix.cc
@@ -290,7 +290,7 @@ gnu::java::net::PlainDatagramSocketImpl::peekData (::java::net::DatagramPacket *
else
throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));
- p->setAddress (new ::java::net::InetAddress (raddr, NULL));
+ p->setAddress (::java::net::InetAddress::getByAddress (raddr));
p->setPort (rport);
p->length = (int) retlen;
return rport;
@@ -430,7 +430,7 @@ gnu::java::net::PlainDatagramSocketImpl::receive (::java::net::DatagramPacket *p
else
throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));
- p->setAddress (new ::java::net::InetAddress (raddr, NULL));
+ p->setAddress (::java::net::InetAddress::getByAddress (raddr));
p->setPort (rport);
p->length = (jint) retlen;
return;
@@ -564,7 +564,7 @@ getLocalAddress (int native_fd)
else
throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));
- return new ::java::net::InetAddress (laddr, NULL);
+ return ::java::net::InetAddress::getByAddress (laddr);
}
void
diff --git a/libjava/gnu/java/net/natPlainSocketImplPosix.cc b/libjava/gnu/java/net/natPlainSocketImplPosix.cc
index 2dfc38c..e4572fa 100644
--- a/libjava/gnu/java/net/natPlainSocketImplPosix.cc
+++ b/libjava/gnu/java/net/natPlainSocketImplPosix.cc
@@ -308,7 +308,7 @@ gnu::java::net::PlainSocketImpl::accept (gnu::java::net::PlainSocketImpl *s)
s->native_fd = new_socket;
s->localport = localport;
- s->address = new ::java::net::InetAddress (raddr, NULL);
+ s->address = ::java::net::InetAddress::getByAddress (raddr);
s->port = rport;
return;
@@ -808,7 +808,7 @@ gnu::java::net::PlainSocketImpl::getOption (jint optID)
else
throw new ::java::net::SocketException
(JvNewStringUTF ("invalid family"));
- localAddress = new ::java::net::InetAddress (laddr, NULL);
+ localAddress = ::java::net::InetAddress::getByAddress (laddr);
}
return localAddress;
diff --git a/libjava/java/net/InetAddress.java b/libjava/java/net/InetAddress.java
index 995e897..bef9a6e 100644
--- a/libjava/java/net/InetAddress.java
+++ b/libjava/java/net/InetAddress.java
@@ -1,5 +1,6 @@
/* InetAddress.java -- Class to model an Internet address
- Copyright (C) 1998, 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2002, 2004, 2005, 2006
+ Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +39,6 @@ exception statement from your version. */
package java.net;
-import gnu.classpath.Configuration;
-
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -58,6 +57,7 @@ import java.io.Serializable;
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Per Bothner
+ * @author Gary Benson (gbenson@redhat.com)
*
* @specnote This class is not final since JK 1.4
*/
@@ -69,23 +69,44 @@ public class InetAddress implements Serializable
* Dummy InetAddress, used to bind socket to any (all) network interfaces.
*/
static InetAddress ANY_IF;
-
- private static final byte[] loopbackAddress = { 127, 0, 0, 1 };
-
- private static final InetAddress loopback
- = new Inet4Address(loopbackAddress, "localhost");
-
- private static InetAddress localhost = null;
-
static
{
- // load the shared library needed for name resolution
- if (Configuration.INIT_LOAD_LIBRARY)
- System.loadLibrary("javanet");
-
- byte[] zeros = { 0, 0, 0, 0 };
- ANY_IF = new Inet4Address(zeros, "0.0.0.0");
+ byte[] addr;
+ try
+ {
+ addr = VMInetAddress.lookupInaddrAny();
+ }
+ catch (UnknownHostException e)
+ {
+ // Make one up and hope it works.
+ addr = new byte[] {0, 0, 0, 0};
+ }
+ try
+ {
+ ANY_IF = getByAddress(addr);
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ ANY_IF.hostName = ANY_IF.getHostName();
}
+
+ /**
+ * Stores static localhost address object.
+ */
+ static InetAddress LOCALHOST;
+ static
+ {
+ try
+ {
+ LOCALHOST = getByAddress("localhost", new byte[] {127, 0, 0, 1});
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ }
/**
* The Serialized Form specifies that an int 'address' is saved/restored.
@@ -105,29 +126,28 @@ public class InetAddress implements Serializable
String hostName;
/**
- * The field 'family' seems to be the AF_ value.
- * FIXME: Much of the code in the other java.net classes does not make
- * use of this family field. A better implementation would be to make
- * use of getaddrinfo() and have other methods just check the family
- * field rather than examining the length of the address each time.
+ * Needed for serialization.
*/
- int family;
+ private int family;
/**
- * Initializes this object's addr instance variable from the passed in
- * byte array. Note that this constructor is protected and is called
- * only by static methods in this class.
+ * Constructor. Prior to the introduction of IPv6 support in 1.4,
+ * methods such as InetAddress.getByName() would return InetAddress
+ * objects. From 1.4 such methods returned either Inet4Address or
+ * Inet6Address objects, but for compatibility Inet4Address objects
+ * are serialized as InetAddresses. As such, there are only two
+ * places where it is appropriate to invoke this constructor: within
+ * subclasses constructors and within Inet4Address.writeReplace().
*
* @param ipaddr The IP number of this address as an array of bytes
* @param hostname The hostname of this IP address.
+ * @param family The address family of this IP address.
*/
- InetAddress(byte[] ipaddr, String hostname)
+ InetAddress(byte[] ipaddr, String hostname, int family)
{
addr = (null == ipaddr) ? null : (byte[]) ipaddr.clone();
hostName = hostname;
-
- if (ipaddr != null)
- family = getFamily(ipaddr);
+ this.family = family;
}
/**
@@ -135,154 +155,263 @@ public class InetAddress implements Serializable
* An address is multicast if the high four bits are "1110". These are
* also known as "Class D" addresses.
*
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
* @return true if mulitcast, false if not
*
* @since 1.1
*/
public boolean isMulticastAddress()
{
- // Mask against high order bits of 1110
- if (addr.length == 4)
- return (addr[0] & 0xf0) == 0xe0;
-
- // Mask against high order bits of 11111111
- if (addr.length == 16)
- return addr [0] == (byte) 0xFF;
-
- return false;
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isMulticastAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
}
/**
* Utility routine to check if the InetAddress in a wildcard address
*
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
* @since 1.4
*/
public boolean isAnyLocalAddress()
{
- // This is the IPv4 implementation.
- // Any class derived from InetAddress should override this.
- return equals(ANY_IF);
+ // This is inefficient, but certain methods on Win32 create
+ // InetAddress objects using "new InetAddress" rather than
+ // "InetAddress.getByAddress" so we provide a method body.
+ // This code is never executed on Posix systems.
+ try
+ {
+ return getByAddress(hostName, addr).isAnyLocalAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
}
/**
* Utility routine to check if the InetAddress is a loopback address
*
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
* @since 1.4
*/
public boolean isLoopbackAddress()
{
- // This is the IPv4 implementation.
- // Any class derived from InetAddress should override this.
- return (addr[0] & 0xff) == 0x7f;
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isLoopbackAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
}
/**
* Utility routine to check if InetAddress is a link local address
*
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
* @since 1.4
*/
public boolean isLinkLocalAddress()
{
- // This is the IPv4 implementation.
- // Any class derived from InetAddress should override this.
- // XXX: This seems to not exist with IPv4 addresses
- return false;
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isLinkLocalAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
}
/**
* Utility routine to check if InetAddress is a site local address
*
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
* @since 1.4
*/
public boolean isSiteLocalAddress()
{
- // This is the IPv4 implementation.
- // Any class derived from InetAddress should override this.
-
- // 10.0.0.0/8
- if ((addr[0] & 0xff) == 0x0a)
- return true;
-
- // 172.16.0.0/12
- if ((addr[0] & 0xff) == 0xac && (addr[1] & 0xf0) == 0x10)
- return true;
-
- // 192.168.0.0/16
- if ((addr[0] & 0xff) == 0xc0 && (addr[1] & 0xff) == 0xa8)
- return true;
-
- // XXX: Do we need to check more addresses here ?
- return false;
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isSiteLocalAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
}
/**
* Utility routine to check if InetAddress is a global multicast address
*
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
* @since 1.4
*/
public boolean isMCGlobal()
{
- // This is the IPv4 implementation.
- // Any class derived from InetAddress should override this.
- // XXX: This seems to not exist with IPv4 addresses
- return false;
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isMCGlobal();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
}
/**
* Utility routine to check if InetAddress is a node local multicast address.
*
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
* @since 1.4
*/
public boolean isMCNodeLocal()
{
- // This is the IPv4 implementation.
- // Any class derived from InetAddress should override this.
- // XXX: This seems to not exist with IPv4 addresses
- return false;
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isMCNodeLocal();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
}
/**
* Utility routine to check if InetAddress is a link local multicast address.
*
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
* @since 1.4
*/
public boolean isMCLinkLocal()
{
- // This is the IPv4 implementation.
- // Any class derived from InetAddress should override this.
- if (! isMulticastAddress())
- return false;
-
- return ((addr[0] & 0xff) == 0xe0
- && (addr[1] & 0xff) == 0x00
- && (addr[2] & 0xff) == 0x00);
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isMCLinkLocal();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
}
/**
* Utility routine to check if InetAddress is a site local multicast address.
*
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
* @since 1.4
*/
public boolean isMCSiteLocal()
{
- // This is the IPv4 implementation.
- // Any class derived from InetAddress should override this.
- // XXX: This seems to not exist with IPv4 addresses
- return false;
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isMCSiteLocal();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
}
/**
* Utility routine to check if InetAddress is a organization local
* multicast address.
*
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
* @since 1.4
*/
public boolean isMCOrgLocal()
{
- // This is the IPv4 implementation.
- // Any class derived from InetAddress should override this.
- // XXX: This seems to not exist with IPv4 addresses
- return false;
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isMCOrgLocal();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
}
/**
@@ -293,28 +422,42 @@ public class InetAddress implements Serializable
*/
public String getHostName()
{
- if (hostName != null)
- return hostName;
+ if (hostName == null)
+ hostName = getCanonicalHostName();
- // Lookup hostname and set field.
- lookup (null, this, false);
-
return hostName;
}
/**
* Returns the canonical hostname represented by this InetAddress
+ */
+ String internalGetCanonicalHostName()
+ {
+ try
+ {
+ return ResolverCache.getHostByAddr(addr);
+ }
+ catch (UnknownHostException e)
+ {
+ return getHostAddress();
+ }
+ }
+
+ /**
+ * Returns the canonical hostname represented by this InetAddress
*
* @since 1.4
*/
public String getCanonicalHostName()
{
+ String hostname = internalGetCanonicalHostName();
+
SecurityManager sm = System.getSecurityManager();
if (sm != null)
{
try
{
- sm.checkConnect(hostName, -1);
+ sm.checkConnect(hostname, -1);
}
catch (SecurityException e)
{
@@ -322,16 +465,7 @@ public class InetAddress implements Serializable
}
}
- // Try to find the FDQN now
- InetAddress address;
- byte[] ipaddr = getAddress();
-
- if (ipaddr.length == 16)
- address = new Inet6Address(getAddress(), null);
- else
- address = new Inet4Address(getAddress(), null);
-
- return address.getHostName();
+ return hostname;
}
/**
@@ -346,91 +480,32 @@ public class InetAddress implements Serializable
return (byte[]) addr.clone();
}
- /* Helper function due to a CNI limitation. */
- private static InetAddress[] allocArray (int count)
- {
- return new InetAddress [count];
- }
-
- /* Helper function due to a CNI limitation. */
- private static SecurityException checkConnect (String hostname)
- {
- SecurityManager s = System.getSecurityManager();
-
- if (s == null)
- return null;
-
- try
- {
- s.checkConnect (hostname, -1);
- return null;
- }
- catch (SecurityException ex)
- {
- return ex;
- }
- }
-
/**
- * Returns the IP address of this object as a String. The address is in
- * the dotted octet notation, for example, "127.0.0.1".
+ * Returns the IP address of this object as a String.
*
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
* @return The IP address of this object in String form
*
* @since 1.0.2
*/
public String getHostAddress()
{
- StringBuffer sb = new StringBuffer(40);
-
- int len = addr.length;
- int i = 0;
-
- if (len == 16)
- { // An IPv6 address.
- for ( ; ; i += 2)
- {
- if (i >= 16)
- return sb.toString();
-
- int x = ((addr [i] & 0xFF) << 8) | (addr [i + 1] & 0xFF);
- boolean empty = sb.length() == 0;
-
- if (empty)
- {
- if (i == 10 && x == 0xFFFF)
- { // IPv4-mapped IPv6 address.
- sb.append (":FFFF:");
- break; // Continue as IPv4 address;
- }
- else if (i == 12)
- { // IPv4-compatible IPv6 address.
- sb.append (':');
- break; // Continue as IPv4 address.
- }
- else if (i > 0)
- sb.append ("::");
- }
- else
- sb.append (':');
-
- if (x != 0 || i >= 14)
- sb.append (Integer.toHexString (x).toUpperCase());
- }
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).getHostAddress();
}
-
- for ( ; ; )
+ catch (UnknownHostException e)
{
- sb.append(addr[i] & 0xff);
- i++;
-
- if (i == len)
- break;
-
- sb.append('.');
+ throw new RuntimeException("should never happen", e);
}
-
- return sb.toString();
}
/**
@@ -555,33 +630,32 @@ public class InetAddress implements Serializable
}
/**
- * If hostname is a valid numeric IP address, return the numeric address.
- * Otherwise, return null.
- *
- * @param hostname the name of the host
- */
- private static native byte[] aton(String hostname);
-
- /**
- * Looks up all addresses of a given host.
+ * Returns an InetAddress object representing the IP address of
+ * the given literal IP address in dotted decimal format such as
+ * "127.0.0.1". This is used by SocketPermission.setHostPort()
+ * to parse literal IP addresses without performing a DNS lookup.
*
- * @param hostname the host to lookup
- * @param ipaddr the IP address to lookup
- * @param all return all known addresses for one host
+ * @param literal The literal IP address to create the InetAddress
+ * object from
*
- * @return an array with all found addresses
+ * @return The address of the host as an InetAddress object, or
+ * null if the IP address is invalid.
*/
- private static native InetAddress[] lookup (String hostname,
- InetAddress ipaddr, boolean all);
-
- /**
- * Returns tha family type of an IP address.
- *
- * @param addr the IP address
- *
- * @return the family
- */
- private static native int getFamily (byte[] ipaddr);
+ static InetAddress getByLiteral(String literal)
+ {
+ byte[] address = VMInetAddress.aton(literal);
+ if (address == null)
+ return null;
+
+ try
+ {
+ return getByAddress(address);
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ }
/**
* Returns an InetAddress object representing the IP address of the given
@@ -604,25 +678,8 @@ public class InetAddress implements Serializable
public static InetAddress getByName(String hostname)
throws UnknownHostException
{
- // If null or the empty string is supplied, the loopback address
- // is returned.
- if (hostname == null || hostname.length() == 0)
- return loopback;
-
- // Assume that the host string is an IP address
- byte[] address = aton(hostname);
- if (address != null)
- return getByAddress(address);
-
- // Perform security check before resolving
- SecurityManager s = System.getSecurityManager();
- if (s != null)
- s.checkConnect(hostname, -1);
-
- // Try to resolve the host by DNS
- InetAddress result = new InetAddress(null, null);
- lookup (hostname, result, false);
- return result;
+ InetAddress[] addresses = getAllByName(hostname);
+ return addresses[0];
}
/**
@@ -648,31 +705,29 @@ public class InetAddress implements Serializable
// If null or the empty string is supplied, the loopback address
// is returned.
if (hostname == null || hostname.length() == 0)
- return new InetAddress[] {loopback};
+ return new InetAddress[] {LOCALHOST};
// Check if hostname is an IP address
- byte[] address = aton (hostname);
+ InetAddress address = getByLiteral(hostname);
if (address != null)
- return new InetAddress[] {getByAddress(address)};
+ return new InetAddress[] {address};
// Perform security check before resolving
- SecurityManager s = System.getSecurityManager();
- if (s != null)
- s.checkConnect(hostname, -1);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkConnect(hostname, -1);
- // Try to resolve the hostname by DNS
- return lookup (hostname, null, true);
- }
+ // Resolve the hostname
+ byte[][] iplist = ResolverCache.getHostByName(hostname);
+ if (iplist.length == 0)
+ throw new UnknownHostException(hostname);
- /**
- * This native method looks up the hostname of the local machine
- * we are on. If the actual hostname cannot be determined, then the
- * value "localhost" will be used. This native method wrappers the
- * "gethostname" function.
- *
- * @return The local hostname.
- */
- private static native String getLocalHostname();
+ InetAddress[] addresses = new InetAddress[iplist.length];
+ for (int i = 0; i < iplist.length; i++)
+ addresses[i] = getByAddress(hostname, iplist[i]);
+
+ return addresses;
+ }
/**
* Returns an InetAddress object representing the address of the current
@@ -685,62 +740,24 @@ public class InetAddress implements Serializable
*/
public static InetAddress getLocalHost() throws UnknownHostException
{
- SecurityManager s = System.getSecurityManager();
-
- // Experimentation shows that JDK1.2 does cache the result.
- // However, if there is a security manager, and the cached result
- // is other than "localhost", we need to check again.
- if (localhost == null
- || (s != null && ! localhost.isLoopbackAddress()))
- getLocalHost (s);
-
- return localhost;
- }
-
- private static synchronized void getLocalHost (SecurityManager s)
- throws UnknownHostException
- {
- // Check the localhost cache again, now that we've synchronized.
- if (s == null && localhost != null)
- return;
-
- String hostname = getLocalHostname();
-
- if (hostname == null || hostname.length() == 0)
- throw new UnknownHostException();
-
+ String hostname = VMInetAddress.getLocalHostname();
try
{
- // "The Java Class Libraries" suggests that if the security
- // manager disallows getting the local host name, then
- // we use the loopback host.
- // However, the JDK 1.2 API claims to throw SecurityException,
- // which seems to suggest SecurityException is *not* caught.
- // In this case, experimentation shows that former is correct.
- if (s != null)
- {
- // This is wrong, if the name returned from getLocalHostname()
- // is not a fully qualified name. FIXME.
- s.checkConnect (hostname, -1);
- }
-
- localhost = new InetAddress (null, null);
- lookup (hostname, localhost, false);
+ return getByName(hostname);
}
- catch (Exception ex)
+ catch (SecurityException e)
{
- UnknownHostException failure = new UnknownHostException(hostname);
- failure.initCause(ex);
- throw failure;
+ return LOCALHOST;
}
}
/**
- * Needed for serialization
+ * Inet4Address objects are serialized as InetAddress objects.
+ * This deserializes them back into Inet4Address objects.
*/
- private void readResolve() throws ObjectStreamException
+ private Object readResolve() throws ObjectStreamException
{
- // FIXME: implement this
+ return new Inet4Address(addr, hostName);
}
private void readObject(ObjectInputStream ois)
@@ -752,13 +769,6 @@ public class InetAddress implements Serializable
for (int i = 2; i >= 0; --i)
addr[i] = (byte) (address >>= 8);
-
- // Ignore family from serialized data. Since the saved address is 32 bits
- // the deserialized object will have an IPv4 address i.e. AF_INET family.
- // FIXME: An alternative is to call the aton method on the deserialized
- // hostname to get a new address. The Serialized Form doc is silent
- // on how these fields are used.
- family = getFamily (addr);
}
private void writeObject(ObjectOutputStream oos) throws IOException
@@ -769,8 +779,35 @@ public class InetAddress implements Serializable
int i = len - 4;
for (; i < len; i++)
- address = address << 8 | (((int) addr[i]) & 0xFF);
+ address = address << 8 | (addr[i] & 0xff);
oos.defaultWriteObject();
}
+
+ // The native methods remain here for now;
+ // methods in VMInetAddress map onto them.
+ static native byte[] aton(String hostname);
+ static native InetAddress[] lookup (String hostname,
+ InetAddress ipaddr, boolean all);
+ static native int getFamily (byte[] ipaddr);
+ static native String getLocalHostname();
+
+ // Some soon-to-be-removed native code synchronizes on this.
+ static InetAddress loopbackAddress = LOCALHOST;
+
+ // Some soon-to-be-removed code uses this old and broken method.
+ InetAddress(byte[] ipaddr, String hostname)
+ {
+ addr = (null == ipaddr) ? null : (byte[]) ipaddr.clone();
+ hostName = hostname;
+
+ if (ipaddr != null)
+ family = getFamily(ipaddr);
+ }
+
+ // Some soon-to-be-removed native code uses this old method.
+ private static InetAddress[] allocArray (int count)
+ {
+ return new InetAddress [count];
+ }
}
diff --git a/libjava/java/net/VMInetAddress.java b/libjava/java/net/VMInetAddress.java
new file mode 100644
index 0000000..b10cf25
--- /dev/null
+++ b/libjava/java/net/VMInetAddress.java
@@ -0,0 +1,117 @@
+/* VMInetAddress.java -- Class to model an Internet address
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.net;
+
+import gnu.classpath.Configuration;
+
+import java.io.Serializable;
+
+class VMInetAddress implements Serializable
+{
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ System.loadLibrary("javanet");
+ }
+
+ /**
+ * This method looks up the hostname of the local machine
+ * we are on. If the actual hostname cannot be determined, then the
+ * value "localhost" will be used. This native method wrappers the
+ * "gethostname" function.
+ *
+ * @return The local hostname.
+ */
+ public static String getLocalHostname()
+ {
+ return InetAddress.getLocalHostname();
+ }
+
+ /**
+ * Returns the value of the special address INADDR_ANY
+ */
+ public static byte[] lookupInaddrAny() throws UnknownHostException
+ {
+ return new byte[] {0, 0, 0, 0};
+ }
+
+ /**
+ * This method returns the hostname for a given IP address. It will
+ * throw an UnknownHostException if the hostname cannot be determined.
+ *
+ * @param ip The IP address as a byte array
+ *
+ * @return The hostname
+ *
+ * @exception UnknownHostException If the reverse lookup fails
+ */
+ public static String getHostByAddr(byte[] ip) throws UnknownHostException
+ {
+ InetAddress addr = InetAddress.getByAddress(ip);
+ InetAddress.lookup(null, addr, false);
+ return addr.getHostName();
+ }
+
+ /**
+ * Returns a list of all IP addresses for a given hostname. Will throw
+ * an UnknownHostException if the hostname cannot be resolved.
+ */
+ public static byte[][] getHostByName(String hostname)
+ throws UnknownHostException
+ {
+ InetAddress[] iaddrs = InetAddress.lookup(hostname, null, true);
+ byte[][] addrs = new byte[iaddrs.length][];
+ for (int i = 0; i < iaddrs.length; i++)
+ addrs[i] = iaddrs[i].getAddress();
+ return addrs;
+ }
+
+ /**
+ * Return the IP address represented by a literal address.
+ * Will return null if the literal address is not valid.
+ *
+ * @param address the name of the host
+ *
+ * @return The IP address as a byte array
+ */
+ public static byte[] aton(String address)
+ {
+ return InetAddress.aton(address);
+ }
+}
diff --git a/libjava/java/net/natVMNetworkInterfacePosix.cc b/libjava/java/net/natVMNetworkInterfacePosix.cc
index 8238d9c..bfb11d2 100644
--- a/libjava/java/net/natVMNetworkInterfacePosix.cc
+++ b/libjava/java/net/natVMNetworkInterfacePosix.cc
@@ -40,7 +40,7 @@ details. */
#include <gcj/cni.h>
#include <jvm.h>
-#include <java/net/Inet4Address.h>
+#include <java/net/InetAddress.h>
#include <java/net/NetworkInterface.h>
#include <java/net/SocketException.h>
#include <java/net/VMNetworkInterface.h>
@@ -148,8 +148,7 @@ java::net::VMNetworkInterface::getInterfaces ()
jbyteArray baddr = JvNewByteArray (len);
memcpy (elements (baddr), &(sa.sin_addr), len);
jstring if_name = JvNewStringLatin1 (if_record->ifr_name);
- Inet4Address* address =
- new java::net::Inet4Address (baddr, JvNewStringLatin1 (""));
+ InetAddress* address = java::net::InetAddress::getByAddress (baddr);
ht->add (new NetworkInterface (if_name, address));
if_record++;
}
diff --git a/libjava/sources.am b/libjava/sources.am
index 56502e2..d7b18f4 100644
--- a/libjava/sources.am
+++ b/libjava/sources.am
@@ -5223,6 +5223,7 @@ classpath/java/net/NoRouteToHostException.java \
classpath/java/net/PasswordAuthentication.java \
classpath/java/net/PortUnreachableException.java \
classpath/java/net/ProtocolException.java \
+classpath/java/net/ResolverCache.java \
classpath/java/net/ServerSocket.java \
classpath/java/net/Socket.java \
classpath/java/net/SocketAddress.java \
@@ -5243,6 +5244,7 @@ classpath/java/net/URLStreamHandler.java \
classpath/java/net/URLStreamHandlerFactory.java \
classpath/java/net/UnknownHostException.java \
classpath/java/net/UnknownServiceException.java \
+java/net/VMInetAddress.java \
java/net/VMNetworkInterface.java \
java/net/VMURLConnection.java