EpollSocketChannelConfig.getOptions() must not throw if TCP_FASTOPEN_CONNECT is not supported

Motivation:

If a user calls EpollSocketChannelConfig.getOptions() and TCP_FASTOPEN_CONNECT is not supported we throw an exception.

Modifications:

- Just return 0 if ENOPROTOOPT is set.
- Add testcase

Result:

getOptions() works as epxected.
This commit is contained in:
Norman Maurer 2017-11-14 11:16:21 +01:00
parent 3648ab0355
commit f115bf50cb
5 changed files with 29 additions and 2 deletions

View File

@ -256,7 +256,14 @@ static jint netty_epoll_linuxsocket_isTcpQuickAck(JNIEnv* env, jclass clazz, jin
static jint netty_epoll_linuxsocket_isTcpFastOpenConnect(JNIEnv* env, jclass clazz, jint fd) {
int optval;
if (netty_unix_socket_getOption(env, fd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT, &optval, sizeof(optval)) == -1) {
int optlen = sizeof(optval);
// We call getsockopt directly so we can handle ENOPROTOOPT by ourself.
if (getsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT, &optval, &optlen) == -1) {
if (errno == ENOPROTOOPT) {
// Not supported by the system, so just return 0.
return 0;
}
netty_unix_socket_getOptionHandleError(env, errno);
return -1;
}
return optval;

View File

@ -17,12 +17,14 @@ package io.netty.channel.epoll;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.net.InetSocketAddress;
import java.util.Map;
import static org.junit.Assert.*;
@ -75,4 +77,10 @@ public class EpollServerSocketChannelConfigTest {
ch.config().setFreeBind(true);
assertTrue(ch.config().isFreeBind());
}
@Test
public void getGetOptions() {
Map<ChannelOption<?>, Object> map = ch.config().getOptions();
assertFalse(map.isEmpty());
}
}

View File

@ -20,10 +20,12 @@ import static org.junit.Assume.*;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import java.net.InetSocketAddress;
import java.nio.channels.ClosedChannelException;
import java.util.Map;
import java.util.Random;
import org.junit.After;
@ -153,4 +155,10 @@ public class EpollSocketChannelConfigTest {
assertTrue(e.getCause() instanceof ClosedChannelException);
}
}
@Test
public void getGetOptions() {
Map<ChannelOption<?>, Object> map = ch.config().getOptions();
assertFalse(map.isEmpty());
}
}

View File

@ -324,7 +324,7 @@ static jobject _recvFrom(JNIEnv* env, jint fd, void* buffer, jint pos, jint limi
return createDatagramSocketAddress(env, &addr, res);
}
static void netty_unix_socket_getOptionHandleError(JNIEnv* env, int err) {
void netty_unix_socket_getOptionHandleError(JNIEnv* env, int err) {
netty_unix_socket_optionHandleError(env, err, "getsockopt() failed: ");
}

View File

@ -24,6 +24,10 @@ int netty_unix_socket_initSockaddr(JNIEnv* env, jbyteArray address, jint scopeId
int netty_unix_socket_getOption(JNIEnv* env, jint fd, int level, int optname, void* optval, socklen_t optlen);
int netty_unix_socket_setOption(JNIEnv* env, jint fd, int level, int optname, const void* optval, socklen_t len);
// These method is sometimes needed if you want to special handle some errno value before throwing an exception.
void netty_unix_socket_getOptionHandleError(JNIEnv* env, int err);
// JNI initialization hooks. Users of this file are responsible for calling these in the JNI_OnLoad and JNI_OnUnload methods.
jint netty_unix_socket_JNI_OnLoad(JNIEnv* env, const char* packagePrefix);
void netty_unix_socket_JNI_OnUnLoad(JNIEnv* env);