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 int socketType;
|
||||||
static char* nettyClassName = NULL;
|
static char* nettyClassName = NULL;
|
||||||
static const char* ip4prefix = "::ffff:";
|
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
|
// Optional external methods
|
||||||
extern int accept4(int sockFd, struct sockaddr* addr, socklen_t* addrlen, int flags) __attribute__((weak));
|
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) {
|
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);
|
uint16_t port = htons((uint16_t) jport);
|
||||||
|
|
||||||
// Use GetPrimitiveArrayCritical and ReleasePrimitiveArrayCritical to signal the VM that we really would like
|
// 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.
|
// 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!
|
// 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) {
|
if (scopeId != 0) {
|
||||||
ip6addr->sin6_scope_id = (uint32_t) scopeId;
|
ip6addr->sin6_scope_id = (uint32_t) scopeId;
|
||||||
}
|
}
|
||||||
|
// 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);
|
memcpy(&(ip6addr->sin6_addr.s6_addr), addressBytes, 16);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
struct sockaddr_in* ipaddr = (struct sockaddr_in*) addr;
|
struct sockaddr_in* ipaddr = (struct sockaddr_in*) addr;
|
||||||
ipaddr->sin_family = AF_INET;
|
ipaddr->sin_family = AF_INET;
|
||||||
|
@ -54,7 +54,7 @@ public class EpollSocketTcpMd5Test {
|
|||||||
server = (EpollServerSocketChannel) bootstrap.group(GROUP)
|
server = (EpollServerSocketChannel) bootstrap.group(GROUP)
|
||||||
.channel(EpollServerSocketChannel.class)
|
.channel(EpollServerSocketChannel.class)
|
||||||
.handler(new ChannelInboundHandlerAdapter())
|
.handler(new ChannelInboundHandlerAdapter())
|
||||||
.bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
|
.bind(new InetSocketAddress(NetUtil.LOCALHOST4, 0)).syncUninterruptibly().channel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
Loading…
Reference in New Issue
Block a user