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
This commit is contained in:
Norman Maurer 2020-09-19 20:40:49 +02:00 committed by GitHub
parent b5d2f53aa0
commit 0751becf03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 110 additions and 45 deletions

View File

@ -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 },

View File

@ -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();

View File

@ -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();

View File

@ -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) {