7112670: Inet4AddressImpl should use getaddrinfo/getnameinfo
Reviewed-by: chegar, alanb, mduigou, ngmr
Contributed-by: Charles Lee <littlee@linux.vnet.ibm.com>
--- a/jdk/src/solaris/native/java/net/Inet4AddressImpl.c Mon Nov 21 12:57:36 2011 +0000
+++ b/jdk/src/solaris/native/java/net/Inet4AddressImpl.c Fri Nov 11 14:40:18 2011 +0000
@@ -43,8 +43,9 @@
#include "java_net_Inet4AddressImpl.h"
/* the initial size of our hostent buffers */
-#define HENT_BUF_SIZE 1024
-#define BIG_HENT_BUF_SIZE 10240 /* a jumbo-sized one */
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
+#endif
/************************************************************************
* Inet4AddressImpl
@@ -57,60 +58,36 @@
*/
JNIEXPORT jstring JNICALL
Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
- char hostname[MAXHOSTNAMELEN+1];
+ char hostname[NI_MAXHOST+1];
hostname[0] = '\0';
if (JVM_GetHostName(hostname, sizeof(hostname))) {
/* Something went wrong, maybe networking is not setup? */
strcpy(hostname, "localhost");
} else {
-#ifdef __linux__
- /* On Linux gethostname() says "host.domain.sun.com". On
- * Solaris gethostname() says "host", so extra work is needed.
- */
-#else
- /* Solaris doesn't want to give us a fully qualified domain name.
- * We do a reverse lookup to try and get one. This works
- * if DNS occurs before NIS in /etc/resolv.conf, but fails
- * if NIS comes first (it still gets only a partial name).
- * We use thread-safe system calls.
- */
-#endif /* __linux__ */
- struct hostent res, res2, *hp;
- // these buffers must be pointer-aligned so they are declared
- // with pointer type
- char *buf[HENT_BUF_SIZE/(sizeof (char *))];
- char *buf2[HENT_BUF_SIZE/(sizeof (char *))];
- int h_error=0;
+ hostname[NI_MAXHOST] = '\0';
+ struct addrinfo hints, *res;
+ int error;
- // ensure null-terminated
- hostname[MAXHOSTNAMELEN] = '\0';
+ bzero(&hints, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_family = AF_INET;
+
+ error = getaddrinfo(hostname, NULL, &hints, &res);
-#ifdef __GLIBC__
- gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &hp, &h_error);
-#else
- hp = gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &h_error);
-#endif
- if (hp) {
-#ifdef __GLIBC__
- gethostbyaddr_r(hp->h_addr, hp->h_length, AF_INET,
- &res2, (char*)buf2, sizeof(buf2), &hp, &h_error);
-#else
- hp = gethostbyaddr_r(hp->h_addr, hp->h_length, AF_INET,
- &res2, (char*)buf2, sizeof(buf2), &h_error);
-#endif
- if (hp) {
- /*
- * If gethostbyaddr_r() found a fully qualified host name,
- * returns that name. Otherwise, returns the hostname
- * found by gethostname().
- */
- char *p = hp->h_name;
- if ((strlen(hp->h_name) > strlen(hostname))
- && (strncmp(hostname, hp->h_name, strlen(hostname)) == 0)
- && (*(p + strlen(hostname)) == '.'))
- strcpy(hostname, hp->h_name);
- }
+ if (error == 0) {/* host is known to name service */
+ getnameinfo(res->ai_addr,
+ res->ai_addrlen,
+ hostname,
+ MAXHOSTNAMELEN,
+ NULL,
+ 0,
+ NI_NAMEREQD);
+
+ /* if getnameinfo fails hostname is still the value
+ from gethostname */
+
+ freeaddrinfo(res);
}
}
return (*env)->NewStringUTF(env, hostname);
@@ -140,14 +117,9 @@
jstring host) {
const char *hostname;
jobjectArray ret = 0;
- struct hostent res, *hp = 0;
- // this buffer must be pointer-aligned so is declared
- // with pointer type
- char *buf[HENT_BUF_SIZE/(sizeof (char *))];
-
- /* temporary buffer, on the off chance we need to expand */
- char *tmp = NULL;
- int h_error=0;
+ int retLen = 0;
+ int error = 0;
+ struct addrinfo hints, *res, *resNew = NULL;
if (!initialized) {
ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
@@ -168,6 +140,11 @@
hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
CHECK_NULL_RETURN(hostname, NULL);
+ /* Try once, with our static buffer. */
+ bzero(&hints, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_family = AF_INET;
+
#ifdef __solaris__
/*
* Workaround for Solaris bug 4160367 - if a hostname contains a
@@ -181,69 +158,93 @@
}
#endif
- /* Try once, with our static buffer. */
-#ifdef __GLIBC__
- gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &hp, &h_error);
-#else
- hp = gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &h_error);
-#endif
+ error = getaddrinfo(hostname, NULL, &hints, &res);
+
+ if (error) {
+ /* report error */
+ ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
+ JNU_ReleaseStringPlatformChars(env, host, hostname);
+ return NULL;
+ } else {
+ int i = 0;
+ struct addrinfo *itr, *last = NULL, *iterator = res;
- /* With the re-entrant system calls, it's possible that the buffer
- * we pass to it is not large enough to hold an exceptionally
- * large DNS entry. This is signaled by errno->ERANGE. We try once
- * more, with a very big size.
- */
- if (hp == NULL && errno == ERANGE) {
- if ((tmp = (char*)malloc(BIG_HENT_BUF_SIZE))) {
-#ifdef __GLIBC__
- gethostbyname_r(hostname, &res, tmp, BIG_HENT_BUF_SIZE,
- &hp, &h_error);
-#else
- hp = gethostbyname_r(hostname, &res, tmp, BIG_HENT_BUF_SIZE,
- &h_error);
-#endif
- }
- }
- if (hp != NULL) {
- struct in_addr **addrp = (struct in_addr **) hp->h_addr_list;
- int i = 0;
+ while (iterator != NULL) {
+ // remove the duplicate one
+ int skip = 0;
+ itr = resNew;
+ while (itr != NULL) {
+ struct sockaddr_in *addr1, *addr2;
+ addr1 = (struct sockaddr_in *)iterator->ai_addr;
+ addr2 = (struct sockaddr_in *)itr->ai_addr;
+ if (addr1->sin_addr.s_addr ==
+ addr2->sin_addr.s_addr) {
+ skip = 1;
+ break;
+ }
+ itr = itr->ai_next;
+ }
- while (*addrp != (struct in_addr *) 0) {
- i++;
- addrp++;
+ if (!skip) {
+ struct addrinfo *next
+ = (struct addrinfo*) malloc(sizeof(struct addrinfo));
+ if (!next) {
+ JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
+ ret = NULL;
+ goto cleanupAndReturn;
+ }
+ memcpy(next, iterator, sizeof(struct addrinfo));
+ next->ai_next = NULL;
+ if (resNew == NULL) {
+ resNew = next;
+ } else {
+ last->ai_next = next;
+ }
+ last = next;
+ i++;
+ }
+ iterator = iterator->ai_next;
}
- ret = (*env)->NewObjectArray(env, i, ni_iacls, NULL);
+ retLen = i;
+ iterator = resNew;
+
+ ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL);
+
if (IS_NULL(ret)) {
/* we may have memory to free at the end of this */
goto cleanupAndReturn;
}
- addrp = (struct in_addr **) hp->h_addr_list;
+
i = 0;
- while (*addrp) {
- jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
- if (IS_NULL(iaObj)) {
- ret = NULL;
- goto cleanupAndReturn;
- }
- (*env)->SetIntField(env, iaObj, ni_iaaddressID,
- ntohl((*addrp)->s_addr));
- (*env)->SetObjectField(env, iaObj, ni_iahostID, host);
- (*env)->SetObjectArrayElement(env, ret, i, iaObj);
- addrp++;
- i++;
+ while (iterator != NULL) {
+ jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
+ if (IS_NULL(iaObj)) {
+ ret = NULL;
+ goto cleanupAndReturn;
+ }
+ (*env)->SetIntField(env, iaObj, ni_iaaddressID,
+ ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
+ (*env)->SetObjectField(env, iaObj, ni_iahostID, host);
+ (*env)->SetObjectArrayElement(env, ret, i++, iaObj);
+ iterator = iterator->ai_next;
}
- } else {
- JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
- (char *)hostname);
- ret = NULL;
}
-cleanupAndReturn:
- JNU_ReleaseStringPlatformChars(env, host, hostname);
- if (tmp != NULL) {
- free(tmp);
+ cleanupAndReturn:
+ {
+ struct addrinfo *iterator, *tmp;
+ iterator = resNew;
+ while (iterator != NULL) {
+ tmp = iterator;
+ iterator = iterator->ai_next;
+ free(tmp);
+ }
+ JNU_ReleaseStringPlatformChars(env, host, hostname);
}
+
+ freeaddrinfo(res);
+
return ret;
}
@@ -256,63 +257,39 @@
Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
jbyteArray addrArray) {
jstring ret = NULL;
- jint addr;
- struct hostent hent, *hp = 0;
- // this buffer must be pointer-aligned so is declared
- // with pointer type
- char *buf[HENT_BUF_SIZE/(sizeof (char *))];
- int h_error = 0;
- char *tmp = NULL;
+
+ char host[NI_MAXHOST+1];
+ int error = 0;
+ int len = 0;
+ jbyte caddr[16];
- /*
- * We are careful here to use the reentrant version of
- * gethostbyname because at the Java level this routine is not
- * protected by any synchronization.
- *
- * Still keeping the reentrant platform dependent calls temporarily
- * We should probably conform to one interface later.
- *
- */
- jbyte caddr[4];
+ struct sockaddr_in him4;
+ struct sockaddr_in6 him6;
+ struct sockaddr *sa;
+
+ jint addr;
(*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
addr = ((caddr[0]<<24) & 0xff000000);
addr |= ((caddr[1] <<16) & 0xff0000);
addr |= ((caddr[2] <<8) & 0xff00);
addr |= (caddr[3] & 0xff);
- addr = htonl(addr);
-#ifdef __GLIBC__
- gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &hent,
- (char*)buf, sizeof(buf), &hp, &h_error);
-#else
- hp = gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &hent,
- (char*)buf, sizeof(buf), &h_error);
-#endif
- /* With the re-entrant system calls, it's possible that the buffer
- * we pass to it is not large enough to hold an exceptionally
- * large DNS entry. This is signaled by errno->ERANGE. We try once
- * more, with a very big size.
- */
- if (hp == NULL && errno == ERANGE) {
- if ((tmp = (char*)malloc(BIG_HENT_BUF_SIZE))) {
-#ifdef __GLIBC__
- gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET,
- &hent, tmp, BIG_HENT_BUF_SIZE, &hp, &h_error);
-#else
- hp = gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET,
- &hent, tmp, BIG_HENT_BUF_SIZE, &h_error);
-#endif
- } else {
- JNU_ThrowOutOfMemoryError(env, "getHostByAddr");
- }
+ memset((void *) &him4, 0, sizeof(him4));
+ him4.sin_addr.s_addr = (uint32_t) htonl(addr);
+ him4.sin_family = AF_INET;
+ sa = (struct sockaddr *) &him4;
+ len = sizeof(him4);
+
+ error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
+ NI_NAMEREQD);
+
+ if (!error) {
+ ret = (*env)->NewStringUTF(env, host);
}
- if (hp == NULL) {
+
+ if (ret == NULL) {
JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", NULL);
- } else {
- ret = (*env)->NewStringUTF(env, hp->h_name);
}
- if (tmp) {
- free(tmp);
- }
+
return ret;
}
--- a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c Mon Nov 21 12:57:36 2011 +0000
+++ b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c Fri Nov 11 14:40:18 2011 +0000
@@ -82,31 +82,29 @@
* We use thread-safe system calls.
*/
#ifdef AF_INET6
- if (NET_addrtransAvailable()) {
- struct addrinfo hints, *res;
- int error;
+ struct addrinfo hints, *res;
+ int error;
- bzero(&hints, sizeof(hints));
- hints.ai_flags = AI_CANONNAME;
- hints.ai_family = AF_UNSPEC;
+ bzero(&hints, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_family = AF_UNSPEC;
- error = (*getaddrinfo_ptr)(hostname, NULL, &hints, &res);
+ error = getaddrinfo(hostname, NULL, &hints, &res);
- if (error == 0) {
- /* host is known to name service */
- error = (*getnameinfo_ptr)(res->ai_addr,
- res->ai_addrlen,
- hostname,
- NI_MAXHOST,
- NULL,
- 0,
- NI_NAMEREQD);
+ if (error == 0) {
+ /* host is known to name service */
+ error = getnameinfo(res->ai_addr,
+ res->ai_addrlen,
+ hostname,
+ NI_MAXHOST,
+ NULL,
+ 0,
+ NI_NAMEREQD);
- /* if getnameinfo fails hostname is still the value
- from gethostname */
+ /* if getnameinfo fails hostname is still the value
+ from gethostname */
- (*freeaddrinfo_ptr)(res);
- }
+ freeaddrinfo(res);
}
#endif /* AF_INET6 */
#endif /* __linux__ */
@@ -173,193 +171,191 @@
CHECK_NULL_RETURN(hostname, NULL);
#ifdef AF_INET6
- if (NET_addrtransAvailable()) {
- static jfieldID ia_preferIPv6AddressID;
- if (ia_preferIPv6AddressID == NULL) {
- jclass c = (*env)->FindClass(env,"java/net/InetAddress");
- if (c) {
- ia_preferIPv6AddressID =
- (*env)->GetStaticFieldID(env, c, "preferIPv6Address", "Z");
- }
- if (ia_preferIPv6AddressID == NULL) {
- JNU_ReleaseStringPlatformChars(env, host, hostname);
- return NULL;
- }
+ static jfieldID ia_preferIPv6AddressID;
+ if (ia_preferIPv6AddressID == NULL) {
+ jclass c = (*env)->FindClass(env,"java/net/InetAddress");
+ if (c) {
+ ia_preferIPv6AddressID =
+ (*env)->GetStaticFieldID(env, c, "preferIPv6Address", "Z");
}
- /* get the address preference */
- preferIPv6Address
- = (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID);
-
- /* Try once, with our static buffer. */
- bzero(&hints, sizeof(hints));
- hints.ai_flags = AI_CANONNAME;
- hints.ai_family = AF_UNSPEC;
-
-#ifdef __solaris__
- /*
- * Workaround for Solaris bug 4160367 - if a hostname contains a
- * white space then 0.0.0.0 is returned
- */
- if (isspace((unsigned char)hostname[0])) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
- hostname);
+ if (ia_preferIPv6AddressID == NULL) {
JNU_ReleaseStringPlatformChars(env, host, hostname);
return NULL;
}
+ }
+ /* get the address preference */
+ preferIPv6Address
+ = (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID);
+
+ /* Try once, with our static buffer. */
+ bzero(&hints, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_family = AF_UNSPEC;
+
+#ifdef __solaris__
+ /*
+ * Workaround for Solaris bug 4160367 - if a hostname contains a
+ * white space then 0.0.0.0 is returned
+ */
+ if (isspace((unsigned char)hostname[0])) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
+ hostname);
+ JNU_ReleaseStringPlatformChars(env, host, hostname);
+ return NULL;
+ }
#endif
- error = (*getaddrinfo_ptr)(hostname, NULL, &hints, &res);
+ error = getaddrinfo(hostname, NULL, &hints, &res);
- if (error) {
- /* report error */
- ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
- JNU_ReleaseStringPlatformChars(env, host, hostname);
- return NULL;
- } else {
- int i = 0;
- int inetCount = 0, inet6Count = 0, inetIndex, inet6Index;
- struct addrinfo *itr, *last = NULL, *iterator = res;
- while (iterator != NULL) {
- int skip = 0;
- itr = resNew;
- while (itr != NULL) {
- if (iterator->ai_family == itr->ai_family &&
- iterator->ai_addrlen == itr->ai_addrlen) {
- if (itr->ai_family == AF_INET) { /* AF_INET */
- struct sockaddr_in *addr1, *addr2;
- addr1 = (struct sockaddr_in *)iterator->ai_addr;
- addr2 = (struct sockaddr_in *)itr->ai_addr;
- if (addr1->sin_addr.s_addr ==
- addr2->sin_addr.s_addr) {
- skip = 1;
- break;
- }
- } else {
- int t;
- struct sockaddr_in6 *addr1, *addr2;
- addr1 = (struct sockaddr_in6 *)iterator->ai_addr;
- addr2 = (struct sockaddr_in6 *)itr->ai_addr;
+ if (error) {
+ /* report error */
+ ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
+ JNU_ReleaseStringPlatformChars(env, host, hostname);
+ return NULL;
+ } else {
+ int i = 0;
+ int inetCount = 0, inet6Count = 0, inetIndex, inet6Index;
+ struct addrinfo *itr, *last = NULL, *iterator = res;
+ while (iterator != NULL) {
+ int skip = 0;
+ itr = resNew;
+ while (itr != NULL) {
+ if (iterator->ai_family == itr->ai_family &&
+ iterator->ai_addrlen == itr->ai_addrlen) {
+ if (itr->ai_family == AF_INET) { /* AF_INET */
+ struct sockaddr_in *addr1, *addr2;
+ addr1 = (struct sockaddr_in *)iterator->ai_addr;
+ addr2 = (struct sockaddr_in *)itr->ai_addr;
+ if (addr1->sin_addr.s_addr ==
+ addr2->sin_addr.s_addr) {
+ skip = 1;
+ break;
+ }
+ } else {
+ int t;
+ struct sockaddr_in6 *addr1, *addr2;
+ addr1 = (struct sockaddr_in6 *)iterator->ai_addr;
+ addr2 = (struct sockaddr_in6 *)itr->ai_addr;
- for (t = 0; t < 16; t++) {
- if (addr1->sin6_addr.s6_addr[t] !=
- addr2->sin6_addr.s6_addr[t]) {
- break;
- }
- }
- if (t < 16) {
- itr = itr->ai_next;
- continue;
- } else {
- skip = 1;
+ for (t = 0; t < 16; t++) {
+ if (addr1->sin6_addr.s6_addr[t] !=
+ addr2->sin6_addr.s6_addr[t]) {
break;
}
}
- } else if (iterator->ai_family != AF_INET &&
- iterator->ai_family != AF_INET6) {
- /* we can't handle other family types */
- skip = 1;
- break;
- }
- itr = itr->ai_next;
- }
-
- if (!skip) {
- struct addrinfo *next
- = (struct addrinfo*) malloc(sizeof(struct addrinfo));
- if (!next) {
- JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
- ret = NULL;
- goto cleanupAndReturn;
+ if (t < 16) {
+ itr = itr->ai_next;
+ continue;
+ } else {
+ skip = 1;
+ break;
+ }
}
- memcpy(next, iterator, sizeof(struct addrinfo));
- next->ai_next = NULL;
- if (resNew == NULL) {
- resNew = next;
- } else {
- last->ai_next = next;
- }
- last = next;
- i++;
- if (iterator->ai_family == AF_INET) {
- inetCount ++;
- } else if (iterator->ai_family == AF_INET6) {
- inet6Count ++;
- }
+ } else if (iterator->ai_family != AF_INET &&
+ iterator->ai_family != AF_INET6) {
+ /* we can't handle other family types */
+ skip = 1;
+ break;
}
- iterator = iterator->ai_next;
- }
- retLen = i;
- iterator = resNew;
-
- ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL);
-
- if (IS_NULL(ret)) {
- /* we may have memory to free at the end of this */
- goto cleanupAndReturn;
+ itr = itr->ai_next;
}
- if (preferIPv6Address) {
- /* AF_INET addresses will be offset by inet6Count */
- inetIndex = inet6Count;
- inet6Index = 0;
- } else {
- /* AF_INET6 addresses will be offset by inetCount */
- inetIndex = 0;
- inet6Index = inetCount;
+ if (!skip) {
+ struct addrinfo *next
+ = (struct addrinfo*) malloc(sizeof(struct addrinfo));
+ if (!next) {
+ JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
+ ret = NULL;
+ goto cleanupAndReturn;
+ }
+ memcpy(next, iterator, sizeof(struct addrinfo));
+ next->ai_next = NULL;
+ if (resNew == NULL) {
+ resNew = next;
+ } else {
+ last->ai_next = next;
+ }
+ last = next;
+ i++;
+ if (iterator->ai_family == AF_INET) {
+ inetCount ++;
+ } else if (iterator->ai_family == AF_INET6) {
+ inet6Count ++;
+ }
}
+ iterator = iterator->ai_next;
+ }
+ retLen = i;
+ iterator = resNew;
- while (iterator != NULL) {
- if (iterator->ai_family == AF_INET) {
+ ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL);
+
+ if (IS_NULL(ret)) {
+ /* we may have memory to free at the end of this */
+ goto cleanupAndReturn;
+ }
+
+ if (preferIPv6Address) {
+ /* AF_INET addresses will be offset by inet6Count */
+ inetIndex = inet6Count;
+ inet6Index = 0;
+ } else {
+ /* AF_INET6 addresses will be offset by inetCount */
+ inetIndex = 0;
+ inet6Index = inetCount;
+ }
+
+ while (iterator != NULL) {
+ if (iterator->ai_family == AF_INET) {
jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
if (IS_NULL(iaObj)) {
- ret = NULL;
- goto cleanupAndReturn;
+ ret = NULL;
+ goto cleanupAndReturn;
}
(*env)->SetIntField(env, iaObj, ni_iaaddressID,
ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
(*env)->SetObjectField(env, iaObj, ni_iahostID, host);
(*env)->SetObjectArrayElement(env, ret, inetIndex, iaObj);
inetIndex++;
- } else if (iterator->ai_family == AF_INET6) {
+ } else if (iterator->ai_family == AF_INET6) {
jint scope = 0;
jbyteArray ipaddress;
jobject iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID);
if (IS_NULL(iaObj)) {
- ret = NULL;
- goto cleanupAndReturn;
+ ret = NULL;
+ goto cleanupAndReturn;
}
ipaddress = (*env)->NewByteArray(env, 16);
if (IS_NULL(ipaddress)) {
- ret = NULL;
- goto cleanupAndReturn;
+ ret = NULL;
+ goto cleanupAndReturn;
}
(*env)->SetByteArrayRegion(env, ipaddress, 0, 16,
(jbyte *)&(((struct sockaddr_in6*)iterator->ai_addr)->sin6_addr));
#ifdef __linux__
if (!kernelIsV22()) {
- scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id;
+ scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id;
}
#else
scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id;
#endif
if (scope != 0) { /* zero is default value, no need to set */
- (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
- (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
+ (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
+ (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
}
(*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress);
(*env)->SetObjectField(env, iaObj, ni_iahostID, host);
(*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj);
inet6Index++;
- }
- iterator = iterator->ai_next;
}
+ iterator = iterator->ai_next;
}
}
-cleanupAndReturn:
+ cleanupAndReturn:
{
- struct addrinfo *iterator, *tmp;
+ struct addrinfo *iterator, *tmp;
iterator = resNew;
while (iterator != NULL) {
tmp = iterator;
@@ -369,8 +365,7 @@
JNU_ReleaseStringPlatformChars(env, host, hostname);
}
- if (NET_addrtransAvailable())
- (*freeaddrinfo_ptr)(res);
+ freeaddrinfo(res);
#endif /* AF_INET6 */
return ret;
@@ -393,44 +388,42 @@
int len = 0;
jbyte caddr[16];
- if (NET_addrtransAvailable()) {
- struct sockaddr_in him4;
- struct sockaddr_in6 him6;
- struct sockaddr *sa;
+ struct sockaddr_in him4;
+ struct sockaddr_in6 him6;
+ struct sockaddr *sa;
+ /*
+ * For IPv4 addresses construct a sockaddr_in structure.
+ */
+ if ((*env)->GetArrayLength(env, addrArray) == 4) {
+ jint addr;
+ (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
+ addr = ((caddr[0]<<24) & 0xff000000);
+ addr |= ((caddr[1] <<16) & 0xff0000);
+ addr |= ((caddr[2] <<8) & 0xff00);
+ addr |= (caddr[3] & 0xff);
+ memset((void *) &him4, 0, sizeof(him4));
+ him4.sin_addr.s_addr = (uint32_t) htonl(addr);
+ him4.sin_family = AF_INET;
+ sa = (struct sockaddr *) &him4;
+ len = sizeof(him4);
+ } else {
/*
- * For IPv4 addresses construct a sockaddr_in structure.
+ * For IPv6 address construct a sockaddr_in6 structure.
*/
- if ((*env)->GetArrayLength(env, addrArray) == 4) {
- jint addr;
- (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
- addr = ((caddr[0]<<24) & 0xff000000);
- addr |= ((caddr[1] <<16) & 0xff0000);
- addr |= ((caddr[2] <<8) & 0xff00);
- addr |= (caddr[3] & 0xff);
- memset((void *) &him4, 0, sizeof(him4));
- him4.sin_addr.s_addr = (uint32_t) htonl(addr);
- him4.sin_family = AF_INET;
- sa = (struct sockaddr *) &him4;
- len = sizeof(him4);
- } else {
- /*
- * For IPv6 address construct a sockaddr_in6 structure.
- */
- (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
- memset((void *) &him6, 0, sizeof(him6));
- memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
- him6.sin6_family = AF_INET6;
- sa = (struct sockaddr *) &him6 ;
- len = sizeof(him6) ;
- }
+ (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
+ memset((void *) &him6, 0, sizeof(him6));
+ memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
+ him6.sin6_family = AF_INET6;
+ sa = (struct sockaddr *) &him6 ;
+ len = sizeof(him6) ;
+ }
- error = (*getnameinfo_ptr)(sa, len, host, NI_MAXHOST, NULL, 0,
- NI_NAMEREQD);
+ error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
+ NI_NAMEREQD);
- if (!error) {
- ret = (*env)->NewStringUTF(env, host);
- }
+ if (!error) {
+ ret = (*env)->NewStringUTF(env, host);
}
#endif /* AF_INET6 */
--- a/jdk/src/solaris/native/java/net/net_util_md.c Mon Nov 21 12:57:36 2011 +0000
+++ b/jdk/src/solaris/native/java/net/net_util_md.c Fri Nov 11 14:40:18 2011 +0000
@@ -377,37 +377,12 @@
* we should also check if the APIs are available.
*/
ipv6_fn = JVM_FindLibraryEntry(RTLD_DEFAULT, "inet_pton");
+ close(fd);
if (ipv6_fn == NULL ) {
- close(fd);
return JNI_FALSE;
+ } else {
+ return JNI_TRUE;
}
-
- /*
- * We've got the library, let's get the pointers to some
- * IPV6 specific functions. We have to do that because, at least
- * on Solaris we may build on a system without IPV6 networking
- * libraries, therefore we can't have a hard link to these
- * functions.
- */
- getaddrinfo_ptr = (getaddrinfo_f)
- JVM_FindLibraryEntry(RTLD_DEFAULT, "getaddrinfo");
-
- freeaddrinfo_ptr = (freeaddrinfo_f)
- JVM_FindLibraryEntry(RTLD_DEFAULT, "freeaddrinfo");
-
- gai_strerror_ptr = (gai_strerror_f)
- JVM_FindLibraryEntry(RTLD_DEFAULT, "gai_strerror");
-
- getnameinfo_ptr = (getnameinfo_f)
- JVM_FindLibraryEntry(RTLD_DEFAULT, "getnameinfo");
-
- if (freeaddrinfo_ptr == NULL || getnameinfo_ptr == NULL) {
- /* We need all 3 of them */
- getaddrinfo_ptr = NULL;
- }
-
- close(fd);
- return JNI_TRUE;
#endif /* AF_INET6 */
}
@@ -920,10 +895,6 @@
return 1;
}
-jboolean NET_addrtransAvailable() {
- return (jboolean)(getaddrinfo_ptr != NULL);
-}
-
/*
* Map the Java level socket option to the platform specific
* level and option name.
--- a/jdk/src/solaris/native/java/net/net_util_md.h Mon Nov 21 12:57:36 2011 +0000
+++ b/jdk/src/solaris/native/java/net/net_util_md.h Fri Nov 11 14:40:18 2011 +0000
@@ -102,10 +102,6 @@
const char* hostname,
int gai_error);
-/* do we have address translation support */
-
-extern jboolean NET_addrtransAvailable();
-
#define NET_WAIT_READ 0x01
#define NET_WAIT_WRITE 0x02
#define NET_WAIT_CONNECT 0x04