uint64_t qpack_blocked_streams;
uint64_t max_field_section_size;
- uint64_t id_goaway; /* stream ID used for a GOAWAY frame */
+ uint64_t id_shut_l; /* GOAWAY ID locally emitted */
struct buffer_wait buf_wait; /* wait list for buffer allocations */
/* Stats counters */
struct ist meth = IST_NULL, path = IST_NULL;
struct ist scheme = IST_NULL, authority = IST_NULL;
struct ist uri;
- uint64_t id_goaway;
int hdr_idx, ret;
int cookie = -1, last_cookie = -1, i;
int relaxed = !!(h3c->qcc->proxy->options2 & PR_O2_REQBUG_OK);
htx_to_buf(htx, &htx_buf);
htx = NULL;
- /* Stream attach may need the new GOAWAY ID, so update it before.
- * Keep a copy of the older value to restore it in case of error.
- */
- id_goaway = h3c->id_goaway;
-
- /* 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;
-
if (qcs_attach_sc(qcs, &htx_buf, fin)) {
- /* Stream not handled, restore old GOAWAY ID. */
- h3c->id_goaway = id_goaway;
len = -1;
goto out;
}
* The endpoint SHOULD continue to do so as more requests or
* pushes arrive.
*/
- if (h3c->flags & H3_CF_GOAWAY_SENT && qcs->id >= h3c->id_goaway &&
+ if (h3c->flags & H3_CF_GOAWAY_SENT && qcs->id >= h3c->id_shut_l &&
quic_stream_is_bidi(qcs->id)) {
/* Local stack should not attached stream on a closed connection. */
BUG_ON(quic_stream_is_local(qcs->qcc, qcs->id));
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);
+ uint64_t id_goaway;
+ size_t frm_len;
size_t xfer;
TRACE_ENTER(H3_EV_H3C_END, h3c->qcc->conn);
+ /* 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.
+ */
+ id_goaway = !conn_is_back(h3c->qcc->conn) ?
+ h3c->qcc->largest_bidi_r : 0;
+
if (!qcs) {
TRACE_ERROR("control stream not initialized", H3_EV_H3C_END, h3c->qcc->conn);
goto err;
pos = b_make((char *)data, sizeof(data), 0, 0);
+ frm_len = quic_int_getsize(id_goaway);
b_quic_enc_int(&pos, H3_FT_GOAWAY, 0);
b_quic_enc_int(&pos, frm_len, 0);
- b_quic_enc_int(&pos, h3c->id_goaway, 0);
+ b_quic_enc_int(&pos, id_goaway, 0);
res = qcc_get_stream_txbuf(qcs, &err, 0);
if (!res || b_room(res) < b_data(&pos) ||
xfer = b_force_xfer(res, &pos, b_data(&pos));
qcc_send_stream(qcs, 1, xfer);
+ h3c->id_shut_l = id_goaway;
h3c->flags |= H3_CF_GOAWAY_SENT;
TRACE_LEAVE(H3_EV_H3C_END, h3c->qcc->conn);
return 0;
/* Consider GOAWAY as sent even if not really the case. This will
* block future stream opening using H3_REQUEST_REJECTED reset.
*/
+ h3c->id_shut_l = id_goaway;
h3c->flags |= H3_CF_GOAWAY_SENT;
TRACE_DEVEL("leaving in error", H3_EV_H3C_END, h3c->qcc->conn);
return 1;
h3c->ctrl_strm = NULL;
h3c->err = 0;
h3c->flags = 0;
- h3c->id_goaway = 0;
+ h3c->id_shut_l = 0;
qcc->ctx = h3c;
h3c->prx_counters = qc_counters(qcc->conn->target, &h3_stats_module);