diff --git a/jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign/src/main/java/org/eclipse/jetty/quic/quiche/foreign/ForeignQuicheConnection.java b/jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign/src/main/java/org/eclipse/jetty/quic/quiche/foreign/ForeignQuicheConnection.java
index 9aa018d0efe4..b71ee494c3d7 100644
--- a/jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign/src/main/java/org/eclipse/jetty/quic/quiche/foreign/ForeignQuicheConnection.java
+++ b/jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign/src/main/java/org/eclipse/jetty/quic/quiche/foreign/ForeignQuicheConnection.java
@@ -853,20 +853,21 @@ public int feedClearBytesForStream(long streamId, ByteBuffer buffer, boolean las
throw new IOException("connection was released");
long written;
- if (buffer.isDirect())
- {
- // If the ByteBuffer is direct, it can be used without any copy.
- MemorySegment bufferSegment = MemorySegment.ofBuffer(buffer);
- written = quiche_h.quiche_conn_stream_send(quicheConn, streamId, bufferSegment, buffer.remaining(), last);
- }
- else
+ try (Arena scope = Arena.ofConfined())
{
- // If the ByteBuffer is heap-allocated, it must be copied to native memory.
- try (Arena scope = Arena.ofConfined())
+ MemorySegment outErrorCode = scope.allocate(NativeHelper.C_LONG);
+ if (buffer.isDirect())
{
+ // If the ByteBuffer is direct, it can be used without any copy.
+ MemorySegment bufferSegment = MemorySegment.ofBuffer(buffer);
+ written = quiche_h.quiche_conn_stream_send(quicheConn, streamId, bufferSegment, buffer.remaining(), last, outErrorCode);
+ }
+ else
+ {
+ // If the ByteBuffer is heap-allocated, it must be copied to native memory.
if (buffer.remaining() == 0)
{
- written = quiche_h.quiche_conn_stream_send(quicheConn, streamId, MemorySegment.NULL, 0, last);
+ written = quiche_h.quiche_conn_stream_send(quicheConn, streamId, MemorySegment.NULL, 0, last, outErrorCode);
}
else
{
@@ -874,7 +875,7 @@ public int feedClearBytesForStream(long streamId, ByteBuffer buffer, boolean las
int prevPosition = buffer.position();
bufferSegment.asByteBuffer().put(buffer);
buffer.position(prevPosition);
- written = quiche_h.quiche_conn_stream_send(quicheConn, streamId, bufferSegment, buffer.remaining(), last);
+ written = quiche_h.quiche_conn_stream_send(quicheConn, streamId, bufferSegment, buffer.remaining(), last, outErrorCode);
}
}
}
@@ -904,21 +905,19 @@ public int drainClearBytesForStream(long streamId, ByteBuffer buffer) throws IOE
long read;
try (Arena scope = Arena.ofConfined())
{
+ MemorySegment fin = scope.allocate(NativeHelper.C_CHAR);
+ MemorySegment outErrorCode = scope.allocate(NativeHelper.C_LONG);
if (buffer.isDirect())
{
// If the ByteBuffer is direct, it can be used without any copy.
MemorySegment bufferSegment = MemorySegment.ofBuffer(buffer);
- MemorySegment fin = scope.allocate(NativeHelper.C_CHAR);
- read = quiche_h.quiche_conn_stream_recv(quicheConn, streamId, bufferSegment, buffer.remaining(), fin);
+ read = quiche_h.quiche_conn_stream_recv(quicheConn, streamId, bufferSegment, buffer.remaining(), fin, outErrorCode);
}
else
{
// If the ByteBuffer is heap-allocated, native memory must be copied to it.
MemorySegment bufferSegment = scope.allocate(buffer.remaining());
-
- MemorySegment fin = scope.allocate(NativeHelper.C_CHAR);
- read = quiche_h.quiche_conn_stream_recv(quicheConn, streamId, bufferSegment, buffer.remaining(), fin);
-
+ read = quiche_h.quiche_conn_stream_recv(quicheConn, streamId, bufferSegment, buffer.remaining(), fin, outErrorCode);
if (read > 0)
{
int prevPosition = buffer.position();
diff --git a/jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign/src/main/java/org/eclipse/jetty/quic/quiche/foreign/quiche_h.java b/jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign/src/main/java/org/eclipse/jetty/quic/quiche/foreign/quiche_h.java
index e55229a8a69d..2125ccfe434a 100644
--- a/jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign/src/main/java/org/eclipse/jetty/quic/quiche/foreign/quiche_h.java
+++ b/jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign/src/main/java/org/eclipse/jetty/quic/quiche/foreign/quiche_h.java
@@ -30,7 +30,7 @@
public class quiche_h
{
- private static final String EXPECTED_QUICHE_VERSION = "0.21.0";
+ private static final String EXPECTED_QUICHE_VERSION = "0.22.0";
private static final Logger LOG = LoggerFactory.getLogger(quiche_h.class);
private static class LoggingCallback
@@ -485,6 +485,7 @@ private static class DowncallHandles
C_LONG,
C_POINTER,
C_LONG,
+ C_POINTER,
C_POINTER
));
private static final MethodHandle quiche_conn_stream_send = NativeHelper.downcallHandle(
@@ -495,7 +496,8 @@ private static class DowncallHandles
C_LONG,
C_POINTER,
C_LONG,
- C_BOOL
+ C_BOOL,
+ C_POINTER
));
private static final MethodHandle quiche_conn_stream_priority = NativeHelper.downcallHandle(
"quiche_conn_stream_priority",
@@ -1662,11 +1664,11 @@ public static long quiche_conn_send_quantum_on_path(MemorySegment conn, MemorySe
}
}
- public static long quiche_conn_stream_recv(MemorySegment conn, long stream_id, MemorySegment out, long buf_len, MemorySegment fin)
+ public static long quiche_conn_stream_recv(MemorySegment conn, long stream_id, MemorySegment out, long buf_len, MemorySegment fin, MemorySegment out_error_code)
{
try
{
- return (long)DowncallHandles.quiche_conn_stream_recv.invokeExact(conn, stream_id, out, buf_len, fin);
+ return (long)DowncallHandles.quiche_conn_stream_recv.invokeExact(conn, stream_id, out, buf_len, fin, out_error_code);
}
catch (Throwable x)
{
@@ -1674,11 +1676,11 @@ public static long quiche_conn_stream_recv(MemorySegment conn, long stream_id, M
}
}
- public static long quiche_conn_stream_send(MemorySegment conn, long stream_id, MemorySegment buf, long buf_len, boolean fin)
+ public static long quiche_conn_stream_send(MemorySegment conn, long stream_id, MemorySegment buf, long buf_len, boolean fin, MemorySegment out_error_code)
{
try
{
- return (long)DowncallHandles.quiche_conn_stream_send.invokeExact(conn, stream_id, buf, buf_len, fin);
+ return (long)DowncallHandles.quiche_conn_stream_send.invokeExact(conn, stream_id, buf, buf_len, fin, out_error_code);
}
catch (Throwable x)
{
diff --git a/jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/JnaQuicheConnection.java b/jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/JnaQuicheConnection.java
index b81021957a2d..ba483c9c33a8 100644
--- a/jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/JnaQuicheConnection.java
+++ b/jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/JnaQuicheConnection.java
@@ -693,7 +693,8 @@ public int feedClearBytesForStream(long streamId, ByteBuffer buffer, boolean las
{
if (quicheConn == null)
throw new IOException("connection was released");
- int written = LibQuiche.INSTANCE.quiche_conn_stream_send(quicheConn, new uint64_t(streamId), jnaBuffer(buffer), new size_t(buffer.remaining()), last).intValue();
+ uint64_t_pointer outErrorCode = new uint64_t_pointer();
+ int written = LibQuiche.INSTANCE.quiche_conn_stream_send(quicheConn, new uint64_t(streamId), jnaBuffer(buffer), new size_t(buffer.remaining()), last, outErrorCode).intValue();
if (written == quiche_error.QUICHE_ERR_DONE)
{
int rc = LibQuiche.INSTANCE.quiche_conn_stream_writable(quicheConn, new uint64_t(streamId), new size_t(buffer.remaining()));
@@ -745,7 +746,8 @@ public int drainClearBytesForStream(long streamId, ByteBuffer buffer) throws IOE
if (quicheConn == null)
throw new IOException("connection was released");
bool_pointer fin = new bool_pointer();
- int read = LibQuiche.INSTANCE.quiche_conn_stream_recv(quicheConn, new uint64_t(streamId), buffer, new size_t(buffer.remaining()), fin).intValue();
+ uint64_t_pointer outErrorCode = new uint64_t_pointer();
+ int read = LibQuiche.INSTANCE.quiche_conn_stream_recv(quicheConn, new uint64_t(streamId), buffer, new size_t(buffer.remaining()), fin, outErrorCode).intValue();
if (read == quiche_error.QUICHE_ERR_DONE)
return isStreamFinished(streamId) ? -1 : 0;
if (read == quiche_error.QUICHE_ERR_STREAM_RESET)
diff --git a/jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/LibQuiche.java b/jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/LibQuiche.java
index 98c2a6ee7148..4a71c6a76855 100644
--- a/jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/LibQuiche.java
+++ b/jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/LibQuiche.java
@@ -31,7 +31,7 @@ public interface LibQuiche extends Library
{
// This interface is a translation of the quiche.h header of a specific version.
// It needs to be reviewed each time the native lib version changes.
- String EXPECTED_QUICHE_VERSION = "0.21.0";
+ String EXPECTED_QUICHE_VERSION = "0.22.0";
// The charset used to convert java.lang.String to char * and vice versa.
Charset CHARSET = StandardCharsets.UTF_8;
@@ -540,10 +540,18 @@ int quiche_conn_stream_shutdown(quiche_conn conn, uint64_t stream_id,
void quiche_stream_iter_free(quiche_stream_iter iter);
// Reads contiguous data from a stream.
- ssize_t quiche_conn_stream_recv(quiche_conn conn, uint64_t stream_id, ByteBuffer out, size_t buf_len, bool_pointer fin);
+ // out_error_code is only set when STREAM_STOPPED or STREAM_RESET are returned.
+ // Set to the reported error code associated with STOP_SENDING or STREAM_RESET.
+ ssize_t quiche_conn_stream_recv(quiche_conn conn, uint64_t stream_id,
+ ByteBuffer out, size_t buf_len, bool_pointer fin,
+ uint64_t_pointer out_error_code);
// Writes data to a stream.
- ssize_t quiche_conn_stream_send(quiche_conn conn, uint64_t stream_id, ByteBuffer buf, size_t buf_len, boolean fin);
+ // out_error_code is only set when STREAM_STOPPED or STREAM_RESET are returned.
+ // Set to the reported error code associated with STOP_SENDING or STREAM_RESET.
+ ssize_t quiche_conn_stream_send(quiche_conn conn, uint64_t stream_id,
+ ByteBuffer buf, size_t buf_len, boolean fin,
+ uint64_t_pointer out_error_code);
// Frees the connection object.
void quiche_conn_free(quiche_conn conn);
diff --git a/pom.xml b/pom.xml
index c75f6e496c5c..233b7873695c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -214,7 +214,7 @@
2.2.1.Final
3.5.3.Final
1.1
- 0.21.0
+ 0.22.0
1.2
2.7
1.0.7