const struct quic_transport_params *xprt_qstrm_lparams(const void *context);
const struct quic_transport_params *xprt_qstrm_rparams(const void *context);
+struct buffer *xprt_qstrm_rxbuf(const void *context);
+
#endif /* _HAPROXY_XPRT_QSTRM_H */
}
if (!conn_is_quic(conn)) {
+ struct buffer *xprt_buf;
+
qcc->tx.qstrm_buf = BUF_NULL;
b_alloc(&qcc->tx.qstrm_buf, DB_MUX_TX);
if (!b_size(&qcc->tx.qstrm_buf)) {
TRACE_ERROR("rx qstrm buf alloc failure", QMUX_EV_QCC_NEW);
goto err;
}
+
+ /* Retrieve data if xprt read too much */
+ xprt_buf = xprt_qstrm_rxbuf(conn->xprt_ctx);
+ if (unlikely(b_data(xprt_buf)))
+ b_xfer(&qcc->rx.qstrm_buf, xprt_buf, b_data(xprt_buf));
}
if (conn_is_back(conn)) {
qcc_reset_idle_start(qcc);
LIST_INIT(&qcc->opening_list);
- if (conn_is_quic(conn))
+ if (conn_is_quic(conn)) {
HA_ATOMIC_STORE(&conn->handle.qc->qcc, qcc);
+ }
+ else {
+ /* Wakeup MUX immediately if data copied from XPRT layer. */
+ if (unlikely(b_data(&qcc->rx.qstrm_buf)))
+ tasklet_wakeup(qcc->wait_event.tasklet);
+ }
/* Register conn as app_ops may use it. */
qcc->conn = conn;
return &ctx->rparams;
}
+/* Returns RX buffer as mutable to allow zero-copy by the caller. */
+struct buffer *xprt_qstrm_rxbuf(void *context)
+{
+ struct xprt_qstrm_ctx *ctx = context;
+ return &ctx->rxbuf;
+}
+
int conn_recv_qstrm(struct connection *conn, struct xprt_qstrm_ctx *ctx, int flag)
{
struct quic_frame frm;