OSDN Git Service

More InetAddress fixes.
authorLorenzo Colitti <lorenzo@google.com>
Thu, 27 Aug 2009 01:41:06 +0000 (18:41 -0700)
committerLorenzo Colitti <lorenzo@google.com>
Fri, 4 Sep 2009 00:56:18 +0000 (17:56 -0700)
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

libcore/luni/src/main/native/java_net_InetAddress.cpp

index 8724817..90a88ee 100644 (file)
@@ -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;
 }
 
 /*