From: Lorenzo Colitti Date: Thu, 27 Aug 2009 01:41:06 +0000 (-0700) Subject: More InetAddress fixes. X-Git-Tag: android-x86-2.2~385^2~64^2 X-Git-Url: http://git.osdn.net/view?p=android-x86%2Fdalvik.git;a=commitdiff_plain;h=364a0a2faae81e5b0844685ad9272f090467db44 More InetAddress fixes. 1. Make sure getHostByAddrImpl actually throws UnknownHostException: set NI_NAMEREQD when calling getnameinfo to ensure it will fail if the IP address looked up does not have a name associated with it, and pass this exception back to the Java code. That way, the UnknownHostException passed back to the Java code has information on what went wrong. 2. Remove superfluous logging on reverse lookups in the C code. Change-Id: Ie195ce1f12e7b43fbf75f494002804f9db68fd8c --- diff --git a/libcore/luni/src/main/native/java_net_InetAddress.cpp b/libcore/luni/src/main/native/java_net_InetAddress.cpp index 8724817fc..90a88ee85 100644 --- a/libcore/luni/src/main/native/java_net_InetAddress.cpp +++ b/libcore/luni/src/main/native/java_net_InetAddress.cpp @@ -111,11 +111,6 @@ static jobjectArray getAllByNameUsingDns(JNIEnv* env, const char* name, jobjectArray addressArray = NULL; memset(&hints, 0, sizeof(hints)); - /* - * IPv4 only for now until the socket code supports IPv6; otherwise, the - * resolver will create two separate requests, one for IPv4 and one, - * currently unnecessary, for IPv6. - */ hints.ai_family = AF_UNSPEC; hints.ai_flags = AI_ADDRCONFIG; /* @@ -233,7 +228,9 @@ jobjectArray InetAddress_getallbyname(JNIEnv* env, jobject obj, } if (!out) { +#if LOG_DNS LOGI("Unknown host %s, throwing UnknownHostException", name); +#endif jniThrowException(env, "java/net/UnknownHostException", name); } env->ReleaseStringUTFChars(javaName, name); @@ -241,6 +238,14 @@ jobjectArray InetAddress_getallbyname(JNIEnv* env, jobject obj, } +/** + * Looks up the name corresponding to an IP address. + * + * @param javaAddress: a byte array containing the raw IP address bytes. Must be + * 4 or 16 bytes long. + * @return the hostname. + * @throws UnknownHostException: the IP address has no associated hostname. + */ static jstring InetAddress_gethostbyaddr(JNIEnv* env, jobject obj, jbyteArray javaAddress) { @@ -257,57 +262,45 @@ static jstring InetAddress_gethostbyaddr(JNIEnv* env, jobject obj, } // Convert the raw address bytes into a socket address structure. + int ret = 0; struct sockaddr_storage ss; struct sockaddr_in *sin = (struct sockaddr_in *) &ss; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &ss; size_t socklen; + memset(&ss, 0, sizeof(ss)); switch (addrlen) { case 4: socklen = sizeof(struct sockaddr_in); - memset(sin, 0, sizeof(struct sockaddr_in)); sin->sin_family = AF_INET; - memcpy(&sin->sin_addr.s_addr, rawAddress, 4); + memcpy(&sin->sin_addr.s_addr, rawAddress, addrlen); env->ReleaseByteArrayElements(javaAddress, rawAddress, JNI_ABORT); break; case 16: socklen = sizeof(struct sockaddr_in6); - memset(sin6, 0, sizeof(struct sockaddr_in6)); sin6->sin6_family = AF_INET6; - memcpy(&sin6->sin6_addr.s6_addr, rawAddress, 16); + memcpy(&sin6->sin6_addr.s6_addr, rawAddress, addrlen); env->ReleaseByteArrayElements(javaAddress, rawAddress, JNI_ABORT); break; default: + // The caller already throws an exception in this case. Don't worry + // about it here. env->ReleaseByteArrayElements(javaAddress, rawAddress, JNI_ABORT); - jniThrowException(env, "java/net/UnknownHostException", - "Invalid address length"); return NULL; } - - // Convert the socket address structure to an IP string for logging. - int ret; - char ipstr[INET6_ADDRSTRLEN]; - ret = getnameinfo((struct sockaddr *) &ss, socklen, ipstr, sizeof(ipstr), - NULL, 0, NI_NUMERICHOST); - if (ret) { - LOGE("gethostbyaddr: getnameinfo: %s", gai_strerror(ret)); - return NULL; + // Look up the host name from the IP address. + char name[NI_MAXHOST]; + if (ret == 0) { + ret = getnameinfo((struct sockaddr *) &ss, socklen, name, sizeof(name), + NULL, 0, NI_NAMEREQD); } - // Look up the IP address from the socket address structure. - jstring result = NULL; - char name[NI_MAXHOST]; - ret = getnameinfo((struct sockaddr *) &ss, socklen, name, sizeof(name), - NULL, 0, 0); if (ret == 0) { - LOGI("gethostbyaddr: getnameinfo: %s = %s", ipstr, name); - result = env->NewStringUTF(name); - } else { - LOGE("gethostbyaddr: getnameinfo: unknown host %s: %s", ipstr, - gai_strerror(ret)); + return env->NewStringUTF(name); } - return result; + jniThrowException(env, "java/net/UnknownHostException", gai_strerror(ret)); + return NULL; } /*