diff --git a/transport-native-epoll/src/main/c/netty_epoll_linuxsocket.c b/transport-native-epoll/src/main/c/netty_epoll_linuxsocket.c index 28d81faebc..0bede92819 100644 --- a/transport-native-epoll/src/main/c/netty_epoll_linuxsocket.c +++ b/transport-native-epoll/src/main/c/netty_epoll_linuxsocket.c @@ -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; diff --git a/transport-native-epoll/src/test/java/io/netty/channel/epoll/EpollServerSocketChannelConfigTest.java b/transport-native-epoll/src/test/java/io/netty/channel/epoll/EpollServerSocketChannelConfigTest.java index 83a441fe3c..6ed052ccfe 100644 --- a/transport-native-epoll/src/test/java/io/netty/channel/epoll/EpollServerSocketChannelConfigTest.java +++ b/transport-native-epoll/src/test/java/io/netty/channel/epoll/EpollServerSocketChannelConfigTest.java @@ -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, Object> map = ch.config().getOptions(); + assertFalse(map.isEmpty()); + } } diff --git a/transport-native-epoll/src/test/java/io/netty/channel/epoll/EpollSocketChannelConfigTest.java b/transport-native-epoll/src/test/java/io/netty/channel/epoll/EpollSocketChannelConfigTest.java index e5d4ad9b2f..58cf5af646 100644 --- a/transport-native-epoll/src/test/java/io/netty/channel/epoll/EpollSocketChannelConfigTest.java +++ b/transport-native-epoll/src/test/java/io/netty/channel/epoll/EpollSocketChannelConfigTest.java @@ -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, Object> map = ch.config().getOptions(); + assertFalse(map.isEmpty()); + } } diff --git a/transport-native-unix-common/src/main/c/netty_unix_socket.c b/transport-native-unix-common/src/main/c/netty_unix_socket.c index dee418d7ef..83d74dbe95 100644 --- a/transport-native-unix-common/src/main/c/netty_unix_socket.c +++ b/transport-native-unix-common/src/main/c/netty_unix_socket.c @@ -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: "); } diff --git a/transport-native-unix-common/src/main/c/netty_unix_socket.h b/transport-native-unix-common/src/main/c/netty_unix_socket.h index 99d27c0983..c9eecd6d6e 100644 --- a/transport-native-unix-common/src/main/c/netty_unix_socket.h +++ b/transport-native-unix-common/src/main/c/netty_unix_socket.h @@ -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);