Allowed IP_FREEBIND option for UDP epoll (#8728)

Motivation:

While using Load Balancers or HA support is needed there are cases when UDP channel need to bind to IP Address which is not available on network interfaces locally.

Modification:

Modified EpollDatagramChannelConfig to allow IP_FREEBIND option

Result:

Fixes ##8727.
This commit is contained in:
yulianoifa-mobius 2019-01-21 08:42:05 +02:00 committed by Norman Maurer
parent 32de6ae18c
commit 7a613c2131
2 changed files with 63 additions and 1 deletions

View File

@ -47,7 +47,7 @@ public final class EpollDatagramChannelConfig extends EpollChannelConfig impleme
ChannelOption.SO_REUSEADDR, ChannelOption.IP_MULTICAST_LOOP_DISABLED, ChannelOption.SO_REUSEADDR, ChannelOption.IP_MULTICAST_LOOP_DISABLED,
ChannelOption.IP_MULTICAST_ADDR, ChannelOption.IP_MULTICAST_IF, ChannelOption.IP_MULTICAST_TTL, ChannelOption.IP_MULTICAST_ADDR, ChannelOption.IP_MULTICAST_IF, ChannelOption.IP_MULTICAST_TTL,
ChannelOption.IP_TOS, ChannelOption.DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION, ChannelOption.IP_TOS, ChannelOption.DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION,
EpollChannelOption.SO_REUSEPORT, EpollChannelOption.IP_TRANSPARENT, EpollChannelOption.SO_REUSEPORT, EpollChannelOption.IP_FREEBIND, EpollChannelOption.IP_TRANSPARENT,
EpollChannelOption.IP_RECVORIGDSTADDR); EpollChannelOption.IP_RECVORIGDSTADDR);
} }
@ -90,6 +90,9 @@ public final class EpollDatagramChannelConfig extends EpollChannelConfig impleme
if (option == EpollChannelOption.IP_TRANSPARENT) { if (option == EpollChannelOption.IP_TRANSPARENT) {
return (T) Boolean.valueOf(isIpTransparent()); return (T) Boolean.valueOf(isIpTransparent());
} }
if (option == EpollChannelOption.IP_FREEBIND) {
return (T) Boolean.valueOf(isFreeBind());
}
if (option == EpollChannelOption.IP_RECVORIGDSTADDR) { if (option == EpollChannelOption.IP_RECVORIGDSTADDR) {
return (T) Boolean.valueOf(isIpRecvOrigDestAddr()); return (T) Boolean.valueOf(isIpRecvOrigDestAddr());
} }
@ -123,6 +126,8 @@ public final class EpollDatagramChannelConfig extends EpollChannelConfig impleme
setActiveOnOpen((Boolean) value); setActiveOnOpen((Boolean) value);
} else if (option == EpollChannelOption.SO_REUSEPORT) { } else if (option == EpollChannelOption.SO_REUSEPORT) {
setReusePort((Boolean) value); setReusePort((Boolean) value);
} else if (option == EpollChannelOption.IP_FREEBIND) {
setFreeBind((Boolean) value);
} else if (option == EpollChannelOption.IP_TRANSPARENT) { } else if (option == EpollChannelOption.IP_TRANSPARENT) {
setIpTransparent((Boolean) value); setIpTransparent((Boolean) value);
} else if (option == EpollChannelOption.IP_RECVORIGDSTADDR) { } else if (option == EpollChannelOption.IP_RECVORIGDSTADDR) {
@ -407,6 +412,31 @@ public final class EpollDatagramChannelConfig extends EpollChannelConfig impleme
} }
} }
/**
* Returns {@code true} if <a href="http://man7.org/linux/man-pages/man7/ip.7.html">IP_FREEBIND</a> is enabled,
* {@code false} otherwise.
*/
public boolean isFreeBind() {
try {
return ((EpollDatagramChannel) channel).socket.isIpFreeBind();
} 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_FREEBIND</a> is enabled,
* {@code false} for disable it. Default is disabled.
*/
public EpollDatagramChannelConfig setFreeBind(boolean freeBind) {
try {
((EpollDatagramChannel) channel).socket.setIpFreeBind(freeBind);
return this;
} catch (IOException e) {
throw new ChannelException(e);
}
}
/** /**
* Returns {@code true} if <a href="http://man7.org/linux/man-pages/man7/ip.7.html">IP_RECVORIGDSTADDR</a> is * Returns {@code true} if <a href="http://man7.org/linux/man-pages/man7/ip.7.html">IP_RECVORIGDSTADDR</a> is
* enabled, {@code false} otherwise. * enabled, {@code false} otherwise.

View File

@ -0,0 +1,32 @@
/*
* Copyright 2019 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.channel.epoll;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
public class EpollDatagramChannelConfigTest {
@Test
public void testIpFreeBind() throws Exception {
Epoll.ensureAvailability();
EpollDatagramChannel channel = new EpollDatagramChannel();
assertTrue(channel.config().setOption(EpollChannelOption.IP_FREEBIND, true));
assertTrue(channel.config().getOption(EpollChannelOption.IP_FREEBIND));
channel.fd().close();
}
}