Skip to content

Commit

Permalink
Add TCP_USER_TIMEOUT
Browse files Browse the repository at this point in the history
Motivation:

See netty#4174.

Modifications:

Modify transport-native-epoll to allow setting TCP_USER_TIMEOUT.

Result:

Hanging connections that are written into will get timeouted.
  • Loading branch information
tomasol committed Aug 31, 2015
1 parent 2d4a8a7 commit 3010366
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 0 deletions.
12 changes: 12 additions & 0 deletions transport-native-epoll/src/main/c/io_netty_channel_epoll_Native.c
Original file line number Diff line number Diff line change
Expand Up @@ -1271,6 +1271,10 @@ JNIEXPORT void Java_io_netty_channel_epoll_Native_setTcpKeepCnt(JNIEnv* env, jcl
setOption(env, fd, IPPROTO_TCP, TCP_KEEPCNT, &optval, sizeof(optval));
}

JNIEXPORT void Java_io_netty_channel_epoll_Native_setTcpUserTimeout(JNIEnv* env, jclass clazz, jint fd, jint optval) {
setOption(env, fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &optval, sizeof(optval));
}

JNIEXPORT void JNICALL Java_io_netty_channel_epoll_Native_setIpFreeBind(JNIEnv* env, jclass clazz, jint fd, jint optval) {
setOption(env, fd, IPPROTO_IP, IP_FREEBIND, &optval, sizeof(optval));
}
Expand Down Expand Up @@ -1391,6 +1395,14 @@ JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_getTcpKeepCnt(JNIEnv*
return optval;
}

JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_getTcpUserTimeout(JNIEnv* env, jclass clazz, jint fd) {
int optval;
if (getOption(env, fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &optval, sizeof(optval)) == -1) {
return -1;
}
return optval;
}

JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_isIpFreeBind(JNIEnv* env, jclass clazz, jint fd) {
int optval;
if (getOption(env, fd, IPPROTO_TCP, IP_FREEBIND, &optval, sizeof(optval)) == -1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public final class EpollChannelOption<T> extends ChannelOption<T> {
public static final ChannelOption<Integer> TCP_KEEPIDLE = valueOf("TCP_KEEPIDLE");
public static final ChannelOption<Integer> TCP_KEEPINTVL = valueOf("TCP_KEEPINTVL");
public static final ChannelOption<Integer> TCP_KEEPCNT = valueOf("TCP_KEEPCNT");
public static final ChannelOption<Integer> TCP_USER_TIMEOUT = valueOf("TCP_USER_TIMEOUT");
public static final ChannelOption<Boolean> IP_FREEBIND = valueOf("IP_FREEBIND");

public static final ChannelOption<DomainSocketReadMode> DOMAIN_SOCKET_READ_MODE =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ public <T> T getOption(ChannelOption<T> option) {
if (option == EpollChannelOption.TCP_KEEPCNT) {
return (T) Integer.valueOf(getTcpKeepCnt());
}
if (option == EpollChannelOption.TCP_USER_TIMEOUT) {
return (T) Integer.valueOf(getTcpUserTimeout());
}
return super.getOption(option);
}

Expand Down Expand Up @@ -127,6 +130,8 @@ public <T> boolean setOption(ChannelOption<T> option, T value) {
setTcpKeepCntl((Integer) value);
} else if (option == EpollChannelOption.TCP_KEEPINTVL) {
setTcpKeepIntvl((Integer) value);
} else if (option == EpollChannelOption.TCP_USER_TIMEOUT) {
setTcpUserTimeout((Integer) value);
} else {
return super.setOption(option, value);
}
Expand Down Expand Up @@ -205,6 +210,13 @@ public int getTcpKeepCnt() {
return Native.getTcpKeepCnt(channel.fd().intValue());
}

/**
* Get the {@code TCP_USER_TIMEOUT} option on the socket. See {@code man 7 tcp} for more details.
*/
public int getTcpUserTimeout() {
return Native.getTcpUserTimeout(channel.fd().intValue());
}

@Override
public EpollSocketChannelConfig setKeepAlive(boolean keepAlive) {
Native.setKeepAlive(channel.fd().intValue(), keepAlive ? 1 : 0);
Expand Down Expand Up @@ -297,6 +309,14 @@ public EpollSocketChannelConfig setTcpKeepCntl(int probes) {
return this;
}

/**
* Set the {@code TCP_USER_TIMEOUT} option on the socket. See {@code man 7 tcp} for more details.
*/
public EpollSocketChannelConfig setTcpUserTimeout(int milliseconds) {
Native.setTcpUserTimeout(channel.fd().intValue(), milliseconds);
return this;
}

@Override
public boolean isAllowHalfClosure() {
return allowHalfClosure;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,7 @@ public static void shutdown(int fd, boolean read, boolean write) throws IOExcept
public static native int getTcpKeepIdle(int fd);
public static native int getTcpKeepIntvl(int fd);
public static native int getTcpKeepCnt(int fd);
public static native int getTcpUserTimeout(int milliseconds);
public static native int getSoError(int fd);
public static native int isIpFreeBind(int fd);

Expand All @@ -652,6 +653,7 @@ public static void shutdown(int fd, boolean read, boolean write) throws IOExcept
public static native void setTcpKeepIdle(int fd, int seconds);
public static native void setTcpKeepIntvl(int fd, int seconds);
public static native void setTcpKeepCnt(int fd, int probes);
public static native void setTcpUserTimeout(int fd, int milliseconds);
public static native void setIpFreeBind(int fd, int freeBind);
public static void tcpInfo(int fd, EpollTcpInfo info) {
tcpInfo0(fd, info.info);
Expand Down

0 comments on commit 3010366

Please sign in to comment.