From aac8697859d550b39baf967900578ee47259c419 Mon Sep 17 00:00:00 2001 From: Gary Benson Date: Wed, 20 Sep 2006 07:55:26 +0000 Subject: InetAddress.java: Mostly merged with Classpath. 2006-09-20 Gary Benson * 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. From-SVN: r117075 --- libjava/ChangeLog | 14 + libjava/Makefile.in | 2 + .../java/net/natPlainDatagramSocketImplPosix.cc | 6 +- libjava/gnu/java/net/natPlainSocketImplPosix.cc | 4 +- libjava/java/net/InetAddress.java | 627 +++++++++++---------- libjava/java/net/VMInetAddress.java | 117 ++++ libjava/java/net/natVMNetworkInterfacePosix.cc | 5 +- libjava/sources.am | 2 + 8 files changed, 474 insertions(+), 303 deletions(-) create mode 100644 libjava/java/net/VMInetAddress.java (limited to 'libjava') 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 + + * 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 * 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. * + *

This method cannot be abstract for backward compatibility reasons. By + * default it always throws {@link UnsupportedOperationException} unless + * overridden.

+ * * @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 * + *

This method cannot be abstract for backward compatibility reasons. By + * default it always throws {@link UnsupportedOperationException} unless + * overridden.

+ * * @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 * + *

This method cannot be abstract for backward compatibility reasons. By + * default it always throws {@link UnsupportedOperationException} unless + * overridden.

+ * * @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 * + *

This method cannot be abstract for backward compatibility reasons. By + * default it always throws {@link UnsupportedOperationException} unless + * overridden.

+ * * @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 * + *

This method cannot be abstract for backward compatibility reasons. By + * default it always throws {@link UnsupportedOperationException} unless + * overridden.

+ * * @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 * + *

This method cannot be abstract for backward compatibility reasons. By + * default it always throws {@link UnsupportedOperationException} unless + * overridden.

+ * * @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. * + *

This method cannot be abstract for backward compatibility reasons. By + * default it always throws {@link UnsupportedOperationException} unless + * overridden.

+ * * @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. * + *

This method cannot be abstract for backward compatibility reasons. By + * default it always throws {@link UnsupportedOperationException} unless + * overridden.

+ * * @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. * + *

This method cannot be abstract for backward compatibility reasons. By + * default it always throws {@link UnsupportedOperationException} unless + * overridden.

+ * * @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. * + *

This method cannot be abstract for backward compatibility reasons. By + * default it always throws {@link UnsupportedOperationException} unless + * overridden.

+ * * @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. * + *

This method cannot be abstract for backward compatibility reasons. By + * default it always throws {@link UnsupportedOperationException} unless + * overridden.

+ * * @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 #include -#include +#include #include #include #include @@ -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 -- cgit v1.1