quiche icon indicating copy to clipboard operation
quiche copied to clipboard

Can quiche connection and http3 connection be shared between requests?

Open psionic12 opened this issue 4 years ago • 6 comments

There are 3 types of connection involves here: (correct if I'm wrong)

  1. a socket connection, which is use for UDP datagram transport.
  2. a quiche connection, which is use for streaming.
  3. a http3 connection, which is use to send and receive http3 requests and response.

for efficiency purpose, I'm wondering which of these 3 connections can be shared?

For example, I have 2 http3 requests, the headers are the same(same host, same port, etc,), but different bodies.

  1. can I reuse the same socket? (I guess it is a yes).
  2. can I reuse the same quiche connection?
  3. can I reuse the same http3 connection?

psionic12 avatar Mar 02 '21 10:03 psionic12

Yes, HTTP/3 allows multiple requests to be issued in the same connection. You'll need to ensure that the same objects -UDP socket, quiche::Connection, quiche::h3::Connection - are used for related requests.

LPardue avatar Mar 02 '21 13:03 LPardue

Then will the response be the same order as the requests? For example, I sent request 1,2,3 in order, though same connections(same socket, same quiche, same http3 connections), will the responses received in 1,2,3 as well?

And no matter the response is ordered or not, is there any id to illustrate which response if for which request? (The only id I found is scid and dcid for quiche connections, I didn't found things like "request id").

psionic12 avatar Mar 03 '21 02:03 psionic12

Requests are made on client-initiated bidirectional streams, responses come back on the same stream ID that they were made. QUIC offers no ordering guarantees for data delivery between streams.

I strongly recommend you read the QUIC and HTTP/3 specs (https://quicwg.org/ is a good starting point). With a better understanding of the protocol you can then move onto the quiche readme and docs.

LPardue avatar Mar 03 '21 02:03 LPardue

Multiplexing of requests is performed using the QUIC stream abstraction, described in Section 2 of [QUIC-TRANSPORT]. Each request-response pair consumes a single QUIC stream. Streams are independent of each other, so one stream that is blocked or suffers packet loss does not prevent progress on other streams.¶

So in my example, the best practice is to create 3 http3 connections for 3 requests, instead of using only one http3 connection, right?

psionic12 avatar Mar 03 '21 03:03 psionic12

No. The best practice is to use a single connection for all requests to the same host:port. The independence of streams in the same QUIC connection is a feature, not a bug. If you don't want that feature you would be better served with a prior version of HTTP.

LPardue avatar Mar 03 '21 03:03 LPardue

Hi @LPardue, thanks very much for your patient, so the stream id is the "request id" I want, right?

so with same connection I can do this:

int64_t stream_id_1 = quiche_h3_send_request(conn_io->http3,
                                                   conn_io->conn,
                                                   headers_1, 5, true);
// flush and send
int64_t stream_id_2 = quiche_h3_send_request(conn_io->http3,
                                                   conn_io->conn,
                                                   headers_2, 5, true);
// flush and send
int64_t stream_id_3 = quiche_h3_send_request(conn_io->http3,
                                                   conn_io->conn,
                                                   headers_3, 5, true);
// flush and send

then when using

int64_t stream_id = quiche_h3_conn_poll(conn_io->http3,
                                            conn_io->conn,
                                            &ev);

I can identify which request is responsed by checking if (stream_id == stream_id_1), right?

psionic12 avatar Mar 03 '21 03:03 psionic12

Sorry for the delay.

The value returned by quiche_h3_conn_poll is an ID that is context dependent on the event type that was returned. The rust docs give a good overview of this https://docs.quic.tech/quiche/h3/struct.Connection.html#method.poll. In your example, if we assume that the ev turned out to be quiche_h3_event_type::QUICHE_H3_EVENT_HEADERS then yes, it would be a stream ID, and you can compare that to the stream ID's you stored earlier.

LPardue avatar Aug 24 '23 02:08 LPardue