src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c

Print this page

        

@@ -63,13 +63,10 @@
 jfieldID pdsi_timeoutID;
 
 jfieldID pdsi_localPortID;
 jfieldID pdsi_connected;
 
-static jclass ia4_clazz;
-static jmethodID ia4_ctor;
-
 static CRITICAL_SECTION sizeCheckLock;
 
 /* Windows OS version is XP or better */
 static int xp_or_later = 0;
 /* Windows OS version is Windows 2000 or better */

@@ -81,50 +78,69 @@
  * fd always points to the IPv4 fd, and fd1 points to the IPv6 fd.
  * Both fds are used when we bind to a wild-card address. When a specific
  * address is used, only one of them is used.
  */
 
-/*
- * Returns a java.lang.Integer based on 'i'
- */
-jobject createInteger(JNIEnv *env, int i) {
-    static jclass i_class;
-    static jmethodID i_ctrID;
-    static jfieldID i_valueID;
+static jclass i_class;
+static jmethodID i_ctrID;
+static jfieldID i_valueID;
 
+int initIntegerIDs(JNIEnv* env) {
     if (i_class == NULL) {
         jclass c = (*env)->FindClass(env, "java/lang/Integer");
         CHECK_NULL_RETURN(c, NULL);
         i_ctrID = (*env)->GetMethodID(env, c, "<init>", "(I)V");
         CHECK_NULL_RETURN(i_ctrID, NULL);
+        i_valueID = (*env)->GetFieldID(env, c, "value", "I");
+        CHECK_NULL_RETURN(i_valueID, NULL);
         i_class = (*env)->NewGlobalRef(env, c);
         CHECK_NULL_RETURN(i_class, NULL);
     }
+    return 1;
+}
 
+/* Returns a java.lang.Integer based on 'i' */
+static jobject createInteger(JNIEnv *env, int i) {
+    CHECK_NULL_RETURN(initIntegerIDs(env), NULL);
     return ( (*env)->NewObject(env, i_class, i_ctrID, i) );
 }
 
-/*
- * Returns a java.lang.Boolean based on 'b'
- */
-jobject createBoolean(JNIEnv *env, int b) {
-    static jclass b_class;
-    static jmethodID b_ctrID;
-    static jfieldID b_valueID;
+/* Returns a jint based on the given java.lang.Integer */
+static jint retrieveInteger(JNIEnv *env, jobject i) {
+    CHECK_NULL_RETURN(initIntegerIDs(env), NULL);
+    return (*env)->GetIntField(env, i, i_valueID);
+}
 
+static jclass b_class;
+static jmethodID b_ctrID;
+static jfieldID b_valueID;
+
+int initBooleanIDs(JNIEnv* env) {
     if (b_class == NULL) {
         jclass c = (*env)->FindClass(env, "java/lang/Boolean");
         CHECK_NULL_RETURN(c, NULL);
         b_ctrID = (*env)->GetMethodID(env, c, "<init>", "(Z)V");
         CHECK_NULL_RETURN(b_ctrID, NULL);
+        b_valueID = (*env)->GetFieldID(env, c, "value", "Z");
+        CHECK_NULL_RETURN(b_valueID, NULL);
         b_class = (*env)->NewGlobalRef(env, c);
         CHECK_NULL_RETURN(b_class, NULL);
     }
+    return 1;
+}
 
+/* Returns a java.lang.Boolean based on 'b' */
+static jobject createBoolean(JNIEnv *env, int b) {
+    CHECK_NULL_RETURN(initBooleanIDs(env), NULL);
     return( (*env)->NewObject(env, b_class, b_ctrID, (jboolean)(b!=0)) );
 }
 
+/* Returns a jboolean based on the given java.lang.Boolean */
+static jboolean retrieveBoolean(JNIEnv *env, jobject b) {
+    CHECK_NULL_RETURN(initBooleanIDs(env), NULL);
+    return (*env)->GetBooleanField(env, b, b_valueID);
+}
 
 static int getFD(JNIEnv *env, jobject this) {
     jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
 
     if (fdObj == NULL) {

@@ -406,18 +422,15 @@
     cls = (*env)->FindClass(env, "java/io/FileDescriptor");
     CHECK_NULL(cls);
     IO_fd_fdID = NET_GetFileDescriptorID(env);
     CHECK_NULL(IO_fd_fdID);
 
-    ia4_clazz = (*env)->FindClass(env, "java/net/Inet4Address");
-    CHECK_NULL(ia4_clazz);
-    ia4_clazz = (*env)->NewGlobalRef(env, ia4_clazz);
-    CHECK_NULL(ia4_clazz);
-    ia4_ctor = (*env)->GetMethodID(env, ia4_clazz, "<init>", "()V");
-    CHECK_NULL(ia4_ctor);
+    // Load static data (jclass, methodIDs, fieldID ) from InetAddress,
+    // Inet4Address, Inet6Address and NetorkInterface.
+    init(env);
+    (*env)->FindClass(env, "java/net/NetworkInterface");
 
-
     InitializeCriticalSection(&sizeCheckLock);
 }
 
 JNIEXPORT void JNICALL
 Java_java_net_TwoStacksPlainDatagramSocketImpl_bind0(JNIEnv *env, jobject this,

@@ -465,21 +478,21 @@
         v6bind.ipv4_fd = fd;
         v6bind.ipv6_fd = fd1;
         if (NET_BindV6(&v6bind) != -1) {
             /* check if the fds have changed */
             if (v6bind.ipv4_fd != fd) {
-                fd = v6bind.ipv4_fd;
+                fd = (int)v6bind.ipv4_fd;
                 if (fd == -1) {
                     /* socket is closed. */
                     (*env)->SetObjectField(env, this, pdsi_fdID, NULL);
                 } else {
                     /* socket was re-created */
                     (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
                 }
             }
             if (v6bind.ipv6_fd != fd1) {
-                fd1 = v6bind.ipv6_fd;
+                fd1 = (int)v6bind.ipv6_fd;
                 if (fd1 == -1) {
                     /* socket is closed. */
                     (*env)->SetObjectField(env, this, pdsi_fd1ID, NULL);
                 } else {
                     /* socket was re-created */

@@ -1508,11 +1521,11 @@
          * when the socket is connected
          */
         t = FALSE;
         WSAIoctl(fd,SIO_UDP_CONNRESET,&t,sizeof(t),&x1,sizeof(x1),&x2,0,0);
         t = TRUE;
-        fd1 = socket (AF_INET6, SOCK_DGRAM, 0);
+        fd1 = (int)socket (AF_INET6, SOCK_DGRAM, 0);
         if (fd1 == JVM_IO_ERR) {
             NET_ThrowCurrent(env, "Socket creation failed");
             return;
         }
         NET_SetSockOpt(fd1, SOL_SOCKET, SO_BROADCAST, (char*)&t, sizeof(BOOL));

@@ -1571,28 +1584,14 @@
  */
 
 static int getInetAddrFromIf (JNIEnv *env, int family, jobject nif, jobject *iaddr)
 {
     jobjectArray addrArray;
-    static jfieldID ni_addrsID=0;
-    static jfieldID ia_familyID=0;
     jsize len;
     jobject addr;
     int i;
 
-    if (ni_addrsID == NULL) {
-        jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
-        CHECK_NULL_RETURN (c, -1);
-        ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
-                                        "[Ljava/net/InetAddress;");
-        CHECK_NULL_RETURN (ni_addrsID, -1);
-        c = (*env)->FindClass(env,"java/net/InetAddress");
-        CHECK_NULL_RETURN (c, -1);
-        ia_familyID = (*env)->GetFieldID(env, c, "family", "I");
-        CHECK_NULL_RETURN (ia_familyID, -1);
-    }
-
     addrArray = (*env)->GetObjectField(env, nif, ni_addrsID);
     len = (*env)->GetArrayLength(env, addrArray);
 
     /*
      * Check that there is at least one address bound to this

@@ -1616,39 +1615,23 @@
 }
 
 static int getInet4AddrFromIf (JNIEnv *env, jobject nif, struct in_addr *iaddr)
 {
     jobject addr;
-    static jfieldID ia_addressID;
 
     int ret = getInetAddrFromIf (env, IPv4, nif, &addr);
     if (ret == -1) {
         return -1;
     }
 
-    if (ia_addressID == 0) {
-        jclass c = (*env)->FindClass(env,"java/net/InetAddress");
-        CHECK_NULL_RETURN (c, -1);
-        ia_addressID = (*env)->GetFieldID(env, c, "address", "I");
-        CHECK_NULL_RETURN (ia_addressID, -1);
-    }
     iaddr->s_addr = htonl((*env)->GetIntField(env, addr, ia_addressID));
     return 0;
 }
 
 /* Get the multicasting index from the interface */
 
 static int getIndexFromIf (JNIEnv *env, jobject nif) {
-    static jfieldID ni_indexID;
-
-    if (ni_indexID == NULL) {
-        jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
-        CHECK_NULL_RETURN(c, -1);
-        ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
-        CHECK_NULL_RETURN(ni_indexID, -1);
-    }
-
     return (*env)->GetIntField(env, nif, ni_indexID);
 }
 
 /*
  * Sets the multicast interface.

@@ -1685,18 +1668,10 @@
          * On IPv6 system get the NetworkInterface that this IP
          * address is bound to and use the IPV6_MULTICAST_IF
          * option instead of IP_MULTICAST_IF
          */
         if (ipv6_supported) {
-            static jclass ni_class;
-            if (ni_class == NULL) {
-                jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
-                CHECK_NULL(c);
-                ni_class = (*env)->NewGlobalRef(env, c);
-                CHECK_NULL(ni_class);
-            }
-
             value = Java_java_net_NetworkInterface_getByInetAddress0(env, ni_class, value);
             if (value == NULL) {
                 if (!(*env)->ExceptionOccurred(env)) {
                     JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                          "bad argument for IP_MULTICAST_IF"

@@ -1704,20 +1679,12 @@
                 }
                 return;
             }
             opt = java_net_SocketOptions_IP_MULTICAST_IF2;
         } else {
-            static jfieldID ia_addressID;
             struct in_addr in;
 
-            if (ia_addressID == NULL) {
-                        jclass c = (*env)->FindClass(env,"java/net/InetAddress");
-                CHECK_NULL(c);
-                ia_addressID = (*env)->GetFieldID(env, c, "address", "I");
-                CHECK_NULL(ia_addressID);
-            }
-
             in.s_addr = htonl((*env)->GetIntField(env, value, ia_addressID));
 
             if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
                                (const char*)&in, sizeof(in)) < 0) {
                 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",

@@ -1734,20 +1701,13 @@
          * IPV6_MULTICAST_IF socket option
          * On IPv4 system extract addr[0] and use the IP_MULTICAST_IF
          * option. For IPv6 both must be done.
          */
         if (ipv6_supported) {
-            static jfieldID ni_indexID;
             struct in_addr in;
             int index;
 
-            if (ni_indexID == NULL) {
-                jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
-                CHECK_NULL(c);
-                ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
-                CHECK_NULL(ni_indexID);
-            }
             index = (*env)->GetIntField(env, value, ni_indexID);
 
             if (setsockopt(fd1, IPPROTO_IPV6, IPV6_MULTICAST_IF,
                                (const char*)&index, sizeof(index)) < 0) {
                 if (errno == EINVAL && index > 0) {

@@ -1849,37 +1809,20 @@
     switch (opt) {
         case java_net_SocketOptions_SO_SNDBUF :
         case java_net_SocketOptions_SO_RCVBUF :
         case java_net_SocketOptions_IP_TOS :
             {
-                jclass cls;
-                jfieldID fid;
-
-                cls = (*env)->FindClass(env, "java/lang/Integer");
-                CHECK_NULL(cls);
-                fid =  (*env)->GetFieldID(env, cls, "value", "I");
-                CHECK_NULL(fid);
-
-                optval.i = (*env)->GetIntField(env, value, fid);
+                optval.i = retrieveInteger(env, value);
                 optlen = sizeof(optval.i);
             }
             break;
 
         case java_net_SocketOptions_SO_REUSEADDR:
         case java_net_SocketOptions_SO_BROADCAST:
         case java_net_SocketOptions_IP_MULTICAST_LOOP:
             {
-                jclass cls;
-                jfieldID fid;
-                jboolean on;
-
-                cls = (*env)->FindClass(env, "java/lang/Boolean");
-                CHECK_NULL(cls);
-                fid =  (*env)->GetFieldID(env, cls, "value", "Z");
-                CHECK_NULL(fid);
-
-                on = (*env)->GetBooleanField(env, value, fid);
+                jboolean on = retrieveBoolean(env, value);
                 optval.i = (on ? 1 : 0);
                 /*
                  * setLoopbackMode (true) disables IP_MULTICAST_LOOP rather
                  * than enabling it.
                  */

@@ -1941,19 +1884,10 @@
 
     /*
      * IPv4 implementation
      */
     if (isIPV4) {
-        static jclass inet4_class;
-        static jmethodID inet4_ctrID;
-        static jfieldID inet4_addrID;
-
-        static jclass ni_class;
-        static jmethodID ni_ctrID;
-        static jfieldID ni_indexID;
-        static jfieldID ni_addrsID;
-
         jobjectArray addrArray;
         jobject addr;
         jobject ni;
 
         struct in_addr in;

@@ -1968,24 +1902,14 @@
         }
 
         /*
          * Construct and populate an Inet4Address
          */
-        if (inet4_class == NULL) {
-            jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
-            CHECK_NULL_RETURN(c, NULL);
-            inet4_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
-            CHECK_NULL_RETURN(inet4_ctrID, NULL);
-            inet4_addrID = (*env)->GetFieldID(env, c, "address", "I");
-            CHECK_NULL_RETURN(inet4_addrID, NULL);
-            inet4_class = (*env)->NewGlobalRef(env, c);
-            CHECK_NULL_RETURN(inet4_class, NULL);
-        }
-        addr = (*env)->NewObject(env, inet4_class, inet4_ctrID, 0);
+        addr = (*env)->NewObject(env, ia4_class, ia4_ctrID, 0);
         CHECK_NULL_RETURN(addr, NULL);
 
-        (*env)->SetIntField(env, addr, inet4_addrID, ntohl(in.s_addr));
+        (*env)->SetIntField(env, addr, ia_addressID, ntohl(in.s_addr));
 
         /*
          * For IP_MULTICAST_IF return InetAddress
          */
         if (opt == java_net_SocketOptions_IP_MULTICAST_IF) {

@@ -1994,23 +1918,10 @@
 
         /*
          * For IP_MULTICAST_IF2 we get the NetworkInterface for
          * this address and return it
          */
-        if (ni_class == NULL) {
-            jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
-            CHECK_NULL_RETURN(c, NULL);
-            ni_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
-            CHECK_NULL_RETURN(ni_ctrID, NULL);
-            ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
-            CHECK_NULL_RETURN(ni_indexID, NULL);
-            ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
-                                            "[Ljava/net/InetAddress;");
-            CHECK_NULL_RETURN(ni_addrsID, NULL);
-            ni_class = (*env)->NewGlobalRef(env, c);
-            CHECK_NULL_RETURN(ni_class, NULL);
-        }
         ni = Java_java_net_NetworkInterface_getByInetAddress0(env, ni_class, addr);
         if (ni) {
             return ni;
         }
 

@@ -2021,11 +1932,11 @@
          */
         ni = (*env)->NewObject(env, ni_class, ni_ctrID, 0);
         CHECK_NULL_RETURN(ni, NULL);
 
         (*env)->SetIntField(env, ni, ni_indexID, -1);
-        addrArray = (*env)->NewObjectArray(env, 1, inet4_class, NULL);
+        addrArray = (*env)->NewObjectArray(env, 1, ia4_class, NULL);
         CHECK_NULL_RETURN(addrArray, NULL);
         (*env)->SetObjectArrayElement(env, addrArray, 0, addr);
         (*env)->SetObjectField(env, ni, ni_addrsID, addrArray);
         return ni;
     }

@@ -2035,15 +1946,10 @@
      * IPv6 implementation
      */
     if ((opt == java_net_SocketOptions_IP_MULTICAST_IF) ||
         (opt == java_net_SocketOptions_IP_MULTICAST_IF2)) {
 
-        static jclass ni_class;
-        static jmethodID ni_ctrID;
-        static jfieldID ni_indexID;
-        static jfieldID ni_addrsID;
-        static jclass ia_class;
         static jmethodID ia_anyLocalAddressID;
 
         int index;
         int len = sizeof(index);
 

@@ -2058,32 +1964,16 @@
                                "Error getting socket option");
                 return NULL;
             }
         }
 
-        if (ni_class == NULL) {
-            jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
-            CHECK_NULL_RETURN(c, NULL);
-            ni_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V");
-            CHECK_NULL_RETURN(ni_ctrID, NULL);
-            ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
-            CHECK_NULL_RETURN(ni_indexID, NULL);
-            ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
-                                            "[Ljava/net/InetAddress;");
-            CHECK_NULL_RETURN(ni_addrsID, NULL);
-
-            ia_class = (*env)->FindClass(env, "java/net/InetAddress");
-            CHECK_NULL_RETURN(ia_class, NULL);
-            ia_class = (*env)->NewGlobalRef(env, ia_class);
-            CHECK_NULL_RETURN(ia_class, NULL);
+        if (ia_anyLocalAddressID == NULL) {
             ia_anyLocalAddressID = (*env)->GetStaticMethodID(env,
                                                              ia_class,
                                                              "anyLocalAddress",
                                                              "()Ljava/net/InetAddress;");
             CHECK_NULL_RETURN(ia_anyLocalAddressID, NULL);
-            ni_class = (*env)->NewGlobalRef(env, c);
-            CHECK_NULL_RETURN(ni_class, NULL);
         }
 
         /*
          * If multicast to a specific interface then return the
          * interface (for IF2) or the any address on that interface