From 7df5bbc61b8b9235c669f4615d537c950d1347cf Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Mon, 8 Nov 2021 17:39:07 +0100 Subject: [PATCH] Issue #6728 - QUIC and HTTP/3 - add windows and mac binding support --- .../quic/quiche/panama/jdk/NativeHelper.java | 20 ++- .../panama/jdk/linux/sockaddr_linux.java | 147 ++++++++++++++++ .../panama/jdk/macos/sockaddr_macos.java | 163 ++++++++++++++++++ .../quic/quiche/panama/jdk/sockaddr.java | 51 ++---- .../quic/quiche/panama/jdk/sockaddr_in.java | 61 ------- .../quic/quiche/panama/jdk/sockaddr_in6.java | 71 -------- .../panama/jdk/windows/sockaddr_windows.java | 147 ++++++++++++++++ 7 files changed, 490 insertions(+), 170 deletions(-) create mode 100644 jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/linux/sockaddr_linux.java create mode 100644 jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/macos/sockaddr_macos.java delete mode 100644 jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/sockaddr_in.java delete mode 100644 jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/sockaddr_in6.java create mode 100644 jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/windows/sockaddr_windows.java diff --git a/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/NativeHelper.java b/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/NativeHelper.java index a727b310159..9da3766e7b8 100644 --- a/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/NativeHelper.java +++ b/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/NativeHelper.java @@ -53,7 +53,7 @@ class NativeHelper private static String getNativePrefix() { - // TODO: add macos and windows + // TODO: check for macos and windows String osName = System.getProperty("os.name").toLowerCase(Locale.ROOT); String osArch = System.getProperty("os.arch"); @@ -68,6 +68,24 @@ class NativeHelper return osName + "-" + osArch; } + public static boolean isLinux() + { + // TODO add constant & check correctness + return System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("linux"); + } + + public static boolean isMac() + { + // TODO add constant & check correctness + return System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("mac"); + } + + public static boolean isWindows() + { + // TODO add constant & check correctness + return System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("windows"); + } + private static File extractFromResourcePath(String libName, ClassLoader classLoader) throws IOException { File target = new File(System.getProperty("java.io.tmpdir"), libName); diff --git a/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/linux/sockaddr_linux.java b/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/linux/sockaddr_linux.java new file mode 100644 index 00000000000..8b0d9cfefd7 --- /dev/null +++ b/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/linux/sockaddr_linux.java @@ -0,0 +1,147 @@ +// +// ======================================================================== +// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.quic.quiche.panama.jdk.linux; + +import java.lang.invoke.VarHandle; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import jdk.incubator.foreign.MemoryLayout; +import jdk.incubator.foreign.MemorySegment; +import jdk.incubator.foreign.ResourceScope; + +import static jdk.incubator.foreign.CLinker.C_CHAR; +import static jdk.incubator.foreign.CLinker.C_INT; +import static jdk.incubator.foreign.CLinker.C_SHORT; + +public class sockaddr_linux +{ + private static final short AF_INET = 2; + private static final short AF_INET6 = 10; + + public static MemorySegment convert(SocketAddress socketAddress, ResourceScope scope) + { + if (!(socketAddress instanceof InetSocketAddress)) + throw new IllegalArgumentException("Expected InetSocketAddress instance, got: " + socketAddress); + InetSocketAddress inetSocketAddress = (InetSocketAddress)socketAddress; + InetAddress address = inetSocketAddress.getAddress(); + if (address instanceof Inet4Address) + { + MemorySegment sin = sockaddr_in.allocate(scope); + sockaddr_in.set_sin_family(sin, AF_INET); + sockaddr_in.set_sin_port(sin, (short) inetSocketAddress.getPort()); + sockaddr_in.set_sin_addr(sin, ByteBuffer.wrap(address.getAddress()).getInt()); + return sin; + } + else if (address instanceof Inet6Address) + { + MemorySegment sin6 = sockaddr_in6.allocate(scope); + sockaddr_in6.set_sin6_family(sin6, AF_INET6); + sockaddr_in6.set_sin6_port(sin6, (short) inetSocketAddress.getPort()); + sockaddr_in6.set_sin6_addr(sin6, address.getAddress()); + sockaddr_in6.set_sin6_scope_id(sin6, 0); + sockaddr_in6.set_sin6_flowinfo(sin6, 0); + return sin6; + } + else + { + throw new UnsupportedOperationException("Unsupported InetAddress: " + address); + } + } + + private static class sockaddr_in + { + private static final MemoryLayout LAYOUT = MemoryLayout.structLayout( + C_SHORT.withName("sin_family"), + C_SHORT.withName("sin_port"), + C_INT.withName("sin_addr"), + MemoryLayout.sequenceLayout(8, C_CHAR).withName("sin_zero") + ).withName("sockaddr_in"); + + private static final VarHandle sin_family = LAYOUT.varHandle(short.class, MemoryLayout.PathElement.groupElement("sin_family")); + private static final VarHandle sin_port = LAYOUT.varHandle(short.class, MemoryLayout.PathElement.groupElement("sin_port")); + private static final VarHandle sin_addr = LAYOUT.varHandle(int.class, MemoryLayout.PathElement.groupElement("sin_addr")); + + public static MemorySegment allocate(ResourceScope scope) + { + return MemorySegment.allocateNative(LAYOUT, scope); + } + + public static void set_sin_family(MemorySegment sin, short value) + { + sin_family.set(sin, value); + } + + public static void set_sin_port(MemorySegment sin, short value) + { + sin_port.set(sin, value); + } + + public static void set_sin_addr(MemorySegment sin, int value) + { + sin_addr.set(sin, value); + } + } + + private static class sockaddr_in6 + { + private static final MemoryLayout LAYOUT = MemoryLayout.structLayout( + C_SHORT.withName("sin6_family"), + C_SHORT.withName("sin6_port"), + C_INT.withName("sin6_flowinfo"), + MemoryLayout.sequenceLayout(16, C_CHAR).withName("sin6_addr"), + C_INT.withName("sin6_scope_id") + ).withName("sockaddr_in6"); + + private static final VarHandle sin6_family = LAYOUT.varHandle(short.class, MemoryLayout.PathElement.groupElement("sin6_family")); + private static final VarHandle sin6_port = LAYOUT.varHandle(short.class, MemoryLayout.PathElement.groupElement("sin6_port")); + private static final VarHandle sin6_scope_id = LAYOUT.varHandle(int.class, MemoryLayout.PathElement.groupElement("sin6_scope_id")); + private static final VarHandle sin6_flowinfo = LAYOUT.varHandle(int.class, MemoryLayout.PathElement.groupElement("sin6_flowinfo")); + + public static MemorySegment allocate(ResourceScope scope) + { + return MemorySegment.allocateNative(LAYOUT, scope); + } + + public static void set_sin6_addr(MemorySegment sin6, byte[] value) + { + sin6.asSlice(8, 16).asByteBuffer().order(ByteOrder.nativeOrder()).put(value); + } + + public static void set_sin6_family(MemorySegment sin6, short value) + { + sin6_family.set(sin6, value); + } + + public static void set_sin6_port(MemorySegment sin6, short value) + { + sin6_port.set(sin6, value); + } + + public static void set_sin6_scope_id(MemorySegment sin6, int value) + { + sin6_scope_id.set(sin6, value); + } + + public static void set_sin6_flowinfo(MemorySegment sin6, int value) + { + sin6_flowinfo.set(sin6, value); + } + } +} diff --git a/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/macos/sockaddr_macos.java b/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/macos/sockaddr_macos.java new file mode 100644 index 00000000000..9ece997e76c --- /dev/null +++ b/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/macos/sockaddr_macos.java @@ -0,0 +1,163 @@ +// +// ======================================================================== +// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.quic.quiche.panama.jdk.macos; + +import java.lang.invoke.VarHandle; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import jdk.incubator.foreign.MemoryLayout; +import jdk.incubator.foreign.MemorySegment; +import jdk.incubator.foreign.ResourceScope; + +import static jdk.incubator.foreign.CLinker.C_CHAR; +import static jdk.incubator.foreign.CLinker.C_INT; +import static jdk.incubator.foreign.CLinker.C_SHORT; + +public class sockaddr_macos +{ + private static final byte AF_INET = 2; + private static final byte AF_INET6 = 30; + + public static MemorySegment convert(SocketAddress socketAddress, ResourceScope scope) + { + if (!(socketAddress instanceof InetSocketAddress)) + throw new IllegalArgumentException("Expected InetSocketAddress instance, got: " + socketAddress); + InetSocketAddress inetSocketAddress = (InetSocketAddress)socketAddress; + InetAddress address = inetSocketAddress.getAddress(); + if (address instanceof Inet4Address) + { + MemorySegment sin = sockaddr_in.allocate(scope); + sockaddr_in.set_sin_len(sin, (byte)sin.byteSize()); + sockaddr_in.set_sin_family(sin, AF_INET); + sockaddr_in.set_sin_port(sin, (short) inetSocketAddress.getPort()); + sockaddr_in.set_sin_addr(sin, ByteBuffer.wrap(address.getAddress()).getInt()); + return sin; + } + else if (address instanceof Inet6Address) + { + MemorySegment sin6 = sockaddr_in6.allocate(scope); + sockaddr_in6.set_sin6_len(sin6, (byte)sin6.byteSize()); + sockaddr_in6.set_sin6_family(sin6, AF_INET6); + sockaddr_in6.set_sin6_port(sin6, (short) inetSocketAddress.getPort()); + sockaddr_in6.set_sin6_addr(sin6, address.getAddress()); + sockaddr_in6.set_sin6_scope_id(sin6, 0); + sockaddr_in6.set_sin6_flowinfo(sin6, 0); + return sin6; + } + else + { + throw new UnsupportedOperationException("Unsupported InetAddress: " + address); + } + } + + private static class sockaddr_in + { + private static final MemoryLayout LAYOUT = MemoryLayout.structLayout( + C_CHAR.withName("sin_len"), + C_CHAR.withName("sin_family"), + C_SHORT.withName("sin_port"), + C_INT.withName("sin_addr"), + MemoryLayout.sequenceLayout(8, C_CHAR).withName("sin_zero") + ).withName("sockaddr_in"); + + private static final VarHandle sin_len = LAYOUT.varHandle(byte.class, MemoryLayout.PathElement.groupElement("sin_len")); + private static final VarHandle sin_family = LAYOUT.varHandle(byte.class, MemoryLayout.PathElement.groupElement("sin_family")); + private static final VarHandle sin_port = LAYOUT.varHandle(short.class, MemoryLayout.PathElement.groupElement("sin_port")); + private static final VarHandle sin_addr = LAYOUT.varHandle(int.class, MemoryLayout.PathElement.groupElement("sin_addr")); + + public static MemorySegment allocate(ResourceScope scope) + { + return MemorySegment.allocateNative(LAYOUT, scope); + } + + public static void set_sin_family(MemorySegment sin, byte value) + { + sin_family.set(sin, value); + } + + public static void set_sin_len(MemorySegment sin, byte value) + { + sin_len.set(sin, value); + } + + public static void set_sin_port(MemorySegment sin, short value) + { + sin_port.set(sin, value); + } + + public static void set_sin_addr(MemorySegment sin, int value) + { + sin_addr.set(sin, value); + } + } + + private static class sockaddr_in6 + { + private static final MemoryLayout LAYOUT = MemoryLayout.structLayout( + C_CHAR.withName("sin6_len"), + C_CHAR.withName("sin6_family"), + C_SHORT.withName("sin6_port"), + C_INT.withName("sin6_flowinfo"), + MemoryLayout.sequenceLayout(16, C_CHAR).withName("sin6_addr"), + C_INT.withName("sin6_scope_id") + ).withName("sockaddr_in6"); + + private static final VarHandle sin6_len = LAYOUT.varHandle(byte.class, MemoryLayout.PathElement.groupElement("sin6_len")); + private static final VarHandle sin6_family = LAYOUT.varHandle(byte.class, MemoryLayout.PathElement.groupElement("sin6_family")); + private static final VarHandle sin6_port = LAYOUT.varHandle(short.class, MemoryLayout.PathElement.groupElement("sin6_port")); + private static final VarHandle sin6_scope_id = LAYOUT.varHandle(int.class, MemoryLayout.PathElement.groupElement("sin6_scope_id")); + private static final VarHandle sin6_flowinfo = LAYOUT.varHandle(int.class, MemoryLayout.PathElement.groupElement("sin6_flowinfo")); + + public static MemorySegment allocate(ResourceScope scope) + { + return MemorySegment.allocateNative(LAYOUT, scope); + } + + public static void set_sin6_addr(MemorySegment sin6, byte[] value) + { + sin6.asSlice(8, 16).asByteBuffer().order(ByteOrder.nativeOrder()).put(value); + } + + public static void set_sin6_len(MemorySegment sin6, byte value) + { + sin6_len.set(sin6, value); + } + + public static void set_sin6_family(MemorySegment sin6, byte value) + { + sin6_family.set(sin6, value); + } + + public static void set_sin6_port(MemorySegment sin6, short value) + { + sin6_port.set(sin6, value); + } + + public static void set_sin6_scope_id(MemorySegment sin6, int value) + { + sin6_scope_id.set(sin6, value); + } + + public static void set_sin6_flowinfo(MemorySegment sin6, int value) + { + sin6_flowinfo.set(sin6, value); + } + } +} diff --git a/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/sockaddr.java b/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/sockaddr.java index 1f89981c5e7..62c2f7c8e2e 100644 --- a/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/sockaddr.java +++ b/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/sockaddr.java @@ -13,51 +13,28 @@ package org.eclipse.jetty.quic.quiche.panama.jdk; -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.InetSocketAddress; import java.net.SocketAddress; -import java.nio.ByteBuffer; import jdk.incubator.foreign.MemorySegment; import jdk.incubator.foreign.ResourceScope; +import org.eclipse.jetty.quic.quiche.panama.jdk.linux.sockaddr_linux; +import org.eclipse.jetty.quic.quiche.panama.jdk.macos.sockaddr_macos; +import org.eclipse.jetty.quic.quiche.panama.jdk.windows.sockaddr_windows; + +import static org.eclipse.jetty.quic.quiche.panama.jdk.NativeHelper.isLinux; +import static org.eclipse.jetty.quic.quiche.panama.jdk.NativeHelper.isMac; +import static org.eclipse.jetty.quic.quiche.panama.jdk.NativeHelper.isWindows; public class sockaddr { - // TODO: linux-specific constants - private static final short AF_INET = 2; - private static final short AF_INET6 = 10; - public static MemorySegment convert(SocketAddress socketAddress, ResourceScope scope) { - if (!(socketAddress instanceof InetSocketAddress)) - throw new IllegalArgumentException("Expected InetSocketAddress instance, got: " + socketAddress); - InetSocketAddress inetSocketAddress = (InetSocketAddress)socketAddress; - InetAddress address = inetSocketAddress.getAddress(); - if (address instanceof Inet4Address) - { - // TODO: linux-specific implementation - MemorySegment sin = sockaddr_in.allocate(scope); - sockaddr_in.set_sin_family(sin, AF_INET); - sockaddr_in.set_sin_port(sin, (short) inetSocketAddress.getPort()); - sockaddr_in.set_sin_addr(sin, ByteBuffer.wrap(address.getAddress()).getInt()); - return sin; - } - else if (address instanceof Inet6Address) - { - // TODO: linux-specific implementation - MemorySegment sin6 = sockaddr_in6.allocate(scope); - sockaddr_in6.set_sin6_family(sin6, AF_INET6); - sockaddr_in6.set_sin6_port(sin6, (short) inetSocketAddress.getPort()); - sockaddr_in6.set_sin6_addr(sin6, address.getAddress()); - sockaddr_in6.set_sin6_scope_id(sin6, 0); - sockaddr_in6.set_sin6_flowinfo(sin6, 0); - return sin6; - } - else - { - throw new UnsupportedOperationException("Unsupported InetAddress: " + address); - } + if (isLinux()) + return sockaddr_linux.convert(socketAddress, scope); + if (isMac()) + return sockaddr_macos.convert(socketAddress, scope); + if (isWindows()) + return sockaddr_windows.convert(socketAddress, scope); + throw new UnsupportedOperationException("Unsupported OS: " + System.getProperty("os.name")); } } diff --git a/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/sockaddr_in.java b/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/sockaddr_in.java deleted file mode 100644 index 441eacac86a..00000000000 --- a/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/sockaddr_in.java +++ /dev/null @@ -1,61 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.quic.quiche.panama.jdk; - -import java.lang.invoke.VarHandle; - -import jdk.incubator.foreign.GroupLayout; -import jdk.incubator.foreign.MemoryLayout; -import jdk.incubator.foreign.MemorySegment; -import jdk.incubator.foreign.ResourceScope; - -import static jdk.incubator.foreign.CLinker.C_CHAR; -import static jdk.incubator.foreign.CLinker.C_INT; -import static jdk.incubator.foreign.CLinker.C_SHORT; - -class sockaddr_in -{ - private static final MemoryLayout LAYOUT = MemoryLayout.structLayout( - C_SHORT.withName("sin_family"), - C_SHORT.withName("sin_port"), - C_INT.withName("sin_addr"), - MemoryLayout.sequenceLayout(8, C_CHAR).withName("sin_zero") - ).withName("sockaddr_in"); - - private static final VarHandle sin_family = LAYOUT.varHandle(short.class, MemoryLayout.PathElement.groupElement("sin_family")); - private static final VarHandle sin_port = LAYOUT.varHandle(short.class, MemoryLayout.PathElement.groupElement("sin_port")); - private static final VarHandle sin_addr = LAYOUT.varHandle(int.class, MemoryLayout.PathElement.groupElement("sin_addr")); - - public static MemorySegment allocate(ResourceScope scope) - { - return MemorySegment.allocateNative(LAYOUT, scope); - } - - public static void set_sin_family(MemorySegment sin, short value) - { - sin_family.set(sin, value); - } - - public static void set_sin_port(MemorySegment sin, short value) - { - sin_port.set(sin, value); - } - - public static void set_sin_addr(MemorySegment sin, int value) - { - sin_addr.set(sin, value); - } -} - - diff --git a/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/sockaddr_in6.java b/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/sockaddr_in6.java deleted file mode 100644 index 872318b8f58..00000000000 --- a/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/sockaddr_in6.java +++ /dev/null @@ -1,71 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.quic.quiche.panama.jdk; - -import java.lang.invoke.VarHandle; -import java.nio.ByteOrder; - -import jdk.incubator.foreign.MemoryLayout; -import jdk.incubator.foreign.MemorySegment; -import jdk.incubator.foreign.ResourceScope; - -import static jdk.incubator.foreign.CLinker.C_CHAR; -import static jdk.incubator.foreign.CLinker.C_INT; -import static jdk.incubator.foreign.CLinker.C_SHORT; - -class sockaddr_in6 -{ - private static final MemoryLayout LAYOUT = MemoryLayout.structLayout( - C_SHORT.withName("sin6_family"), - C_SHORT.withName("sin6_port"), - C_INT.withName("sin6_flowinfo"), - MemoryLayout.sequenceLayout(16, C_CHAR).withName("sin6_addr"), - C_INT.withName("sin6_scope_id") - ).withName("sockaddr_in6"); - - private static final VarHandle sin6_family = LAYOUT.varHandle(short.class, MemoryLayout.PathElement.groupElement("sin6_family")); - private static final VarHandle sin6_port = LAYOUT.varHandle(short.class, MemoryLayout.PathElement.groupElement("sin6_port")); - private static final VarHandle sin6_scope_id = LAYOUT.varHandle(int.class, MemoryLayout.PathElement.groupElement("sin6_scope_id")); - private static final VarHandle sin6_flowinfo = LAYOUT.varHandle(int.class, MemoryLayout.PathElement.groupElement("sin6_flowinfo")); - - public static MemorySegment allocate(ResourceScope scope) - { - return MemorySegment.allocateNative(LAYOUT, scope); - } - - public static void set_sin6_addr(MemorySegment sin6, byte[] value) - { - sin6.asSlice(8, 16).asByteBuffer().order(ByteOrder.nativeOrder()).put(value); - } - - public static void set_sin6_family(MemorySegment sin6, short value) - { - sin6_family.set(sin6, value); - } - - public static void set_sin6_port(MemorySegment sin6, short value) - { - sin6_port.set(sin6, value); - } - - public static void set_sin6_scope_id(MemorySegment sin6, int value) - { - sin6_scope_id.set(sin6, value); - } - - public static void set_sin6_flowinfo(MemorySegment sin6, int value) - { - sin6_flowinfo.set(sin6, value); - } -} diff --git a/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/windows/sockaddr_windows.java b/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/windows/sockaddr_windows.java new file mode 100644 index 00000000000..6a8aa915a46 --- /dev/null +++ b/jetty-quic/quic-quiche/quic-quiche-panama-jdk/src/main/java/org/eclipse/jetty/quic/quiche/panama/jdk/windows/sockaddr_windows.java @@ -0,0 +1,147 @@ +// +// ======================================================================== +// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.quic.quiche.panama.jdk.windows; + +import java.lang.invoke.VarHandle; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import jdk.incubator.foreign.MemoryLayout; +import jdk.incubator.foreign.MemorySegment; +import jdk.incubator.foreign.ResourceScope; + +import static jdk.incubator.foreign.CLinker.C_CHAR; +import static jdk.incubator.foreign.CLinker.C_INT; +import static jdk.incubator.foreign.CLinker.C_SHORT; + +public class sockaddr_windows +{ + private static final short AF_INET = 2; + private static final short AF_INET6 = 23; + + public static MemorySegment convert(SocketAddress socketAddress, ResourceScope scope) + { + if (!(socketAddress instanceof InetSocketAddress)) + throw new IllegalArgumentException("Expected InetSocketAddress instance, got: " + socketAddress); + InetSocketAddress inetSocketAddress = (InetSocketAddress)socketAddress; + InetAddress address = inetSocketAddress.getAddress(); + if (address instanceof Inet4Address) + { + MemorySegment sin = sockaddr_in.allocate(scope); + sockaddr_in.set_sin_family(sin, AF_INET); + sockaddr_in.set_sin_port(sin, (short) inetSocketAddress.getPort()); + sockaddr_in.set_sin_addr(sin, ByteBuffer.wrap(address.getAddress()).getInt()); + return sin; + } + else if (address instanceof Inet6Address) + { + MemorySegment sin6 = sockaddr_in6.allocate(scope); + sockaddr_in6.set_sin6_family(sin6, AF_INET6); + sockaddr_in6.set_sin6_port(sin6, (short) inetSocketAddress.getPort()); + sockaddr_in6.set_sin6_addr(sin6, address.getAddress()); + sockaddr_in6.set_sin6_scope_id(sin6, 0); + sockaddr_in6.set_sin6_flowinfo(sin6, 0); + return sin6; + } + else + { + throw new UnsupportedOperationException("Unsupported InetAddress: " + address); + } + } + + private static class sockaddr_in + { + private static final MemoryLayout LAYOUT = MemoryLayout.structLayout( + C_SHORT.withName("sin_family"), + C_SHORT.withName("sin_port"), + C_INT.withName("sin_addr"), + MemoryLayout.sequenceLayout(8, C_CHAR).withName("sin_zero") + ).withName("sockaddr_in"); + + private static final VarHandle sin_family = LAYOUT.varHandle(short.class, MemoryLayout.PathElement.groupElement("sin_family")); + private static final VarHandle sin_port = LAYOUT.varHandle(short.class, MemoryLayout.PathElement.groupElement("sin_port")); + private static final VarHandle sin_addr = LAYOUT.varHandle(int.class, MemoryLayout.PathElement.groupElement("sin_addr")); + + public static MemorySegment allocate(ResourceScope scope) + { + return MemorySegment.allocateNative(LAYOUT, scope); + } + + public static void set_sin_family(MemorySegment sin, short value) + { + sin_family.set(sin, value); + } + + public static void set_sin_port(MemorySegment sin, short value) + { + sin_port.set(sin, value); + } + + public static void set_sin_addr(MemorySegment sin, int value) + { + sin_addr.set(sin, value); + } + } + + private static class sockaddr_in6 + { + private static final MemoryLayout LAYOUT = MemoryLayout.structLayout( + C_SHORT.withName("sin6_family"), + C_SHORT.withName("sin6_port"), + C_INT.withName("sin6_flowinfo"), + MemoryLayout.sequenceLayout(16, C_CHAR).withName("sin6_addr"), + C_INT.withName("sin6_scope_id") + ).withName("sockaddr_in6"); + + private static final VarHandle sin6_family = LAYOUT.varHandle(short.class, MemoryLayout.PathElement.groupElement("sin6_family")); + private static final VarHandle sin6_port = LAYOUT.varHandle(short.class, MemoryLayout.PathElement.groupElement("sin6_port")); + private static final VarHandle sin6_scope_id = LAYOUT.varHandle(int.class, MemoryLayout.PathElement.groupElement("sin6_scope_id")); + private static final VarHandle sin6_flowinfo = LAYOUT.varHandle(int.class, MemoryLayout.PathElement.groupElement("sin6_flowinfo")); + + public static MemorySegment allocate(ResourceScope scope) + { + return MemorySegment.allocateNative(LAYOUT, scope); + } + + public static void set_sin6_addr(MemorySegment sin6, byte[] value) + { + sin6.asSlice(8, 16).asByteBuffer().order(ByteOrder.nativeOrder()).put(value); + } + + public static void set_sin6_family(MemorySegment sin6, short value) + { + sin6_family.set(sin6, value); + } + + public static void set_sin6_port(MemorySegment sin6, short value) + { + sin6_port.set(sin6, value); + } + + public static void set_sin6_scope_id(MemorySegment sin6, int value) + { + sin6_scope_id.set(sin6, value); + } + + public static void set_sin6_flowinfo(MemorySegment sin6, int value) + { + sin6_flowinfo.set(sin6, value); + } + } +}