The second issue of the hidden stream is more complex and requires some understanding of the server. Effectively, the server does something like this (sudo code, original code in the repo provided):
let conn = endpoint.accept_connection()
print(
"[server] connection accepted: addr=\(conn.remote_address())",
)
print("[server] waiting for bi stream");
let (send_end, recv_end) = conn.accept_bi()
print("[server] awaiting recv")
recv_end.recv(....)
Now if I establish a connection with options.direction = .bidirectional on the client side:
let options = NWProtocolQUIC.Options(alpn: ["demo"])
// Set the initial stream direction.
options.direction = .bidirectional
...
let parameters = NWParameters(quic: options)
let descriptor = NWMultiplexGroup(to: endpoint)
let group = NWConnectionGroup(with: descriptor, using: parameters)
and then in the group state handler, once the connection is ready I make a new stream (same directionality):
group.stateUpdateHandler = { newState in
switch newState {
case .ready:
print("Connected using QUIC!")
let options = NWProtocolQUIC.Options(alpn: ["demo"])
options.direction = .bidirectional
mainConn = group.extract()! // force unwrap
print("new stream made: \(mainConn)")
...
case .failed(let error):
print("main connection failed.")
break
}
}
...
When sending bytes through that new connection from the swift client, on the server side I will get logs like so:
[server] connection accepted: addr=127.0.0.1:53890
[server] waiting for bi stream
[server] awaiting recv
The server will receive the connection, wait for the bidirectional stream to be opened and then await the bytes but the bytes will never come through the newly accepted stream.
I can see the swift client sending bytes and in higher verbosity levels the server IS getting the bytes.
quinn_proto::connection: got Data packet (67 bytes) from 127.0.0.1:56022 using id 8c3bc319a7211707
quinn_proto::connection: got Data packet (67 bytes) from 127.0.0.1:56022 using id 8c3bc319a7211707
but the only way for me start to recving the bytes from the stream accepted on the server and opened on the swift client in the group state handler is to accept the bidirectional stream twice.
print("[server] waiting for bi stream");
let (_, _) = conn.accept_bi()
let (send_end, recv_end) = conn.accept_bi()
I have already investigated with the maintainers of the package I use that is not a weird bug on their end and in higher verbosity levels we can see TWO stream being opened. But on the swift side, as far as I can see we are only establish a single stream and that 'first' stream is not accessible from the NWConnectionGroup at all.
If I don't send bytes that the server never makes to even attempting to recv bytes but I do think this indicates that there is stream being initiated under the hood of the NWConnection and the RFC quit does outline this behavior:
[A stream ID that is used out of order results in all streams of that type with lower-numbered stream IDs also being opened.
](https://www.rfc-editor.org/rfc/rfc9000.html#name-stream-types-and-identifier)
Is there a way for me to increase logging or inspect further where this initial stream is being opened?