ChannelConfig operations should wrap ClosedChannelException if Channel was closed before.

Motivation:

To be consistent with the JDK we should ensure our native methods throw a ClosedChannelException if the Channel was previously closed. This will then be wrapped in a ChannelException as usual. For all other errors we continue to just throw a ChannelException directly.

Modifications:

Ensure getsockopt and setsockopt will throw a ClosedChannelException if the channel was closed before, on other errors we throw a ChannelException as before diretly.

Result:

Consistent with the NIO Channel implementations.
This commit is contained in:
Norman Maurer 2016-03-15 10:38:25 +01:00
parent dcf553f1aa
commit 1090d7200d
11 changed files with 385 additions and 126 deletions

View File

@ -296,7 +296,12 @@ static jobject _recvFrom(JNIEnv* env, jint fd, void* buffer, jint pos, jint limi
int netty_unix_socket_getOption(JNIEnv* env, jint fd, int level, int optname, void* optval, socklen_t optlen) {
int rc = getsockopt(fd, level, optname, optval, &optlen);
if (rc < 0) {
netty_unix_errors_throwChannelExceptionErrorNo(env, "getsockopt() failed: ", errno);
int err = errno;
if (err == EBADF) {
netty_unix_errors_throwClosedChannelException(env);
} else {
netty_unix_errors_throwChannelExceptionErrorNo(env, "setsockopt() failed: ", err);
}
}
return rc;
}
@ -304,7 +309,12 @@ int netty_unix_socket_getOption(JNIEnv* env, jint fd, int level, int optname, vo
int netty_unix_socket_setOption(JNIEnv* env, jint fd, int level, int optname, const void* optval, socklen_t len) {
int rc = setsockopt(fd, level, optname, optval, len);
if (rc < 0) {
netty_unix_errors_throwChannelExceptionErrorNo(env, "setsockopt() failed: ", errno);
int err = errno;
if (err == EBADF) {
netty_unix_errors_throwClosedChannelException(env);
} else {
netty_unix_errors_throwChannelExceptionErrorNo(env, "setsockopt() failed: ", err);
}
}
return rc;
}

View File

@ -16,12 +16,14 @@
package io.netty.channel.epoll;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelOption;
import io.netty.channel.FixedRecvByteBufAllocator;
import io.netty.channel.MessageSizeEstimator;
import io.netty.channel.RecvByteBufAllocator;
import io.netty.channel.socket.DatagramChannelConfig;
import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Map;
@ -191,57 +193,97 @@ public final class EpollDatagramChannelConfig extends EpollChannelConfig impleme
@Override
public int getSendBufferSize() {
return datagramChannel.fd().getSendBufferSize();
try {
return datagramChannel.fd().getSendBufferSize();
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public EpollDatagramChannelConfig setSendBufferSize(int sendBufferSize) {
datagramChannel.fd().setSendBufferSize(sendBufferSize);
return this;
try {
datagramChannel.fd().setSendBufferSize(sendBufferSize);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public int getReceiveBufferSize() {
return datagramChannel.fd().getReceiveBufferSize();
try {
return datagramChannel.fd().getReceiveBufferSize();
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public EpollDatagramChannelConfig setReceiveBufferSize(int receiveBufferSize) {
datagramChannel.fd().setReceiveBufferSize(receiveBufferSize);
return this;
try {
datagramChannel.fd().setReceiveBufferSize(receiveBufferSize);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public int getTrafficClass() {
return Native.getTrafficClass(datagramChannel.fd().intValue());
try {
return Native.getTrafficClass(datagramChannel.fd().intValue());
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public EpollDatagramChannelConfig setTrafficClass(int trafficClass) {
Native.setTrafficClass(datagramChannel.fd().intValue(), trafficClass);
return this;
try {
Native.setTrafficClass(datagramChannel.fd().intValue(), trafficClass);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public boolean isReuseAddress() {
return Native.isReuseAddress(datagramChannel.fd().intValue()) == 1;
try {
return Native.isReuseAddress(datagramChannel.fd().intValue()) == 1;
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public EpollDatagramChannelConfig setReuseAddress(boolean reuseAddress) {
Native.setReuseAddress(datagramChannel.fd().intValue(), reuseAddress ? 1 : 0);
return this;
try {
Native.setReuseAddress(datagramChannel.fd().intValue(), reuseAddress ? 1 : 0);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public boolean isBroadcast() {
return Native.isBroadcast(datagramChannel.fd().intValue()) == 1;
try {
return Native.isBroadcast(datagramChannel.fd().intValue()) == 1;
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public EpollDatagramChannelConfig setBroadcast(boolean broadcast) {
Native.setBroadcast(datagramChannel.fd().intValue(), broadcast ? 1 : 0);
return this;
try {
Native.setBroadcast(datagramChannel.fd().intValue(), broadcast ? 1 : 0);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
@ -294,7 +336,11 @@ public final class EpollDatagramChannelConfig extends EpollChannelConfig impleme
* Returns {@code true} if the SO_REUSEPORT option is set.
*/
public boolean isReusePort() {
return Native.isReusePort(datagramChannel.fd().intValue()) == 1;
try {
return Native.isReusePort(datagramChannel.fd().intValue()) == 1;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
@ -305,7 +351,11 @@ public final class EpollDatagramChannelConfig extends EpollChannelConfig impleme
* any affect.
*/
public EpollDatagramChannelConfig setReusePort(boolean reusePort) {
Native.setReusePort(datagramChannel.fd().intValue(), reusePort ? 1 : 0);
return this;
try {
Native.setReusePort(datagramChannel.fd().intValue(), reusePort ? 1 : 0);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
}

View File

@ -16,11 +16,13 @@
package io.netty.channel.epoll;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelOption;
import io.netty.channel.MessageSizeEstimator;
import io.netty.channel.RecvByteBufAllocator;
import io.netty.util.NetUtil;
import java.io.IOException;
import java.util.Map;
import static io.netty.channel.ChannelOption.SO_BACKLOG;
@ -80,21 +82,37 @@ public class EpollServerChannelConfig extends EpollChannelConfig {
}
public boolean isReuseAddress() {
return Native.isReuseAddress(channel.fd().intValue()) == 1;
try {
return Native.isReuseAddress(channel.fd().intValue()) == 1;
} catch (IOException e) {
throw new ChannelException(e);
}
}
public EpollServerChannelConfig setReuseAddress(boolean reuseAddress) {
Native.setReuseAddress(channel.fd().intValue(), reuseAddress ? 1 : 0);
return this;
try {
Native.setReuseAddress(channel.fd().intValue(), reuseAddress ? 1 : 0);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
public int getReceiveBufferSize() {
return channel.fd().getReceiveBufferSize();
try {
return channel.fd().getReceiveBufferSize();
} catch (IOException e) {
throw new ChannelException(e);
}
}
public EpollServerChannelConfig setReceiveBufferSize(int receiveBufferSize) {
channel.fd().setReceiveBufferSize(receiveBufferSize);
return this;
try {
channel.fd().setReceiveBufferSize(receiveBufferSize);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
public int getBacklog() {

View File

@ -21,6 +21,7 @@ import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.unix.FileDescriptor;
import io.netty.channel.unix.Socket;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
@ -125,7 +126,7 @@ public final class EpollServerSocketChannel extends AbstractEpollServerChannel i
return tcpMd5SigAddresses;
}
void setTcpMd5Sig(Map<InetAddress, byte[]> keys) {
void setTcpMd5Sig(Map<InetAddress, byte[]> keys) throws IOException {
this.tcpMd5SigAddresses = TcpMd5Util.newTcpMd5Sigs(this, tcpMd5SigAddresses, keys);
}
}

View File

@ -16,11 +16,13 @@
package io.netty.channel.epoll;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelOption;
import io.netty.channel.MessageSizeEstimator;
import io.netty.channel.RecvByteBufAllocator;
import io.netty.channel.socket.ServerSocketChannelConfig;
import java.io.IOException;
import java.net.InetAddress;
import java.util.Map;
@ -161,15 +163,23 @@ public final class EpollServerSocketChannelConfig extends EpollServerChannelConf
* Allowing them being read would mean anyone with access to the channel could get them.
*/
public EpollServerSocketChannelConfig setTcpMd5Sig(Map<InetAddress, byte[]> keys) {
((EpollServerSocketChannel) channel).setTcpMd5Sig(keys);
return this;
try {
((EpollServerSocketChannel) channel).setTcpMd5Sig(keys);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
* Returns {@code true} if the SO_REUSEPORT option is set.
*/
public boolean isReusePort() {
return Native.isReusePort(channel.fd().intValue()) == 1;
try {
return Native.isReusePort(channel.fd().intValue()) == 1;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
@ -180,8 +190,12 @@ public final class EpollServerSocketChannelConfig extends EpollServerChannelConf
* any affect.
*/
public EpollServerSocketChannelConfig setReusePort(boolean reusePort) {
Native.setReusePort(channel.fd().intValue(), reusePort ? 1 : 0);
return this;
try {
Native.setReusePort(channel.fd().intValue(), reusePort ? 1 : 0);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
@ -189,7 +203,11 @@ public final class EpollServerSocketChannelConfig extends EpollServerChannelConf
* {@code false} otherwise.
*/
public boolean isFreeBind() {
return Native.isIpFreeBind(channel.fd().intValue()) != 0;
try {
return Native.isIpFreeBind(channel.fd().intValue()) != 0;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
@ -197,22 +215,34 @@ public final class EpollServerSocketChannelConfig extends EpollServerChannelConf
* {@code false} for disable it. Default is disabled.
*/
public EpollServerSocketChannelConfig setFreeBind(boolean freeBind) {
Native.setIpFreeBind(channel.fd().intValue(), freeBind ? 1: 0);
return this;
try {
Native.setIpFreeBind(channel.fd().intValue(), freeBind ? 1 : 0);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
* Set the {@code TCP_DEFER_ACCEPT} option on the socket. See {@code man 7 tcp} for more details.
*/
public EpollServerSocketChannelConfig setTcpDeferAccept(int deferAccept) {
channel.fd().setTcpDeferAccept(deferAccept);
return this;
try {
channel.fd().setTcpDeferAccept(deferAccept);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
* Returns a positive value if <a href="http://linux.die.net/man/7/tcp">TCP_DEFER_ACCEPT</a> is enabled.
*/
public int getTcpDeferAccept() {
return channel.fd().getTcpDeferAccept();
try {
return channel.fd().getTcpDeferAccept();
} catch (IOException e) {
throw new ChannelException(e);
}
}
}

View File

@ -16,6 +16,7 @@
package io.netty.channel.epoll;
import io.netty.channel.Channel;
import io.netty.channel.ChannelException;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.unix.FileDescriptor;
@ -23,6 +24,7 @@ import io.netty.channel.unix.Socket;
import io.netty.util.concurrent.GlobalEventExecutor;
import io.netty.util.internal.PlatformDependent;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
@ -103,8 +105,12 @@ public final class EpollSocketChannel extends AbstractEpollStreamChannel impleme
* See <a href="http://linux.die.net/man/7/tcp">man 7 tcp</a>.
*/
public EpollTcpInfo tcpInfo(EpollTcpInfo info) {
Native.tcpInfo(fd().intValue(), info);
return info;
try {
Native.tcpInfo(fd().intValue(), info);
return info;
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
@ -223,7 +229,7 @@ public final class EpollSocketChannel extends AbstractEpollStreamChannel impleme
}
}
void setTcpMd5Sig(Map<InetAddress, byte[]> keys) {
void setTcpMd5Sig(Map<InetAddress, byte[]> keys) throws IOException {
this.tcpMd5SigAddresses = TcpMd5Util.newTcpMd5Sigs(this, tcpMd5SigAddresses, keys);
}
}

View File

@ -16,12 +16,14 @@
package io.netty.channel.epoll;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelOption;
import io.netty.channel.MessageSizeEstimator;
import io.netty.channel.RecvByteBufAllocator;
import io.netty.channel.socket.SocketChannelConfig;
import io.netty.util.internal.PlatformDependent;
import java.io.IOException;
import java.net.InetAddress;
import java.util.Map;
@ -152,44 +154,76 @@ public final class EpollSocketChannelConfig extends EpollChannelConfig implement
@Override
public int getReceiveBufferSize() {
return channel.fd().getReceiveBufferSize();
try {
return channel.fd().getReceiveBufferSize();
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public int getSendBufferSize() {
return channel.fd().getSendBufferSize();
try {
return channel.fd().getSendBufferSize();
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public int getSoLinger() {
return channel.fd().getSoLinger();
try {
return channel.fd().getSoLinger();
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public int getTrafficClass() {
return Native.getTrafficClass(channel.fd().intValue());
try {
return Native.getTrafficClass(channel.fd().intValue());
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public boolean isKeepAlive() {
return channel.fd().isKeepAlive();
try {
return channel.fd().isKeepAlive();
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public boolean isReuseAddress() {
return Native.isReuseAddress(channel.fd().intValue()) == 1;
try {
return Native.isReuseAddress(channel.fd().intValue()) == 1;
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public boolean isTcpNoDelay() {
return channel.fd().isTcpNoDelay();
try {
return channel.fd().isTcpNoDelay();
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
* Get the {@code TCP_CORK} option on the socket. See {@code man 7 tcp} for more details.
*/
public boolean isTcpCork() {
return channel.fd().isTcpCork();
try {
return channel.fd().isTcpCork();
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
@ -197,41 +231,65 @@ public final class EpollSocketChannelConfig extends EpollChannelConfig implement
* @return value is a uint32_t
*/
public long getTcpNotSentLowAt() {
return Native.getTcpNotSentLowAt(channel.fd().intValue()) & MAX_UINT32_T;
try {
return Native.getTcpNotSentLowAt(channel.fd().intValue()) & MAX_UINT32_T;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
* Get the {@code TCP_KEEPIDLE} option on the socket. See {@code man 7 tcp} for more details.
*/
public int getTcpKeepIdle() {
return Native.getTcpKeepIdle(channel.fd().intValue());
try {
return Native.getTcpKeepIdle(channel.fd().intValue());
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
* Get the {@code TCP_KEEPINTVL} option on the socket. See {@code man 7 tcp} for more details.
*/
public int getTcpKeepIntvl() {
return Native.getTcpKeepIntvl(channel.fd().intValue());
try {
return Native.getTcpKeepIntvl(channel.fd().intValue());
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
* Get the {@code TCP_KEEPCNT} option on the socket. See {@code man 7 tcp} for more details.
*/
public int getTcpKeepCnt() {
return Native.getTcpKeepCnt(channel.fd().intValue());
try {
return Native.getTcpKeepCnt(channel.fd().intValue());
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
* Get the {@code TCP_USER_TIMEOUT} option on the socket. See {@code man 7 tcp} for more details.
*/
public int getTcpUserTimeout() {
try {
return Native.getTcpUserTimeout(channel.fd().intValue());
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public EpollSocketChannelConfig setKeepAlive(boolean keepAlive) {
channel.fd().setKeepAlive(keepAlive);
return this;
try {
channel.fd().setKeepAlive(keepAlive);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
@ -242,40 +300,64 @@ public final class EpollSocketChannelConfig extends EpollChannelConfig implement
@Override
public EpollSocketChannelConfig setReceiveBufferSize(int receiveBufferSize) {
channel.fd().setReceiveBufferSize(receiveBufferSize);
return this;
try {
channel.fd().setReceiveBufferSize(receiveBufferSize);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public EpollSocketChannelConfig setReuseAddress(boolean reuseAddress) {
Native.setReuseAddress(channel.fd().intValue(), reuseAddress ? 1 : 0);
return this;
try {
Native.setReuseAddress(channel.fd().intValue(), reuseAddress ? 1 : 0);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public EpollSocketChannelConfig setSendBufferSize(int sendBufferSize) {
channel.fd().setSendBufferSize(sendBufferSize);
return this;
try {
channel.fd().setSendBufferSize(sendBufferSize);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public EpollSocketChannelConfig setSoLinger(int soLinger) {
channel.fd().setSoLinger(soLinger);
return this;
try {
channel.fd().setSoLinger(soLinger);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public EpollSocketChannelConfig setTcpNoDelay(boolean tcpNoDelay) {
channel.fd().setTcpNoDelay(tcpNoDelay);
return this;
try {
channel.fd().setTcpNoDelay(tcpNoDelay);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
* Set the {@code TCP_CORK} option on the socket. See {@code man 7 tcp} for more details.
*/
public EpollSocketChannelConfig setTcpCork(boolean tcpCork) {
channel.fd().setTcpCork(tcpCork);
return this;
try {
channel.fd().setTcpCork(tcpCork);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
@ -286,46 +368,70 @@ public final class EpollSocketChannelConfig extends EpollChannelConfig implement
if (tcpNotSentLowAt < 0 || tcpNotSentLowAt > MAX_UINT32_T) {
throw new IllegalArgumentException("tcpNotSentLowAt must be a uint32_t");
}
Native.setTcpNotSentLowAt(channel.fd().intValue(), (int) tcpNotSentLowAt);
return this;
try {
Native.setTcpNotSentLowAt(channel.fd().intValue(), (int) tcpNotSentLowAt);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override
public EpollSocketChannelConfig setTrafficClass(int trafficClass) {
Native.setTrafficClass(channel.fd().intValue(), trafficClass);
return this;
try {
Native.setTrafficClass(channel.fd().intValue(), trafficClass);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
* Set the {@code TCP_KEEPIDLE} option on the socket. See {@code man 7 tcp} for more details.
*/
public EpollSocketChannelConfig setTcpKeepIdle(int seconds) {
Native.setTcpKeepIdle(channel.fd().intValue(), seconds);
return this;
try {
Native.setTcpKeepIdle(channel.fd().intValue(), seconds);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
* Set the {@code TCP_KEEPINTVL} option on the socket. See {@code man 7 tcp} for more details.
*/
public EpollSocketChannelConfig setTcpKeepIntvl(int seconds) {
Native.setTcpKeepIntvl(channel.fd().intValue(), seconds);
return this;
try {
Native.setTcpKeepIntvl(channel.fd().intValue(), seconds);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
* Set the {@code TCP_KEEPCNT} option on the socket. See {@code man 7 tcp} for more details.
*/
public EpollSocketChannelConfig setTcpKeepCntl(int probes) {
Native.setTcpKeepCnt(channel.fd().intValue(), probes);
return this;
try {
Native.setTcpKeepCnt(channel.fd().intValue(), probes);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
* 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;
try {
Native.setTcpUserTimeout(channel.fd().intValue(), milliseconds);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
@ -334,8 +440,12 @@ public final class EpollSocketChannelConfig extends EpollChannelConfig implement
* Allowing them being read would mean anyone with access to the channel could get them.
*/
public EpollSocketChannelConfig setTcpMd5Sig(Map<InetAddress, byte[]> keys) {
channel.setTcpMd5Sig(keys);
return this;
try {
channel.setTcpMd5Sig(keys);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
@ -343,8 +453,12 @@ public final class EpollSocketChannelConfig extends EpollChannelConfig implement
* for more details.
*/
public EpollSocketChannelConfig setTcpQuickAck(boolean quickAck) {
channel.fd().setTcpQuickAck(quickAck);
return this;
try {
channel.fd().setTcpQuickAck(quickAck);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/**
@ -352,7 +466,11 @@ public final class EpollSocketChannelConfig extends EpollChannelConfig implement
* {@code false} otherwise.
*/
public boolean isTcpQuickAck() {
return channel.fd().isTcpQuickAck();
try {
return channel.fd().isTcpQuickAck();
} catch (IOException e) {
throw new ChannelException(e);
}
}
@Override

View File

@ -208,40 +208,40 @@ public final class Native {
private static native int sendFd0(int socketFd, int fd);
// Socket option operations
public static native int isReuseAddress(int fd);
public static native int isReusePort(int fd);
public static native int getTcpNotSentLowAt(int fd);
public static native int getTrafficClass(int fd);
public static native int isBroadcast(int fd);
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 isIpFreeBind(int fd);
public static native int isReuseAddress(int fd) throws IOException;
public static native int isReusePort(int fd) throws IOException;
public static native int getTcpNotSentLowAt(int fd) throws IOException;
public static native int getTrafficClass(int fd) throws IOException;
public static native int isBroadcast(int fd) throws IOException;
public static native int getTcpKeepIdle(int fd) throws IOException;
public static native int getTcpKeepIntvl(int fd) throws IOException;
public static native int getTcpKeepCnt(int fd) throws IOException;
public static native int getTcpUserTimeout(int milliseconds) throws IOException;
public static native int isIpFreeBind(int fd)throws IOException;
public static native void setReuseAddress(int fd, int reuseAddress);
public static native void setReusePort(int fd, int reuseAddress);
public static native void setTcpFastopen(int fd, int tcpFastopenBacklog);
public static native void setTcpNotSentLowAt(int fd, int tcpNotSentLowAt);
public static native void setTrafficClass(int fd, int tcpNoDelay);
public static native void setBroadcast(int fd, int broadcast);
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) {
public static native void setReuseAddress(int fd, int reuseAddress) throws IOException;
public static native void setReusePort(int fd, int reuseAddress) throws IOException;
public static native void setTcpFastopen(int fd, int tcpFastopenBacklog) throws IOException;
public static native void setTcpNotSentLowAt(int fd, int tcpNotSentLowAt) throws IOException;
public static native void setTrafficClass(int fd, int tcpNoDelay) throws IOException;
public static native void setBroadcast(int fd, int broadcast) throws IOException;
public static native void setTcpKeepIdle(int fd, int seconds) throws IOException;
public static native void setTcpKeepIntvl(int fd, int seconds) throws IOException;
public static native void setTcpKeepCnt(int fd, int probes) throws IOException;
public static native void setTcpUserTimeout(int fd, int milliseconds)throws IOException;
public static native void setIpFreeBind(int fd, int freeBind) throws IOException;
public static void tcpInfo(int fd, EpollTcpInfo info) throws IOException {
tcpInfo0(fd, info.info);
}
private static native void tcpInfo0(int fd, int[] array);
private static native void tcpInfo0(int fd, int[] array) throws IOException;
public static void setTcpMd5Sig(int fd, InetAddress address, byte[] key) {
public static void setTcpMd5Sig(int fd, InetAddress address, byte[] key) throws IOException {
final NativeInetAddress a = NativeInetAddress.newInstance(address);
setTcpMd5Sig0(fd, a.address(), a.scopeId(), key);
}
private static native void setTcpMd5Sig0(int fd, byte[] address, int scopeId, byte[] key);
private static native void setTcpMd5Sig0(int fd, byte[] address, int scopeId, byte[] key) throws IOException;
// epoll_event related
public static native int sizeofEpollEvent();

View File

@ -16,6 +16,8 @@
package io.netty.channel.epoll;
import io.netty.util.internal.ObjectUtil;
import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collection;
@ -26,7 +28,7 @@ import java.util.Map.Entry;
final class TcpMd5Util {
static Collection<InetAddress> newTcpMd5Sigs(AbstractEpollChannel channel, Collection<InetAddress> current,
Map<InetAddress, byte[]> newKeys) {
Map<InetAddress, byte[]> newKeys) throws IOException {
ObjectUtil.checkNotNull(channel, "channel");
ObjectUtil.checkNotNull(current, "current");
ObjectUtil.checkNotNull(newKeys, "newKeys");

View File

@ -239,35 +239,35 @@ public final class Socket extends FileDescriptor {
return address(addr, 0, addr.length);
}
public int getReceiveBufferSize() {
public int getReceiveBufferSize() throws IOException {
return getReceiveBufferSize(intValue());
}
public int getSendBufferSize() {
public int getSendBufferSize() throws IOException {
return getSendBufferSize(intValue());
}
public boolean isKeepAlive() {
public boolean isKeepAlive() throws IOException {
return isKeepAlive(intValue()) != 0;
}
public boolean isTcpNoDelay() {
public boolean isTcpNoDelay() throws IOException {
return isTcpNoDelay(intValue()) != 0;
}
public boolean isTcpCork() {
public boolean isTcpCork() throws IOException {
return isTcpCork(intValue()) != 0;
}
public int getSoLinger() {
public int getSoLinger() throws IOException {
return getSoLinger(intValue());
}
public int getTcpDeferAccept() {
public int getTcpDeferAccept() throws IOException {
return getTcpDeferAccept(intValue());
}
public boolean isTcpQuickAck() {
public boolean isTcpQuickAck() throws IOException {
return isTcpQuickAck(intValue()) != 0;
}
@ -275,35 +275,35 @@ public final class Socket extends FileDescriptor {
return getSoError(intValue());
}
public void setKeepAlive(boolean keepAlive) {
public void setKeepAlive(boolean keepAlive) throws IOException {
setKeepAlive(intValue(), keepAlive ? 1 : 0);
}
public void setReceiveBufferSize(int receiveBufferSize) {
public void setReceiveBufferSize(int receiveBufferSize) throws IOException {
setReceiveBufferSize(intValue(), receiveBufferSize);
}
public void setSendBufferSize(int sendBufferSize) {
public void setSendBufferSize(int sendBufferSize) throws IOException {
setSendBufferSize(intValue(), sendBufferSize);
}
public void setTcpNoDelay(boolean tcpNoDelay) {
public void setTcpNoDelay(boolean tcpNoDelay) throws IOException {
setTcpNoDelay(intValue(), tcpNoDelay ? 1 : 0);
}
public void setTcpCork(boolean tcpCork) {
public void setTcpCork(boolean tcpCork) throws IOException {
setTcpCork(intValue(), tcpCork ? 1 : 0);
}
public void setSoLinger(int soLinger) {
public void setSoLinger(int soLinger) throws IOException {
setSoLinger(intValue(), soLinger);
}
public void setTcpDeferAccept(int deferAccept) {
public void setTcpDeferAccept(int deferAccept) throws IOException {
setTcpDeferAccept(intValue(), deferAccept);
}
public void setTcpQuickAck(boolean quickAck) {
public void setTcpQuickAck(boolean quickAck) throws IOException {
setTcpQuickAck(intValue(), quickAck ? 1 : 0);
}

View File

@ -18,10 +18,12 @@ package io.netty.channel.epoll;
import static org.junit.Assert.*;
import static org.junit.Assume.*;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.EventLoopGroup;
import java.net.InetSocketAddress;
import java.nio.channels.ClosedChannelException;
import java.util.Random;
import org.junit.AfterClass;
@ -122,4 +124,26 @@ public class EpollSocketChannelConfigTest {
ch.config().setTcpQuickAck(true);
assertTrue(ch.config().isTcpQuickAck());
}
@Test
public void testSetOptionWhenClosed() {
ch.close().syncUninterruptibly();
try {
ch.config().setSoLinger(0);
fail();
} catch (ChannelException e) {
assertTrue(e.getCause() instanceof ClosedChannelException);
}
}
@Test
public void testGetOptionWhenClosed() {
ch.close().syncUninterruptibly();
try {
ch.config().getSoLinger();
fail();
} catch (ChannelException e) {
assertTrue(e.getCause() instanceof ClosedChannelException);
}
}
}