提交 f276ca90 编写于 作者: M mullan

Merge

......@@ -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;
// ensure null-terminated
hostname[MAXHOSTNAMELEN] = '\0';
#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);
}
struct addrinfo hints, *res;
int error;
hostname[NI_MAXHOST] = '\0';
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_INET;
error = getaddrinfo(hostname, NULL, &hints, &res);
if (error == 0) {/* host is known to name service */
getnameinfo(res->ai_addr,
res->ai_addrlen,
hostname,
NI_MAXHOST,
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 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
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 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
CHECK_NULL_RETURN(hostname, NULL);
/* Try once, with our static buffer. */
memset(&hints, 0, 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 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
}
#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);
/* 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;
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;
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,38 @@ JNIEXPORT jstring JNICALL
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;
/*
* 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.
*
*/
char host[NI_MAXHOST+1];
int error = 0;
int len = 0;
jbyte caddr[4];
struct sockaddr_in him4;
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;
}
......
......@@ -82,31 +82,29 @@ Java_java_net_Inet6AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
* We use thread-safe system calls.
*/
#ifdef AF_INET6
if (NET_addrtransAvailable()) {
struct addrinfo hints, *res;
int error;
bzero(&hints, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_UNSPEC;
error = (*getaddrinfo_ptr)(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 getnameinfo fails hostname is still the value
from gethostname */
(*freeaddrinfo_ptr)(res);
}
struct addrinfo hints, *res;
int error;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_UNSPEC;
error = getaddrinfo(hostname, NULL, &hints, &res);
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 */
freeaddrinfo(res);
}
#endif /* AF_INET6 */
#endif /* __linux__ */
......@@ -173,193 +171,191 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
CHECK_NULL_RETURN(hostname, NULL);
#ifdef AF_INET6
if (NET_addrtransAvailable()) {
static jfieldID ia_preferIPv6AddressID;
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) {
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;
}
JNU_ReleaseStringPlatformChars(env, host, hostname);
return NULL;
}
/* get the address preference */
preferIPv6Address
= (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID);
}
/* 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;
/* Try once, with our static buffer. */
memset(&hints, 0, 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;
}
/*
* 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;
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 {
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;
break;
}
skip = 1;
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;
} 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;
}
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 ++;
}
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;
iterator = iterator->ai_next;
}
retLen = i;
iterator = resNew;
ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL);
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 (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;
}
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) {
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 @@ cleanupAndReturn:
JNU_ReleaseStringPlatformChars(env, host, hostname);
}
if (NET_addrtransAvailable())
(*freeaddrinfo_ptr)(res);
freeaddrinfo(res);
#endif /* AF_INET6 */
return ret;
......@@ -393,44 +388,42 @@ Java_java_net_Inet6AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
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 */
......
......@@ -377,37 +377,12 @@ jint IPv6_supported()
* 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 @@ NET_IsEqual(jbyte* caddr1, jbyte* caddr2) {
return 1;
}
jboolean NET_addrtransAvailable() {
return (jboolean)(getaddrinfo_ptr != NULL);
}
/*
* Map the Java level socket option to the platform specific
* level and option name.
......
......@@ -102,10 +102,6 @@ void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册