From 0751becf03d5cc04e0ac347c3c18a0d80c542068 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Sat, 19 Sep 2020 20:40:49 +0200 Subject: [PATCH] Make reading and writing of sockaddr_in / sockaddr_in6 more robust (#10591) Motivation: While the current code works just fine we should better lookup the offsets of the various struct members on init and use these. This way we are sure the code is portable and correct. Modifications: Lookup various offsets on init and than use the offsets when reading and writing to / from the structs Result: More robust and portable code --- .../src/main/c/netty_io_uring_native.c | 50 +++++++++++++ .../java/io/netty/channel/uring/Native.java | 18 +++++ .../NativeStaticallyReferencedJniMethods.java | 12 ++- .../io/netty/channel/uring/SockaddrIn.java | 75 ++++++++----------- 4 files changed, 110 insertions(+), 45 deletions(-) diff --git a/transport-native-io_uring/src/main/c/netty_io_uring_native.c b/transport-native-io_uring/src/main/c/netty_io_uring_native.c index 57a0b0bc25..b269520d36 100644 --- a/transport-native-io_uring/src/main/c/netty_io_uring_native.c +++ b/transport-native-io_uring/src/main/c/netty_io_uring_native.c @@ -283,6 +283,46 @@ static jint netty_io_uring_sizeofSockaddrIn6(JNIEnv* env, jclass clazz) { return sizeof(struct sockaddr_in6); } +static jint netty_io_uring_sockaddrInOffsetofSinFamily(JNIEnv* env, jclass clazz) { + return offsetof(struct sockaddr_in, sin_family); +} + +static jint netty_io_uring_sockaddrInOffsetofSinPort(JNIEnv* env, jclass clazz) { + return offsetof(struct sockaddr_in, sin_port); +} + +static jint netty_io_uring_sockaddrInOffsetofSinAddr(JNIEnv* env, jclass clazz) { + return offsetof(struct sockaddr_in, sin_addr); +} + +static jint netty_io_uring_inAddressOffsetofSAddr(JNIEnv* env, jclass clazz) { + return offsetof(struct in_addr, s_addr); +} + +static jint netty_io_uring_sockaddrIn6OffsetofSin6Family(JNIEnv* env, jclass clazz) { + return offsetof(struct sockaddr_in6, sin6_family); +} + +static jint netty_io_uring_sockaddrIn6OffsetofSin6Port(JNIEnv* env, jclass clazz) { + return offsetof(struct sockaddr_in6, sin6_port); +} + +static jint netty_io_uring_sockaddrIn6OffsetofSin6Flowinfo(JNIEnv* env, jclass clazz) { + return offsetof(struct sockaddr_in6, sin6_flowinfo); +} + +static jint netty_io_uring_sockaddrIn6OffsetofSin6Addr(JNIEnv* env, jclass clazz) { + return offsetof(struct sockaddr_in6, sin6_addr); +} + +static jint netty_io_uring_sockaddrIn6OffsetofSin6ScopeId(JNIEnv* env, jclass clazz) { + return offsetof(struct sockaddr_in6, sin6_scope_id); +} + +static jint netty_io_uring_in6AddressOffsetofS6Addr(JNIEnv* env, jclass clazz) { + return offsetof(struct in6_addr, s6_addr); +} + static jint netty_io_uring_etime(JNIEnv* env, jclass clazz) { return ETIME; } @@ -356,6 +396,16 @@ static const JNINativeMethod statically_referenced_fixed_method_table[] = { { "afInet6", "()I", (void *) netty_io_uring_afInet6 }, { "sizeofSockaddrIn", "()I", (void *) netty_io_uring_sizeofSockaddrIn }, { "sizeofSockaddrIn6", "()I", (void *) netty_io_uring_sizeofSockaddrIn6 }, + { "sockaddrInOffsetofSinFamily", "()I", (void *) netty_io_uring_sockaddrInOffsetofSinFamily }, + { "sockaddrInOffsetofSinPort", "()I", (void *) netty_io_uring_sockaddrInOffsetofSinPort }, + { "sockaddrInOffsetofSinAddr", "()I", (void *) netty_io_uring_sockaddrInOffsetofSinAddr }, + { "inAddressOffsetofSAddr", "()I", (void *) netty_io_uring_inAddressOffsetofSAddr }, + { "sockaddrIn6OffsetofSin6Family", "()I", (void *) netty_io_uring_sockaddrIn6OffsetofSin6Family }, + { "sockaddrIn6OffsetofSin6Port", "()I", (void *) netty_io_uring_sockaddrIn6OffsetofSin6Port }, + { "sockaddrIn6OffsetofSin6Flowinfo", "()I", (void *) netty_io_uring_sockaddrIn6OffsetofSin6Flowinfo }, + { "sockaddrIn6OffsetofSin6Addr", "()I", (void *) netty_io_uring_sockaddrIn6OffsetofSin6Addr }, + { "sockaddrIn6OffsetofSin6ScopeId", "()I", (void *) netty_io_uring_sockaddrIn6OffsetofSin6ScopeId }, + { "in6AddressOffsetofS6Addr", "()I", (void *) netty_io_uring_in6AddressOffsetofS6Addr }, { "etime", "()I", (void *) netty_io_uring_etime }, { "ecanceled", "()I", (void *) netty_io_uring_ecanceled }, { "pollin", "()I", (void *) netty_io_uring_pollin }, diff --git a/transport-native-io_uring/src/main/java/io/netty/channel/uring/Native.java b/transport-native-io_uring/src/main/java/io/netty/channel/uring/Native.java index 9206488af7..77f8ba5566 100644 --- a/transport-native-io_uring/src/main/java/io/netty/channel/uring/Native.java +++ b/transport-native-io_uring/src/main/java/io/netty/channel/uring/Native.java @@ -68,6 +68,24 @@ final class Native { static final short AF_INET6 = (short) NativeStaticallyReferencedJniMethods.afInet6(); static final int SIZEOF_SOCKADDR_IN = NativeStaticallyReferencedJniMethods.sizeofSockaddrIn(); static final int SIZEOF_SOCKADDR_IN6 = NativeStaticallyReferencedJniMethods.sizeofSockaddrIn6(); + static final int SOCKADDR_IN_OFFSETOF_SIN_FAMILY = + NativeStaticallyReferencedJniMethods.sockaddrInOffsetofSinFamily(); + static final int SOCKADDR_IN_OFFSETOF_SIN_PORT = NativeStaticallyReferencedJniMethods.sockaddrInOffsetofSinPort(); + static final int SOCKADDR_IN_OFFSETOF_SIN_ADDR = NativeStaticallyReferencedJniMethods.sockaddrInOffsetofSinAddr(); + static final int IN_ADDRESS_OFFSETOF_S_ADDR = NativeStaticallyReferencedJniMethods.inAddressOffsetofSAddr(); + + static final int SOCKADDR_IN6_OFFSETOF_SIN6_FAMILY = + NativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6Family(); + static final int SOCKADDR_IN6_OFFSETOF_SIN6_PORT = + NativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6Port(); + static final int SOCKADDR_IN6_OFFSETOF_SIN6_FLOWINFO = + NativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6Flowinfo(); + static final int SOCKADDR_IN6_OFFSETOF_SIN6_ADDR = + NativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6Addr(); + static final int SOCKADDR_IN6_OFFSETOF_SIN6_SCOPE_ID = + NativeStaticallyReferencedJniMethods.sockaddrIn6OffsetofSin6ScopeId(); + static final int IN6_ADDRESS_OFFSETOF_S6_ADDR = NativeStaticallyReferencedJniMethods.in6AddressOffsetofS6Addr(); + static final int POLLIN = NativeStaticallyReferencedJniMethods.pollin(); static final int POLLOUT = NativeStaticallyReferencedJniMethods.pollout(); static final int POLLRDHUP = NativeStaticallyReferencedJniMethods.pollrdhup(); diff --git a/transport-native-io_uring/src/main/java/io/netty/channel/uring/NativeStaticallyReferencedJniMethods.java b/transport-native-io_uring/src/main/java/io/netty/channel/uring/NativeStaticallyReferencedJniMethods.java index b96361550a..abbced5374 100644 --- a/transport-native-io_uring/src/main/java/io/netty/channel/uring/NativeStaticallyReferencedJniMethods.java +++ b/transport-native-io_uring/src/main/java/io/netty/channel/uring/NativeStaticallyReferencedJniMethods.java @@ -36,13 +36,21 @@ final class NativeStaticallyReferencedJniMethods { static native int afInet6(); static native int sizeofSockaddrIn(); static native int sizeofSockaddrIn6(); - + static native int sockaddrInOffsetofSinFamily(); + static native int sockaddrInOffsetofSinPort(); + static native int sockaddrInOffsetofSinAddr(); + static native int inAddressOffsetofSAddr(); + static native int sockaddrIn6OffsetofSin6Family(); + static native int sockaddrIn6OffsetofSin6Port(); + static native int sockaddrIn6OffsetofSin6Flowinfo(); + static native int sockaddrIn6OffsetofSin6Addr(); + static native int sockaddrIn6OffsetofSin6ScopeId(); + static native int in6AddressOffsetofS6Addr(); static native int etime(); static native int ecanceled(); static native int pollin(); static native int pollout(); static native int pollrdhup(); - static native int ioringOpWritev(); static native int ioringOpPollAdd(); static native int ioringOpPollRemove(); diff --git a/transport-native-io_uring/src/main/java/io/netty/channel/uring/SockaddrIn.java b/transport-native-io_uring/src/main/java/io/netty/channel/uring/SockaddrIn.java index 0a60964ef9..16c110d738 100644 --- a/transport-native-io_uring/src/main/java/io/netty/channel/uring/SockaddrIn.java +++ b/transport-native-io_uring/src/main/java/io/netty/channel/uring/SockaddrIn.java @@ -44,26 +44,20 @@ final class SockaddrIn { * */ static int writeIPv4(long memory, InetAddress address, int port) { - int written = 0; - PlatformDependent.putShort(memory, Native.AF_INET); - written += 2; - PlatformDependent.putShort(memory + written, handleNetworkOrder((short) port)); - written += 2; + PlatformDependent.setMemory(memory, Native.SIZEOF_SOCKADDR_IN, (byte) 0); + + PlatformDependent.putShort(memory + Native.SOCKADDR_IN_OFFSETOF_SIN_FAMILY, Native.AF_INET); + PlatformDependent.putShort(memory + Native.SOCKADDR_IN_OFFSETOF_SIN_PORT, handleNetworkOrder((short) port)); byte[] bytes = address.getAddress(); int offset = 0; if (bytes.length == 16) { - // IPV6 mapped IPV4 address + // IPV6 mapped IPV4 address, we only need the last 4 bytes. offset = 12; } assert bytes.length == offset + 4; - PlatformDependent.copyMemory(bytes, offset, memory + written, 4); - written += 4; - - int padding = Native.SIZEOF_SOCKADDR_IN - written; - PlatformDependent.setMemory(memory + written, padding, (byte) 0); - written += padding; - assert written == Native.SIZEOF_SOCKADDR_IN; - return written; + PlatformDependent.copyMemory(bytes, offset, + memory + Native.SOCKADDR_IN_OFFSETOF_SIN_ADDR + Native.IN_ADDRESS_OFFSETOF_S_ADDR, 4); + return Native.SIZEOF_SOCKADDR_IN; } /** @@ -75,44 +69,36 @@ final class SockaddrIn { * uint32_t sin6_scope_id; /* Scope ID (new in 2.4) * }; * - * struct in6_addr{ + * struct in6_addr { * unsigned char s6_addr[16]; // IPv6 address * }; */ static int writeIPv6(long memory, InetAddress address, int port) { - int written = 0; - // AF_INET6 - PlatformDependent.putShort(memory, Native.AF_INET6); - written += 2; - PlatformDependent.putShort(memory + written, handleNetworkOrder((short) port)); - written += 2; - PlatformDependent.putInt(memory + written, 0); - written += 4; + PlatformDependent.setMemory(memory, Native.SIZEOF_SOCKADDR_IN6, (byte) 0); + PlatformDependent.putShort(memory + Native.SOCKADDR_IN6_OFFSETOF_SIN6_FAMILY, Native.AF_INET6); + PlatformDependent.putShort(memory + Native.SOCKADDR_IN6_OFFSETOF_SIN6_PORT, handleNetworkOrder((short) port)); + // Skip sin6_flowinfo as we did memset before byte[] bytes = address.getAddress(); if (bytes.length == 4) { - PlatformDependent.copyMemory(IPV4_MAPPED_IPV6_PREFIX, 0, memory + written, IPV4_MAPPED_IPV6_PREFIX.length); - written += IPV4_MAPPED_IPV6_PREFIX.length; - PlatformDependent.copyMemory(bytes, 0, memory + written, 4); - written += 4; - PlatformDependent.putInt(memory + written, 0); - written += 4; + int offset = Native.SOCKADDR_IN6_OFFSETOF_SIN6_ADDR + Native.IN6_ADDRESS_OFFSETOF_S6_ADDR; + PlatformDependent.copyMemory(IPV4_MAPPED_IPV6_PREFIX, 0, memory + offset, IPV4_MAPPED_IPV6_PREFIX.length); + PlatformDependent.copyMemory(bytes, 0, memory + offset + IPV4_MAPPED_IPV6_PREFIX.length, 4); + // Skip sin6_scope_id as we did memset before } else { - PlatformDependent.copyMemory(bytes, 0, memory + written, 16); - written += 16; - PlatformDependent.putInt(memory + written, ((Inet6Address) address).getScopeId()); - written += 4; + PlatformDependent.copyMemory(bytes, 0, + memory + Native.SOCKADDR_IN6_OFFSETOF_SIN6_ADDR + Native.IN6_ADDRESS_OFFSETOF_S6_ADDR, 16); + PlatformDependent.putInt( + memory + Native.SOCKADDR_IN6_OFFSETOF_SIN6_SCOPE_ID, ((Inet6Address) address).getScopeId()); } - int padding = Native.SIZEOF_SOCKADDR_IN6 - written; - PlatformDependent.setMemory(memory + written, padding, (byte) 0); - written += padding; - assert written == Native.SIZEOF_SOCKADDR_IN6; - return written; + return Native.SIZEOF_SOCKADDR_IN6; } static InetSocketAddress readIPv4(long memory, byte[] tmpArray) { assert tmpArray.length == 4; - int port = handleNetworkOrder(PlatformDependent.getShort(memory + 2)) & 0xFFFF; - PlatformDependent.copyMemory(memory + 4, tmpArray, 0, 4); + int port = handleNetworkOrder(PlatformDependent.getShort( + memory + Native.SOCKADDR_IN_OFFSETOF_SIN_PORT)) & 0xFFFF; + PlatformDependent.copyMemory(memory + Native.SOCKADDR_IN_OFFSETOF_SIN_ADDR + Native.IN_ADDRESS_OFFSETOF_S_ADDR, + tmpArray, 0, 4); try { return new InetSocketAddress(InetAddress.getByAddress(tmpArray), port); } catch (UnknownHostException ignore) { @@ -122,9 +108,12 @@ final class SockaddrIn { static InetSocketAddress readIPv6(long memory, byte[] tmpArray) { assert tmpArray.length == 16; - int port = handleNetworkOrder(PlatformDependent.getShort(memory + 2)) & 0xFFFF; - PlatformDependent.copyMemory(memory + 8, tmpArray, 0, 16); - int scopeId = PlatformDependent.getInt(memory + 24); + int port = handleNetworkOrder(PlatformDependent.getShort( + memory + Native.SOCKADDR_IN6_OFFSETOF_SIN6_PORT)) & 0xFFFF; + PlatformDependent.copyMemory( + memory + Native.SOCKADDR_IN6_OFFSETOF_SIN6_ADDR + Native.IN6_ADDRESS_OFFSETOF_S6_ADDR, + tmpArray, 0, 16); + int scopeId = PlatformDependent.getInt(memory + Native.SOCKADDR_IN6_OFFSETOF_SIN6_SCOPE_ID); try { return new InetSocketAddress(Inet6Address.getByAddress(null, tmpArray, scopeId), port); } catch (UnknownHostException ignore) {