[kaffe] IPv6 and pure java DNS patch
Timothy Stack
stack@cs.utah.edu
Tue Apr 15 12:45:02 2003
--%--multipart-mixed-boundary-1.21652.1050436020--%
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
hi,
I've attached a patch that adds support for IPv6 and doing DNS lookups in
pure Java using dnsjava. I'll take care of actually committing it, this
is mostly a heads up before I do that. Theres a short FAQ and Changelog
entry in the patch, so take a look at those for some more details.
thanks,
tim stack
--%--multipart-mixed-boundary-1.21652.1050436020--%
Content-Type: application/octet-stream
Content-Transfer-Encoding: 7bit
Content-Description: ASCII English text
Content-Disposition: attachment; filename="net.diff"
--- /dev/null Tue Apr 15 13:18:29 2003
+++ net.ChangeLog Tue Apr 15 08:23:34 2003
@@ -0,0 +1,84 @@
+2003-04-14 Tim Stack <stack@cs.utah.edu>
+
+ * Makefile.am:
+ Add DNSJAVA_JAR to the BUILD_ENVIRONMENT.
+
+ * configure.in:
+ Add --with-dnsjava option that lets the user specify a dnsjava Jar
+ file from www.xbill.org/dnsjava.
+
+ * FAQ/FAQ.dns:
+ Explanation of DNS stuff in kaffe.
+
+ * include/Arrays.h:
+ Add more unhand_*_array() macros.
+
+ * include/Makefile.am:
+ Add java_net_NativeInetAddressImpl.h and
+ java_net_NetworkInterfaceImpl.h.
+
+ * include/errors.h:
+ Add JAVA_NET() macro.
+
+ * libraries/clib/net/InetAddressImpl.c:
+ Rewrite to use getaddrinfo()/getnameinfo() and support the new
+ InetAddressImpl API.
+
+ * libraries/clib/net/Makefile.am:
+ Change NetworkInterface.c to NetworkInterfaceImpl.c.
+
+ * libraries/clib/net/NetworkInterface.c:
+ Renamed to NetworkInterfaceImpl.c.
+
+ * libraries/clib/net/NetworkInterfaceImpl.c:
+ Name change and add support for IPv6 addresses.
+
+ * libraries/javalib/Makefile.am:
+ Add support for pure java DNS. Add Inet4Address/Inet6Address from
+ classpath. Add NetworkInterfaceImpl.java.
+
+ * libraries/javalib/bootstrap.classlist:
+ Add java/net/NativeInetAddressImpl.class and
+ java/net/NetworkInterfaceImpl.class.
+
+ * libraries/javalib/essential.files:
+ Add java/net/NativeInetAddressImpl.java.
+
+ * libraries/javalib/rebuildLib.in:
+ Test for zero arguments and exit with zero. Use the
+ BUILD_ENVIRONMENT for jikes too.
+
+ * libraries/javalib/java/lang/IllegalArgumentException.java:
+ Add exception chaining.
+
+ * libraries/javalib/java/net/DNSJavaInetAddressImpl.java:
+ InetAddressImpl that uses dnsjava from xbill.org.
+
+ * libraries/javalib/java/net/Inet4Address.java,
+ libraries/javalib/java/net/Inet6Address.java:
+ Merged from GNU classpath and fixed.
+
+ * libraries/javalib/java/net/InetAddress.java:
+ Add support for IPv6 addresses and multiple implementations.
+
+ * libraries/javalib/java/net/InetAddressImpl.java:
+ Changes to support IPv6 and multiple implementations.
+
+ * libraries/javalib/java/net/NativeInetAddressImpl.java:
+ Default native InetAddressImpl.
+
+ * libraries/javalib/java/net/NetworkInterface.java:
+ Move implementation details to NetworkInterfaceImpl.java and
+ detection is now done on every call instead of once at startup.
+
+ * libraries/javalib/java/net/NetworkInterfaceImpl.java:
+ Implementation details for NetworkInterface.java.
+
+ * libraries/javalib/java/net/UnknownHostException.java:
+ Add exception chaining.
+
+ * test/regression/InetAddressTest.java:
+ Simple test for InetAddresses.
+
+ * test/regression/Makefile.am:
+ Add InetAddressTest.java.
--- /dev/null Tue Apr 15 13:18:29 2003
+++ FAQ/FAQ.dns Tue Apr 15 13:12:32 2003
@@ -0,0 +1,105 @@
+
+Introduction
+------------
+
+Kaffe is able to perform DNS lookups in two ways, the OS provided
+resolver or a pure Java version that utilizes dnsjava[1]. By default,
+Kaffe will use the native resolvers, however, in some configurations,
+it will cause the whole JVM to block during name lookups.
+Alternatively, by configuring with dnsjava, there are less
+dependencies on the underlying OS and the whole process will not block
+during lookups.
+
+
+Configure Options
+-----------------
+
+ --with-dnsjava=<jar> - Specify a Jar file containing the dnsjava
+ classes.
+
+
+Properties
+----------
+
+ org.kaffe.dns (get only) - Contains the name of the DNS
+ implementation being used.
+
+
+Examples
+--------
+
+The following code will create a class whose main will do a lookup on
+the first argument and report all the results, along with the DNS
+implementation in use.
+
+>>> BEGIN DNSExample.java
+import java.net.InetAddress;
+
+class DNSExample
+{
+ public static void main(String args[])
+ throws Throwable
+ {
+ InetAddress ia[];
+ int lpc;
+
+ System.out.println("Start query...");
+ ia = InetAddress.getAllByName(args[0]);
+ System.out.println("Query done using: "
+ + System.getProperty("org.kaffe.dns"));
+ for( lpc = 0; lpc < ia.length; lpc++ )
+ {
+ System.out.println(ia[lpc].toString());
+ }
+ }
+}
+<<< END DNSExample.java
+
+You can then run the example with a host name that has a mix of IPv4
+and IPv6 addresses.
+
+rory@yale> java DNSExample ns1.ipv6.he.net
+Start query...
+Query done using: java.net.DNSJavaInetAddressImpl
+ns1.ipv6.he.net./64.71.188.2
+ns1.ipv6.he.net./3ffe:81d0:ffff::250:4ff:fe3c:aa95
+
+
+Manifest
+--------
+
+ libraries/javalib/java/net/InetAddress.java - The standard interface
+ to DNS services for IP.
+
+ libraries/javalib/java/net/Inet4Address.java, Inet6Address.java -
+ IPv4 and IPv6 InetAddress implementations pulled from GNU
+ Classpath[2]. These were modified somewhat since the original
+ versions were buggy.
+
+ libraries/javalib/java/net/InetAddressImpl.java - The base class for
+ implementation classes.
+
+ libraries/javalib/java/net/NativeInetAddressImpl.java - The native
+ implementation that uses InetAddressImpl.c.
+
+ libraries/cilb/net/InetAddressImpl.c - The native DNS implementation
+ that uses getaddrinfo()/getnameinfo() when possible and falls back to
+ gethostbyname()/gethostbyaddr().
+
+ libraries/javalib/java/net/DNSJavaInetAddressImpl.java - The pure
+ Java implementation that uses dnsjava[1].
+
+
+References
+----------
+
+[1] A DNS implementation in Java, http://www.xbill.org/dnsjava,
+ Brian Wellington
+
+[2] GNU Classpath, http://www.gnu.org/software/classpath/classpath.html
+
+
+History
+-------
+
+April 15, 2003: Initial version.
--- /dev/null Tue Apr 15 13:18:29 2003
+++ libraries/clib/net/NetworkInterfaceImpl.c Mon Apr 14 20:12:37 2003
@@ -0,0 +1,147 @@
+/*
+ * NetworkInterfaceImpl.c
+ * Native implementation of java.net.NetworkInterface functions.
+ *
+ * Copyright (c) 2002, 2003 University of Utah and the Flux Group.
+ * All rights reserved.
+ *
+ * This file is licensed under the terms of the GNU Public License.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * Contributed by the Flux Research Group, Department of Computer Science,
+ * University of Utah, http://www.cs.utah.edu/flux/
+ */
+
+#include "config.h"
+#include "config-std.h"
+#include "config-mem.h"
+#include "config-net.h"
+#include "config-io.h"
+#include "config-hacks.h"
+#include <native.h>
+#include "java_net_NetworkInterfaceImpl.h"
+#include "nets.h"
+#include <arpa/inet.h>
+#include <jsyscall.h>
+#include "../../../kaffe/kaffevm/debug.h"
+
+#include <ifaddrs.h>
+
+struct Hkaffe_util_Ptr *
+java_net_NetworkInterfaceImpl_detectInterfaces(void)
+{
+ struct Hkaffe_util_Ptr *retval = NULL;
+ struct ifaddrs *ifa;
+ errorInfo einfo;
+
+ if( getifaddrs(&ifa) == 0 )
+ {
+ retval = (struct Hkaffe_util_Ptr *)ifa;
+ }
+ else
+ {
+ switch( errno )
+ {
+ case ENOMEM:
+ postOutOfMemory(&einfo);
+ break;
+ case ENOSYS:
+ postExceptionMessage(
+ &einfo,
+ "kaffe.util.NotImplemented",
+ "OS doesn't support getifaddrs()");
+ break;
+ default:
+ postExceptionMessage(
+ &einfo,
+ "java.net.SocketException",
+ "%s",
+ SYS_ERROR(errno));
+ break;
+ }
+ throwError(&einfo);
+ }
+ return( retval );
+}
+
+void
+java_net_NetworkInterfaceImpl_freeInterfaces(struct Hkaffe_util_Ptr *jifa)
+{
+ if( jifa )
+ {
+ freeifaddrs((struct ifaddrs *)jifa);
+ }
+}
+
+struct Hkaffe_util_Ptr *
+java_net_NetworkInterfaceImpl_getNext(struct Hkaffe_util_Ptr *jifa)
+{
+ struct Hkaffe_util_Ptr *retval = NULL;
+
+ if( jifa )
+ {
+ struct ifaddrs *ifa = (struct ifaddrs *)jifa;
+
+ retval = (struct Hkaffe_util_Ptr *)ifa->ifa_next;
+ }
+ return( retval );
+}
+
+struct Hjava_lang_String *
+java_net_NetworkInterfaceImpl_getName(struct Hkaffe_util_Ptr *jifa)
+{
+ struct Hjava_lang_String *retval = NULL;
+
+ if( jifa )
+ {
+ struct ifaddrs *ifa = (struct ifaddrs *)jifa;
+
+ retval = stringC2Java(ifa->ifa_name);
+ }
+ return( retval );
+}
+
+struct Hjava_lang_String *
+java_net_NetworkInterfaceImpl_getIPAddress(struct Hkaffe_util_Ptr *jifa)
+{
+ struct Hjava_lang_String *retval = NULL;
+
+ if( jifa )
+ {
+ struct ifaddrs *ifa = (struct ifaddrs *)jifa;
+ struct sockaddr *sa;
+
+ if( (sa = ifa->ifa_addr) )
+ {
+#define NII_MAX_ADDRESS_SIZE 128
+ char addr[NII_MAX_ADDRESS_SIZE];
+
+ switch( sa->sa_family )
+ {
+ case AF_INET:
+ inet_ntop(sa->sa_family,
+ &((struct sockaddr_in *)sa)->
+ sin_addr,
+ addr,
+ NII_MAX_ADDRESS_SIZE);
+ retval = stringC2Java(addr);
+ break;
+#if defined(AF_INET6)
+ case AF_INET6:
+ inet_ntop(sa->sa_family,
+ &((struct sockaddr_in6 *)sa)->
+ sin6_addr,
+ addr,
+ NII_MAX_ADDRESS_SIZE);
+ retval = stringC2Java(addr);
+ break;
+#endif
+ default:
+ /* XXX What to do? */
+ break;
+ }
+ }
+ }
+ return( retval );
+}
--- /dev/null Tue Apr 15 13:18:29 2003
+++ libraries/javalib/java/net/DNSJavaInetAddressImpl.java Tue Apr 15 09:42:47 2003
@@ -0,0 +1,507 @@
+/*
+ * DNSJavaInetAddressImpl.java
+ *
+ * Copyright (c) 2003 The University of Utah and the Flux Group.
+ * All rights reserved.
+ *
+ * @JANOSVM_KAFFE_BASED_LICENSE@
+ */
+
+package java.net;
+
+import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
+
+import java.io.IOException;
+
+import org.xbill.DNS.Name;
+import org.xbill.DNS.Type;
+import org.xbill.DNS.Cache;
+import org.xbill.DNS.RRset;
+import org.xbill.DNS.Rcode;
+import org.xbill.DNS.DClass;
+import org.xbill.DNS.Record;
+import org.xbill.DNS.ARecord;
+import org.xbill.DNS.Message;
+import org.xbill.DNS.A6Record;
+import org.xbill.DNS.PTRRecord;
+import org.xbill.DNS.AAAARecord;
+import org.xbill.DNS.FindServer;
+import org.xbill.DNS.CNAMERecord;
+import org.xbill.DNS.Credibility;
+import org.xbill.DNS.DNAMERecord;
+import org.xbill.DNS.SetResponse;
+import org.xbill.DNS.ExtendedResolver;
+import org.xbill.DNS.TextParseException;
+import org.xbill.DNS.NameTooLongException;
+
+/**
+ * InetAddressImpl that uses DNSJAVA (http://www.xbill.org/dnsjava).
+ */
+final class DNSJavaInetAddressImpl
+ extends InetAddressImpl
+{
+ /**
+ * Suffix used when doing reverse lookups in IPv4 space.
+ */
+ private static final Name IN_ADDR_ARPA;
+
+ /**
+ * Suffix used when doing reverse lookups in IPv6 space.
+ */
+ private static final Name IP6_INT;
+
+ /**
+ * Maximum number of CNAME records to traverse.
+ */
+ private static final int CNAME_MAX = 6;
+
+ static
+ {
+ try
+ {
+ IN_ADDR_ARPA = Name.fromString("IN-ADDR.ARPA.");
+ IP6_INT = Name.fromString("IP6.INT.");
+ }
+ catch(TextParseException e)
+ {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ /**
+ * Exception thrown when the name server is queried about a non-existent
+ * domain.
+ */
+ static class NXDomainException
+ extends Exception
+ {
+ /**
+ * Construct an NXDomainException with the given value.
+ *
+ * @param s A message describing the problem.
+ */
+ public NXDomainException(String s)
+ {
+ super(s);
+ }
+ }
+
+ /*
+ * The Resolver we'll be using.
+ */
+ private final ExtendedResolver er;
+
+ /**
+ * The default search path.
+ */
+ private final Name searchPath[];
+
+ /**
+ * Lookup cache.
+ */
+ private final Cache cache = new Cache();
+
+ /**
+ * @throws UnknownHostException if the super class could not find the DNS
+ * server.
+ */
+ DNSJavaInetAddressImpl()
+ throws UnknownHostException
+ {
+ boolean foundRootPath = false;
+ Name paths[];
+ int lpc;
+
+ this.er = new ExtendedResolver();
+ /*
+ * Initialize the search path. First, make sure the root name space is
+ * part of the path.
+ */
+ paths = FindServer.searchPath();
+ for( lpc = 0; lpc < paths.length; lpc++ )
+ {
+ if( paths[lpc].equals(Name.root) )
+ {
+ foundRootPath = true;
+ }
+ }
+ if( !foundRootPath )
+ {
+ /* The root name space is not in the path, add it. */
+ this.searchPath = new Name[paths.length + 1];
+ this.searchPath[this.searchPath.length - 1] = Name.root;
+ }
+ else
+ {
+ this.searchPath = new Name[paths.length];
+ }
+ System.arraycopy(paths, 0,
+ this.searchPath, 0,
+ paths.length);
+ }
+
+ /**
+ * Send and process the response to a query.
+ *
+ * @param question The question to ask the name server.
+ * @param reverse True if this is a reverse lookup and the caller expects
+ * PTRRecords or false if they want A*Records.
+ * @param depth Query counter, used to detect loops in CNAME records.
+ * @return An array of Records corresponding to the ones requested.
+ * @throws UnknownHostException if a problem is encountered while handling
+ * the query.
+ * @throws NXDomainException if the query is for a non-existent domain.
+ */
+ private Record[] doQuery(Record question, boolean reverse, int depth)
+ throws UnknownHostException,
+ NXDomainException
+ {
+ Record retval[] = null;
+ Message query;
+
+ if( depth >= CNAME_MAX )
+ {
+ /* Break a CNAME loop. */
+ throw new UnknownHostException("CNAME loop for: "
+ + question.getName());
+ }
+
+ query = Message.newQuery(question);
+ try
+ {
+ Message response;
+ SetResponse sr;
+
+ response = this.er.send(query);
+ switch( response.getHeader().getRcode() )
+ {
+ case Rcode.NOERROR:
+ sr = this.cache.addMessage(response);
+
+ if( sr == null )
+ {
+ sr = this.cache.lookupRecords(question.getName(),
+ Type.ANY,
+ Credibility.NORMAL);
+ }
+
+ if( sr.isSuccessful() )
+ {
+ RRset rrsets[] = sr.answers();
+ List list = new ArrayList();
+ int lpc;
+
+ /* Presumably, we got what we wanted. */
+ for( lpc = 0; lpc < rrsets.length; lpc++ )
+ {
+ Iterator it;
+
+ it = rrsets[lpc].rrs();
+ while( it.hasNext() )
+ {
+ Object record;
+
+ record = it.next();
+ /*
+ * Add only the records the caller is interested
+ * in...
+ */
+ if( !reverse && record instanceof ARecord )
+ {
+ /* ... IPv4 */
+ list.add(record);
+ }
+ else if( !reverse && record instanceof A6Record )
+ {
+ /* ... IPv6 */
+ list.add(record);
+ }
+ else if( !reverse && record instanceof AAAARecord )
+ {
+ /* ... IPv6 */
+ list.add(record);
+ }
+ else if( reverse && record instanceof PTRRecord )
+ {
+ /* ... reverse lookup */
+ list.add(record);
+ }
+ }
+ }
+ retval = new Record[list.size()];
+ list.toArray(retval);
+ }
+ else if( sr.isCNAME() )
+ {
+ CNAMERecord cname = sr.getCNAME();
+
+ /* Given name is an alias, follow the canonical name. */
+ retval = this.doQuery(Record.newRecord(cname.getTarget(),
+ Type.ANY,
+ DClass.IN),
+ reverse,
+ depth + 1);
+ }
+ else if( sr.isNXRRSET() )
+ {
+ /* The server has the name but no data. */
+ throw new UnknownHostException("No data for host: "
+ + question.getName());
+ }
+ else if( sr.isDNAME() )
+ {
+ DNAMERecord dname = sr.getDNAME();
+
+ /*
+ * Substitute part of the domain name with one from the
+ * server.
+ */
+ try
+ {
+ retval = this.doQuery(
+ Record.newRecord(question.getName().
+ fromDNAME(dname),
+ Type.ANY,
+ DClass.IN),
+ reverse,
+ depth + 1);
+ }
+ catch(NameTooLongException e)
+ {
+ throw new UnknownHostException(
+ "Substituting "
+ + dname.getTarget()
+ + " for "
+ + dname.getName()
+ + " in "
+ + question.getName()
+ + " created an illegally long name",
+ e);
+ }
+ }
+ else
+ {
+ /* Bad response (or bad handling by us). */
+ throw new UnknownHostException("Broken name server");
+ }
+ break;
+ case Rcode.NXDOMAIN:
+ sr = this.cache.addMessage(response);
+ throw new NXDomainException("Unknown host: "
+ + question.getName());
+ default:
+ throw new UnknownHostException("Broken name server");
+ }
+ }
+ catch(IOException e)
+ {
+ throw new UnknownHostException("Cannot reach name server", e);
+ }
+ return retval;
+ }
+
+ private Record[] doQuery(Record question, boolean reverse)
+ throws NameTooLongException,
+ UnknownHostException,
+ NXDomainException
+ {
+ return this.doQuery(question, reverse, 0);
+ }
+
+ private Record[] doQuery(Name name, Name suffix, boolean reverse)
+ throws NameTooLongException,
+ UnknownHostException,
+ NXDomainException
+ {
+ if( suffix != null )
+ {
+ name = Name.concatenate(name, suffix);
+ }
+ return this.doQuery(Record.newRecord(name, Type.ANY, DClass.IN),
+ reverse);
+ }
+
+ private Record[] doQuery(Name name)
+ throws UnknownHostException,
+ NXDomainException
+ {
+ try
+ {
+ return this.doQuery(name, (Name)null, false);
+ }
+ catch(NameTooLongException e)
+ {
+ throw new InternalError(e);
+ }
+ }
+
+ private Record[] doQuery(byte addr[])
+ throws UnknownHostException,
+ NXDomainException
+ {
+ try
+ {
+ StringBuffer sb = new StringBuffer();
+ Name suffix;
+ int lpc;
+
+ /* Need to construct a name that is in IP address form. */
+ switch( addr.length )
+ {
+ case 4:
+ for( lpc = addr.length - 1; lpc >= 0; lpc-- )
+ {
+ sb.append(addr[lpc] & 0xFF);
+ if( lpc > 0 )
+ sb.append(".");
+ }
+ suffix = IN_ADDR_ARPA;
+ break;
+ case 16:
+ for( lpc = addr.length - 1; lpc >= 0; lpc-- )
+ {
+ sb.append(addr[lpc] & 0x0F);
+ sb.append(".");
+ sb.append(addr[lpc] & 0xF0);
+ if( lpc > 0 )
+ sb.append(".");
+ }
+ suffix = IP6_INT;
+ break;
+ default:
+ throw new InternalError("Cannot handle address length: "
+ + addr.length);
+ }
+ return this.doQuery(Name.fromString(sb.toString()),
+ suffix,
+ true);
+ }
+ catch(TextParseException e)
+ {
+ throw new InternalError(e);
+ }
+ catch(NameTooLongException e)
+ {
+ throw new InternalError(e);
+ }
+ }
+
+ byte[][] lookupAllHostAddr(String host)
+ throws UnknownHostException
+ {
+ byte retval[][];
+
+ try
+ {
+ Name name = Name.fromString(host);
+ Record answer[] = null;
+ int lpc;
+
+ if( name.isAbsolute() )
+ {
+ try
+ {
+ /*
+ * Absolute address, don't try it with the suffixes in the
+ * search path.
+ */
+ answer = this.doQuery(name);
+ }
+ catch(NXDomainException e)
+ {
+ throw new UnknownHostException("Unknown host: "
+ + host,
+ e);
+ }
+ }
+ else
+ {
+ /* Relative address, scan the path. */
+ for( lpc = 0;
+ (lpc < this.searchPath.length) && (answer == null);
+ lpc++ )
+ {
+ try
+ {
+ answer = this.doQuery(name,
+ this.searchPath[lpc],
+ false);
+ }
+ catch(NameTooLongException e)
+ {
+ /* Ignore. */
+ }
+ catch(NXDomainException e)
+ {
+ /* Ignore. */
+ }
+ }
+ if( answer == null )
+ {
+ throw new UnknownHostException("Unknown host: "
+ + host);
+ }
+ }
+
+ /* Convert the reply to a set of byte arrays. */
+ retval = new byte[answer.length][];
+ for( lpc = 0; lpc < answer.length; lpc++ )
+ {
+ if( answer[lpc] instanceof ARecord )
+ {
+ String str;
+
+ str = answer[lpc].rdataToString();
+ retval[lpc] = InetAddress.getByName(str).getAddress();
+ }
+ else if( answer[lpc] instanceof A6Record )
+ {
+ retval[lpc] = ((A6Record)answer[lpc]).getSuffix().
+ toBytes();
+ }
+ else if( answer[lpc] instanceof AAAARecord )
+ {
+ retval[lpc] = ((AAAARecord)answer[lpc]).getAddress().
+ toBytes();
+ }
+ else
+ {
+ throw new InternalError("Unhandled record type: "
+ + answer[lpc]);
+ }
+ }
+ }
+ catch(TextParseException e)
+ {
+ throw new UnknownHostException("Badly formatted host name: "
+ + host,
+ e);
+ }
+ return retval;
+ }
+
+ String getHostByAddr(byte addr[])
+ throws UnknownHostException
+ {
+ try
+ {
+ String retval;
+
+ retval = this.doQuery(addr)[0].rdataToString();
+ return retval.substring(0, retval.length() - 1);
+ }
+ catch(NXDomainException e)
+ {
+ throw new UnknownHostException();
+ }
+ }
+
+ public String toString()
+ {
+ return "DNSJavaInetAddressImpl["
+ + super.toString()
+ + "]";
+ }
+}
--- /dev/null Tue Apr 15 13:18:29 2003
+++ libraries/javalib/java/net/Inet4Address.java Mon Apr 14 20:17:34 2003
@@ -0,0 +1,302 @@
+/* Inet4Address.java
+ Copyright (C) 2002, 2003 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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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 java.io.IOException;
+import java.io.ObjectStreamException;
+
+import java.util.StringTokenizer;
+import java.util.NoSuchElementException;
+
+/**
+ * @author Michael Koch
+ * @date August 3, 2002.
+ */
+
+/*
+ * Written using on-line Java Platform 1.4 API Specification and
+ * RFC 1884 (http://www.ietf.org/rfc/rfc1884.txt),
+ * RFC 1918 (http://www.ietf.org/rfc/rfc1918.txt),
+ * RFC 2365 (http://www.ietf.org/rfc/rfc2365.txt)
+ * Status: Believed complete and correct.
+ */
+
+public final class Inet4Address extends InetAddress
+{
+ static final long serialVersionUID = 7615067291688066509L;
+
+ /**
+ * Convert a string formatted as an IPv4 address into a byte array.
+ *
+ * @param address The address to convert.
+ * @return A byte array containing the converted address.
+ * @throws IllegalArgumentException if the address string does not represent
+ * a properly formatted address.
+ */
+ static byte[] fromString(String address)
+ throws IllegalArgumentException
+ {
+ StringTokenizer st = new StringTokenizer(address, ".");
+ byte retval[] = new byte[4];
+
+ try
+ {
+ int lpc;
+
+ for( lpc = 0; lpc < retval.length; lpc++ )
+ {
+ int number;
+
+ number = Integer.parseInt(st.nextToken());
+ if( (number < 0) || (number > 255) )
+ {
+ throw new IllegalArgumentException("IP address component out of "
+ + "range: "
+ + number);
+ }
+ retval[lpc] = (byte)number;
+ }
+ if( st.hasMoreTokens() )
+ {
+ throw new IllegalArgumentException(
+ "Extraneous data after IP address: "
+ + address);
+ }
+ }
+ catch(NoSuchElementException e)
+ {
+ throw new IllegalArgumentException(e);
+ }
+ catch(NumberFormatException e)
+ {
+ throw new IllegalArgumentException(e);
+ }
+ return retval;
+ }
+
+ /**
+ * needed for serialization
+ */
+ private Object writeReplace () throws ObjectStreamException
+ {
+ return new InetAddress (addr, hostName);
+ }
+
+ /**
+ * Creates a Inet4Address
+ *
+ * @param addr The IP address
+ * @param host The Hostname
+ */
+ protected Inet4Address(byte[] addr, String host)
+ {
+ super (addr, host);
+ }
+
+ /**
+ * Checks if the address is a multicast address
+ *
+ * @since 1.1
+ */
+ public boolean isMulticastAddress ()
+ {
+ return (addr [0] & 0xF0) == 0xE0;
+ }
+
+ /**
+ * Checks if this address is a loopback address
+ */
+ public boolean isLoopbackAddress ()
+ {
+ return addr [0] == 0x7F;
+ }
+
+ /**
+ * Checks if this address is a wildcard address
+ *
+ * @since 1.4
+ */
+ public boolean isAnyLocalAddress ()
+ {
+ return super.address == 0;
+ }
+
+ /**
+ * Checks if this address is a link local address
+ *
+ * @since 1.4
+ */
+ public boolean isLinkLocalAddress ()
+ {
+ // XXX: This seems to not exist with IPv4 addresses
+ return false;
+ }
+
+ /**
+ * Checks if this address is a site local address
+ *
+ * @since 1.4
+ */
+ public boolean isSiteLocalAddress ()
+ {
+ // 10.0.0.0/8
+ if (addr [0] == 0x0A)
+ return true;
+
+ // XXX: Suns JDK 1.4.1 (on Linux) seems to have a bug here:
+ // it says 172.16.0.0 - 172.255.255.255 are site local addresses
+ //
+ // 172.16.0.0/12
+ if (addr [0] == 0xAC && (addr [1] & 0xF0) == 0x01)
+ return true;
+
+ // 192.168.0.0/16
+ if (addr [0] == 0xC0 && addr [1] == 0xA8)
+ return true;
+
+ // XXX: Do we need to check more addresses here ?
+ return false;
+ }
+
+ /**
+ * Checks if this multicast address has global scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCGlobal ()
+ {
+ // XXX: This seems to net exist with IPv4 addresses
+ return false;
+ }
+
+ /**
+ * Checks if this multicast address has node scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCNodeLocal ()
+ {
+ // XXX: This seems to net exist with IPv4 addresses
+ return false;
+ }
+
+ /**
+ * Checks if this multicast address has link scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCLinkLocal ()
+ {
+ if (!isMulticastAddress ())
+ return false;
+
+ return (addr [0] == 0xE0)
+ && (addr [1] == 0x00)
+ && (addr [2] == 0x00);
+ }
+
+ /**
+ * Checks if this multicast address has site scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCSiteLocal ()
+ {
+ // XXX: This seems to net exist with IPv4 addresses
+ return false;
+ }
+
+ /**
+ * Checks if this multicast address has organization scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCOrgLocal ()
+ {
+ // XXX: This seems to net exist with IPv4 addresses
+ return false;
+ }
+
+ /**
+ * Returns the address of the current instance
+ */
+ public byte[] getAddress ()
+ {
+ return (byte[])addr.clone();
+ }
+
+ /**
+ * Returns the address as string
+ *
+ * @since 1.0.2
+ */
+ public String getHostAddress ()
+ {
+ StringBuffer sbuf = new StringBuffer (40);
+ int len = addr.length;
+ int i = 0;
+
+ for ( ; ; )
+ {
+ sbuf.append (addr [i] & 0xFF);
+ i++;
+
+ if (i == len)
+ break;
+
+ sbuf.append ('.');
+ }
+
+ return sbuf.toString ();
+ }
+
+ /**
+ * Computes the hashcode of the instance
+ */
+ public int hashCode ()
+ {
+ int hash = 0;
+ int len = addr.length;
+ int i = len > 4 ? len - 4 : 0;
+
+ for ( ; i < len; i++)
+ hash = (hash << 8) | (addr [i] & 0xFF);
+
+ return hash;
+ }
+} // class Inet4Address
--- /dev/null Tue Apr 15 13:18:29 2003
+++ libraries/javalib/java/net/Inet6Address.java Tue Apr 15 09:39:15 2003
@@ -0,0 +1,284 @@
+/* Inet6Address.java
+ Copyright (C) 2002, 2003 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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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 java.io.IOException;
+
+/**
+ * @author Michael Koch
+ * @date August 3, 2002.
+ */
+
+/*
+ * Written using on-line Java Platform 1.4 API Specification and
+ * RFC 1884 (http://www.ietf.org/rfc/rfc1884.txt)
+ * Status: Believed complete and correct.
+ */
+
+public final class Inet6Address extends InetAddress
+{
+ static final long serialVersionUID = 6880410070516793377L;
+
+ private static final byte ANY_LOCAL[] = { 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ private static final byte LOOPBACK[] = { 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1 };
+
+ private static boolean compareAddresses(byte a1[], byte a2[])
+ {
+ boolean retval = true;
+ int lpc;
+
+ for( lpc = 0; lpc < a1.length && retval; lpc++ )
+ {
+ retval = (a1[lpc] == a2[lpc]);
+ }
+ return retval;
+ }
+
+ /**
+ * Needed for serialization
+ */
+ byte[] ipaddress;
+
+ /**
+ * Create an Inet6Address object
+ *
+ * @param addr The IP address
+ * @param host The hostname
+ */
+ protected Inet6Address (byte[] addr, String host)
+ {
+ super (addr, host);
+ this.ipaddress = addr;
+ }
+
+ /**
+ * Utility routine to check if the InetAddress is an IP multicast address
+ *
+ * @since 1.1
+ */
+ public boolean isMulticastAddress ()
+ {
+ return ipaddress [0] == 0xFF;
+ }
+
+ /**
+ * Utility routine to check if the InetAddress in a wildcard address
+ *
+ * @since 1.4
+ */
+ public boolean isAnyLocalAddress ()
+ {
+ return compareAddresses(this.ipaddress, ANY_LOCAL);
+ }
+
+ /**
+ * Utility routine to check if the InetAddress is a loopback address
+ *
+ * @since 1.4
+ */
+ public boolean isLoopbackAddress ()
+ {
+ return compareAddresses(this.ipaddress, LOOPBACK);
+ }
+
+ /**
+ * Utility routine to check if the InetAddress is an link local address
+ *
+ * @since 1.4
+ */
+ public boolean isLinkLocalAddress ()
+ {
+ return ipaddress [0] == 0xFA;
+ }
+
+ /**
+ * Utility routine to check if the InetAddress is a site local address
+ *
+ * @since 1.4
+ */
+ public boolean isSiteLocalAddress ()
+ {
+ return ipaddress [0] == 0xFB;
+ }
+
+ /**
+ * Utility routine to check if the multicast address has global scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCGlobal ()
+ {
+ if (!isMulticastAddress ())
+ return false;
+
+ return (ipaddress [1] & 0x0F) == 0xE;
+ }
+
+ /**
+ * Utility routine to check if the multicast address has node scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCNodeLocal ()
+ {
+ if (!isMulticastAddress ())
+ return false;
+
+ return (ipaddress [1] & 0x0F) == 0x1;
+ }
+
+ /**
+ * Utility routine to check if the multicast address has link scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCLinkLocal ()
+ {
+ if (!isMulticastAddress ())
+ return false;
+
+ return (ipaddress [1] & 0x0F) == 0x2;
+ }
+
+ /**
+ * Utility routine to check if the multicast address has site scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCSiteLocal ()
+ {
+ if (!isMulticastAddress ())
+ return false;
+
+ return (ipaddress [1] & 0x0F) == 0x5;
+ }
+
+ /**
+ * Utility routine to check if the multicast address has organization scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCOrgLocal ()
+ {
+ if (!isMulticastAddress ())
+ return false;
+
+ return (ipaddress [1] & 0x0F) == 0x8;
+ }
+
+ /**
+ * Returns the raw IP address of this InetAddress object. The result is in
+ * network byte order: the highest order byte of the address is i
+ * n getAddress()[0]
+ */
+ public byte[] getAddress ()
+ {
+ return ipaddress;
+ }
+
+ /**
+ * Returns the IP address string in textual presentation
+ */
+ public String getHostAddress ()
+ {
+ StringBuffer sbuf = new StringBuffer (40);
+
+ for (int i = 0; i < 16; i += 2)
+ {
+ int x = ((ipaddress [i] & 0xFF) << 8) | (ipaddress [i + 1] & 0xFF);
+ boolean empty = sbuf.length () == 0;
+
+ if (empty)
+ {
+ if (i > 0)
+ sbuf.append ("::");
+ }
+ else
+ sbuf.append (':');
+
+ if (x != 0 || i >= 14)
+ sbuf.append (Integer.toHexString (x));
+ }
+
+ return sbuf.toString ();
+ }
+
+ /**
+ * Returns a hashcode for this IP address
+ */
+ public int hashCode ()
+ {
+ return super.hashCode ();
+ }
+
+ /**
+ * Compares this object against the specified object
+ */
+ public boolean equals (Object obj)
+ {
+ if (obj == null || ! (obj instanceof Inet6Address))
+ return false;
+
+ Inet6Address tmp = (Inet6Address) obj;
+
+ return super.equals (tmp)
+ && compareAddresses(this.ipaddress, tmp.ipaddress);
+ }
+
+ /**
+ * Utility routine to check if the InetAddress is an
+ * IPv4 compatible IPv6 address
+ *
+ * @since 1.4
+ */
+ public boolean isIPv4CompatibleAddress ()
+ {
+ if (ipaddress [0] != 0x00 || ipaddress [1] != 0x00 ||
+ ipaddress [2] != 0x00 || ipaddress [3] != 0x00 ||
+ ipaddress [4] != 0x00 || ipaddress [5] != 0x00 ||
+ ipaddress [6] != 0x00 || ipaddress [7] != 0x00 ||
+ ipaddress [8] != 0x00 || ipaddress [9] != 0x00 ||
+ ipaddress [10] != 0x00 || ipaddress [11] != 0x00)
+ return false;
+
+ return true;
+ }
+}
--- /dev/null Tue Apr 15 13:18:29 2003
+++ libraries/javalib/java/net/NativeInetAddressImpl.java Mon Apr 14 20:18:23 2003
@@ -0,0 +1,36 @@
+/*
+ * Java core library component.
+ *
+ * Copyright (c) 1997, 1998
+ * Transvirtual Technologies, Inc. All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file.
+ */
+
+package java.net;
+
+/**
+ * InetAddressImpl that uses native functions (getaddrinfo(), getnameinfo()).
+ */
+class NativeInetAddressImpl
+ extends InetAddressImpl
+{
+ native byte[][] lookupAllHostAddr0(String host)
+ throws UnknownHostException;
+
+ byte[][] lookupAllHostAddr(String host)
+ throws UnknownHostException
+ {
+ return this.lookupAllHostAddr0(host);
+ }
+
+ native String getHostByAddr0(byte addr[])
+ throws UnknownHostException;
+
+ String getHostByAddr(byte addr[])
+ throws UnknownHostException
+ {
+ return this.getHostByAddr0(addr);
+ }
+}
--- /dev/null Tue Apr 15 13:18:29 2003
+++ libraries/javalib/java/net/NetworkInterfaceImpl.java Mon Apr 14 20:18:04 2003
@@ -0,0 +1,168 @@
+/*
+ * NetworkInterfaceImpl.java
+ *
+ * Copyright (c) 2003 University of Utah and the Flux Group.
+ * All rights reserved.
+ *
+ * This file is licensed under the terms of the GNU Public License.
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * Contributed by the Flux Research Group, Department of Computer Science,
+ * University of Utah, http://www.cs.utah.edu/flux/
+ */
+
+package java.net;
+
+import java.util.Hashtable;
+
+/**
+ * Implementation specific functions for querying the set of NetworkInterfaces
+ */
+class NetworkInterfaceImpl
+{
+ static
+ {
+ /* Our native implementation is in kaffenet */
+ System.loadLibrary("net");
+ }
+
+ /**
+ * Detect the interfaces in this machine.
+ *
+ * @return The native list of interfaces.
+ * @throws SocketException if there is a problem with the native code.
+ */
+ private static native kaffe.util.Ptr detectInterfaces()
+ throws SocketException;
+
+ /**
+ * Free the native objects returned by detectInterfaces.
+ *
+ * @param ifaddrs The pointer returned by detectInterfaces or null.
+ */
+ private static native void freeInterfaces(kaffe.util.Ptr ifaddrs);
+
+ /**
+ * Get the next interface in the native list.
+ *
+ * @param ifaddr The current interface.
+ * @return The next interface in the list or null if there are no more.
+ */
+ private static native kaffe.util.Ptr getNext(kaffe.util.Ptr ifaddr);
+
+ /**
+ * @param ifaddr The current interface.
+ * @return The name encoded in the native object.
+ */
+ private static native String getName(kaffe.util.Ptr ifaddr);
+
+ /**
+ * @param ifaddr The current interface.
+ * @return The IP address of this interface as a string or null if the
+ * native object doesn't have an IP address.
+ */
+ private static native String getIPAddress(kaffe.util.Ptr ifaddr);
+
+ /**
+ * The detected interfaces, the table maps names to NetworkInterface
+ * objects.
+ */
+ private final Hashtable detectedInterfaces = new Hashtable();
+
+ /**
+ * Secondary mapping from InetAddresses to interface names.
+ */
+ private final Hashtable addressToName = new Hashtable();
+
+ /**
+ * Construct a NetworkInterfaceImpl.
+ *
+ * @throws SocketException if there was a problem reading the set of
+ * NetworkInterfaces.
+ */
+ NetworkInterfaceImpl()
+ throws SocketException
+ {
+ kaffe.util.Ptr ifaddrs = null, curr = null;
+
+ try
+ {
+ /* Detect all the network interfaces. */
+ curr = ifaddrs = detectInterfaces();
+ while( curr != null )
+ {
+ NetworkInterface ni;
+ String name;
+
+ name = getName(curr);
+ if( (ni = (NetworkInterface)this.detectedInterfaces.get(name))
+ == null )
+ {
+ ni = new NetworkInterface(name, name /* XXX */);
+ this.detectedInterfaces.put(name, ni);
+ }
+ try
+ {
+ String address;
+
+ if( (address = getIPAddress(curr)) != null )
+ {
+ InetAddress ia;
+
+ ia = InetAddress.getByName(address);
+ ni.setPrimaryAddress(ia);
+ this.addressToName.put(ia, ni.getName());
+ ni.getInetAddressesInternal().addElement(ia);
+ }
+ }
+ catch(UnknownHostException e)
+ {
+ /* Ignore... */
+ }
+ curr = getNext(curr);
+ }
+ this.detectedInterfaces.elements();
+ }
+ finally
+ {
+ /* Make sure to free the native objects. */
+ freeInterfaces(ifaddrs);
+ }
+ }
+
+ /**
+ * @return The table of detected interfaces.
+ */
+ Hashtable getDetectedInterfaces()
+ {
+ return this.detectedInterfaces;
+ }
+
+ /**
+ * @return The table that maps InetAddress' to the NIC name.
+ */
+ Hashtable getAddressToName()
+ {
+ return this.addressToName;
+ }
+
+ /**
+ * @param ia An InetAddress to map to a NIC name.
+ * @return The NIC name that has the given address or null if there is no
+ * mapping.
+ */
+ String nameForAddress(InetAddress ia)
+ {
+ return (String)this.addressToName.get(ia);
+ }
+
+ public String toString()
+ {
+ return "NetworkInterfaceImpl[detectedInterfaces={ "
+ + this.detectedInterfaces
+ + " }; addressToName={ "
+ + this.addressToName
+ + "]";
+ }
+}
--- /dev/null Tue Apr 15 13:18:29 2003
+++ test/regression/InetAddressTest.java Mon Apr 14 20:53:41 2003
@@ -0,0 +1,30 @@
+
+import java.net.InetAddress;
+
+public class InetAddressTest
+{
+ public static void main(String args[])
+ throws Throwable
+ {
+ InetAddress ia;
+
+ ia = InetAddress.getByName(null);
+ System.out.println("(null) = " + ia);
+
+ ia = InetAddress.getByName("");
+ System.out.println("\"\" = " + ia);
+
+ ia = InetAddress.getByName("localhost");
+ System.out.println("localhost = " + ia);
+ if( !ia.isLoopbackAddress() )
+ {
+ System.out.println("Not a loopback?");
+ }
+ }
+}
+
+/* Expected Output:
+(null) = localhost/127.0.0.1
+"" = localhost/127.0.0.1
+localhost = localhost/127.0.0.1
+*/
Index: Makefile.am
===================================================================
RCS file: /cvs/kaffe/kaffe/Makefile.am,v
retrieving revision 1.25
diff -u -r1.25 Makefile.am
--- Makefile.am 21 Feb 2003 09:51:06 -0000 1.25
+++ Makefile.am 15 Apr 2003 19:28:57 -0000
@@ -96,7 +96,7 @@
"DEBUG_ENV=$(DEBUG_ENV)" BUILD_ENVIRONMENT-make
BUILD_ENVIRONMENT-make: Makefile
- echo CLASSPATH=\$${CLASSPATH}\''$(PATHSEP)'\'.\''$(PATHSEP)'\'$(top_builddir)/libraries/javalib/rt.jar\''$(PATHSEP)'\'$(top_srcdir)/libraries/javalib/kjc.jar\; export CLASSPATH | sed 's,/,$(DIRSEP),g;s,\\,\\\\,g' > BUILD_ENVIRONMENT.new; \
+ echo CLASSPATH=\$${CLASSPATH}\''$(PATHSEP)'\'.\''$(PATHSEP)'\'$(top_builddir)/libraries/javalib/rt.jar\''$(PATHSEP)'\'$(top_srcdir)/libraries/javalib/kjc.jar\''$(PATHSEP)'\'$(DNSJAVA_JAR)\; export CLASSPATH | sed 's,/,$(DIRSEP),g;s,\\,\\\\,g' > BUILD_ENVIRONMENT.new; \
echo KAFFELIBRARYPATH=\$${KAFFELIBRARYPATH+\"\$$KAFFELIBRARYPATH\"\''$(PATHSEP)'\'}`for f in $(JAVA_LIBS); do echo "$$f" | sed 's%/[^/]*$$%%'; done | (tr '\012' ' '; echo) | sed -e 's/ $$//' -e "s/ /\'$(PATHSEP)\'/g"`\; export KAFFELIBRARYPATH >> BUILD_ENVIRONMENT.new; \
echo JAVA=$(top_builddir)/kaffe/kaffe/kaffe-bin$(EXEEXT)\; export JAVA >> BUILD_ENVIRONMENT.new
rm -f BUILD_ENVIRONMENT
Index: configure.in
===================================================================
RCS file: /cvs/kaffe/kaffe/configure.in,v
retrieving revision 1.188
diff -u -r1.188 configure.in
--- configure.in 11 Mar 2003 08:00:14 -0000 1.188
+++ configure.in 15 Apr 2003 19:28:59 -0000
@@ -336,6 +336,18 @@
esac
dnl =========================================================================
+dnl Allow user to specify a dnsjava.jar file for class file testing.
+dnl -------------------------------------------------------------------------
+
+AC_ARG_WITH(dnsjava,
+ [ --with-dnsjava=<jar> Use the specified DNS java Jar file.],
+ [ DNSJAVA_JAR="$withval" ],
+ [ DNSJAVA_JAR="" ])
+
+AC_SUBST(DNSJAVA_JAR)
+AM_CONDITIONAL(HAVE_DNSJAVA, test x"$DNSJAVA_JAR" != x"")
+
+dnl =========================================================================
dnl Allow support for profiling of C/jitted code
dnl -------------------------------------------------------------------------
@@ -982,6 +994,7 @@
AC_CHECK_FUNCS([mkdir rmdir])
AC_CHECK_FUNCS([getcwd chdir getwd gettimeofday ftime time uname getuid])
AC_CHECK_FUNCS([localtime])
+AC_CHECK_FUNCS([getaddrinfo])
AM_ICONV
LIBS="$LIBS $LIBICONV"
Index: include/Arrays.h
===================================================================
RCS file: /cvs/kaffe/kaffe/include/Arrays.h,v
retrieving revision 1.3
diff -u -r1.3 Arrays.h
--- include/Arrays.h 13 Feb 1999 09:21:55 -0000 1.3
+++ include/Arrays.h 15 Apr 2003 19:28:59 -0000
@@ -29,5 +29,14 @@
/* Get length of arrays */
#define obj_length(_obj) ((_obj)->length)
#define unhand_array(_arr) ((_arr)->data)
+#define unhand_byte_array(_arr) ((jbyte *)((_arr)->data))
+#define unhand_char_array(_arr) ((jchar *)((_arr)->data))
+#define unhand_double_array(_arr) ((jdouble *)((_arr)->data))
+#define unhand_float_array(_arr) ((jfloat *)((_arr)->data))
+#define unhand_int_array(_arr) ((jint *)((_arr)->data))
+#define unhand_short_array(_arr) ((jshort *)((_arr)->data))
+#define unhand_long_array(_arr) ((jlong *)((_arr)->data))
+#define unhand_array_array(_arr) ((Hjava_lang_Object **)((_arr)->data))
+#define unhand_object_array(_arr) ((Hjava_lang_Object *)((_arr)->data))
#endif
Index: include/Makefile.am
===================================================================
RCS file: /cvs/kaffe/kaffe/include/Makefile.am,v
retrieving revision 1.32
diff -u -r1.32 Makefile.am
--- include/Makefile.am 13 Apr 2003 09:20:33 -0000 1.32
+++ include/Makefile.am 15 Apr 2003 19:28:59 -0000
@@ -70,8 +70,10 @@
java_net_DatagramPacket.h \
java_net_InetAddress.h \
java_net_InetAddressImpl.h \
+ java_net_NativeInetAddressImpl.h \
java_net_InetSocketAddress.h \
java_net_NetworkInterface.h \
+ java_net_NetworkInterfaceImpl.h \
java_net_PlainDatagramSocketImpl.h \
java_net_PlainSocketImpl.h \
java_net_SocketAddress.h \
Index: include/errors.h
===================================================================
RCS file: /cvs/kaffe/kaffe/include/errors.h,v
retrieving revision 1.6
diff -u -r1.6 errors.h
--- include/errors.h 2 Jun 2002 02:24:03 -0000 1.6
+++ include/errors.h 15 Apr 2003 19:28:59 -0000
@@ -64,6 +64,7 @@
#define JAVA_LANG(NAME) "java.lang." #NAME
#define JAVA_IO(NAME) "java.io." #NAME
+#define JAVA_NET(NAME) "java.net." #NAME
#define NEW_LANG_EXCEPTION(NAME) \
Index: libraries/clib/net/InetAddressImpl.c
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/clib/net/InetAddressImpl.c,v
retrieving revision 1.12
diff -u -r1.12 InetAddressImpl.c
--- libraries/clib/net/InetAddressImpl.c 26 Dec 2000 14:01:48 -0000 1.12
+++ libraries/clib/net/InetAddressImpl.c 15 Apr 2003 19:29:00 -0000
@@ -13,6 +13,7 @@
#include "config-mem.h"
#include "config-net.h"
#include "config-io.h"
+#include <arpa/inet.h>
#include "../../../kaffe/kaffevm/gtypes.h"
#include "../../../kaffe/kaffevm/object.h"
#include <native.h>
@@ -21,132 +22,530 @@
#include "../../../kaffe/kaffevm/support.h"
#include "java_net_InetAddress.h"
#include "java_net_InetAddressImpl.h"
+#include "java_net_NativeInetAddressImpl.h"
#include "nets.h"
#include "jsyscall.h"
-#define HOSTNMSZ 80
+#include "baseClasses.h"
+#include "locks.h"
+
+#define HOSTNMSZ 1024
/*
- * Get localhost name.
+ * Return the inet address family.
*/
-struct Hjava_lang_String*
-java_net_InetAddressImpl_getLocalHostName(struct Hjava_net_InetAddressImpl* none)
+jint
+java_net_InetAddressImpl_getInetFamily(jint kind)
{
- char hostname[HOSTNMSZ];
-
- if (gethostname(hostname, HOSTNMSZ-1) < 0) {
- strcpy(hostname, "localhost");
+ jint retval = -1;
+ errorInfo einfo;
+
+ assert(kind > java_net_InetAddressImpl_INET_ADDRESS_MIN);
+ assert(kind < java_net_InetAddressImpl_INET_ADDRESS_MAX);
+
+ switch( kind )
+ {
+ case java_net_InetAddressImpl_INET_ADDRESS_V4:
+ retval = AF_INET;
+ break;
+#if defined(AF_INET6)
+ case java_net_InetAddressImpl_INET_ADDRESS_V6:
+ retval = AF_INET6;
+ break;
+#endif
+ default:
+ postExceptionMessage(&einfo,
+ JAVA_LANG(InternalError),
+ "Unknown family: %d",
+ kind);
+ throwError(&einfo);
+ break;
}
- return (checkPtr(stringC2Java(hostname)));
+ return( retval );
}
/*
- * Provide one of my local address (I guess).
+ * Get localhost name.
*/
-void
-java_net_InetAddressImpl_makeAnyLocalAddress(struct Hjava_net_InetAddressImpl* none, struct Hjava_net_InetAddress* this)
+struct Hjava_lang_String*
+java_net_InetAddressImpl_getLocalHostName(void)
{
- unhand(this)->hostName = 0;
- unhand(this)->address = INADDR_ANY;
- unhand(this)->family = AF_INET;
+ static char hostname[HOSTNMSZ] = "localhost";
+ static iLock *hostLock = 0;
+
+ struct Hjava_lang_String *retval = 0;
+ int iLockRoot;
+
+ lockStaticMutex(&hostLock);
+ if( gethostname(hostname, HOSTNMSZ - 1) < 0 )
+ {
+ assert(0);
+ }
+ retval = stringC2Java(hostname);
+ unlockStaticMutex(&hostLock);
+
+ return( checkPtr(retval) );
}
/*
- * Convert a hostname to the primary host address.
+ * Attempt to convert a string containing an IP address into a byte array.
*/
-jint
-java_net_InetAddressImpl_lookupHostAddr(struct Hjava_net_InetAddressImpl* none, struct Hjava_lang_String* str)
+HArrayOfByte*
+java_net_InetAddressImpl_stringToBits(Hjava_lang_String *jStr)
{
- char name[MAXHOSTNAME];
- struct hostent* ent;
- int rc;
-
- stringJava2CBuf(str, name, sizeof(name));
+ HArrayOfByte *retval = NULL;
- rc = KGETHOSTBYNAME(name, &ent);
- if (rc) {
- if (ent == (void *)-1) {
- SignalError("java.io.IOException", SYS_ERROR(rc));
+#define MAX_IPV6_STRING_SIZE 128
+ if( jStr->count < MAX_IPV6_STRING_SIZE )
+ {
+ char str[MAX_IPV6_STRING_SIZE];
+
+ stringJava2CBuf(jStr, str, MAX_IPV6_STRING_SIZE);
+ {
+ struct in_addr ia;
+
+ if( inet_pton(AF_INET, str, &ia) == 1 )
+ {
+ retval = (HArrayOfByte *)
+ newArray(TYPE_CLASS(TYPE_Byte),
+ sizeof(ia));
+ memcpy(unhand_byte_array(retval),
+ &ia,
+ sizeof(ia));
+ }
}
- else {
- SignalErrorf("java.net.UnknownHostException", "%s: %s",
- SYS_HERROR(rc), name);
+#if defined(AF_INET6)
+ if( retval == NULL )
+ {
+ struct in6_addr ia;
+
+ if( inet_pton(AF_INET6, str, &ia) == 1 )
+ {
+ retval = (HArrayOfByte *)
+ newArray(TYPE_CLASS(TYPE_Byte),
+ sizeof(ia));
+ memcpy(unhand_byte_array(retval),
+ &ia,
+ sizeof(ia));
+ }
}
+#endif
}
- return (ntohl(*(jint*)ent->h_addr_list[0]));
+ return( retval );
}
+static iLock *nsLock = 0;
+
/*
* Convert a hostname to an array of host addresses.
*/
-HArrayOfInt*
-java_net_InetAddressImpl_lookupAllHostAddr(struct Hjava_net_InetAddressImpl* none, struct Hjava_lang_String* str)
+HArrayOfArray*
+java_net_NativeInetAddressImpl_lookupAllHostAddr0(struct Hjava_net_NativeInetAddressImpl* none, struct Hjava_lang_String* jStr)
{
+#if defined(HAVE_GETADDRINFO)
+ int index = 0, count = 0, retryCount = 5, rc;
+ struct addrinfo hints, *ai = 0, *curr;
+ HArrayOfArray *retval = 0;
+ int iLockRoot;
+ errorInfo einfo;
+ char *name;
+
+ name = checkPtr(stringJava2C(jStr));
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ lockStaticMutex(&nsLock);
+ while( ((rc = getaddrinfo(name, NULL, &hints, &ai)) ==
+ EAI_AGAIN) &&
+ (retryCount > 0) )
+ {
+ unlockStaticMutex(&nsLock);
+ jthread_sleep(1 * 1000);
+ lockStaticMutex(&nsLock);
+ retryCount -= 1;
+ }
+ unlockStaticMutex(&nsLock);
+
+ switch( rc )
+ {
+ case 0:
+ /* Count the number of addresses. */
+ curr = ai;
+ while( curr )
+ {
+ switch( curr->ai_family )
+ {
+ case PF_INET:
+#if defined(PF_INET6)
+ case PF_INET6:
+#endif
+ count += 1;
+ break;
+ }
+ curr = curr->ai_next;
+ }
+
+ retval = (HArrayOfArray *)
+ newArrayChecked(ObjectClass, count, &einfo);
+ curr = ai;
+ while( curr && retval )
+ {
+#if defined(PF_INET6)
+ struct sockaddr_in6 *in6;
+#endif
+ struct sockaddr_in *in4;
+ HArrayOfByte *addr = 0;
+
+ switch( curr->ai_family )
+ {
+ case PF_INET:
+ in4 = (struct sockaddr_in *)
+ curr->ai_addr;
+ addr = (HArrayOfByte *)newArrayChecked(
+ TYPE_CLASS(TYPE_Byte),
+ sizeof(in4->sin_addr),
+ &einfo);
+ if( addr )
+ {
+ memcpy(unhand_byte_array(addr),
+ &in4->sin_addr,
+ sizeof(in4->sin_addr));
+ }
+ else
+ {
+ retval = 0;
+ }
+ break;
+#if defined(PF_INET6)
+ case PF_INET6:
+ in6 = (struct sockaddr_in6 *)
+ curr->ai_addr;
+ addr = (HArrayOfByte *)newArrayChecked(
+ TYPE_CLASS(TYPE_Byte),
+ sizeof(in6->sin6_addr),
+ &einfo);
+ if( addr )
+ {
+ memcpy(unhand_byte_array(addr),
+ &in6->sin6_addr,
+ sizeof(in6->sin6_addr));
+ }
+ else
+ {
+ retval = 0;
+ }
+ break;
+#endif
+ default:
+ /* Ignore */
+ break;
+ }
+ if( addr && retval )
+ {
+ unhand_array_array(retval)[index] =
+ &addr->base;
+ index += 1;
+ }
+ curr = curr->ai_next;
+ }
+ break;
+ case EAI_FAIL:
+ case EAI_AGAIN:
+ postExceptionMessage(&einfo,
+ JAVA_NET(UnknownHostException),
+ "Unable to contact name server");
+ break;
+ case EAI_NODATA:
+ postExceptionMessage(&einfo,
+ JAVA_NET(UnknownHostException),
+ "Unknown host: %s",
+ name);
+ break;
+ case EAI_MEMORY:
+ postOutOfMemory(&einfo);
+ break;
+ case EAI_SYSTEM:
+ postExceptionMessage(&einfo,
+ JAVA_NET(UnknownHostException),
+ "%s: %s",
+ SYS_ERROR(errno),
+ name);
+ break;
+
+ default:
+ postExceptionMessage(&einfo,
+ JAVA_LANG(InternalError),
+ "Unhandled getaddrinfo error: %s: %s",
+ gai_strerror(rc),
+ name);
+ break;
+ }
+ if( ai )
+ {
+ freeaddrinfo(ai);
+ }
+ gc_free(name);
+ if( !retval )
+ {
+ throwError(&einfo);
+ }
+ return( retval );
+#else
+ HArrayOfArray* retval = 0;
char name[MAXHOSTNAME];
struct hostent* ent;
- HArrayOfInt* array;
- int i;
- int alength;
- int rc;
-
- stringJava2CBuf(str, name, sizeof(name));
-
+ int i, alength, rc;
+ errorInfo einfo;
+
+ stringJava2CBuf(jStr, name, sizeof(name));
rc = KGETHOSTBYNAME(name, &ent);
- if (rc) {
- if (ent == (void *)-1) {
- SignalError("java.io.IOException", SYS_ERROR(rc));
+ if( rc == 0 )
+ {
+ for (alength = 0; ent->h_addr_list[alength]; alength++)
+ ;
+
+ if( (retval = (HArrayOfArray*)
+ newArrayChecked(ObjectClass,
+ alength,
+ &einfo)) == 0 )
+ {
+ postOutOfMemory(&einfo);
+ goto done;
}
- else {
- SignalErrorf("java.net.UnknownHostException", "%s: %s",
- SYS_HERROR(rc), name);
+
+ for( i = 0; i < alength; i++ )
+ {
+ HArrayOfByte *addr = 0;
+
+ /* Copy in the network address */
+ if( (addr = (HArrayOfByte *)
+ newArrayChecked(TYPE_CLASS(TYPE_Byte),
+ ent->h_length,
+ &einfo)) == 0 )
+ {
+ postOutOfMemory(&einfo);
+ goto done;
+ }
+ memcpy(unhand_byte_array(addr),
+ ent->h_addr_list[i],
+ ent->h_length);
+
+ unhand_array_array(retval)[i] = &addr->base;
}
}
-
- for (alength = 0; ent->h_addr_list[alength]; alength++)
- ;
-
- array = (HArrayOfInt*)AllocArray(alength, TYPE_Int);
- assert(array != 0);
-
- for (i = 0; i < alength; i++) {
- /* Copy in the network address */
- unhand_array(array)->body[i] = ntohl(*(jint*)ent->h_addr_list[i]);
+ else
+ {
+ const char *msg;
+
+ if( ent == (void *)-1 )
+ {
+ msg = SYS_ERROR(rc);
+ }
+ else
+ {
+ msg = SYS_HERROR(rc);
+ }
+ postExceptionMessage(&einfo,
+ JAVA_NET(UnknownHostException),
+ "%s: %s",
+ msg,
+ name);
+ }
+
+ done:
+ if( !retval )
+ {
+ throwError(&einfo);
}
- return (array);
+ return( retval );
+#endif
}
/*
* Convert a network order address into the hostname.
*/
struct Hjava_lang_String*
-java_net_InetAddressImpl_getHostByAddr(struct Hjava_net_InetAddressImpl* none, jint addr)
+java_net_NativeInetAddressImpl_getHostByAddr0(struct Hjava_net_NativeInetAddressImpl* none, HArrayOfByte *addr)
{
+#if defined(HAVE_GETADDRINFO)
+ struct Hjava_lang_String *retval = 0;
+#if defined(AF_INET6)
+ struct sockaddr_in6 sa_buf;
+ struct sockaddr_in6 *sin6 = &sa_buf;
+#else
+ struct sockaddr_in sa_buf;
+#endif
+ struct sockaddr_in *sin = (struct sockaddr_in *)&sa_buf;
+ int rc, retryCount = 5;
+ int iLockRoot;
+ errorInfo einfo;
+ char *hostname;
+
+ hostname = gc_malloc(NI_MAXHOST, GC_ALLOC_FIXED);
+ switch( addr->length )
+ {
+ case 4:
+ sin->sin_len = sizeof(struct sockaddr_in);
+ sin->sin_family = AF_INET;
+ sin->sin_port = 0;
+ memcpy(&sin->sin_addr, unhand_byte_array(addr), addr->length);
+ break;
+#if defined(AF_INET6)
+ case 16:
+ sin6->sin6_len = sizeof(struct sockaddr_in6);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = 0;
+ sin6->sin6_flowinfo = 0;
+ memcpy(&sin6->sin6_addr,
+ unhand_byte_array(addr),
+ addr->length);
+ sin6->sin6_scope_id = 0;
+ break;
+#endif
+ default:
+ postExceptionMessage(&einfo,
+ JAVA_LANG(InternalError),
+ "Illegal address length: %d",
+ addr->length);
+ goto done;
+ }
+ lockStaticMutex(&nsLock);
+ while( ((rc = getnameinfo((const struct sockaddr *)&sa_buf,
+ sin->sin_len,
+ hostname,
+ NI_MAXHOST,
+ NULL,
+ 0,
+ NI_NAMEREQD)) == EAI_AGAIN) &&
+ (retryCount > 0) )
+ {
+ unlockStaticMutex(&nsLock);
+ jthread_sleep(1 * 1000);
+ lockStaticMutex(&nsLock);
+ retryCount -= 1;
+ }
+ unlockStaticMutex(&nsLock);
+ switch( rc )
+ {
+ case 0:
+ if( (retval = stringC2Java(hostname)) == 0 )
+ {
+ postOutOfMemory(&einfo);
+ }
+ break;
+ case EAI_FAIL:
+ case EAI_AGAIN:
+ postExceptionMessage(&einfo,
+ JAVA_NET(UnknownHostException),
+ "Unable to contact name server");
+ break;
+ case EAI_MEMORY:
+ postOutOfMemory(&einfo);
+ break;
+ case EAI_NONAME:
+ inet_ntop(sin->sin_family,
+ unhand_byte_array(addr),
+ hostname,
+ NI_MAXHOST);
+ postExceptionMessage(&einfo,
+ JAVA_NET(UnknownHostException),
+ "Unknown host: %s",
+ hostname);
+ break;
+ case EAI_SYSTEM:
+ inet_ntop(sin->sin_family,
+ unhand_byte_array(addr),
+ hostname,
+ NI_MAXHOST);
+ postExceptionMessage(&einfo,
+ JAVA_NET(UnknownHostException),
+ "%s: %s",
+ SYS_ERROR(errno),
+ hostname);
+ break;
+ default:
+ inet_ntop(sin->sin_family,
+ unhand_byte_array(addr),
+ hostname,
+ NI_MAXHOST);
+ postExceptionMessage(&einfo,
+ JAVA_LANG(InternalError),
+ "Unhandled getnameinfo error: %s: %s",
+ gai_strerror(rc),
+ hostname);
+ break;
+ }
+ gc_free(hostname);
+ done:
+ if( !retval )
+ {
+ throwError(&einfo);
+ }
+
+ return( retval );
+#else
+ struct Hjava_lang_String *retval = 0;
+ char ipaddr[MAX_IPV6_STRING_SIZE];
struct hostent* ent;
- int rc;
-
- addr = htonl(addr);
- rc = KGETHOSTBYADDR((char*)&addr, sizeof(jint), AF_INET, &ent);
- if (rc) {
- char ipaddr[16];
- sprintf(ipaddr, "%3d.%3d.%3d.%3d",
- /* XXX Make sure it is the right endiannes */
- (addr >> 24) & 0xff,
- (addr >> 16) & 0xff,
- (addr >> 8) & 0xff,
- (addr) & 0xff);
- SignalErrorf("java.net.UnknownHostException", "%s: %s",
- SYS_HERROR(rc), ipaddr);
+ int family, rc = 0;
+ const char *msg;
+ errorInfo einfo;
+ int iLockRoot;
+
+ switch( obj_length(addr) )
+ {
+ case 4:
+ family = AF_INET;
+ break;
+#if defined(AF_INET6)
+ case 16:
+ family = AF_INET6;
+ break;
+#endif
+ default:
+ postExceptionMessage(&einfo,
+ JAVA_LANG(InternalError),
+ "Illegal address length: %d",
+ obj_length(addr));
+ goto done;
}
-
- return (checkPtr(stringC2Java((char*)ent->h_name)));
-}
-
-/*
- * Return the inet address family.
- */
-jint
-java_net_InetAddressImpl_getInetFamily(struct Hjava_net_InetAddressImpl* none)
-{
- return (AF_INET);
+ lockStaticMutex(&nsLock);
+ rc = KGETHOSTBYADDR(unhand_byte_array(addr),
+ obj_length(addr),
+ family,
+ &ent);
+ switch( rc )
+ {
+ case 0:
+ retval = stringC2Java((char *)ent->h_name);
+ break;
+ default:
+ if( ent == (void *)-1 )
+ {
+ msg = SYS_ERROR(rc);
+ }
+ else
+ {
+ msg = SYS_HERROR(rc);
+ }
+ postExceptionMessage(&einfo,
+ JAVA_NET(UnknownHostException),
+ "%s: %s",
+ msg,
+ inet_ntop(family,
+ unhand_byte_array(addr),
+ ipaddr,
+ sizeof(ipaddr)));
+ break;
+ }
+ done:
+ unlockStaticMutex(&nsLock);
+ if( !retval )
+ {
+ throwError(&einfo);
+ }
+
+ return( checkPtr(retval) );
+#endif
}
Index: libraries/clib/net/Makefile.am
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/clib/net/Makefile.am,v
retrieving revision 1.8
diff -u -r1.8 Makefile.am
--- libraries/clib/net/Makefile.am 21 Feb 2003 09:51:09 -0000 1.8
+++ libraries/clib/net/Makefile.am 15 Apr 2003 19:29:00 -0000
@@ -14,7 +14,7 @@
libnet_la_LIBADD = $(NET_LIBS) $(top_builddir)/replace/libreplace.la
libnet_la_SOURCES = \
InetAddressImpl.c \
- NetworkInterface.c \
+ NetworkInterfaceImpl.c \
PlainDatagramSocketImpl.c \
PlainSocketImpl.c
Index: libraries/javalib/Makefile.am
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/javalib/Makefile.am,v
retrieving revision 1.98
diff -u -r1.98 Makefile.am
--- libraries/javalib/Makefile.am 26 Feb 2003 21:44:34 -0000 1.98
+++ libraries/javalib/Makefile.am 15 Apr 2003 19:29:01 -0000
@@ -26,6 +26,12 @@
jrelib_DATA = rt.jar
toolslib_DATA = kjc.jar
+if HAVE_DNSJAVA
+DNSJAVA_InetAddressImpl = java/net/DNSJavaInetAddressImpl.java
+else
+DNSJAVA_InetAddressImpl =
+endif
+
Klasses_jar_SRCS = \
$(gnu_java_lang_SRCS) \
$(gnu_java_util_SRCS) \
@@ -834,16 +840,21 @@
java/net/DatagramSocket.java \
java/net/DatagramSocketImpl.java \
java/net/DatagramSocketImplFactory.java \
+ $(DNSJAVA_InetAddressImpl) \
java/net/FileNameMap.java \
java/net/HttpURLConnection.java \
java/net/InetAddress.java \
+ java/net/Inet4Address.java \
+ java/net/Inet6Address.java \
java/net/InetAddressImpl.java \
java/net/InetSocketAddress.java \
java/net/JarURLConnection.java \
java/net/MalformedURLException.java \
java/net/MulticastSocket.java \
+ java/net/NativeInetAddressImpl.java \
java/net/NetPermission.java \
java/net/NetworkInterface.java \
+ java/net/NetworkInterfaceImpl.java \
java/net/NoRouteToHostException.java \
java/net/PasswordAuthentication.java \
java/net/PlainDatagramSocketImpl.java \
@@ -2261,6 +2272,7 @@
mkdir $(LIBDIR)
$(SHELL) $(rebuildLib) @essential.files
$(SHELL) $(rebuildLib) @@java_math_files@
+ $(SHELL) $(rebuildLib) $(DNSJAVA_InetAddressImpl)
for i in `cat $(srcdir)/profiles/$(PROFILE)/profile` ; do $(SHELL) $(rebuildLib) @profiles/$(PROFILE)/$$i ; done
echo timestamp > $(LIBDIR)/stamp
Index: libraries/javalib/bootstrap.classlist
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/javalib/bootstrap.classlist,v
retrieving revision 1.11
diff -u -r1.11 bootstrap.classlist
--- libraries/javalib/bootstrap.classlist 21 Feb 2003 09:51:10 -0000 1.11
+++ libraries/javalib/bootstrap.classlist 15 Apr 2003 19:29:02 -0000
@@ -209,8 +209,10 @@
java/net/DatagramPacket.class
java/net/InetAddress.class
java/net/InetAddressImpl.class
+java/net/NativeInetAddressImpl.class
java/net/InetSocketAddress.class
java/net/NetworkInterface.class
+java/net/NetworkInterfaceImpl.class
java/net/PlainDatagramSocketImpl.class
java/net/PlainSocketImpl.class
java/net/SocketAddress.class
Index: libraries/javalib/essential.files
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/javalib/essential.files,v
retrieving revision 1.2
diff -u -r1.2 essential.files
--- libraries/javalib/essential.files 20 Feb 2003 13:52:08 -0000 1.2
+++ libraries/javalib/essential.files 15 Apr 2003 19:29:02 -0000
@@ -153,6 +153,7 @@
java/net/InetAddress.java
java/net/InetAddressImpl.java
java/net/MalformedURLException.java
+java/net/NativeInetAddressImpl.java
java/net/NetPermission.java
java/net/SocketPermission.java
java/net/UnknownHostException.java
Index: libraries/javalib/rebuildLib.in
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/javalib/rebuildLib.in,v
retrieving revision 1.31
diff -u -r1.31 rebuildLib.in
--- libraries/javalib/rebuildLib.in 3 Feb 2003 11:39:46 -0000 1.31
+++ libraries/javalib/rebuildLib.in 15 Apr 2003 19:29:02 -0000
@@ -9,6 +9,10 @@
# of this file.
#
+if [ -z "$1" ] ; then
+ exit 0
+fi
+
SRCDIR=${srcdir-`sed -n '/^srcdir *= */ s///p' < Makefile`}
LIBDIR=${LIBDIR-`sed -n '/^LIBDIR *= */ s///p' < Makefile`}
LIBDIR=${LIBDIR-lib}
@@ -34,6 +38,7 @@
CPATH="${CPATH+-classpath $LIBRARY${CPATH+@PATHSEP@$CPATH}}"
CLASSPATH=./Klasses.jar.bootstrap:$CLASSPATH; export CLASSPATH
else
+ test -f ${TOPBLD}/BUILD_ENVIRONMENT && . ${TOPBLD}/BUILD_ENVIRONMENT
JAVAC="$JIKES"
CPATH="${CPATH+-classpath $CPATH}"
# VERBOSE=${VERBOSE-"-verbose"}
Index: libraries/javalib/java/lang/IllegalArgumentException.java
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/javalib/java/lang/IllegalArgumentException.java,v
retrieving revision 1.1
diff -u -r1.1 IllegalArgumentException.java
--- libraries/javalib/java/lang/IllegalArgumentException.java 14 Jul 1998 14:20:01 -0000 1.1
+++ libraries/javalib/java/lang/IllegalArgumentException.java 15 Apr 2003 19:29:02 -0000
@@ -20,4 +20,12 @@
public IllegalArgumentException (String s) {
super(s);
}
+
+public IllegalArgumentException (Throwable th) {
+ super(th);
+}
+
+public IllegalArgumentException (String s, Throwable th) {
+ super(s, th);
+}
}
Index: libraries/javalib/java/net/InetAddress.java
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/javalib/java/net/InetAddress.java,v
retrieving revision 1.12
diff -u -r1.12 InetAddress.java
--- libraries/javalib/java/net/InetAddress.java 21 Feb 2003 09:51:10 -0000 1.12
+++ libraries/javalib/java/net/InetAddress.java 15 Apr 2003 19:29:02 -0000
@@ -13,197 +13,488 @@
import java.io.Serializable;
import java.util.StringTokenizer;
-final public class InetAddress
- implements Serializable {
+/**
+ * Base class for IP addresses. Implementation details are handled by the
+ * InetAddressImpl class.
+ */
+public class InetAddress
+ implements Serializable
+{
+ private static final long serialVersionUID = 3286316764910316507L;
+
+ private static final int IPV4_LOOPBACK_BITS = 0x7F000001;
+
+ /**
+ * Our handle on the implementation.
+ */
+ private static final InetAddressImpl impl;
+
+ /**
+ * The list of implementation classes, ordered from most to least
+ * desirable.
+ */
+ static final String INET_ADDRESS_IMPLS[] = {
+ "java.net.DNSJavaInetAddressImpl",
+ "java.net.NativeInetAddressImpl",
+ };
+
+ static
+ {
+ InetAddressImpl iai = null;
+ int lpc;
+
+ for( lpc = 0;
+ (lpc < INET_ADDRESS_IMPLS.length) && (iai == null);
+ lpc++ )
+ {
+ try
+ {
+ Class cl;
+
+ cl = Class.forName(INET_ADDRESS_IMPLS[lpc]);
+ iai = (InetAddressImpl)cl.newInstance();
+ System.setProperty("org.kaffe.dns", INET_ADDRESS_IMPLS[lpc]);
+ }
+ catch(IllegalAccessException e)
+ {
+ /* Really should not happen. */
+ throw new InternalError(e);
+ }
+ catch(ExceptionInInitializerError e)
+ {
+ }
+ catch(InstantiationException e)
+ {
+ }
+ catch(NoClassDefFoundError e)
+ {
+ }
+ catch(ClassNotFoundException e)
+ {
+ }
+ }
+ if( iai == null )
+ {
+ /* Not sure about this error type. */
+ throw new UnsatisfiedLinkError(
+ "Cannot find working InetAddressImpl");
+ }
+ impl = iai;
+ }
-private static final long serialVersionUID = 3286316764910316507L;
+ /**
+ * Convert an IPv4 address encoded in a byte to an integer.
+ *
+ * @param addr The address to convert.
+ * @return The address from addr or zero if the length of addr was not
+ * four.
+ */
+ private static int fromBytes(byte addr[])
+ {
+ int retval = 0;
-private static InetAddressImpl impl;
+ if( addr.length == 4 )
+ {
+ retval = (((addr[0] & 0xFF) << 24) |
+ ((addr[1] & 0xFF) << 16) |
+ ((addr[2] & 0xFF) << 8) |
+ ((addr[3] & 0xFF) ));
+ }
+ return retval;
+ }
-private String hostName;
-private int address;
-private int family;
+ /**
+ * Convert an IPv4 address encoded as an integer to a byte array.
+ *
+ * @param address The address to convert.
+ * @return A byte array containing the address value in network order.
+ */
+ private static byte[] toBytes(int address)
+ {
+ byte retval[] = new byte[4];
+
+ retval[0] = (byte)((address >> 24) & 0xFF);
+ retval[1] = (byte)((address >> 16) & 0xFF);
+ retval[2] = (byte)((address >> 8) & 0xFF);
+ retval[3] = (byte) (address & 0xFF);
+ return retval;
+ }
-static {
- impl = new InetAddressImpl();
-}
+ /**
+ * The host name as specified by the user or derived from a DNS lookup.
+ */
+ transient String hostName;
+
+ /**
+ * The IP address encoded as an array.
+ */
+ transient byte addr[];
+
+ /**
+ * The IPv4 address encoded as an integer.
+ */
+ int address;
+
+ /**
+ * The address family.
+ */
+ private int family;
+
+ /**
+ * The designated InetAddress constructor.
+ *
+ * @param addr The IP address.
+ * @param address The IPv4 address encoded as an integer or zero.
+ * @param name The given host name or null if a lookup should eventually be
+ * done.
+ */
+ InetAddress(byte addr[], int address, String name)
+ {
+ this.family = impl.getInetFamily(this instanceof Inet6Address ?
+ InetAddressImpl.INET_ADDRESS_V6 :
+ InetAddressImpl.INET_ADDRESS_V4);
+ this.hostName = name;
+ this.addr = addr;
+ this.address = address;
+ }
-private InetAddress(String name, int addr) {
- family = impl.getInetFamily();
- hostName = name;
- address = addr;
-}
+ /**
+ * @param addr The IP address.
+ * @param name The given host name or null if a lookup should eventually be
+ * done.
+ */
+ InetAddress(byte addr[], String name)
+ {
+ this(addr, fromBytes(addr), name);
+ }
-InetAddress() {
- family = impl.getInetFamily();
-}
+ /**
+ * @param address The IPv4 address encoded as an integer.
+ * @param name The given host name or null if a lookup should eventually be
+ * done.
+ */
+ InetAddress(int address, String name)
+ {
+ this(toBytes(address), address, name);
+ }
-public boolean equals(Object obj) {
- try
- {
- InetAddress ia;
+ /**
+ * Construct an empty InetAddress.
+ */
+ InetAddress()
+ {
+ this(null, 0, null);
+ }
- ia = (InetAddress)obj;
- if( (this.family == ia.family) &&
- (this.address == ia.address) )
+ public static InetAddress[] getAllByName(String host)
+ throws UnknownHostException,
+ SecurityException
+ {
+ InetAddress retval[];
+
+ if( host == null || host.equals("") || host.equals("localhost") )
+ {
+ retval = new InetAddress[] {
+ new Inet4Address(toBytes(IPV4_LOOPBACK_BITS), "localhost"),
+ };
+ }
+ else
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if( sm != null )
+ sm.checkConnect(host, -1);
+
+ byte ip[] = InetAddressImpl.stringToBits(host);
+ byte addrs[][];
+ int lpc;
+
+ if( ip == null )
+ {
+ /* Its a host name. */
+ addrs = impl.lookupAllHostAddr(host);
+ }
+ else
+ {
+ /* Its an IP address. */
+ addrs = new byte[][] { ip };
+ }
+ retval = new InetAddress[addrs.length];
+ /* Convert to the correct InetAddress type. */
+ for( lpc = 0; lpc < addrs.length; lpc++ )
+ {
+ switch( addrs[lpc].length )
{
- return true;
+ case 4:
+ retval[lpc] = new Inet4Address(addrs[lpc],
+ ip == null ?
+ host :
+ null);
+ break;
+ case 16:
+ retval[lpc] = new Inet6Address(addrs[lpc],
+ ip == null ?
+ host :
+ null);
+ break;
+ default:
+ throw new InternalError("Unhandled address length: "
+ + addrs[lpc].length);
}
+ }
}
- catch(ClassCastException e)
+ return retval;
+ }
+
+ public static InetAddress getByAddress(byte[] addr)
+ throws UnknownHostException
+ {
+ InetAddress retval;
+
+ switch( addr.length )
{
+ case 4:
+ retval = new Inet4Address(addr, null);
+ break;
+ case 16:
+ retval = new Inet6Address(addr, null);
+ break;
+
+ default:
+ throw new UnknownHostException("Bad address length: "
+ + addr.length
+ + " bytes");
}
- return false;
-}
-public byte[] getAddress() {
- byte result[] = new byte[4];
+ return retval;
+ }
- result[0] = (byte)((address >> 24) & 0xFF);
- result[1] = (byte)((address >> 16) & 0xFF);
- result[2] = (byte)((address >> 8) & 0xFF);
- result[3] = (byte) (address & 0xFF);
-
- return (result);
-}
-
-public static InetAddress[] getAllByName(String host) throws UnknownHostException {
- if (host == null || host.equals("")) {
- throw new UnknownHostException(host == null ? "" : host);
- }
-
- InetAddress[] addrs;
- if (Character.isDigit(host.charAt(0))) {
- addrs = new InetAddress[1];
- addrs[0] = getByName(host);
- }
- else {
- int data[] = impl.lookupAllHostAddr(host);
- int nr = data.length;
- addrs = new InetAddress[nr];
- for (int i = 0; i < nr; i++) {
- addrs[i] = new InetAddress(host, data[i]);
- }
+ public static InetAddress getByName(String host)
+ throws UnknownHostException
+ {
+ InetAddress retval = null, addrs[];
+ int lpc;
+
+ addrs = getAllByName(host);
+ /*
+ * Alas, the spec does not specify _which_ address to return. So, for
+ * the sake of backwards compatibility, we'll prefer the first IPv4
+ * address.
+ */
+ for( lpc = 0; (lpc < addrs.length) && (retval == null); lpc++ )
+ {
+ if( addrs[lpc] instanceof Inet4Address )
+ {
+ retval = addrs[lpc];
+ }
}
- return (addrs);
-}
+ if( (retval == null) && (addrs.length > 0) )
+ {
+ /* No IPv4 addresses, use the first IPv6. */
+ retval = addrs[0];
+ }
+ return retval;
+ }
-public static InetAddress getByAddress(byte[] addr) throws UnknownHostException {
- if (addr.length != 4 && addr.length != 16) {
- throw new UnknownHostException("bad address length: " + addr.length + " bytes");
- }
-
- if (addr.length == 16) {
- throw new kaffe.util.NotImplemented("Inet6 addresses are not supported.");
- }
-
- int address = ((addr[0] & 0xFF) << 24)
- + ((addr[1] & 0xFF) << 16)
- + ((addr[2] & 0xFF) << 8)
- + (addr[3]);
-
- return new InetAddress(null, address);
-}
-
-public static synchronized InetAddress getByName(String host) throws UnknownHostException {
- if (host == null || host.equals("")) {
- return (InetAddress.getLoopback());
- }
- int ip;
- if (!Character.isDigit(host.charAt(0))) {
- ip = impl.lookupHostAddr(host);
- }
- else {
- ip = 0;
- StringTokenizer tok = new StringTokenizer(host, ".");
- while (tok.hasMoreElements()) {
- String s = tok.nextToken();
- ip <<= 8;
- try {
- ip |= Integer.parseInt(s);
- }
- catch (NumberFormatException _) {
- }
- }
- host = null;
+ public static InetAddress getLocalHost()
+ throws UnknownHostException
+ {
+ try
+ {
+ String name = impl.getLocalHostName();
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkConnect(name, 0);
+ return InetAddress.getByName(name);
}
- return (new InetAddress(host, ip));
-}
+ catch(SecurityException se)
+ {
+ return InetAddress.getLoopback();
+ }
+ }
-public String getHostAddress() {
- byte b[] = getAddress();
- StringBuffer buf = new StringBuffer();
- buf.append(Integer.toString(b[0] & 0xFF));
- buf.append(".");
- buf.append(Integer.toString(b[1] & 0xFF));
- buf.append(".");
- buf.append(Integer.toString(b[2] & 0xFF));
- buf.append(".");
- buf.append(Integer.toString(b[3] & 0xFF));
- return (buf.toString());
-}
-
-public String getHostName() {
- try {
- if (hostName == null) {
- hostName = impl.getHostByAddr(address);
- }
+ public String getHostAddress()
+ {
+ return null;
+ }
+
+ public String getCanonicalHostName()
+ {
+ String retval;
+
+ try
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if( sm != null )
+ sm.checkConnect(this.hostName, -1);
+
+ /*
+ * Since this.hostName can be a local reference (e.g.'foo') we need
+ * to do a full lookup to get 'foo.bar.com'.
+ */
+ retval = impl.getHostByAddr(this.addr);
+
+ /* XXX Should we call checkConnect on retval? */
+ }
+ catch(UnknownHostException _)
+ {
+ retval = this.getHostAddress();
}
- catch (UnknownHostException _) {
- hostName = getHostAddress();
+ catch(SecurityException _)
+ {
+ retval = this.getHostAddress();
}
- return (hostName);
-}
+ return retval;
+ }
-public static InetAddress getLocalHost() throws UnknownHostException {
- try {
- String name = impl.getLocalHostName();
+ public String getHostName()
+ {
+ String retval;
+
+ try
+ {
+ if( this.hostName == null )
+ {
+ /* Lookup not done yet... */
+ this.hostName = impl.getHostByAddr(this.addr);
+ }
+ retval = this.hostName;
+
+ try
+ {
+ /* Make sure its visible to them. */
SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkConnect(name, 0);
- return (getByName(name));
+ if( sm != null )
+ sm.checkConnect(this.hostName, -1);
+ }
+ catch(SecurityException e)
+ {
+ retval = this.getHostAddress();
+ }
}
- catch (SecurityException se) {
- return (InetAddress.getLoopback());
+ catch(UnknownHostException _)
+ {
+ /* No joy on the lookup. */
+ retval = this.hostName = this.getHostAddress();
}
-}
+ return retval;
+ }
-public int hashCode() {
- return (address);
-}
+ public boolean isMulticastAddress()
+ {
+ return false;
+ }
-public boolean isMulticastAddress() {
- if ((address & 0xE0000000) == 0xE0000000) {
- return (true);
+ public boolean isAnyLocalAddress()
+ {
+ return false;
+ }
+
+ public boolean isLoopbackAddress()
+ {
+ return false;
+ }
+
+ public boolean isLinkLocalAddress()
+ {
+ return false;
+ }
+
+ public boolean isSiteLocalAddress()
+ {
+ return false;
+ }
+
+ public boolean isMCGlobal()
+ {
+ return false;
+ }
+
+ public boolean isMCNodeLocal()
+ {
+ return false;
+
+ }
+
+ public boolean isMCLinkLocal()
+ {
+ return false;
+ }
+
+ public boolean isMCSiteLocal()
+ {
+ return false;
+ }
+
+ public boolean isMCOrgLocal()
+ {
+ return false;
+ }
+
+ public byte[] getAddress()
+ {
+ return null;
+ }
+
+ public int hashCode()
+ {
+ return 0;
+ }
+
+ public boolean equals(Object obj)
+ {
+ try
+ {
+ InetAddress ia;
+
+ ia = (InetAddress)obj;
+ if( (this.family == ia.family) &&
+ (this.address == ia.address) )
+ {
+ return true;
+ }
}
- else {
- return (false);
+ catch(ClassCastException e)
+ {
}
-}
-
-public boolean isAnyLocalAddress() {
- return this.address == 0;
-}
+ return false;
+ }
-public String toString() {
+ public String toString()
+ {
StringBuffer result = new StringBuffer();
- result.append(getHostName());
+ if( this.hostName == null )
+ {
+ result.append("");
+ }
+ else
+ {
+ result.append(this.hostName);
+ }
result.append("/");
result.append(getHostAddress());
- return (result.toString());
-}
+ return result.toString();
+ }
-static InetAddress getLoopback() {
- return (new InetAddress("loopback", 0x7F000001));
-}
-
-static InetAddress getAnyAddress() {
- InetAddress a = new InetAddress();
- impl.makeAnyLocalAddress(a);
- return (a);
-}
+ static InetAddress getLoopback()
+ {
+ return new InetAddress(IPV4_LOOPBACK_BITS, "localhost");
+ }
+ /** JanosVM extension for JSR-121 prototype */
+ /*package*/ InetAddress dup()
+ {
+ InetAddress retval = new InetAddress();
+
+ retval.hostName = this.hostName == null ? null : new String(this.hostName.toCharArray());
+ retval.address = this.address;
+ retval.family = this.family;
+ return retval;
+ }
+ static InetAddress getAnyAddress()
+ {
+ return new InetAddress(new byte[] { 0, 0, 0, 0 }, null);
+ }
}
Index: libraries/javalib/java/net/InetAddressImpl.java
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/javalib/java/net/InetAddressImpl.java,v
retrieving revision 1.5
diff -u -r1.5 InetAddressImpl.java
--- libraries/javalib/java/net/InetAddressImpl.java 22 Nov 2001 06:21:14 -0000 1.5
+++ libraries/javalib/java/net/InetAddressImpl.java 15 Apr 2003 19:29:02 -0000
@@ -10,18 +10,71 @@
package java.net;
+/**
+ * Base class for DNS implementations.
+ */
+abstract class InetAddressImpl
+{
+ public static final int INET_ADDRESS_MIN = 0;
-class InetAddressImpl {
+ /**
+ * IPv4 address family.
+ */
+ public static final int INET_ADDRESS_V4 = 1;
-static {
+ /**
+ * IPv6 address family.
+ */
+ public static final int INET_ADDRESS_V6 = 2;
+
+ public static final int INET_ADDRESS_MAX = 3;
+
+ static
+ {
System.loadLibrary("net");
-}
+ }
+
+ /**
+ * Map an INET_ADDRESS_V* value to the address family value.
+ *
+ * @param kind One of the INET_ADDRESS_V* constants.
+ * @return The integer representing the address family used by the OS.
+ */
+ static native int getInetFamily(int kind);
+
+ /**
+ * @return The machine's host name.
+ */
+ static native String getLocalHostName();
+
+ /**
+ * Convert an address string to the appropriate address bits.
+ *
+ * @param addr The address string to convert.
+ * @return Null if the string was not in a known format, a four byte array
+ * if it was an IPv4 address, and a sixteen byte array if it was an IPv6
+ * address.
+ */
+ static native byte[] stringToBits(String addr);
-native public int getInetFamily();
-native public int[] lookupAllHostAddr(String host) throws UnknownHostException;
-native public int lookupHostAddr(String host) throws UnknownHostException;
-native public String getHostByAddr(int addr) throws UnknownHostException;
-native public String getLocalHostName();
-native public void makeAnyLocalAddress(InetAddress addr);
+ /**
+ * Call back used to map a host name to its addresses.
+ *
+ * @param host The host name to query the DNS server about.
+ * @return An array of byte arrays containing the IP addresses. Sub-arrays
+ * of length four are IPv4 addresses and length sixteen are IPv6.
+ * @throws UnknownHostException if the DNS lookup failed.
+ */
+ abstract byte[][] lookupAllHostAddr(String host)
+ throws UnknownHostException;
+ /**
+ * Call back used to perform a reverse lookup.
+ *
+ * @param addr The IP address to map to a host name.
+ * @return The host name.
+ * @throws UnknownHostException if the DNS lookup failed.
+ */
+ abstract String getHostByAddr(byte addr[])
+ throws UnknownHostException;
}
Index: libraries/javalib/java/net/NetworkInterface.java
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/javalib/java/net/NetworkInterface.java,v
retrieving revision 1.1
diff -u -r1.1 NetworkInterface.java
--- libraries/javalib/java/net/NetworkInterface.java 21 Feb 2003 09:51:10 -0000 1.1
+++ libraries/javalib/java/net/NetworkInterface.java 15 Apr 2003 19:29:02 -0000
@@ -20,183 +20,76 @@
public final class NetworkInterface
{
- /*
- * This implementation specific stuff should probably be moved elsewhere.
- * Also, the implementation will not detect changes in the interfaces.
- * It does the detection at class initialization and saves these objects
- * in a global variable.
- */
-
- /**
- * The detected interfaces, the table maps names to NetworkInterface
- * objects.
- */
- private static final Hashtable DETECTED_INTERFACES = new Hashtable();
-
/**
- * Secondary mapping from InetAddresses to interface names.
+ * XXX Currently, we just create a new NetworkInterfaceImpl for each
+ * request. It would be nicer to either timeout the cache or check for
+ * diffs before throwing the objects away.
*/
- private static final Hashtable ADDRESS_TO_NAME = new Hashtable();
-
- /**
- * If not null, the SocketException thrown on initialization.
- */
- private static SocketException detectException;
-
- /**
- * Detect the interfaces in this machine.
- *
- * @return The native list of interfaces.
- * @throws SocketException if there is a problem with the native code.
- */
- private static native kaffe.util.Ptr detectInterfaces()
- throws SocketException;
-
- /**
- * Free the native objects returned by detectInterfaces.
- *
- * @param ifaddrs The pointer returned by detectInterfaces or null.
- */
- private static native void freeInterfaces(kaffe.util.Ptr ifaddrs);
-
- /**
- * Get the next interface in the native list.
- *
- * @param ifaddr The current interface.
- * @return The next interface in the list or null if there are no more.
- */
- private static native kaffe.util.Ptr getNext(kaffe.util.Ptr ifaddr);
-
- /**
- * @param ifaddr The current interface.
- * @return The name encoded in the native object.
- */
- private static native String getName(kaffe.util.Ptr ifaddr);
-
- /**
- * @param ifaddr The current interface.
- * @return The IPv4 address of this interface as a string or null if the
- * native object doesn't have an IPv4 address.
- */
- private static native String getIPv4Address(kaffe.util.Ptr ifaddr);
-
- static
- {
- kaffe.util.Ptr ifaddrs = null, curr = null;
-
- /* Our native implementation is in kaffenet */
- System.loadLibrary("net");
-
- try
- {
- /* Detect all the network interfaces. */
- curr = ifaddrs = detectInterfaces();
- while( curr != null )
- {
- NetworkInterface ni;
- String name;
-
- name = getName(curr);
- if( (ni = (NetworkInterface)DETECTED_INTERFACES.get(name))
- == null )
- {
- ni = new NetworkInterface(name, name /* XXX */);
- DETECTED_INTERFACES.put(name, ni);
- }
- try
- {
- String address;
-
- if( (address = getIPv4Address(curr)) != null )
- {
- InetAddress ia;
-
- ia = InetAddress.getByName(address);
- ni.setPrimaryAddress(ia);
- ADDRESS_TO_NAME.put(ia, ni.getName());
- ni.getInetAddressesInternal().addElement(ia);
- }
- }
- catch(UnknownHostException e)
- {
- /* Ignore... */
- }
- curr = getNext(curr);
- }
- DETECTED_INTERFACES.elements();
- }
- catch(SocketException e)
- {
- detectException = e;
- }
- finally
- {
- /* Make sure to free the native objects. */
- freeInterfaces(ifaddrs);
- }
- }
public static NetworkInterface getByName(String name)
throws SocketException
{
- if( detectException == null )
- {
- NetworkInterface retval = null;
-
- retval = (NetworkInterface)DETECTED_INTERFACES.get(name);
- return retval;
- }
- else
- {
- throw detectException;
- }
+ NetworkInterfaceImpl nii = new NetworkInterfaceImpl();
+ NetworkInterface retval;
+
+ retval = (NetworkInterface)nii.getDetectedInterfaces().get(name);
+ return retval;
}
public static NetworkInterface getByInetAddress(InetAddress ia)
throws SocketException
{
- if( detectException == null )
+ NetworkInterfaceImpl nii = new NetworkInterfaceImpl();
+ NetworkInterface retval = null;
+ String name;
+
+ if( (name = nii.nameForAddress(ia)) != null )
{
- NetworkInterface retval = null;
- String name;
-
- if( (name = (String)ADDRESS_TO_NAME.get(ia)) != null )
- {
- retval = (NetworkInterface)DETECTED_INTERFACES.get(name);
- }
- return retval;
- }
- else
- {
- throw detectException;
+ retval = (NetworkInterface)nii.getDetectedInterfaces().get(name);
}
+ return retval;
}
public static Enumeration getNetworkInterfaces()
throws SocketException
{
- if( detectException == null )
- {
- Enumeration retval = null;
+ NetworkInterfaceImpl nii = new NetworkInterfaceImpl();
+ Enumeration retval = null;
- if( DETECTED_INTERFACES.size() > 0 )
- {
- retval = DETECTED_INTERFACES.elements();
- }
- return retval;
- }
- else
+ if( nii.getDetectedInterfaces().size() > 0 )
{
- throw detectException;
+ retval = nii.getDetectedInterfaces().elements();
}
+ return retval;
}
-
+
+ /**
+ * The OS provided NIC name.
+ */
private final String name;
+
+ /**
+ * Same as the above for now.
+ */
private final String displayName;
+
+ /**
+ * An IPv4 address suitable for identifying this interface.
+ */
private InetAddress primaryAddress;
+
+ /**
+ * The set of InetAddresses for this interface.
+ */
private final Vector inetAddresses = new Vector();
-
- private NetworkInterface(String name, String displayName)
+
+ /**
+ * Construct a NetworkInterface with the given values.
+ *
+ * @param name The OS provided NIC name.
+ * @param displayName The user-interpretable NIC name.
+ */
+ NetworkInterface(String name, String displayName)
{
this.name = name;
this.displayName = displayName;
@@ -225,6 +118,9 @@
return this.primaryAddress;
}
+ /**
+ * @return The Vector containing the NetworkInterface's addresses.
+ */
Vector getInetAddressesInternal()
{
return this.inetAddresses;
Index: libraries/javalib/java/net/UnknownHostException.java
===================================================================
RCS file: /cvs/kaffe/kaffe/libraries/javalib/java/net/UnknownHostException.java,v
retrieving revision 1.3
diff -u -r1.3 UnknownHostException.java
--- libraries/javalib/java/net/UnknownHostException.java 22 Nov 2001 06:21:14 -0000 1.3
+++ libraries/javalib/java/net/UnknownHostException.java 15 Apr 2003 19:29:02 -0000
@@ -20,4 +20,12 @@
public UnknownHostException (String s) {
super(s);
}
+
+public UnknownHostException (Throwable cause) {
+ super(cause);
+}
+
+public UnknownHostException (String s, Throwable cause) {
+ super(s, cause);
+}
}
Index: test/regression/Makefile.am
===================================================================
RCS file: /cvs/kaffe/kaffe/test/regression/Makefile.am,v
retrieving revision 1.71
diff -u -r1.71 Makefile.am
--- test/regression/Makefile.am 13 Mar 2003 23:21:07 -0000 1.71
+++ test/regression/Makefile.am 15 Apr 2003 19:29:03 -0000
@@ -138,6 +138,7 @@
GetField.java \
LostTrampolineFrame.java \
NetworkInterfaceTest.java \
+ InetAddressTest.java \
InetSocketAddressTest.java
TEST_REFLECTION = \
--%--multipart-mixed-boundary-1.21652.1050436020--%--