mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-06 05:22:10 +00:00
MINOR: h3/mux: detect fin on last h3 frame of the stream
This commit is contained in:
parent
8e2a998b17
commit
42bb8aac65
@ -202,6 +202,7 @@ struct qcs {
|
||||
uint64_t bytes; /* number of bytes sent */
|
||||
struct buffer buf; /* transmit buffer, always valid (buf_empty or real buffer) */
|
||||
struct buffer mbuf[QCC_MBUF_CNT];
|
||||
uint64_t left; /* data currently stored in mbuf waiting for send */
|
||||
} tx;
|
||||
struct wait_event *subs; /* recv wait_event the conn_stream associated is waiting on (via qc_subscribe) */
|
||||
struct list list; /* To be used when adding in qcc->send_list or qcc->fctl_lsit */
|
||||
|
7
src/h3.c
7
src/h3.c
@ -517,6 +517,7 @@ static int h3_resp_headers_send(struct qcs *qcs, struct htx *htx)
|
||||
if (!b_quic_enc_int(res, b_data(&headers_buf)))
|
||||
ABORT_NOW();
|
||||
b_add(res, b_data(&headers_buf));
|
||||
qcs->tx.left += 1 + frame_length_size + b_data(&headers_buf);
|
||||
|
||||
ret = 0;
|
||||
blk = htx_get_head_blk(htx);
|
||||
@ -528,6 +529,9 @@ static int h3_resp_headers_send(struct qcs *qcs, struct htx *htx)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((htx->flags & HTX_FL_EOM) && htx_is_empty(htx) && status >= 200)
|
||||
qcs->flags |= QC_SF_FIN_STREAM;
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
@ -585,6 +589,7 @@ static int h3_resp_data_send(struct qcs *qcs, struct buffer *buf, size_t count)
|
||||
htx_cut_data_blk(htx, blk, fsize);
|
||||
|
||||
b_add(res, b_data(&outbuf));
|
||||
qcs->tx.left += b_data(&outbuf);
|
||||
goto new_frame;
|
||||
|
||||
end:
|
||||
@ -648,6 +653,8 @@ size_t h3_snd_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int
|
||||
}
|
||||
}
|
||||
|
||||
if ((htx->flags & HTX_FL_EOM) && htx_is_empty(htx))
|
||||
qcs->flags |= QC_SF_FIN_STREAM;
|
||||
// TODO should I call the mux directly here ?
|
||||
qc_snd_buf(cs, buf, total, flags);
|
||||
|
||||
|
@ -984,6 +984,7 @@ struct qcs *bidi_qcs_new(struct qcc *qcc, uint64_t id)
|
||||
qcs->tx.max_data = qcc->strms[qcs_type].tx.max_data;
|
||||
qcs->tx.buf = BUF_NULL;
|
||||
br_init(qcs->tx.mbuf, sizeof(qcs->tx.mbuf) / sizeof(qcs->tx.mbuf[0]));
|
||||
qcs->tx.left = 0;
|
||||
|
||||
eb64_insert(&qcc->streams_by_id, &qcs->by_id);
|
||||
qcc->strms[qcs_type].nb_streams++;
|
||||
@ -1048,6 +1049,7 @@ struct qcs *luqs_new(struct qcc *qcc)
|
||||
qcs->tx.offset = qcs->tx.bytes = 0;
|
||||
qcs->tx.buf = BUF_NULL;
|
||||
br_init(qcs->tx.mbuf, sizeof(qcs->tx.mbuf) / sizeof(qcs->tx.mbuf[0]));
|
||||
qcs->tx.left = 0;
|
||||
|
||||
qcs->subs = NULL;
|
||||
LIST_INIT(&qcs->list);
|
||||
@ -1089,6 +1091,7 @@ struct qcs *ruqs_new(struct qcc *qcc, uint64_t id)
|
||||
qcs->rx.offset = qcs->rx.bytes = 0;
|
||||
qcs->rx.buf = BUF_NULL;
|
||||
br_init(qcs->tx.mbuf, sizeof(qcs->tx.mbuf) / sizeof(qcs->tx.mbuf[0]));
|
||||
qcs->tx.left = 0;
|
||||
|
||||
qcs->subs = NULL;
|
||||
LIST_INIT(&qcs->list);
|
||||
@ -1448,10 +1451,21 @@ static int qc_process(struct qcc *qcc)
|
||||
for (buf = br_head(qcs->tx.mbuf); b_data(buf); buf = br_del_head(qcs->tx.mbuf)) {
|
||||
if (b_data(buf)) {
|
||||
int ret;
|
||||
ret = qcs_push_frame(qcs, buf, 0, qcs->tx.offset);
|
||||
char fin = 0;
|
||||
|
||||
/* if FIN is activated, ensure the buffer to
|
||||
* send is the last
|
||||
*/
|
||||
if (qcs->flags & QC_SF_FIN_STREAM) {
|
||||
BUG_ON(qcs->tx.left < b_data(buf));
|
||||
fin = !(qcs->tx.left - b_data(buf));
|
||||
}
|
||||
|
||||
ret = qcs_push_frame(qcs, buf, fin, qcs->tx.offset);
|
||||
if (ret <= 0)
|
||||
ABORT_NOW();
|
||||
|
||||
qcs->tx.left -= ret;
|
||||
qcs->tx.offset += ret;
|
||||
qcs->qcc->wait_event.events &= ~SUB_RETRY_SEND;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user