mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-05-05 04:56:10 +02:00
MINOR: xprt_qstrm: implement reception of transport parameters
Extend xprt_qstrm to implement the reception of QMux transport parameters. This is performed via conn_recv_qstrm() which relies on the lower xprt rcv_buf operation. Once received, parameters are kept in xprt_qstrm context, so that the MUX can retrieve them on init. For the reception of parameters to be active, the connection must first be flagged with CO_FL_QSTRM_RECV.
This commit is contained in:
parent
91ea5809e9
commit
531a2b9f1a
@ -130,7 +130,8 @@ enum {
|
||||
|
||||
CO_FL_OPT_TOS = 0x00000020, /* connection has a special sockopt tos */
|
||||
|
||||
/* unused : 0x00000040, 0x00000080 */
|
||||
/* unused : 0x00000040 */
|
||||
CO_FL_QSTRM_RECV = 0x00000080, /* connection uses QMux protocol, needs to exchange transport parameters before starting mux layer */
|
||||
|
||||
/* These flags indicate whether the Control and Transport layers are initialized */
|
||||
CO_FL_CTRL_READY = 0x00000100, /* FD was registered, fd_delete() needed */
|
||||
|
||||
@ -21,14 +21,71 @@ struct xprt_qstrm_ctx {
|
||||
|
||||
DECLARE_STATIC_TYPED_POOL(xprt_qstrm_ctx_pool, "xprt_qstrm_ctx", struct xprt_qstrm_ctx);
|
||||
|
||||
int conn_recv_qstrm(struct connection *conn, struct xprt_qstrm_ctx *ctx, int flag)
|
||||
{
|
||||
struct quic_frame frm;
|
||||
const unsigned char *pos, *end;
|
||||
int ret;
|
||||
|
||||
if (!conn_ctrl_ready(conn))
|
||||
goto fail;
|
||||
|
||||
BUG_ON(conn->flags & CO_FL_FDLESS);
|
||||
|
||||
if (!fd_recv_ready(conn->handle.fd))
|
||||
goto not_ready;
|
||||
|
||||
while (1) {
|
||||
ret = ctx->ops_lower->rcv_buf(conn, ctx->ctx_lower, &trash, trash.size, NULL, 0, MSG_PEEK);
|
||||
BUG_ON(conn->flags & CO_FL_ERROR); /* TODO handle fatal errors */
|
||||
trash.data = ret;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!trash.data)
|
||||
goto not_ready;
|
||||
|
||||
pos = (unsigned char *)b_orig(&trash);
|
||||
end = (unsigned char *)(b_orig(&trash) + b_data(&trash));
|
||||
ret = qc_parse_frm_type(&frm, &pos, end, NULL);
|
||||
BUG_ON(!ret); /* TODO handle a truncated frame, recv must be performed again. */
|
||||
|
||||
/* TODO close connection with TRANSPORT_PARAMETER_ERROR if frame not present. */
|
||||
BUG_ON(frm.type != QUIC_FT_QX_TRANSPORT_PARAMETERS);
|
||||
|
||||
ret = qc_parse_frm_payload(&frm, &pos, end, NULL);
|
||||
BUG_ON(!ret); /* TODO handle a truncated frame, recv must be performed again. */
|
||||
|
||||
ctx->rparams = frm.qmux_transport_params.params;
|
||||
|
||||
conn->flags &= ~flag;
|
||||
return 1;
|
||||
|
||||
not_ready:
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
conn->flags |= CO_FL_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct task *xprt_qstrm_io_cb(struct task *t, void *context, unsigned int state)
|
||||
{
|
||||
struct xprt_qstrm_ctx *ctx = context;
|
||||
struct connection *conn = ctx->conn;
|
||||
int ret;
|
||||
|
||||
if (conn->flags & CO_FL_QSTRM_RECV) {
|
||||
if (!conn_recv_qstrm(conn, ctx, CO_FL_QSTRM_RECV)) {
|
||||
ctx->ops_lower->subscribe(conn, ctx->ctx_lower,
|
||||
SUB_RETRY_RECV, &ctx->wait_event);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (conn->flags & CO_FL_ERROR) {
|
||||
if ((conn->flags & CO_FL_ERROR) ||
|
||||
!(conn->flags & CO_FL_QSTRM_RECV)) {
|
||||
/* MUX will access members from xprt_ctx on init, so create
|
||||
* operation should be called before any members are resetted.
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user