8053479: (dc) DatagramChannel.read() throws exception instead of discarding data when buffer too small

Reviewed-by: redestad, dfuchs
This commit is contained in:
Alan Bateman 2020-01-18 19:11:28 +00:00
parent c6da6681d4
commit 6ef474a4f4
3 changed files with 185 additions and 45 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,32 +23,30 @@
* questions.
*/
/*
*/
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <string.h>
#include <limits.h>
#include "jni.h"
#include "jni_util.h"
#include "jvm.h"
#include "jlong.h"
#include "sun_nio_ch_DatagramDispatcher.h"
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <string.h>
#include "nio.h"
#include "nio_util.h"
#include <limits.h>
#include "sun_nio_ch_DatagramDispatcher.h"
JNIEXPORT jint JNICALL
Java_sun_nio_ch_DatagramDispatcher_read0(JNIEnv *env, jclass clazz,
jobject fdo, jlong address, jint len)
jobject fdo, jlong address, jint len)
{
jint fd = fdval(env, fdo);
void *buf = (void *)jlong_to_ptr(address);
int result = recv(fd, buf, len, 0);
if (result < 0 && errno == ECONNREFUSED) {
JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
return -2;
return IOS_THROWN;
}
return convertReturnVal(env, result, JNI_TRUE);
}
@ -56,7 +54,7 @@ Java_sun_nio_ch_DatagramDispatcher_read0(JNIEnv *env, jclass clazz,
JNIEXPORT jlong JNICALL
Java_sun_nio_ch_DatagramDispatcher_readv0(JNIEnv *env, jclass clazz,
jobject fdo, jlong address, jint len)
jobject fdo, jlong address, jint len)
{
jint fd = fdval(env, fdo);
ssize_t result = 0;
@ -74,28 +72,28 @@ Java_sun_nio_ch_DatagramDispatcher_readv0(JNIEnv *env, jclass clazz,
result = recvmsg(fd, &m, 0);
if (result < 0 && errno == ECONNREFUSED) {
JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
return -2;
return IOS_THROWN;
}
return convertLongReturnVal(env, (jlong)result, JNI_TRUE);
}
JNIEXPORT jint JNICALL
Java_sun_nio_ch_DatagramDispatcher_write0(JNIEnv *env, jclass clazz,
jobject fdo, jlong address, jint len)
jobject fdo, jlong address, jint len)
{
jint fd = fdval(env, fdo);
void *buf = (void *)jlong_to_ptr(address);
int result = send(fd, buf, len, 0);
if (result < 0 && errno == ECONNREFUSED) {
JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
return -2;
return IOS_THROWN;
}
return convertReturnVal(env, result, JNI_FALSE);
}
JNIEXPORT jlong JNICALL
Java_sun_nio_ch_DatagramDispatcher_writev0(JNIEnv *env, jclass clazz,
jobject fdo, jlong address, jint len)
jobject fdo, jlong address, jint len)
{
jint fd = fdval(env, fdo);
struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
@ -113,7 +111,7 @@ Java_sun_nio_ch_DatagramDispatcher_writev0(JNIEnv *env, jclass clazz,
result = sendmsg(fd, &m, 0);
if (result < 0 && errno == ECONNREFUSED) {
JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
return -2;
return IOS_THROWN;
}
return convertLongReturnVal(env, (jlong)result, JNI_FALSE);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,21 +23,19 @@
* questions.
*/
/*
*/
#include <windows.h>
#include <winsock2.h>
#include <ctype.h>
#include "jni.h"
#include "jni_util.h"
#include "jvm.h"
#include "jlong.h"
#include "sun_nio_ch_DatagramDispatcher.h"
#include "nio.h"
#include "nio_util.h"
#include "sun_nio_ch_DatagramDispatcher.h"
/**************************************************************
* DatagramDispatcher.c
@ -45,7 +43,7 @@
JNIEXPORT jint JNICALL
Java_sun_nio_ch_DatagramDispatcher_read0(JNIEnv *env, jclass clazz, jobject fdo,
jlong address, jint len)
jlong address, jint len)
{
/* set up */
int i = 0;
@ -69,16 +67,18 @@ Java_sun_nio_ch_DatagramDispatcher_read0(JNIEnv *env, jclass clazz, jobject fdo,
if (i == SOCKET_ERROR) {
int theErr = (jint)WSAGetLastError();
if (theErr == WSAEWOULDBLOCK) {
return IOS_UNAVAILABLE;
}
if (theErr == WSAECONNRESET) {
purgeOutstandingICMP(env, clazz, fd);
JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
if (theErr != WSAEMSGSIZE) {
if (theErr == WSAEWOULDBLOCK) {
return IOS_UNAVAILABLE;
}
if (theErr == WSAECONNRESET) {
purgeOutstandingICMP(env, clazz, fd);
JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
return IOS_THROWN;
}
JNU_ThrowIOExceptionWithLastError(env, "WSARecv failed");
return IOS_THROWN;
}
JNU_ThrowIOExceptionWithLastError(env, "Write failed");
return IOS_THROWN;
}
return convertReturnVal(env, (jint)read, JNI_TRUE);
@ -104,7 +104,7 @@ Java_sun_nio_ch_DatagramDispatcher_readv0(JNIEnv *env, jclass clazz,
for(i=0; i<len; i++) {
bufs[i].buf = (char *)iovp[i].iov_base;
bufs[i].len = (u_long)iovp[i].iov_len;
}
}
/* read into the buffers */
i = WSARecv((SOCKET)fd, /* Socket */
@ -120,16 +120,18 @@ Java_sun_nio_ch_DatagramDispatcher_readv0(JNIEnv *env, jclass clazz,
if (i != 0) {
int theErr = (jint)WSAGetLastError();
if (theErr == WSAEWOULDBLOCK) {
return IOS_UNAVAILABLE;
}
if (theErr == WSAECONNRESET) {
purgeOutstandingICMP(env, clazz, fd);
JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
if (theErr != WSAEMSGSIZE) {
if (theErr == WSAEWOULDBLOCK) {
return IOS_UNAVAILABLE;
}
if (theErr == WSAECONNRESET) {
purgeOutstandingICMP(env, clazz, fd);
JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
return IOS_THROWN;
}
JNU_ThrowIOExceptionWithLastError(env, "WSARecv failed");
return IOS_THROWN;
}
JNU_ThrowIOExceptionWithLastError(env, "Write failed");
return IOS_THROWN;
}
return convertLongReturnVal(env, (jlong)read, JNI_TRUE);
@ -169,7 +171,7 @@ Java_sun_nio_ch_DatagramDispatcher_write0(JNIEnv *env, jclass clazz,
JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
return IOS_THROWN;
}
JNU_ThrowIOExceptionWithLastError(env, "Write failed");
JNU_ThrowIOExceptionWithLastError(env, "WSASend failed");
return IOS_THROWN;
}
@ -178,7 +180,7 @@ Java_sun_nio_ch_DatagramDispatcher_write0(JNIEnv *env, jclass clazz,
JNIEXPORT jlong JNICALL
Java_sun_nio_ch_DatagramDispatcher_writev0(JNIEnv *env, jclass clazz,
jobject fdo, jlong address, jint len)
jobject fdo, jlong address, jint len)
{
/* set up */
int i = 0;
@ -219,7 +221,7 @@ Java_sun_nio_ch_DatagramDispatcher_writev0(JNIEnv *env, jclass clazz,
JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
return IOS_THROWN;
}
JNU_ThrowIOExceptionWithLastError(env, "Write failed");
JNU_ThrowIOExceptionWithLastError(env, "WSASend failed");
return IOS_THROWN;
}