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);
-size_t xprt_qstrm_rxrlen(const void *context);
+size_t xprt_qstrm_xfer_rxbuf(const void *context, struct buffer *out);
#endif /* _HAPROXY_XPRT_QSTRM_H */
}
if (!conn_is_quic(conn)) {
- struct buffer *xprt_buf;
-
qcc->tx.qstrm_buf = BUF_NULL;
qcc->rx.qstrm_buf = BUF_NULL;
- /* Retrieve data if xprt read too much */
- xprt_buf = xprt_qstrm_rxbuf(conn->xprt_ctx);
- if (unlikely(b_data(xprt_buf))) {
- b_alloc(&qcc->rx.qstrm_buf, DB_MUX_RX);
- if (!b_size(&qcc->rx.qstrm_buf)) {
- TRACE_ERROR("rx qstrm buf alloc failure", QMUX_EV_QCC_NEW);
- goto err;
- }
- b_xfer(&qcc->rx.qstrm_buf, xprt_buf, b_data(xprt_buf));
- qcc->rx.rlen = xprt_qstrm_rxrlen(conn->xprt_ctx);
- }
- else {
- qcc->rx.rlen = 0;
- }
+ /* Rx buffer is transfered from xprt layer - necessary if too many data where read */
+ qcc->rx.rlen = xprt_qstrm_xfer_rxbuf(conn->xprt_ctx, &qcc->rx.qstrm_buf);
+ /* Cannot have a non empty record with an empty buffer. */
+ BUG_ON(qcc->rx.rlen && !b_data(&qcc->rx.qstrm_buf));
}
if (conn_is_back(conn)) {
return &ctx->rparams;
}
-/* Returns RX buffer as mutable to allow zero-copy by the caller. */
-struct buffer *xprt_qstrm_rxbuf(void *context)
+/* Transfer Rx buffer into <out>. */
+size_t xprt_qstrm_xfer_rxbuf(void *context, struct buffer *out)
{
struct xprt_qstrm_ctx *ctx = context;
- return &ctx->rxbuf;
-}
-size_t xprt_qstrm_rxrlen(const void *context)
-{
- const struct xprt_qstrm_ctx *ctx = context;
+ if (b_data(&ctx->rxbuf)) {
+ *out = ctx->rxbuf;
+ ctx->rxbuf = BUF_NULL;
+ }
+
return ctx->rxrlen;
}
conn->xprt_ctx = ctx->ctx_lower;
conn->xprt = ctx->ops_lower;
+ /* MUX layer is responsible to retrieve any remaining data in
+ * the Rx buffer prior to reset it.
+ */
+ BUG_ON(b_data(&ctx->rxbuf));
b_free(&ctx->rxbuf);
b_free(&ctx->txbuf);