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 }
|