here is a quick patch to be able to have a modular getHostByName and a getHostByAddr.
To change implementation the user has just to provide a property gnu.java.net.dns
containing the full class name of an implementation.
I hope that it's fine for you even though I introduce a slight overhead when solving because I don't use static method anymore for getHostByName and getHostByAddr.
Cheers, Guilhem.
P.S.: This is against classpath 2003-10-26.
ChangeLog entry:
2003-10-26 Guilhem Lavaux <[EMAIL PROTECTED]>
* java/net/InetAddress.java: (<clinit>) check the system property "gnu.java.net.dns" and change implementation accordingly (getHostName, getAllByName) use the implementation to solve name and address.
* gnu/java/net/InetAddressImpl.java: new interface for modular DNS.
* gnu/java/net/SysInetAddressImpl.java: DNS solver using native system call.
* native/jni/java-net/java_net_InetAddress.c, native/jni/java-net/gnu_java_net_SysInetAddressImpl.c: moved the implementation of getHostByAddr and getHostByName from java.net.InetAddress to gnu.java.net.SysInetAddressImpl.
Index: gnu/java/net/Makefile.am =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/net/Makefile.am,v retrieving revision 1.6 diff -u -r1.6 Makefile.am --- gnu/java/net/Makefile.am 9 Oct 2003 16:04:22 -0000 1.6 +++ gnu/java/net/Makefile.am 26 Oct 2003 07:55:35 -0000 @@ -5,5 +5,7 @@ EXTRA_DIST = \ HeaderFieldHelper.java \ PlainDatagramSocketImpl.java \ -PlainSocketImpl.java +PlainSocketImpl.java \ +InetAddressImpl.java \ +SysInetAddressImpl.java Index: java/net/InetAddress.java =================================================================== RCS file: /cvsroot/classpath/classpath/java/net/InetAddress.java,v retrieving revision 1.28 diff -u -r1.28 InetAddress.java --- java/net/InetAddress.java 9 Oct 2003 15:59:56 -0000 1.28 +++ java/net/InetAddress.java 26 Oct 2003 07:55:37 -0000 @@ -39,6 +39,7 @@ package java.net; import gnu.classpath.Configuration; +import gnu.java.net.InetAddressImpl; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; @@ -114,6 +115,12 @@ */ private static HashMap cache; + /** + * Real implementation for DNS resolution. This implementation is specified + * at run time. + */ + private static InetAddressImpl impl; + static { // load the shared library needed for name resolution @@ -121,7 +128,26 @@ { System.loadLibrary ("javanet"); } + + // Initialize DNS implementation + String dnsImpl = System.getProperty("gnu.java.net.dns"); + if (dnsImpl == null) + { + impl = new gnu.java.net.SysInetAddressImpl(); + } + else + { + try + { + impl = (InetAddressImpl) Class.forName(dnsImpl).newInstance(); + } + catch (Exception _) + { + impl = new gnu.java.net.SysInetAddressImpl(); + } + } + // Look for properties that override default caching behavior cache_size = Integer.getInteger ("gnu.java.net.dns_cache_size", DEFAULT_CACHE_SIZE).intValue(); @@ -420,7 +446,7 @@ try { - hostName = getHostByAddr (addr); + hostName = impl.getHostByAddr (addr); return hostName; } catch (UnknownHostException e) @@ -697,7 +723,7 @@ return addresses; // Not in cache, try the lookup - byte[][] iplist = getHostByName (hostname); + byte[][] iplist = impl.getHostByName (hostname); if (iplist.length == 0) throw new UnknownHostException (hostname); @@ -829,26 +855,6 @@ * Returns the value of the special address INADDR_ANY */ private static native byte[] lookupInaddrAny() throws UnknownHostException; - - /** - * 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 int array - * - * @return The hostname - * - * @exception UnknownHostException If the reverse lookup fails - */ - private static native String getHostByAddr (byte[] ip) - throws UnknownHostException; - - /** - * Returns a list of all IP addresses for a given hostname. Will throw - * an UnknownHostException if the hostname cannot be resolved. - */ - private static native byte[][] getHostByName (String hostname) - throws UnknownHostException; /* * Needed for serialization. Index: native/jni/java-net/Makefile.am =================================================================== RCS file: /cvsroot/classpath/classpath/native/jni/java-net/Makefile.am,v retrieving revision 1.5 diff -u -r1.5 Makefile.am --- native/jni/java-net/Makefile.am 19 Sep 2003 06:12:39 -0000 1.5 +++ native/jni/java-net/Makefile.am 26 Oct 2003 07:55:38 -0000 @@ -5,7 +5,8 @@ java_net_InetAddress.c \ java_net_NetworkInterface.c \ gnu_java_net_PlainDatagramSocketImpl.c \ - gnu_java_net_PlainSocketImpl.c + gnu_java_net_PlainSocketImpl.c \ + gnu_java_net_SysInetAddressImpl.c libjavanet_la_LDFLAGS = -module -version-info @LIBVERSION@ libjavanet_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo Index: native/jni/java-net/java_net_InetAddress.c =================================================================== RCS file: /cvsroot/classpath/classpath/native/jni/java-net/java_net_InetAddress.c,v retrieving revision 1.7 diff -u -r1.7 java_net_InetAddress.c --- native/jni/java-net/java_net_InetAddress.c 9 Oct 2003 15:59:57 -0000 1.7 +++ native/jni/java-net/java_net_InetAddress.c 26 Oct 2003 07:55:38 -0000 @@ -128,152 +128,4 @@ return(IParray); } -/*************************************************************************/ - -/* - * Function to return the canonical hostname for a given IP address passed - * in as a byte array - */ -JNIEXPORT jstring JNICALL -Java_java_net_InetAddress_getHostByAddr(JNIEnv *env, jclass class, jarray arr) -{ -#ifndef WITHOUT_NETWORK - jbyte *octets; - jsize len; - int addr; - char hostname[255]; - int result; - jstring retval; - - assert(env!=NULL); - assert((*env)!=NULL); - - /* Grab the byte[] array with the IP out of the input data */ - len = (*env)->GetArrayLength(env, arr); - if (len != 4) - { - JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address"); - return (jstring)NULL; - } - - octets = (*env)->GetByteArrayElements(env, arr, 0); - if (!octets) - { - JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address"); - return (jstring)NULL; - } - - /* Convert it to a 32 bit address */ - TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT(octets[0], - octets[1], - octets[2], - octets[3], - addr - ); - - /* Release some memory */ - (*env)->ReleaseByteArrayElements(env, arr, octets, 0); - - /* Resolve the address and return the name */ - TARGET_NATIVE_NETWORK_GET_HOSTNAME_BY_ADDRESS(addr,hostname,sizeof(hostname),result); - if (result != TARGET_NATIVE_OK) - { - JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Bad IP address"); - return (jstring)NULL; - } - - retval = (*env)->NewStringUTF(env, hostname); - - return(retval); -#else /* not WITHOUT_NETWORK */ - return (jstring)NULL; -#endif /* not WITHOUT_NETWORK */ -} - -/*************************************************************************/ - -JNIEXPORT jobjectArray JNICALL -Java_java_net_InetAddress_getHostByName(JNIEnv *env, jclass class, jstring host) -{ -#ifndef WITHOUT_NETWORK - const char *hostname; -/* FIXME: limitation of max. 64 addresses - how to make it more flexibale? */ - int addresses[64]; - jsize addresses_count; - int result; - jclass arr_class; - jobjectArray addrs; - int i; - jbyte *octets; - jarray ret_octets; - - assert(env!=NULL); - assert((*env)!=NULL); - - /* Grab the hostname string */ - hostname = (*env)->GetStringUTFChars(env, host, 0); - if (!hostname) - { - JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Null hostname"); - return (jobjectArray)NULL; - } - - /* Look up the host */ - TARGET_NATIVE_NETWORK_GET_HOSTNAME_BY_NAME(hostname, - addresses, - sizeof(addresses)/sizeof(addresses[0]), - addresses_count, - result - ); - if (result != TARGET_NATIVE_OK) - { - JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, (char*)hostname); - return (jobjectArray)NULL; - } - (*env)->ReleaseStringUTFChars(env, host, hostname); - - arr_class = (*env)->FindClass(env,"[B"); - if (!arr_class) - { - JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); - return (jobjectArray)NULL; - } - - addrs = (*env)->NewObjectArray(env, addresses_count, arr_class, 0); - if (!addrs) - { - JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); - return (jobjectArray)NULL; - } - - /* Now loop and copy in each address */ - for (i = 0; i < addresses_count; i++) - { - ret_octets = (*env)->NewByteArray(env, 4); - if (!ret_octets) - { - JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); - return (jobjectArray)NULL; - } - - octets = (*env)->GetByteArrayElements(env, ret_octets, 0); - - TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES(addresses[i], - octets[0], - octets[1], - octets[2], - octets[3] - ); - - (*env)->ReleaseByteArrayElements(env, ret_octets, octets, 0); - - (*env)->SetObjectArrayElement(env, addrs, i, ret_octets); - } - - return(addrs); -#else /* not WITHOUT_NETWORK */ - return (jobjectArray)NULL; -#endif /* not WITHOUT_NETWORK */ -} - /* end of file */ --- /dev/null 1970-01-01 01:00:00.000000000 +0100 +++ native/jni/java-net/gnu_java_net_SysInetAddressImpl.c 2003-10-26 08:50:43.000000000 +0100 @@ -0,0 +1,206 @@ +/* SysInetAddressImpl.c - Native methods for SysInetAddressImpl class + Copyright (C) 1998, 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. */ + +/* do not move; needed here because of some macro definitions */ +#include <config.h> + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include <jni.h> +#include <jcl.h> + +#include "javanet.h" + +#include "target_native.h" +#ifndef WITHOUT_NETWORK + #include "target_native_network.h" +#endif /* WITHOUT_NETWORK */ + +#include "java_net_InetAddress.h" + +/*************************************************************************/ + +/* + * Function to return the canonical hostname for a given IP address passed + * in as a byte array + */ +JNIEXPORT jstring JNICALL +Java_gnu_java_net_SysInetAddressImpl_getHostByAddr(JNIEnv *env, jclass class, jobject obj, jarray arr) +{ +#ifndef WITHOUT_NETWORK + jbyte *octets; + jsize len; + int addr; + char hostname[255]; + int result; + jstring retval; + + assert(env!=NULL); + assert((*env)!=NULL); + + /* Grab the byte[] array with the IP out of the input data */ + len = (*env)->GetArrayLength(env, arr); + if (len != 4) + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address"); + return (jstring)NULL; + } + + octets = (*env)->GetByteArrayElements(env, arr, 0); + if (!octets) + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address"); + return (jstring)NULL; + } + + /* Convert it to a 32 bit address */ + TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT(octets[0], + octets[1], + octets[2], + octets[3], + addr + ); + + /* Release some memory */ + (*env)->ReleaseByteArrayElements(env, arr, octets, 0); + + /* Resolve the address and return the name */ + TARGET_NATIVE_NETWORK_GET_HOSTNAME_BY_ADDRESS(addr,hostname,sizeof(hostname),result); + if (result != TARGET_NATIVE_OK) + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Bad IP address"); + return (jstring)NULL; + } + + retval = (*env)->NewStringUTF(env, hostname); + + return(retval); +#else /* not WITHOUT_NETWORK */ + return (jstring)NULL; +#endif /* not WITHOUT_NETWORK */ +} + +/*************************************************************************/ + +JNIEXPORT jobjectArray JNICALL +Java_gnu_java_net_SysInetAddressImpl_getHostByName(JNIEnv *env, jclass class, jobject obj, jstring host) +{ +#ifndef WITHOUT_NETWORK + const char *hostname; +/* FIXME: limitation of max. 64 addresses - how to make it more flexibale? */ + int addresses[64]; + jsize addresses_count; + int result; + jclass arr_class; + jobjectArray addrs; + int i; + jbyte *octets; + jarray ret_octets; + + assert(env!=NULL); + assert((*env)!=NULL); + + /* Grab the hostname string */ + hostname = (*env)->GetStringUTFChars(env, host, 0); + if (!hostname) + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Null hostname"); + return (jobjectArray)NULL; + } + + /* Look up the host */ + TARGET_NATIVE_NETWORK_GET_HOSTNAME_BY_NAME(hostname, + addresses, + sizeof(addresses)/sizeof(addresses[0]), + addresses_count, + result + ); + if (result != TARGET_NATIVE_OK) + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, (char*)hostname); + return (jobjectArray)NULL; + } + (*env)->ReleaseStringUTFChars(env, host, hostname); + + arr_class = (*env)->FindClass(env,"[B"); + if (!arr_class) + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + return (jobjectArray)NULL; + } + + addrs = (*env)->NewObjectArray(env, addresses_count, arr_class, 0); + if (!addrs) + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + return (jobjectArray)NULL; + } + + /* Now loop and copy in each address */ + for (i = 0; i < addresses_count; i++) + { + ret_octets = (*env)->NewByteArray(env, 4); + if (!ret_octets) + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + return (jobjectArray)NULL; + } + + octets = (*env)->GetByteArrayElements(env, ret_octets, 0); + + TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES(addresses[i], + octets[0], + octets[1], + octets[2], + octets[3] + ); + + (*env)->ReleaseByteArrayElements(env, ret_octets, octets, 0); + + (*env)->SetObjectArrayElement(env, addrs, i, ret_octets); + } + + return(addrs); +#else /* not WITHOUT_NETWORK */ + return (jobjectArray)NULL; +#endif /* not WITHOUT_NETWORK */ +} + +/* end of file */ --- /dev/null 1970-01-01 01:00:00.000000000 +0100 +++ gnu/java/net/SysInetAddressImpl.java 2003-10-26 08:46:25.000000000 +0100 @@ -0,0 +1,50 @@ +/* SysInetAddressImpl.java -- Internet address implementation using + system solvers. + Copyright (C) 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 gnu.java.net; + +import java.net.UnknownHostException; + +/* This class is just a forward to native implementation. */ +public class SysInetAddressImpl implements InetAddressImpl +{ + public native String getHostByAddr (byte[] ip) + throws UnknownHostException; + + public native byte[][] getHostByName (String hostname) + throws UnknownHostException; +} --- /dev/null 1970-01-01 01:00:00.000000000 +0100 +++ gnu/java/net/InetAddressImpl.java 2003-10-26 08:46:25.000000000 +0100 @@ -0,0 +1,68 @@ +/* InetAddressImpl.java -- Class to model an Internet address implementation + Copyright (C) 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 gnu.java.net; + +import java.net.UnknownHostException; + +/** + * This interface precises the shape of the implementation of an InetAddress. + * This interface can be used to build new way to resolve host names. This + * can be useful when system dns resolution is failing in a way or another. + * + * @author Guilhem Lavaux + */ +public interface InetAddressImpl { + /** + * 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 int array + * + * @return The hostname + * + * @exception UnknownHostException If the reverse lookup fails + */ + public String getHostByAddr (byte[] ip) + throws UnknownHostException; + + /** + * Returns a list of all IP addresses for a given hostname. Will throw + * an UnknownHostException if the hostname cannot be resolved. + */ + public byte[][] getHostByName (String hostname) + throws UnknownHostException; +}
_______________________________________________ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath