Correctly handle wildcard address when bind to socket and using native transport
Motivation: When a wildcard address is used to bind a socket and ipv4 and ipv6 are usable we should accept both (just like JDK IO/NIO does). Modifications: Detect wildcard address and if so use in6addr_any Result: Correctly accept ipv4 and ipv6
This commit is contained in:
parent
cf2e829a0e
commit
52ba4f4ec7
@ -38,6 +38,8 @@ static jmethodID netUtilClassIpv4PreferredMethodId = NULL;
|
||||
static int socketType;
|
||||
static char* nettyClassName = NULL;
|
||||
static const char* ip4prefix = "::ffff:";
|
||||
static const unsigned char wildcardAddress[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static const unsigned char ipv4MappedWildcardAddress[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
// Optional external methods
|
||||
extern int accept4(int sockFd, struct sockaddr* addr, socklen_t* addrlen, int flags) __attribute__((weak));
|
||||
@ -212,6 +214,7 @@ static jint _socket(JNIEnv* env, jclass clazz, int type) {
|
||||
|
||||
int netty_unix_socket_initSockaddr(JNIEnv* env, jbyteArray address, jint scopeId, jint jport, const struct sockaddr_storage* addr) {
|
||||
uint16_t port = htons((uint16_t) jport);
|
||||
|
||||
// Use GetPrimitiveArrayCritical and ReleasePrimitiveArrayCritical to signal the VM that we really would like
|
||||
// to not do a memory copy here. This is ok as we not do any blocking action here anyway.
|
||||
// This is important as the VM may suspend GC for the time!
|
||||
@ -229,7 +232,12 @@ int netty_unix_socket_initSockaddr(JNIEnv* env, jbyteArray address, jint scopeId
|
||||
if (scopeId != 0) {
|
||||
ip6addr->sin6_scope_id = (uint32_t) scopeId;
|
||||
}
|
||||
memcpy(&(ip6addr->sin6_addr.s6_addr), addressBytes, 16);
|
||||
// check if this is an any address and if so we need to handle it like this.
|
||||
if (memcmp(addressBytes, wildcardAddress, 16) == 0 || memcmp(addressBytes, ipv4MappedWildcardAddress, 16) == 0) {
|
||||
ip6addr->sin6_addr = in6addr_any;
|
||||
} else {
|
||||
memcpy(&(ip6addr->sin6_addr.s6_addr), addressBytes, 16);
|
||||
}
|
||||
} else {
|
||||
struct sockaddr_in* ipaddr = (struct sockaddr_in*) addr;
|
||||
ipaddr->sin_family = AF_INET;
|
||||
|
@ -54,7 +54,7 @@ public class EpollSocketTcpMd5Test {
|
||||
server = (EpollServerSocketChannel) bootstrap.group(GROUP)
|
||||
.channel(EpollServerSocketChannel.class)
|
||||
.handler(new ChannelInboundHandlerAdapter())
|
||||
.bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
|
||||
.bind(new InetSocketAddress(NetUtil.LOCALHOST4, 0)).syncUninterruptibly().channel();
|
||||
}
|
||||
|
||||
@After
|
||||
|
Loading…
Reference in New Issue
Block a user