jdk/src/windows/native/sun/nio/ch/DatagramChannelImpl.c

Print this page
rev 5725 : Merge


  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include "jni.h"
  27 #include "jni_util.h"
  28 #include "jvm.h"
  29 #include "jlong.h"
  30 #include <io.h>
  31 #include "sun_nio_ch_DatagramChannelImpl.h"
  32 #include "nio.h"
  33 #include "nio_util.h"
  34 #include "net_util.h"
  35 #include <winsock2.h>
  36 
  37 static jfieldID isa_addrID;     /* address in java.net.InetSocketAddress */
  38 static jfieldID isa_portID;     /* port in java.net.InetSocketAddress */
  39 static jfieldID dci_senderID;   /* sender in sun.nio.ch.DatagramChannelImpl */
  40 static jfieldID dci_senderAddrID; /* sender InetAddress in sun.nio.ch.DatagramChannelImpl */
  41 static jfieldID dci_senderPortID; /* sender port in sun.nio.ch.DatagramChannelImpl */
  42 static jclass isa_class;        /* java.net.InetSocketAddress */
  43 static jmethodID isa_ctorID;    /* java.net.InetSocketAddress(InetAddress, int) */
  44 
  45 
  46 JNIEXPORT void JNICALL
  47 Java_sun_nio_ch_DatagramChannelImpl_initIDs(JNIEnv *env, jclass clazz)
  48 {
  49     clazz = (*env)->FindClass(env, "java/net/InetSocketAddress");
  50     isa_class = (*env)->NewGlobalRef(env, clazz);
  51     isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>",
  52                                      "(Ljava/net/InetAddress;I)V");
  53     isa_addrID = (*env)->GetFieldID(env, clazz, "addr",
  54                                     "Ljava/net/InetAddress;");
  55     isa_portID = (*env)->GetFieldID(env, clazz, "port", "I");
  56 
  57     clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl");
  58     dci_senderID = (*env)->GetFieldID(env, clazz, "sender",
  59                                       "Ljava/net/SocketAddress;");
  60     dci_senderAddrID = (*env)->GetFieldID(env, clazz,
  61                                           "cachedSenderInetAddress",
  62                                           "Ljava/net/InetAddress;");
  63     dci_senderPortID = (*env)->GetFieldID(env, clazz,
  64                                           "cachedSenderPort", "I");
  65 }
  66 
  67 /*
  68  * This function "purges" all outstanding ICMP port unreachable packets
  69  * outstanding on a socket and returns JNI_TRUE if any ICMP messages
  70  * have been purged. The rational for purging is to emulate normal BSD
  71  * behaviour whereby receiving a "connection reset" status resets the
  72  * socket.
  73  */
  74 jboolean purgeOutstandingICMP(JNIEnv *env, jclass clazz, jint fd)
  75 {


 197             isa = (*env)->NewObject(env, isa_class, isa_ctorID, ia, port);
 198         }
 199 
 200         if (isa == NULL) {
 201             JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
 202             return IOS_THROWN;
 203         }
 204 
 205         // update cachedSenderInetAddress/cachedSenderPort
 206         (*env)->SetObjectField(env, this, dci_senderAddrID, ia);
 207         (*env)->SetIntField(env, this, dci_senderPortID,
 208                             NET_GetPortFromSockaddr((struct sockaddr *)&sa));
 209         (*env)->SetObjectField(env, this, dci_senderID, isa);
 210     }
 211     return n;
 212 }
 213 
 214 JNIEXPORT jint JNICALL
 215 Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this,
 216                                           jboolean preferIPv6, jobject fdo,
 217                                           jlong address, jint len, jobject dest)

 218 {
 219     jint fd = fdval(env, fdo);
 220     void *buf = (void *)jlong_to_ptr(address);
 221     SOCKETADDRESS sa;
 222     int sa_len;
 223     jint rv = 0;
 224     jobject destAddress = (*env)->GetObjectField(env, dest, isa_addrID);
 225     jint destPort = (*env)->GetIntField(env, dest, isa_portID);
 226 
 227     if (NET_InetAddressToSockaddr(env, destAddress, destPort,
 228                                   (struct sockaddr *)&sa,
 229                                    &sa_len, preferIPv6) != 0) {
 230       return IOS_THROWN;
 231     }
 232 
 233     rv = sendto((SOCKET)fd,
 234                buf,
 235                len,
 236                0,
 237                (struct sockaddr *)&sa,
 238                sa_len);
 239     if (rv == SOCKET_ERROR) {
 240         int theErr = (jint)WSAGetLastError();
 241         if (theErr == WSAEWOULDBLOCK) {
 242             return IOS_UNAVAILABLE;
 243         }
 244         return handleSocketError(env, (jint)WSAGetLastError());
 245     }


  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include "jni.h"
  27 #include "jni_util.h"
  28 #include "jvm.h"
  29 #include "jlong.h"
  30 #include <io.h>
  31 #include "sun_nio_ch_DatagramChannelImpl.h"
  32 #include "nio.h"
  33 #include "nio_util.h"
  34 #include "net_util.h"
  35 #include <winsock2.h>
  36 


  37 static jfieldID dci_senderID;   /* sender in sun.nio.ch.DatagramChannelImpl */
  38 static jfieldID dci_senderAddrID; /* sender InetAddress in sun.nio.ch.DatagramChannelImpl */
  39 static jfieldID dci_senderPortID; /* sender port in sun.nio.ch.DatagramChannelImpl */
  40 static jclass isa_class;        /* java.net.InetSocketAddress */
  41 static jmethodID isa_ctorID;    /* java.net.InetSocketAddress(InetAddress, int) */
  42 
  43 
  44 JNIEXPORT void JNICALL
  45 Java_sun_nio_ch_DatagramChannelImpl_initIDs(JNIEnv *env, jclass clazz)
  46 {
  47     clazz = (*env)->FindClass(env, "java/net/InetSocketAddress");
  48     isa_class = (*env)->NewGlobalRef(env, clazz);
  49     isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>",
  50                                      "(Ljava/net/InetAddress;I)V");



  51 
  52     clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl");
  53     dci_senderID = (*env)->GetFieldID(env, clazz, "sender",
  54                                       "Ljava/net/SocketAddress;");
  55     dci_senderAddrID = (*env)->GetFieldID(env, clazz,
  56                                           "cachedSenderInetAddress",
  57                                           "Ljava/net/InetAddress;");
  58     dci_senderPortID = (*env)->GetFieldID(env, clazz,
  59                                           "cachedSenderPort", "I");
  60 }
  61 
  62 /*
  63  * This function "purges" all outstanding ICMP port unreachable packets
  64  * outstanding on a socket and returns JNI_TRUE if any ICMP messages
  65  * have been purged. The rational for purging is to emulate normal BSD
  66  * behaviour whereby receiving a "connection reset" status resets the
  67  * socket.
  68  */
  69 jboolean purgeOutstandingICMP(JNIEnv *env, jclass clazz, jint fd)
  70 {


 192             isa = (*env)->NewObject(env, isa_class, isa_ctorID, ia, port);
 193         }
 194 
 195         if (isa == NULL) {
 196             JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
 197             return IOS_THROWN;
 198         }
 199 
 200         // update cachedSenderInetAddress/cachedSenderPort
 201         (*env)->SetObjectField(env, this, dci_senderAddrID, ia);
 202         (*env)->SetIntField(env, this, dci_senderPortID,
 203                             NET_GetPortFromSockaddr((struct sockaddr *)&sa));
 204         (*env)->SetObjectField(env, this, dci_senderID, isa);
 205     }
 206     return n;
 207 }
 208 
 209 JNIEXPORT jint JNICALL
 210 Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this,
 211                                           jboolean preferIPv6, jobject fdo,
 212                                           jlong address, jint len,
 213                                           jobject destAddress, jint destPort)
 214 {
 215     jint fd = fdval(env, fdo);
 216     void *buf = (void *)jlong_to_ptr(address);
 217     SOCKETADDRESS sa;
 218     int sa_len;
 219     jint rv = 0;


 220 
 221     if (NET_InetAddressToSockaddr(env, destAddress, destPort,
 222                                   (struct sockaddr *)&sa,
 223                                    &sa_len, preferIPv6) != 0) {
 224       return IOS_THROWN;
 225     }
 226 
 227     rv = sendto((SOCKET)fd,
 228                buf,
 229                len,
 230                0,
 231                (struct sockaddr *)&sa,
 232                sa_len);
 233     if (rv == SOCKET_ERROR) {
 234         int theErr = (jint)WSAGetLastError();
 235         if (theErr == WSAEWOULDBLOCK) {
 236             return IOS_UNAVAILABLE;
 237         }
 238         return handleSocketError(env, (jint)WSAGetLastError());
 239     }