mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-18 06:59:29 +00:00
6989190: SO_SNDBUF/SO_RCVBUF limits should only be checked when setsockopt fails (sol)
Reviewed-by: chegar, michaelm
This commit is contained in:
parent
b44a1bd105
commit
41cc1e2f4a
@ -363,17 +363,20 @@ void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
|
||||
const char* hostname,
|
||||
int gai_error)
|
||||
{
|
||||
int size;
|
||||
char *buf;
|
||||
const char *format = "%s: %s";
|
||||
const char *error_string =
|
||||
(gai_strerror_ptr == NULL) ? NULL : (*gai_strerror_ptr)(gai_error);
|
||||
if (error_string == NULL)
|
||||
error_string = "unknown error";
|
||||
|
||||
int size = strlen(format) + strlen(hostname) + strlen(error_string) + 2;
|
||||
char *buf = (char *) malloc(size);
|
||||
size = strlen(format) + strlen(hostname) + strlen(error_string) + 2;
|
||||
buf = (char *) malloc(size);
|
||||
if (buf) {
|
||||
jstring s;
|
||||
sprintf(buf, format, hostname, error_string);
|
||||
jstring s = JNU_NewStringPlatform(env, buf);
|
||||
s = JNU_NewStringPlatform(env, buf);
|
||||
if (s != NULL) {
|
||||
jobject x = JNU_NewObjectByName(env,
|
||||
"java/net/UnknownHostException",
|
||||
@ -1203,19 +1206,26 @@ NET_SetSockOpt(int fd, int level, int opt, const void *arg,
|
||||
}
|
||||
|
||||
/*
|
||||
* SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris need to
|
||||
* ensure that value is <= max_buf as otherwise we get
|
||||
* an invalid argument.
|
||||
* SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris we may need to clamp
|
||||
* the value when it exceeds the system limit.
|
||||
*/
|
||||
#ifdef __solaris__
|
||||
if (level == SOL_SOCKET) {
|
||||
if (opt == SO_SNDBUF || opt == SO_RCVBUF) {
|
||||
int sotype, arglen;
|
||||
int *bufsize, maxbuf;
|
||||
int ret;
|
||||
|
||||
/* Attempt with the original size */
|
||||
ret = setsockopt(fd, level, opt, arg, len);
|
||||
if ((ret == 0) || (ret == -1 && errno != ENOBUFS))
|
||||
return ret;
|
||||
|
||||
/* Exceeded system limit so clamp and retry */
|
||||
|
||||
if (!init_max_buf) {
|
||||
tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf", 64*1024);
|
||||
udp_max_buf = getParam("/dev/udp", "udp_max_buf", 64*1024);
|
||||
tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf", 1024*1024);
|
||||
udp_max_buf = getParam("/dev/udp", "udp_max_buf", 2048*1024);
|
||||
init_max_buf = 1;
|
||||
}
|
||||
|
||||
|
||||
@ -29,7 +29,9 @@
|
||||
|
||||
import java.nio.channels.*;
|
||||
import java.net.*;
|
||||
import static java.net.StandardSocketOption.*;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@ -39,6 +41,7 @@ public class Basic {
|
||||
public static void main(String[] args) throws Exception {
|
||||
testBind();
|
||||
testAccept();
|
||||
testSocketOptions();
|
||||
}
|
||||
|
||||
static void testBind() throws Exception {
|
||||
@ -131,4 +134,39 @@ public class Basic {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void testSocketOptions() throws Exception {
|
||||
System.out.println("-- socket options --");
|
||||
AsynchronousServerSocketChannel ch = AsynchronousServerSocketChannel.open();
|
||||
try {
|
||||
// check supported options
|
||||
Set<SocketOption<?>> options = ch.supportedOptions();
|
||||
if (!options.contains(SO_REUSEADDR))
|
||||
throw new RuntimeException("SO_REUSEADDR should be supported");
|
||||
if (!options.contains(SO_RCVBUF))
|
||||
throw new RuntimeException("SO_RCVBUF should be supported");
|
||||
|
||||
// allowed to change when not bound
|
||||
ch.setOption(SO_RCVBUF, 256*1024); // can't check
|
||||
int before = ch.getOption(SO_RCVBUF);
|
||||
int after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
|
||||
if (after < before)
|
||||
throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
|
||||
ch.setOption(SO_REUSEADDR, true);
|
||||
checkOption(ch, SO_REUSEADDR, true);
|
||||
ch.setOption(SO_REUSEADDR, false);
|
||||
checkOption(ch, SO_REUSEADDR, false);
|
||||
} finally {
|
||||
ch.close();
|
||||
}
|
||||
}
|
||||
|
||||
static void checkOption(AsynchronousServerSocketChannel ch,
|
||||
SocketOption name, Object expectedValue)
|
||||
throws IOException
|
||||
{
|
||||
Object value = ch.getOption(name);
|
||||
if (!value.equals(expectedValue))
|
||||
throw new RuntimeException("value not as expected");
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,8 +121,20 @@ public class Basic {
|
||||
AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()
|
||||
.setOption(SO_RCVBUF, 128*1024)
|
||||
.setOption(SO_SNDBUF, 128*1024)
|
||||
.setOption(SO_REUSEADDR, true)
|
||||
.bind(new InetSocketAddress(0));
|
||||
.setOption(SO_REUSEADDR, true);
|
||||
|
||||
// check SO_SNDBUF/SO_RCVBUF limits
|
||||
int before, after;
|
||||
before = ch.getOption(SO_SNDBUF);
|
||||
after = ch.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
|
||||
if (after < before)
|
||||
throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
|
||||
before = ch.getOption(SO_RCVBUF);
|
||||
after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
|
||||
if (after < before)
|
||||
throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
|
||||
|
||||
ch.bind(new InetSocketAddress(0));
|
||||
|
||||
// default values
|
||||
if ((Boolean)ch.getOption(SO_KEEPALIVE))
|
||||
|
||||
@ -68,8 +68,17 @@ public class SocketOptionTests {
|
||||
checkOption(dc, SO_BROADCAST, true);
|
||||
dc.setOption(SO_BROADCAST, false);
|
||||
checkOption(dc, SO_BROADCAST, false);
|
||||
dc.setOption(SO_SNDBUF, 16*1024); // can't check
|
||||
dc.setOption(SO_RCVBUF, 16*1024); // can't check
|
||||
dc.setOption(SO_SNDBUF, 128*1024); // can't check
|
||||
dc.setOption(SO_RCVBUF, 128*1024); // can't check
|
||||
int before, after;
|
||||
before = dc.getOption(SO_SNDBUF);
|
||||
after = dc.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
|
||||
if (after < before)
|
||||
throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
|
||||
before = dc.getOption(SO_RCVBUF);
|
||||
after = dc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
|
||||
if (after < before)
|
||||
throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
|
||||
dc.setOption(SO_REUSEADDR, true);
|
||||
checkOption(dc, SO_REUSEADDR, true);
|
||||
dc.setOption(SO_REUSEADDR, false);
|
||||
|
||||
@ -56,6 +56,10 @@ public class SocketOptionTests {
|
||||
|
||||
// allowed to change when not bound
|
||||
ssc.setOption(SO_RCVBUF, 256*1024); // can't check
|
||||
int before = ssc.getOption(SO_RCVBUF);
|
||||
int after = ssc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
|
||||
if (after < before)
|
||||
throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
|
||||
ssc.setOption(SO_REUSEADDR, true);
|
||||
checkOption(ssc, SO_REUSEADDR, true);
|
||||
ssc.setOption(SO_REUSEADDR, false);
|
||||
|
||||
@ -70,6 +70,15 @@ public class SocketOptionTests {
|
||||
checkOption(sc, SO_KEEPALIVE, false);
|
||||
sc.setOption(SO_SNDBUF, 128*1024); // can't check
|
||||
sc.setOption(SO_RCVBUF, 256*1024); // can't check
|
||||
int before, after;
|
||||
before = sc.getOption(SO_SNDBUF);
|
||||
after = sc.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
|
||||
if (after < before)
|
||||
throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
|
||||
before = sc.getOption(SO_RCVBUF);
|
||||
after = sc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
|
||||
if (after < before)
|
||||
throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
|
||||
sc.setOption(SO_REUSEADDR, true);
|
||||
checkOption(sc, SO_REUSEADDR, true);
|
||||
sc.setOption(SO_REUSEADDR, false);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user