Add support for IP_TRANSPARENT socket option
Motivation: This allows netty to operate in 'transparent proxy' mode, intercepting connections to other addresses by means of Linux firewalling rules, as per https://www.kernel.org/doc/Documentation/networking/tproxy.txt The original destination address can be obtained by referencing ch.localAddress(). Modification: Add methods similar to those for ipFreeBind, to set the IP_TRANSPARENT option. Result: Allows setting and getting of the IP_TRANSPARENT option, which allows retrieval of the ultimate socket address originally requested.
This commit is contained in:
parent
b6c27b9f6b
commit
051e0ad4be
@ -86,6 +86,10 @@ static void netty_epoll_linuxsocket_setIpFreeBind(JNIEnv* env, jclass clazz, jin
|
||||
netty_unix_socket_setOption(env, fd, IPPROTO_IP, IP_FREEBIND, &optval, sizeof(optval));
|
||||
}
|
||||
|
||||
static void netty_epoll_linuxsocket_setIpTransparent(JNIEnv* env, jclass clazz, jint fd, jint optval) {
|
||||
netty_unix_socket_setOption(env, fd, SOL_IP, IP_TRANSPARENT, &optval, sizeof(optval));
|
||||
}
|
||||
|
||||
static void netty_epoll_linuxsocket_setTcpMd5Sig(JNIEnv* env, jclass clazz, jint fd, jbyteArray address, jint scopeId, jbyteArray key) {
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrSize;
|
||||
@ -164,6 +168,14 @@ static jint netty_epoll_linuxsocket_isIpFreeBind(JNIEnv* env, jclass clazz, jint
|
||||
return optval;
|
||||
}
|
||||
|
||||
static jint netty_epoll_linuxsocket_isIpTransparent(JNIEnv* env, jclass clazz, jint fd) {
|
||||
int optval;
|
||||
if (netty_unix_socket_getOption(env, fd, SOL_IP, IP_TRANSPARENT, &optval, sizeof(optval)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
return optval;
|
||||
}
|
||||
|
||||
static void netty_epoll_linuxsocket_getTcpInfo(JNIEnv* env, jclass clazz, jint fd, jintArray array) {
|
||||
struct tcp_info tcp_info;
|
||||
if (netty_unix_socket_getOption(env, fd, IPPROTO_TCP, TCP_INFO, &tcp_info, sizeof(tcp_info)) == -1) {
|
||||
@ -265,11 +277,13 @@ static const JNINativeMethod fixed_method_table[] = {
|
||||
{ "setTcpKeepCnt", "(II)V", (void *) netty_epoll_linuxsocket_setTcpKeepCnt },
|
||||
{ "setTcpUserTimeout", "(II)V", (void *) netty_epoll_linuxsocket_setTcpUserTimeout },
|
||||
{ "setIpFreeBind", "(II)V", (void *) netty_epoll_linuxsocket_setIpFreeBind },
|
||||
{ "setIpTransparent", "(II)V", (void *) netty_epoll_linuxsocket_setIpTransparent },
|
||||
{ "getTcpKeepIdle", "(I)I", (void *) netty_epoll_linuxsocket_getTcpKeepIdle },
|
||||
{ "getTcpKeepIntvl", "(I)I", (void *) netty_epoll_linuxsocket_getTcpKeepIntvl },
|
||||
{ "getTcpKeepCnt", "(I)I", (void *) netty_epoll_linuxsocket_getTcpKeepCnt },
|
||||
{ "getTcpUserTimeout", "(I)I", (void *) netty_epoll_linuxsocket_getTcpUserTimeout },
|
||||
{ "isIpFreeBind", "(I)I", (void *) netty_epoll_linuxsocket_isIpFreeBind },
|
||||
{ "isIpTransparent", "(I)I", (void *) netty_epoll_linuxsocket_isIpTransparent },
|
||||
{ "getTcpInfo", "(I[I)V", (void *) netty_epoll_linuxsocket_getTcpInfo },
|
||||
{ "setTcpMd5Sig", "(I[BI[B)V", (void *) netty_epoll_linuxsocket_setTcpMd5Sig }
|
||||
};
|
||||
|
@ -30,6 +30,7 @@ public final class EpollChannelOption<T> extends UnixChannelOption<T> {
|
||||
public static final ChannelOption<Integer> TCP_USER_TIMEOUT =
|
||||
valueOf(EpollChannelOption.class, "TCP_USER_TIMEOUT");
|
||||
public static final ChannelOption<Boolean> IP_FREEBIND = valueOf("IP_FREEBIND");
|
||||
public static final ChannelOption<Boolean> IP_TRANSPARENT = valueOf("IP_TRANSPARENT");
|
||||
public static final ChannelOption<Integer> TCP_FASTOPEN = valueOf(EpollChannelOption.class, "TCP_FASTOPEN");
|
||||
public static final ChannelOption<Integer> TCP_DEFER_ACCEPT =
|
||||
ChannelOption.valueOf(EpollChannelOption.class, "TCP_DEFER_ACCEPT");
|
||||
|
@ -42,7 +42,7 @@ public final class EpollServerSocketChannelConfig extends EpollServerChannelConf
|
||||
@Override
|
||||
public Map<ChannelOption<?>, Object> getOptions() {
|
||||
return getOptions(super.getOptions(), EpollChannelOption.SO_REUSEPORT, EpollChannelOption.IP_FREEBIND,
|
||||
EpollChannelOption.TCP_DEFER_ACCEPT);
|
||||
EpollChannelOption.IP_TRANSPARENT, EpollChannelOption.TCP_DEFER_ACCEPT);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -54,6 +54,9 @@ public final class EpollServerSocketChannelConfig extends EpollServerChannelConf
|
||||
if (option == EpollChannelOption.IP_FREEBIND) {
|
||||
return (T) Boolean.valueOf(isFreeBind());
|
||||
}
|
||||
if (option == EpollChannelOption.IP_TRANSPARENT) {
|
||||
return (T) Boolean.valueOf(isIpTransparent());
|
||||
}
|
||||
if (option == EpollChannelOption.TCP_DEFER_ACCEPT) {
|
||||
return (T) Integer.valueOf(getTcpDeferAccept());
|
||||
}
|
||||
@ -68,6 +71,8 @@ public final class EpollServerSocketChannelConfig extends EpollServerChannelConf
|
||||
setReusePort((Boolean) value);
|
||||
} else if (option == EpollChannelOption.IP_FREEBIND) {
|
||||
setFreeBind((Boolean) value);
|
||||
} else if (option == EpollChannelOption.IP_TRANSPARENT) {
|
||||
setIpTransparent((Boolean) value);
|
||||
} else if (option == EpollChannelOption.TCP_MD5SIG) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final Map<InetAddress, byte[]> m = (Map<InetAddress, byte[]>) value;
|
||||
@ -233,6 +238,31 @@ public final class EpollServerSocketChannelConfig extends EpollServerChannelConf
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if <a href="http://man7.org/linux/man-pages/man7/ip.7.html">IP_TRANSPARENT</a> is enabled,
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
public boolean isIpTransparent() {
|
||||
try {
|
||||
return channel.socket.isIpTransparent();
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If {@code true} is used <a href="http://man7.org/linux/man-pages/man7/ip.7.html">IP_TRANSPARENT</a> is enabled,
|
||||
* {@code false} for disable it. Default is disabled.
|
||||
*/
|
||||
public EpollServerSocketChannelConfig setIpTransparent(boolean transparent) {
|
||||
try {
|
||||
channel.socket.setIpTransparent(transparent);
|
||||
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.
|
||||
*/
|
||||
|
@ -75,6 +75,10 @@ final class LinuxSocket extends Socket {
|
||||
setIpFreeBind(intValue(), enabled ? 1 : 0);
|
||||
}
|
||||
|
||||
void setIpTransparent(boolean enabled) throws IOException {
|
||||
setIpTransparent(intValue(), enabled ? 1 : 0);
|
||||
}
|
||||
|
||||
void getTcpInfo(EpollTcpInfo info) throws IOException {
|
||||
getTcpInfo(intValue(), info.info);
|
||||
}
|
||||
@ -120,6 +124,10 @@ final class LinuxSocket extends Socket {
|
||||
return isIpFreeBind(intValue()) != 0;
|
||||
}
|
||||
|
||||
boolean isIpTransparent() throws IOException {
|
||||
return isIpTransparent(intValue()) != 0;
|
||||
}
|
||||
|
||||
PeerCredentials getPeerCredentials() throws IOException {
|
||||
return getPeerCredentials(intValue());
|
||||
}
|
||||
@ -145,6 +153,7 @@ final class LinuxSocket extends Socket {
|
||||
private static native int getTcpKeepCnt(int fd) throws IOException;
|
||||
private static native int getTcpUserTimeout(int fd) throws IOException;
|
||||
private static native int isIpFreeBind(int fd) throws IOException;
|
||||
private static native int isIpTransparent(int fd) throws IOException;
|
||||
private static native void getTcpInfo(int fd, int[] array) throws IOException;
|
||||
private static native PeerCredentials getPeerCredentials(int fd) throws IOException;
|
||||
|
||||
@ -158,5 +167,6 @@ final class LinuxSocket extends Socket {
|
||||
private static native void setTcpKeepCnt(int fd, int probes) throws IOException;
|
||||
private static native void setTcpUserTimeout(int fd, int milliseconds)throws IOException;
|
||||
private static native void setIpFreeBind(int fd, int freeBind) throws IOException;
|
||||
private static native void setIpTransparent(int fd, int transparent) throws IOException;
|
||||
private static native void setTcpMd5Sig(int fd, byte[] address, int scopeId, byte[] key) throws IOException;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user