diff --git a/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/ForeignIncubatorQuicheConnection.java b/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/ForeignIncubatorQuicheConnection.java
index c338308c328..31045cf5c57 100644
--- a/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/ForeignIncubatorQuicheConnection.java
+++ b/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/ForeignIncubatorQuicheConnection.java
@@ -838,20 +838,21 @@ public class ForeignIncubatorQuicheConnection extends QuicheConnection
throw new IOException("connection was released");
long written;
- if (buffer.isDirect())
+ try (ResourceScope scope = ResourceScope.newConfinedScope())
{
- // If the ByteBuffer is direct, it can be used without any copy.
- MemorySegment bufferSegment = MemorySegment.ofByteBuffer(buffer);
- written = quiche_h.quiche_conn_stream_send(quicheConn, streamId, bufferSegment.address(), buffer.remaining(), last ? C_TRUE : C_FALSE);
- }
- else
- {
- // If the ByteBuffer is heap-allocated, it must be copied to native memory.
- try (ResourceScope scope = ResourceScope.newConfinedScope())
+ MemorySegment outErrorCode = MemorySegment.allocateNative(CLinker.C_LONG, scope);
+ if (buffer.isDirect())
{
+ // If the ByteBuffer is direct, it can be used without any copy.
+ MemorySegment bufferSegment = MemorySegment.ofByteBuffer(buffer);
+ written = quiche_h.quiche_conn_stream_send(quicheConn, streamId, bufferSegment.address(), buffer.remaining(), last ? C_TRUE : C_FALSE, outErrorCode.address());
+ }
+ 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, MemoryAddress.NULL, 0, last ? C_TRUE : C_FALSE);
+ written = quiche_h.quiche_conn_stream_send(quicheConn, streamId, MemoryAddress.NULL, 0, last ? C_TRUE : C_FALSE, outErrorCode.address());
}
else
{
@@ -859,7 +860,7 @@ public class ForeignIncubatorQuicheConnection extends QuicheConnection
int prevPosition = buffer.position();
bufferSegment.asByteBuffer().put(buffer);
buffer.position(prevPosition);
- written = quiche_h.quiche_conn_stream_send(quicheConn, streamId, bufferSegment.address(), buffer.remaining(), last ? C_TRUE : C_FALSE);
+ written = quiche_h.quiche_conn_stream_send(quicheConn, streamId, bufferSegment.address(), buffer.remaining(), last ? C_TRUE : C_FALSE, outErrorCode.address());
}
}
}
@@ -889,24 +890,25 @@ public class ForeignIncubatorQuicheConnection extends QuicheConnection
long read;
try (ResourceScope scope = ResourceScope.newConfinedScope())
{
+ MemorySegment fin = MemorySegment.allocateNative(CLinker.C_CHAR, scope);
+ MemorySegment outErrorCode = MemorySegment.allocateNative(CLinker.C_LONG, scope);
if (buffer.isDirect())
{
// If the ByteBuffer is direct, it can be used without any copy.
MemorySegment bufferSegment = MemorySegment.ofByteBuffer(buffer);
- MemorySegment fin = MemorySegment.allocateNative(CLinker.C_CHAR, scope);
- read = quiche_h.quiche_conn_stream_recv(quicheConn, streamId, bufferSegment.address(), buffer.remaining(), fin.address());
+ read = quiche_h.quiche_conn_stream_recv(quicheConn, streamId, bufferSegment.address(), buffer.remaining(), fin.address(), outErrorCode.address());
}
else
{
// If the ByteBuffer is heap-allocated, native memory must be copied to it.
MemorySegment bufferSegment = MemorySegment.allocateNative(buffer.remaining(), scope);
-
- MemorySegment fin = MemorySegment.allocateNative(CLinker.C_CHAR, scope);
- read = quiche_h.quiche_conn_stream_recv(quicheConn, streamId, bufferSegment.address(), buffer.remaining(), fin.address());
-
- int prevPosition = buffer.position();
- buffer.put(bufferSegment.asByteBuffer().limit((int)read));
- buffer.position(prevPosition);
+ read = quiche_h.quiche_conn_stream_recv(quicheConn, streamId, bufferSegment.address(), buffer.remaining(), fin.address(), outErrorCode.address());
+ if (read > 0)
+ {
+ int prevPosition = buffer.position();
+ buffer.put(bufferSegment.asByteBuffer().limit((int)read));
+ buffer.position(prevPosition);
+ }
}
}
diff --git a/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/quiche_h.java b/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/quiche_h.java
index 1c7f08db24f..dbe6869f5ac 100644
--- a/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/quiche_h.java
+++ b/jetty-quic/quic-quiche/quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/quiche_h.java
@@ -33,7 +33,7 @@ public class quiche_h
{
// 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.
- private static final String EXPECTED_QUICHE_VERSION = "0.21.0";
+ private static final String EXPECTED_QUICHE_VERSION = "0.22.0";
public static final byte C_FALSE = 0;
public static final byte C_TRUE = 1;
@@ -312,8 +312,8 @@ public class quiche_h
private static final MethodHandle quiche_conn_stream_send$MH = downcallHandle(
"quiche_conn_stream_send",
- "(Ljdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;JB)J",
- FunctionDescriptor.of(C_LONG, C_POINTER, C_LONG, C_POINTER, C_LONG, C_CHAR)
+ "(Ljdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;JBLjdk/incubator/foreign/MemoryAddress;)J",
+ FunctionDescriptor.of(C_LONG, C_POINTER, C_LONG, C_POINTER, C_LONG, C_CHAR, C_POINTER)
);
private static final MethodHandle quiche_conn_stream_writable$MH = downcallHandle(
@@ -324,8 +324,8 @@ public class quiche_h
private static final MethodHandle quiche_conn_stream_recv$MH = downcallHandle(
"quiche_conn_stream_recv",
- "(Ljdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;)J",
- FunctionDescriptor.of(C_LONG, C_POINTER, C_LONG, C_POINTER, C_LONG, C_POINTER)
+ "(Ljdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;)J",
+ FunctionDescriptor.of(C_LONG, C_POINTER, C_LONG, C_POINTER, C_LONG, C_POINTER, C_POINTER)
);
private static final MethodHandle quiche_stream_iter_next$MH = downcallHandle(
@@ -658,11 +658,11 @@ public class quiche_h
}
}
- public static long quiche_conn_stream_recv(MemoryAddress conn, long stream_id, MemoryAddress buf, long buf_len, MemoryAddress fin)
+ public static long quiche_conn_stream_recv(MemoryAddress conn, long stream_id, MemoryAddress buf, long buf_len, MemoryAddress fin, MemoryAddress outErrorCode)
{
try
{
- return (long) quiche_conn_stream_recv$MH.invokeExact(conn, stream_id, buf, buf_len, fin);
+ return (long) quiche_conn_stream_recv$MH.invokeExact(conn, stream_id, buf, buf_len, fin, outErrorCode);
}
catch (Throwable ex)
{
@@ -670,11 +670,11 @@ public class quiche_h
}
}
- public static long quiche_conn_stream_send(MemoryAddress conn, long stream_id, MemoryAddress buf, long buf_len, byte fin)
+ public static long quiche_conn_stream_send(MemoryAddress conn, long stream_id, MemoryAddress buf, long buf_len, byte fin, MemoryAddress outErrorCode)
{
try
{
- return (long) quiche_conn_stream_send$MH.invokeExact(conn, stream_id, buf, buf_len, fin);
+ return (long) quiche_conn_stream_send$MH.invokeExact(conn, stream_id, buf, buf_len, fin, outErrorCode);
}
catch (Throwable ex)
{
diff --git a/jetty-quic/quic-quiche/quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/JnaQuicheConnection.java b/jetty-quic/quic-quiche/quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/JnaQuicheConnection.java
index d5567bb2cfa..ce5e7d670bc 100644
--- a/jetty-quic/quic-quiche/quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/JnaQuicheConnection.java
+++ b/jetty-quic/quic-quiche/quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/JnaQuicheConnection.java
@@ -690,7 +690,8 @@ public class JnaQuicheConnection extends QuicheConnection
{
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()));
@@ -742,7 +743,8 @@ public class JnaQuicheConnection extends QuicheConnection
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 < 0L)
diff --git a/jetty-quic/quic-quiche/quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/LibQuiche.java b/jetty-quic/quic-quiche/quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/LibQuiche.java
index 98c2a6ee714..4a71c6a7685 100644
--- a/jetty-quic/quic-quiche/quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/LibQuiche.java
+++ b/jetty-quic/quic-quiche/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 @@ public interface LibQuiche extends Library
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 77871f182aa..5b5bce6b92d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -265,7 +265,7 @@
2.2.1.Final
3.6.0.Final
1.1
- 0.21.0
+ 0.22.0
1.2
2.7
1.0.7