I was currently testing my quiche based node.js webtransport plugin, against node.js quic implementation.
During the test I saw: F0517 05:33:10.985518 17324 quic_stream.cc:818] quic_bug_10586_3: Fin already buffered, or RESET_STREAM_AT sent
I hunted down the cause and I can mitigate my own code. But the pattern is probably an issue also for other quiche-based implementations,
It works as follows: 1.) quiche is running the server 2.) node.js is the quic is the client.
3.) I during my frist test I passed aheader when creating the bidrectional stream for the session, which automatically sends a fin in the control stream and so WebTransportHttp3::OnConnectStreamFinReceived is called. This immediately sends a fin on the control stream.
4.) The parsing of the initial body is inflight and does not know about fin, so that calls to size_t QuicSpdyStream::WriteHeaders or similar calls of QuicSpdyStream cause quic_bug_10586_3.
My lib is derived partially from libquiche test, though the issue is present in:
|
void QuicSimpleServerStream::SendResponse() { |
|
void QuicSimpleServerStream::SendErrorResponse(int resp_code) { |
etc. and may be in other quiche based code. (I do not know if envoy may be affected).
Please look at my repo at the commit: fails-components/webtransport@ccc15b5 it mitigates the issue, and I would suggest that the examples in the quiche repo are updated.
Steps to reproduce: 1.) Build current (as of mid may, but should still work) node.js main (I did it on windows and use the PR quic-issue-63216 nodejs/node#63230, but I do not think it matters) 2.) Connect to a webtransport endpoint and path on a quiche based server, e.g. with something like:
import { connect } from 'node:quic'
import { isIP } from 'node:net'
function(host, port, path) {
if (typeof port === 'undefined') port = 443
/** @type {import('../session.js').HttpClient} */
const quicOptions = {
alpn: 'h3', // it is the default,
application: {
enableConnectProtocol: true, // needed to start a webtransport session
enableDatagrams: true,
maxStreamWindow: 6 * 1024 * 1024,
maxWindow: 15 * 1024 * 1024
// I am wondering, how certificates are verified.
},
transportParams: {
initialMaxStreamDataBidiLocal: 100,
initialMaxStreamDataBidiRemote: 100,
initialMaxStreamDataUni: 100,
initialMaxData: 15 * 1024 * 1024, // or something else
initialMaxStreamsBidi: 100,
initialMaxStreamsUni: 100,
maxDatagramFrameSize: 1200 // required to start a webtransport session
}
}
if (!isIP(host)) {
quicOptions.servername = host
}
const clientInt = connect(host + ':' + port, quicOptions)
console.log('tried to connect to', host + ':' + port)
let connected = false
clientInt
.then(async (session) => {
console.log('http3 client created')
session.onsessionticket = (ticket) => {
console.log('ticket', ticket)
}
await session.opened
console.log('http3 client connected')
let headersReceivedResolve
const headersReceivedProm = new Promise((resolve, reject) => {
headersReceivedResolve = resolve
})
session
.createBidirectionalStream({
headers: { /* this is important as it immediately sends a fin */
':method': 'CONNECT',
':scheme': 'https',
// this one depends on draft, draft14 says "webtransport", draft15 says "webtransport-h3"
':protocol': 'webtransport',
':path': path,
':authority': host + ':' + port
},
onheaders(headers) {
headersReceivedResolve(headers)
}
})
.then((stream) => {
console.log('session established')
})
.catch((error) => {
console.log('Error creating sessionstream')
throw error
})
})
.catch((error) => {
connected = false
console.log('http3 connection fail', error)
})
}
Note that this is untested code I distilled from my code inside a bigger framework, though you should be able to build code to trigger the event. The path should point to a webtransport endpoint.
If this is applied to an implementation that did not mitigate the issue, you can trigger the quic bug and crash the server. (Note I have this issue before using another way, and the team said I should file it here so that it may be fixed.)
I was currently testing my quiche based node.js webtransport plugin, against node.js quic implementation.
During the test I saw: F0517 05:33:10.985518 17324 quic_stream.cc:818] quic_bug_10586_3: Fin already buffered, or RESET_STREAM_AT sent
I hunted down the cause and I can mitigate my own code. But the pattern is probably an issue also for other quiche-based implementations,
It works as follows: 1.) quiche is running the server 2.) node.js is the quic is the client.
3.) I during my frist test I passed aheader when creating the bidrectional stream for the session, which automatically sends a fin in the control stream and so WebTransportHttp3::OnConnectStreamFinReceived is called. This immediately sends a fin on the control stream.
4.) The parsing of the initial body is inflight and does not know about fin, so that calls to size_t QuicSpdyStream::WriteHeaders or similar calls of QuicSpdyStream cause quic_bug_10586_3.
My lib is derived partially from libquiche test, though the issue is present in:
quiche/quiche/quic/tools/quic_simple_server_stream.cc
Line 164 in ce53d30
quiche/quiche/quic/tools/quic_simple_server_stream.cc
Line 417 in ce53d30
Please look at my repo at the commit: fails-components/webtransport@ccc15b5 it mitigates the issue, and I would suggest that the examples in the quiche repo are updated.
Steps to reproduce: 1.) Build current (as of mid may, but should still work) node.js main (I did it on windows and use the PR quic-issue-63216 nodejs/node#63230, but I do not think it matters) 2.) Connect to a webtransport endpoint and path on a quiche based server, e.g. with something like:
import { connect } from 'node:quic'
import { isIP } from 'node:net'
function(host, port, path) {
if (typeof port === 'undefined') port = 443
/** @type {import('../session.js').HttpClient} */
}
Note that this is untested code I distilled from my code inside a bigger framework, though you should be able to build code to trigger the event. The path should point to a webtransport endpoint.
If this is applied to an implementation that did not mitigate the issue, you can trigger the quic bug and crash the server. (Note I have this issue before using another way, and the team said I should file it here so that it may be fixed.)