src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c
Print this page
*** 63,75 ****
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 */
--- 63,72 ----
*** 81,130 ****
* 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;
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_class = (*env)->NewGlobalRef(env, c);
CHECK_NULL_RETURN(i_class, 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;
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_class = (*env)->NewGlobalRef(env, c);
CHECK_NULL_RETURN(b_class, NULL);
}
return( (*env)->NewObject(env, b_class, b_ctrID, (jboolean)(b!=0)) );
}
static int getFD(JNIEnv *env, jobject this) {
jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
if (fdObj == NULL) {
--- 78,146 ----
* 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.
*/
! 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 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,423 ****
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);
-
InitializeCriticalSection(&sizeCheckLock);
}
JNIEXPORT void JNICALL
Java_java_net_TwoStacksPlainDatagramSocketImpl_bind0(JNIEnv *env, jobject this,
--- 422,436 ----
cls = (*env)->FindClass(env, "java/io/FileDescriptor");
CHECK_NULL(cls);
IO_fd_fdID = NET_GetFileDescriptorID(env);
CHECK_NULL(IO_fd_fdID);
! // 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,485 ****
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;
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;
if (fd1 == -1) {
/* socket is closed. */
(*env)->SetObjectField(env, this, pdsi_fd1ID, NULL);
} else {
/* socket was re-created */
--- 478,498 ----
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 = (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 = (int)v6bind.ipv6_fd;
if (fd1 == -1) {
/* socket is closed. */
(*env)->SetObjectField(env, this, pdsi_fd1ID, NULL);
} else {
/* socket was re-created */
*** 1508,1518 ****
* 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);
if (fd1 == JVM_IO_ERR) {
NET_ThrowCurrent(env, "Socket creation failed");
return;
}
NET_SetSockOpt(fd1, SOL_SOCKET, SO_BROADCAST, (char*)&t, sizeof(BOOL));
--- 1521,1531 ----
* when the socket is connected
*/
t = FALSE;
WSAIoctl(fd,SIO_UDP_CONNRESET,&t,sizeof(t),&x1,sizeof(x1),&x2,0,0);
t = TRUE;
! 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,1598 ****
*/
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
--- 1584,1597 ----
*** 1616,1654 ****
}
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.
--- 1615,1637 ----
*** 1685,1702 ****
* 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"
--- 1668,1677 ----
*** 1704,1723 ****
}
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",
--- 1679,1690 ----
*** 1734,1753 ****
* 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) {
--- 1701,1713 ----
*** 1849,1885 ****
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);
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);
optval.i = (on ? 1 : 0);
/*
* setLoopbackMode (true) disables IP_MULTICAST_LOOP rather
* than enabling it.
*/
--- 1809,1828 ----
switch (opt) {
case java_net_SocketOptions_SO_SNDBUF :
case java_net_SocketOptions_SO_RCVBUF :
case java_net_SocketOptions_IP_TOS :
{
! 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:
{
! jboolean on = retrieveBoolean(env, value);
optval.i = (on ? 1 : 0);
/*
* setLoopbackMode (true) disables IP_MULTICAST_LOOP rather
* than enabling it.
*/
*** 1941,1959 ****
/*
* 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;
--- 1884,1893 ----
*** 1968,1991 ****
}
/*
* 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);
CHECK_NULL_RETURN(addr, NULL);
! (*env)->SetIntField(env, addr, inet4_addrID, ntohl(in.s_addr));
/*
* For IP_MULTICAST_IF return InetAddress
*/
if (opt == java_net_SocketOptions_IP_MULTICAST_IF) {
--- 1902,1915 ----
}
/*
* Construct and populate an Inet4Address
*/
! addr = (*env)->NewObject(env, ia4_class, ia4_ctrID, 0);
CHECK_NULL_RETURN(addr, NULL);
! (*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,2016 ****
/*
* 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;
}
--- 1918,1927 ----
*** 2021,2031 ****
*/
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);
CHECK_NULL_RETURN(addrArray, NULL);
(*env)->SetObjectArrayElement(env, addrArray, 0, addr);
(*env)->SetObjectField(env, ni, ni_addrsID, addrArray);
return ni;
}
--- 1932,1942 ----
*/
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, ia4_class, NULL);
CHECK_NULL_RETURN(addrArray, NULL);
(*env)->SetObjectArrayElement(env, addrArray, 0, addr);
(*env)->SetObjectField(env, ni, ni_addrsID, addrArray);
return ni;
}
*** 2035,2049 ****
* 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);
--- 1946,1955 ----
*** 2058,2089 ****
"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);
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
--- 1964,1979 ----
"Error getting socket option");
return NULL;
}
}
! if (ia_anyLocalAddressID == NULL) {
ia_anyLocalAddressID = (*env)->GetStaticMethodID(env,
ia_class,
"anyLocalAddress",
"()Ljava/net/InetAddress;");
CHECK_NULL_RETURN(ia_anyLocalAddressID, NULL);
}
/*
* If multicast to a specific interface then return the
* interface (for IF2) or the any address on that interface