#11656 fix quiche_stats and quiche_transport_params mapping

Signed-off-by: Ludovic Orban <lorban@bitronix.be>
This commit is contained in:
Ludovic Orban 2024-04-17 15:03:40 +02:00
parent 3d4f8fabad
commit 646e68dde9
6 changed files with 143 additions and 68 deletions

View File

@ -54,7 +54,7 @@ public class ForeignIncubatorQuicheConnection extends QuicheConnection
private ResourceScope scope;
private MemorySegment sendInfo;
private MemorySegment recvInfo;
private MemorySegment stats;
private MemorySegment transportParams;
private MemorySegment pathStats;
private ForeignIncubatorQuicheConnection(MemoryAddress quicheConn, MemoryAddress quicheConfig, ResourceScope scope)
@ -64,7 +64,7 @@ public class ForeignIncubatorQuicheConnection extends QuicheConnection
this.scope = scope;
this.sendInfo = quiche_send_info.allocate(scope);
this.recvInfo = quiche_recv_info.allocate(scope);
this.stats = quiche_stats.allocate(scope);
this.transportParams = quiche_transport_params.allocate(scope);
this.pathStats = quiche_path_stats.allocate(scope);
}
@ -757,7 +757,7 @@ public class ForeignIncubatorQuicheConnection extends QuicheConnection
scope = null;
sendInfo = null;
recvInfo = null;
stats = null;
transportParams = null;
pathStats = null;
}
}
@ -780,8 +780,8 @@ public class ForeignIncubatorQuicheConnection extends QuicheConnection
{
if (quicheConn == null)
throw new IllegalStateException("connection was released");
quiche_h.quiche_conn_stats(quicheConn, stats.address());
return (int)quiche_stats.get_peer_initial_max_streams_bidi(stats);
quiche_h.quiche_conn_peer_transport_params(quicheConn, transportParams.address());
return (int)quiche_transport_params.get_peer_initial_max_streams_bidi(transportParams);
}
}

View File

@ -280,6 +280,12 @@ public class quiche_h
FunctionDescriptor.ofVoid(C_POINTER, C_POINTER)
);
private static final MethodHandle quiche_conn_peer_transport_params$MH = downcallHandle(
"quiche_conn_peer_transport_params",
"(Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;)B",
FunctionDescriptor.of(C_CHAR, C_POINTER, C_POINTER)
);
private static final MethodHandle quiche_conn_path_stats$MH = downcallHandle(
"quiche_conn_path_stats",
"(Ljdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;)I",
@ -832,6 +838,18 @@ public class quiche_h
}
}
public static byte quiche_conn_peer_transport_params(MemoryAddress conn, MemoryAddress transportParams)
{
try
{
return (byte)quiche_conn_peer_transport_params$MH.invokeExact(conn, transportParams);
}
catch (Throwable ex)
{
throw new AssertionError("should not reach here", ex);
}
}
public static int quiche_conn_path_stats(MemoryAddress conn, long idx, MemoryAddress stats)
{
try

View File

@ -13,13 +13,10 @@
package org.eclipse.jetty.quic.quiche.foreign.incubator;
import java.lang.invoke.VarHandle;
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_LONG;
public class quiche_stats
@ -34,20 +31,10 @@ public class quiche_stats
C_LONG.withName("lost_bytes"),
C_LONG.withName("stream_retrans_bytes"),
C_LONG.withName("paths_count"),
C_LONG.withName("peer_max_idle_timeout"),
C_LONG.withName("peer_max_udp_payload_size"),
C_LONG.withName("peer_initial_max_data"),
C_LONG.withName("peer_initial_max_stream_data_bidi_local"),
C_LONG.withName("peer_initial_max_stream_data_bidi_remote"),
C_LONG.withName("peer_initial_max_stream_data_uni"),
C_LONG.withName("peer_initial_max_streams_bidi"),
C_LONG.withName("peer_initial_max_streams_uni"),
C_LONG.withName("peer_ack_delay_exponent"),
C_LONG.withName("peer_max_ack_delay"),
C_CHAR.withName("peer_disable_active_migration"),
MemoryLayout.paddingLayout(56),
C_LONG.withName("peer_active_conn_id_limit"),
C_LONG.withName("peer_max_datagram_frame_size")
C_LONG.withName("reset_stream_count_local"),
C_LONG.withName("stopped_stream_count_local"),
C_LONG.withName("reset_stream_count_remote"),
C_LONG.withName("stopped_stream_count_remote")
);
public static MemorySegment allocate(ResourceScope scope)
@ -55,10 +42,4 @@ public class quiche_stats
return MemorySegment.allocateNative(LAYOUT, scope);
}
private static final VarHandle peer_initial_max_streams_bidi = LAYOUT.varHandle(long.class, MemoryLayout.PathElement.groupElement("peer_initial_max_streams_bidi"));
public static long get_peer_initial_max_streams_bidi(MemorySegment stats)
{
return (long)peer_initial_max_streams_bidi.get(stats);
}
}

View File

@ -0,0 +1,55 @@
//
// ========================================================================
// Copyright (c) 1995 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.foreign.incubator;
import java.lang.invoke.VarHandle;
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_LONG;
public class quiche_transport_params
{
private static final MemoryLayout LAYOUT = MemoryLayout.structLayout(
C_LONG.withName("peer_max_idle_timeout"),
C_LONG.withName("peer_max_udp_payload_size"),
C_LONG.withName("peer_initial_max_data"),
C_LONG.withName("peer_initial_max_stream_data_bidi_local"),
C_LONG.withName("peer_initial_max_stream_data_bidi_remote"),
C_LONG.withName("peer_initial_max_stream_data_uni"),
C_LONG.withName("peer_initial_max_streams_bidi"),
C_LONG.withName("peer_initial_max_streams_uni"),
C_LONG.withName("peer_ack_delay_exponent"),
C_LONG.withName("peer_max_ack_delay"),
C_CHAR.withName("peer_disable_active_migration"),
MemoryLayout.paddingLayout(56),
C_LONG.withName("peer_active_conn_id_limit"),
C_LONG.withName("peer_max_datagram_frame_size")
);
public static MemorySegment allocate(ResourceScope scope)
{
return MemorySegment.allocateNative(LAYOUT, scope);
}
private static final VarHandle peer_initial_max_streams_bidi = LAYOUT.varHandle(long.class, MemoryLayout.PathElement.groupElement("peer_initial_max_streams_bidi"));
public static long get_peer_initial_max_streams_bidi(MemorySegment stats)
{
return (long)peer_initial_max_streams_bidi.get(stats);
}
}

View File

@ -23,8 +23,8 @@ import java.util.ArrayList;
import java.util.List;
import org.eclipse.jetty.quic.quiche.Quiche;
import org.eclipse.jetty.quic.quiche.Quiche.quiche_error;
import org.eclipse.jetty.quic.quiche.Quiche.quic_error;
import org.eclipse.jetty.quic.quiche.Quiche.quiche_error;
import org.eclipse.jetty.quic.quiche.QuicheConfig;
import org.eclipse.jetty.quic.quiche.QuicheConnection;
import org.eclipse.jetty.util.BufferUtil;
@ -632,9 +632,9 @@ public class JnaQuicheConnection extends QuicheConnection
{
if (quicheConn == null)
throw new IllegalStateException("connection was released");
LibQuiche.quiche_stats stats = new LibQuiche.quiche_stats();
LibQuiche.INSTANCE.quiche_conn_stats(quicheConn, stats);
return stats.peer_initial_max_streams_bidi.intValue();
LibQuiche.quiche_transport_params params = new LibQuiche.quiche_transport_params();
LibQuiche.INSTANCE.quiche_conn_peer_transport_params(quicheConn, params);
return params.peer_initial_max_streams_bidi.intValue();
}
}

View File

@ -148,43 +148,14 @@ public interface LibQuiche extends Library
}
@Structure.FieldOrder({
"recv", "sent", "lost", "retrans", "sent_bytes", "recv_bytes", "lost_bytes",
"stream_retrans_bytes", "paths_count", "peer_max_idle_timeout",
"peer_max_udp_payload_size", "peer_initial_max_data", "peer_initial_max_stream_data_bidi_local",
"peer_initial_max_stream_data_bidi_remote", "peer_initial_max_stream_data_uni",
"peer_initial_max_streams_bidi", "peer_initial_max_streams_uni", "peer_ack_delay_exponent",
"peer_max_ack_delay", "peer_disable_active_migration", "peer_active_conn_id_limit",
"peer_max_idle_timeout", "peer_max_udp_payload_size", "peer_initial_max_data",
"peer_initial_max_stream_data_bidi_local", "peer_initial_max_stream_data_bidi_remote",
"peer_initial_max_stream_data_uni", "peer_initial_max_streams_bidi", "peer_initial_max_streams_uni",
"peer_ack_delay_exponent", "peer_max_ack_delay", "peer_disable_active_migration", "peer_active_conn_id_limit",
"peer_max_datagram_frame_size"
})
class quiche_stats extends Structure
class quiche_transport_params extends Structure
{
// The number of QUIC packets received on this connection.
public size_t recv;
// The number of QUIC packets sent on this connection.
public size_t sent;
// The number of QUIC packets that were lost.
public size_t lost;
// The number of sent QUIC packets with retranmitted data.
public size_t retrans;
// The number of sent bytes.
public uint64_t sent_bytes;
// The number of received bytes.
public uint64_t recv_bytes;
// The number of bytes lost.
public uint64_t lost_bytes;
// The number of stream bytes retransmitted.
public uint64_t stream_retrans_bytes;
// The number of known paths for the connection.
public size_t paths_count;
// The maximum idle timeout.
public uint64_t peer_max_idle_timeout;
@ -225,6 +196,52 @@ public interface LibQuiche extends Library
public ssize_t peer_max_datagram_frame_size;
}
@Structure.FieldOrder({
"recv", "sent", "lost", "retrans", "sent_bytes", "recv_bytes", "lost_bytes", "stream_retrans_bytes", "paths_count",
"reset_stream_count_local", "stopped_stream_count_local", "reset_stream_count_remote", "stopped_stream_count_remote"
})
class quiche_stats extends Structure
{
// The number of QUIC packets received on this connection.
public size_t recv;
// The number of QUIC packets sent on this connection.
public size_t sent;
// The number of QUIC packets that were lost.
public size_t lost;
// The number of sent QUIC packets with retransmitted data.
public size_t retrans;
// The number of sent bytes.
public uint64_t sent_bytes;
// The number of received bytes.
public uint64_t recv_bytes;
// The number of bytes lost.
public uint64_t lost_bytes;
// The number of stream bytes retransmitted.
public uint64_t stream_retrans_bytes;
// The number of known paths for the connection.
public size_t paths_count;
// The number of streams reset by local.
public uint64_t reset_stream_count_local;
// The number of streams stopped by local.
public uint64_t stopped_stream_count_local;
// The number of streams reset by remote.
public uint64_t reset_stream_count_remote;
// The number of streams stopped by remote.
public uint64_t stopped_stream_count_remote;
}
@Structure.FieldOrder({
"local_addr", "local_addr_len", "peer_addr", "peer_addr_len",
"validation_state", "active", "recv", "sent", "lost", "retrans",
@ -373,6 +390,10 @@ public interface LibQuiche extends Library
// field of `quiche_stats`).
int quiche_conn_path_stats(quiche_conn conn, size_t idx, quiche_path_stats out);
// Returns the peer's transport parameters in |out|. Returns false if we have
// not yet processed the peer's transport parameters.
boolean quiche_conn_peer_transport_params(quiche_conn conn, quiche_transport_params out);
// Returns whether or not this is a server-side connection.
boolean quiche_conn_is_server(quiche_conn conn);
@ -381,8 +402,8 @@ public interface LibQuiche extends Library
// Schedule an ack-eliciting packet on the specified path.
ssize_t quiche_conn_send_ack_eliciting_on_path(quiche_conn conn,
sockaddr local, size_t local_len,
sockaddr peer, size_t peer_len);
sockaddr local, size_t local_len,
sockaddr peer, size_t peer_len);
@Structure.FieldOrder({"from", "from_len", "to", "to_len", "at"})
class quiche_send_info extends Structure