Issue #6728 - QUIC and HTTP/3

- add windows and mac binding support
This commit is contained in:
Ludovic Orban 2021-11-08 17:39:07 +01:00 committed by Simone Bordet
parent eb8444e2c2
commit 7df5bbc61b
7 changed files with 490 additions and 170 deletions

View File

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

View File

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

View File

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

View File

@ -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"));
}
}

View File

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

View File

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

View File

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