Fix MulticastSocket implementation.

Give up when an exception is thrown, do not try the next
interface with an exception pending.

Change-Id: I9870e5b06cec3b9120f31704badfd11adf1f98e7
diff --git a/ojluni/src/main/native/PlainDatagramSocketImpl.c b/ojluni/src/main/native/PlainDatagramSocketImpl.c
index 9a5ec17..ac657d7 100755
--- a/ojluni/src/main/native/PlainDatagramSocketImpl.c
+++ b/ojluni/src/main/native/PlainDatagramSocketImpl.c
@@ -1170,8 +1170,10 @@
 /*
  * Set outgoing multicast interface designated by a NetworkInterface.
  * Throw exception if failed.
+ *
+ * Android changed: return 0 on success, negative on failure.
  */
-static void mcast_set_if_by_if_v4(JNIEnv *env, jobject this, int fd, jobject value) {
+static int mcast_set_if_by_if_v4(JNIEnv *env, jobject this, int fd, jobject value) {
     static jfieldID ni_addrsID;
     struct in_addr in;
     jobjectArray addrArray;
@@ -1181,10 +1183,12 @@
 
     if (ni_addrsID == NULL ) {
         jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
-        CHECK_NULL(c);
+        // Android-changed: return -1 if null.
+        CHECK_NULL_RETURN(c, -1);
         ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
                                         "[Ljava/net/InetAddress;");
-        CHECK_NULL(ni_addrsID);
+        // Android-changed: return -1 if null.
+        CHECK_NULL_RETURN(ni_addrsID, -1);
     }
 
     addrArray = (*env)->GetObjectField(env, value, ni_addrsID);
@@ -1197,7 +1201,7 @@
     if (len < 1) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
             "bad argument for IP_MULTICAST_IF2: No IP addresses bound to interface");
-        return;
+        return -1;
     }
 
     /*
@@ -1215,7 +1219,10 @@
                        (const char*)&in, sizeof(in)) < 0) {
         NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
                        "Error setting socket option");
+        return -1;
     }
+
+    return 0;
 }
 
 /*
@@ -1264,8 +1271,10 @@
 /*
  * Set outgoing multicast interface designated by an InetAddress.
  * Throw exception if failed.
+ *
+ * Android-changed : Return type, return 0 on success, negative on failure.
  */
-static void mcast_set_if_by_addr_v4(JNIEnv *env, jobject this, int fd, jobject value) {
+static int mcast_set_if_by_addr_v4(JNIEnv *env, jobject this, int fd, jobject value) {
     struct in_addr in;
 
     in.s_addr = htonl( getInetAddress_addr(env, value) );
@@ -1274,7 +1283,10 @@
                        (const char*)&in, sizeof(in)) < 0) {
         NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
                          "Error setting socket option");
+        return -1;
     }
+
+    return 0;
 }
 
 /*
@@ -1341,7 +1353,11 @@
          */
 #ifdef AF_INET6
 #ifdef __linux__
-        mcast_set_if_by_addr_v4(env, this, fd, value);
+        // Android-changed: Return early if mcast_set_if_by_addr_v4 threw.
+        // We don't want to call into the IPV6 code with a pending exception.
+        if (mcast_set_if_by_addr_v4(env, this, fd, value)) {
+            return;
+        }
         if (ipv6_available()) {
             mcast_set_if_by_addr_v6(env, this, fd, value);
         }
@@ -1363,7 +1379,11 @@
          */
 #ifdef AF_INET6
 #ifdef __linux__
-        mcast_set_if_by_if_v4(env, this, fd, value);
+        // Android-changed: Return early if mcast_set_if_by_addr_v4 threw.
+        // We don't want to call into the IPV6 code with a pending exception.
+        if (mcast_set_if_by_if_v4(env, this, fd, value)) {
+            return;
+        }
         if (ipv6_available()) {
             mcast_set_if_by_if_v6(env, this, fd, value);
         }