Skip to content

Commit dccd5ae

Browse files
committed
TMP
1 parent f5459ae commit dccd5ae

File tree

4 files changed

+75
-16
lines changed

4 files changed

+75
-16
lines changed

include/haproxy/quic_conn.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ void quic_set_connection_close(struct quic_conn *qc, const struct quic_err err);
163163
void quic_set_tls_alert(struct quic_conn *qc, int alert);
164164
int quic_set_app_ops(struct quic_conn *qc, const unsigned char *alpn, size_t alpn_len);
165165
int qc_check_dcid(struct quic_conn *qc, unsigned char *dcid, size_t dcid_len);
166-
int qc_send_mux(struct quic_conn *qc, struct list *frms);
166+
enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms, int max_pkts);
167167

168168
void qc_notify_err(struct quic_conn *qc);
169169
int qc_notify_send(struct quic_conn *qc);

include/haproxy/quic_tx-t.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,10 @@ enum qc_build_pkt_err {
6464
QC_BUILD_PKT_ERR_BUFROOM, /* no more room in input buf or congestion window */
6565
};
6666

67+
enum quic_tx_err {
68+
QUIC_TX_ERR_NONE,
69+
QUIC_TX_ERR_AGAIN,
70+
QUIC_TX_ERR_FATAL,
71+
};
72+
6773
#endif /* _HAPROXY_TX_T_H */

src/mux_quic.c

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <haproxy/quic_sock.h>
2323
#include <haproxy/quic_stream.h>
2424
#include <haproxy/quic_tp-t.h>
25+
#include <haproxy/quic_tx-t.h>
2526
#include <haproxy/session.h>
2627
#include <haproxy/ssl_sock-t.h>
2728
#include <haproxy/stconn.h>
@@ -388,6 +389,13 @@ static void qcc_refresh_timeout(struct qcc *qcc)
388389

389390
static void qcc_wakeup(struct qcc *qcc)
390391
{
392+
HA_ATOMIC_AND(&qcc->wait_event.tasklet->state, ~TASK_F_USR1);
393+
tasklet_wakeup(qcc->wait_event.tasklet);
394+
}
395+
396+
static void qcc_wakeup_pacing(struct qcc *qcc)
397+
{
398+
HA_ATOMIC_OR(&qcc->wait_event.tasklet->state, TASK_F_USR1);
391399
tasklet_wakeup(qcc->wait_event.tasklet);
392400
}
393401

@@ -2076,36 +2084,42 @@ static int qcc_subscribe_send(struct qcc *qcc)
20762084
*
20772085
* Returns 0 if all data sent with success else non-zero.
20782086
*/
2079-
static int qcc_send_frames(struct qcc *qcc, struct list *frms)
2087+
static int qcc_send_frames(struct qcc *qcc, struct list *frms, int strm_content)
20802088
{
2089+
enum quic_tx_err ret;
2090+
int max_burst = strm_content ? global.tune.quic_frontend_max_tx_burst : 0;
2091+
20812092
TRACE_ENTER(QMUX_EV_QCC_SEND, qcc->conn);
20822093

20832094
if (LIST_ISEMPTY(frms)) {
20842095
TRACE_DEVEL("leaving on no frame to send", QMUX_EV_QCC_SEND, qcc->conn);
2085-
return 1;
2096+
return -1;
20862097
}
20872098

2088-
if (!qc_send_mux(qcc->conn->handle.qc, frms)) {
2099+
ret = qc_send_mux(qcc->conn->handle.qc, frms, max_burst);
2100+
if (ret == QUIC_TX_ERR_FATAL) {
20892101
TRACE_DEVEL("error on sending", QMUX_EV_QCC_SEND, qcc->conn);
20902102
qcc_subscribe_send(qcc);
20912103
goto err;
20922104
}
20932105

2106+
BUG_ON(ret == QUIC_TX_ERR_AGAIN && !max_burst);
2107+
20942108
/* If there is frames left at this stage, transport layer is blocked.
20952109
* Subscribe on it to retry later.
20962110
*/
2097-
if (!LIST_ISEMPTY(frms)) {
2111+
if (!LIST_ISEMPTY(frms) && ret != QUIC_TX_ERR_AGAIN) {
20982112
TRACE_DEVEL("remaining frames to send", QMUX_EV_QCC_SEND, qcc->conn);
20992113
qcc_subscribe_send(qcc);
21002114
goto err;
21012115
}
21022116

21032117
TRACE_LEAVE(QMUX_EV_QCC_SEND, qcc->conn);
2104-
return 0;
2118+
return ret == QUIC_TX_ERR_AGAIN ? 1 : 0;
21052119

21062120
err:
21072121
TRACE_DEVEL("leaving on error", QMUX_EV_QCC_SEND, qcc->conn);
2108-
return 1;
2122+
return -1;
21092123
}
21102124

21112125
/* Emit a RESET_STREAM on <qcs>.
@@ -2130,7 +2144,7 @@ static int qcs_send_reset(struct qcs *qcs)
21302144
frm->reset_stream.final_size = qcs->tx.fc.off_real;
21312145

21322146
LIST_APPEND(&frms, &frm->list);
2133-
if (qcc_send_frames(qcs->qcc, &frms)) {
2147+
if (qcc_send_frames(qcs->qcc, &frms, 0)) {
21342148
if (!LIST_ISEMPTY(&frms))
21352149
qc_frm_free(qcs->qcc->conn->handle.qc, &frm);
21362150
TRACE_DEVEL("cannot send RESET_STREAM", QMUX_EV_QCS_SEND, qcs->qcc->conn, qcs);
@@ -2181,7 +2195,7 @@ static int qcs_send_stop_sending(struct qcs *qcs)
21812195
frm->stop_sending.app_error_code = qcs->err;
21822196

21832197
LIST_APPEND(&frms, &frm->list);
2184-
if (qcc_send_frames(qcs->qcc, &frms)) {
2198+
if (qcc_send_frames(qcs->qcc, &frms, 0)) {
21852199
if (!LIST_ISEMPTY(&frms))
21862200
qc_frm_free(qcc->conn->handle.qc, &frm);
21872201
TRACE_DEVEL("cannot send STOP_SENDING", QMUX_EV_QCS_SEND, qcs->qcc->conn, qcs);
@@ -2286,7 +2300,7 @@ static int qcc_io_send(struct qcc *qcc)
22862300
}
22872301

22882302
if (!LIST_ISEMPTY(&qcc->lfctl.frms)) {
2289-
if (qcc_send_frames(qcc, &qcc->lfctl.frms)) {
2303+
if (qcc_send_frames(qcc, &qcc->lfctl.frms, 0)) {
22902304
TRACE_DEVEL("flow-control frames rejected by transport, aborting send", QMUX_EV_QCC_SEND, qcc->conn);
22912305
goto out;
22922306
}
@@ -2365,7 +2379,7 @@ static int qcc_io_send(struct qcc *qcc)
23652379
/* Retry sending until no frame to send, data rejected or connection
23662380
* flow-control limit reached.
23672381
*/
2368-
while (qcc_send_frames(qcc, &qcc->tx.frms) == 0 && !qfctl_rblocked(&qcc->tx.fc)) {
2382+
while ((ret = qcc_send_frames(qcc, &qcc->tx.frms, 1)) == 0 && !qfctl_rblocked(&qcc->tx.fc)) {
23692383
window_conn = qfctl_rcap(&qcc->tx.fc);
23702384
resent = 0;
23712385

@@ -2397,7 +2411,10 @@ static int qcc_io_send(struct qcc *qcc)
23972411

23982412
sent_done:
23992413
/* Deallocate frames that the transport layer has rejected. */
2400-
if (!LIST_ISEMPTY(&qcc->tx.frms)) {
2414+
if (ret == 1) {
2415+
qcc_wakeup_pacing(qcc);
2416+
}
2417+
else if (!LIST_ISEMPTY(&qcc->tx.frms)) {
24012418
struct quic_frame *frm, *frm2;
24022419

24032420
list_for_each_entry_safe(frm, frm2, &qcc->tx.frms, list)
@@ -2751,12 +2768,38 @@ static void qcc_release(struct qcc *qcc)
27512768
TRACE_LEAVE(QMUX_EV_QCC_END);
27522769
}
27532770

2771+
static int qcc_purge_sending(struct qcc *qcc)
2772+
{
2773+
int ret;
2774+
2775+
//fprintf(stderr, "%s\n", __func__);
2776+
ret = qcc_send_frames(qcc, &qcc->tx.frms, 1);
2777+
if (ret > 0) {
2778+
qcc_wakeup_pacing(qcc);
2779+
return 1;
2780+
}
2781+
2782+
return 0;
2783+
}
2784+
27542785
struct task *qcc_io_cb(struct task *t, void *ctx, unsigned int status)
27552786
{
27562787
struct qcc *qcc = ctx;
27572788

27582789
TRACE_ENTER(QMUX_EV_QCC_WAKE, qcc->conn);
27592790

2791+
if (status & TASK_F_USR1) {
2792+
qcc_purge_sending(qcc);
2793+
return NULL;
2794+
}
2795+
else {
2796+
while (!LIST_ISEMPTY(&qcc->tx.frms)) {
2797+
struct quic_frame *frm = LIST_ELEM(qcc->tx.frms.n, struct quic_frame *, list);
2798+
qc_frm_free(qcc->conn->handle.qc, &frm);
2799+
}
2800+
LIST_INIT(&qcc->tx.frms);
2801+
}
2802+
27602803
if (!(qcc->wait_event.events & SUB_RETRY_SEND))
27612804
qcc_io_send(qcc);
27622805

src/quic_tx.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -468,18 +468,20 @@ int qc_purge_txbuf(struct quic_conn *qc, struct buffer *buf)
468468
*
469469
* Returns the result from qc_send() function.
470470
*/
471-
int qc_send_mux(struct quic_conn *qc, struct list *frms)
471+
enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms,
472+
int max_dgram)
472473
{
473474
struct list send_list = LIST_HEAD_INIT(send_list);
474-
int ret;
475+
enum quic_tx_err ret = QUIC_TX_ERR_NONE;
476+
int max = max_dgram;
475477

476478
TRACE_ENTER(QUIC_EV_CONN_TXPKT, qc);
477479
BUG_ON(qc->mux_state != QC_MUX_READY); /* Only MUX can uses this function so it must be ready. */
478480

479481
if (qc->conn->flags & CO_FL_SOCK_WR_SH) {
480482
qc->conn->flags |= CO_FL_ERROR | CO_FL_SOCK_RD_SH;
481483
TRACE_DEVEL("connection on error", QUIC_EV_CONN_TXPKT, qc);
482-
return 0;
484+
return QUIC_TX_ERR_FATAL;
483485
}
484486

485487
/* Try to send post handshake frames first unless on 0-RTT. */
@@ -492,7 +494,15 @@ int qc_send_mux(struct quic_conn *qc, struct list *frms)
492494

493495
TRACE_STATE("preparing data (from MUX)", QUIC_EV_CONN_TXPKT, qc);
494496
qel_register_send(&send_list, qc->ael, frms);
495-
ret = qc_send(qc, 0, &send_list, NULL);
497+
if (!qc_send(qc, 0, &send_list, max_dgram ? &max : NULL)) {
498+
ret = QUIC_TX_ERR_FATAL;
499+
ABORT_NOW();
500+
}
501+
502+
if (max_dgram && !max) {
503+
ret = QUIC_TX_ERR_AGAIN;
504+
//ABORT_NOW();
505+
}
496506

497507
TRACE_LEAVE(QUIC_EV_CONN_TXPKT, qc);
498508
return ret;

0 commit comments

Comments
 (0)