uint64_t qpack_blocked_streams;
uint64_t max_field_section_size;
+ uint64_t id_goaway; /* stream ID used for a GOAWAY frame */
+
struct buffer_wait buf_wait; /* wait list for buffer allocations */
/* Stats counters */
struct h3_counters *prx_counters;
return -1;
}
+ /* RFC 9114 5.2. Connection Shutdown
+ *
+ * The GOAWAY frame contains an identifier that
+ * indicates to the receiver the range of requests or pushes that were
+ * or might be processed in this connection. The server sends a client-
+ * initiated bidirectional stream ID; the client sends a push ID.
+ * Requests or pushes with the indicated identifier or greater are
+ * rejected (Section 4.1.1) by the sender of the GOAWAY. This
+ * identifier MAY be zero if no requests or pushes were processed.
+ */
+ if (qcs->id >= h3c->id_goaway)
+ h3c->id_goaway = qcs->id + 4;
+
/* buffer is transferred to the stream connector and set to NULL
* except on stream creation error.
*/
return 1;
}
+/* Generate a GOAWAY frame for <h3c> connection on the control stream.
+ *
+ * Returns 0 on success else non-zero.
+ */
+static int h3_send_goaway(struct h3c *h3c)
+{
+ struct qcs *qcs = h3c->ctrl_strm;
+ struct buffer pos, *res;
+ unsigned char data[3 * QUIC_VARINT_MAX_SIZE];
+ size_t frm_len = quic_int_getsize(h3c->id_goaway);
+
+ if (!qcs)
+ return 1;
+
+ pos = b_make((char *)data, sizeof(data), 0, 0);
+
+ b_quic_enc_int(&pos, H3_FT_GOAWAY);
+ b_quic_enc_int(&pos, frm_len);
+ b_quic_enc_int(&pos, h3c->id_goaway);
+
+ res = mux_get_buf(qcs);
+ if (!res || b_room(res) < b_data(&pos)) {
+ /* Do not try forcefully to emit GOAWAY if no space left. */
+ return 1;
+ }
+
+ b_force_xfer(res, &pos, b_data(&pos));
+
+ return 0;
+}
+
/* Initialize the HTTP/3 context for <qcc> mux.
* Return 1 if succeeded, 0 if not.
*/
h3c->ctrl_strm = NULL;
h3c->err = H3_NO_ERROR;
h3c->flags = 0;
+ h3c->id_goaway = 0;
qcc->ctx = h3c;
h3c->prx_counters =
{
struct h3c *h3c = ctx;
+ /* RFC 9114 5.2. Connection Shutdown
+ *
+ * Even when a connection is not idle, either endpoint can decide to
+ * stop using the connection and initiate a graceful connection close.
+ * Endpoints initiate the graceful shutdown of an HTTP/3 connection by
+ * sending a GOAWAY frame.
+ */
+ h3_send_goaway(h3c);
+
/* RFC 9114 5.2. Connection Shutdown
*
* An endpoint that completes a