]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: mux-spop/spoe: Save negociated max-frame-size value in the mux
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 9 Jul 2024 17:20:16 +0000 (19:20 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 12 Jul 2024 13:27:05 +0000 (15:27 +0200)
The SPOE applet is just a pass-through now. It is no longer reponsible to
check the frame size. On the other hand, the SPOP multiplexer negociate the
maximum frame size with the agent. So, it seems logical to store this
negociated value in the mux and no longer in the applet context.

The related issue is #2502.

src/flt_spoe.c
src/mux_spop.c

index fd86761b26dd958e09629921eecc60b8d40bc2b2..fcceee230dd6fc21e595d7e6d85ece85e636d17f 100644 (file)
@@ -206,13 +206,9 @@ struct spoe_context {
 struct spoe_appctx {
        struct appctx      *owner;          /* the owner */
        struct spoe_agent  *agent;          /* agent on which the applet is attached */
-
        unsigned int        version;        /* the negotiated version */
-       unsigned int        max_frame_size; /* the negotiated max-frame-size value */
        unsigned int        flags;          /* SPOE_APPCTX_FL_* */
-
        unsigned int        status_code;    /* SPOE_FRM_ERR_* */
-
        struct spoe_context *spoe_ctx;      /* The SPOE context to handle */
 };
 
@@ -472,7 +468,7 @@ static int spoe_handle_receiving_frame_appctx(struct appctx *appctx)
                goto end;
        if (!spoe_acquire_buffer(&spoe_ctx->buffer, &spoe_ctx->buffer_wait))
                goto end;
-       if (co_data(oc) > spoe_appctx->max_frame_size) {
+       if (co_data(oc) > spoe_appctx->agent->max_frame_size) {
                spoe_appctx->status_code = SPOP_ERR_TOO_BIG;
                goto exit;
        }
@@ -574,7 +570,6 @@ static struct appctx *spoe_create_appctx(struct spoe_context *ctx)
 
        spoe_appctx->agent           = agent;
        spoe_appctx->version         = 0;
-       spoe_appctx->max_frame_size  = agent->max_frame_size;
        spoe_appctx->flags           = 0;
        spoe_appctx->status_code     = SPOP_ERR_NONE;
        spoe_appctx->spoe_ctx        = ctx;
index 20fca78d905bca0485d0e91d4ee76c649291a22c..1ec77b93f8bf0b210b5acebfd2970b9e8bf57caf 100644 (file)
@@ -44,6 +44,7 @@ struct spop_conn {
        int timeout;                         /* idle timeout duration in ticks */
        int shut_timeout;                    /* idle timeout duration in ticks after shutdown */
 
+       unsigned int max_frame_size;         /* the negotiated max-frame-size value */
        unsigned int nb_streams;             /* number of streams in the tree */
        unsigned int nb_sc;                  /* number of attached stream connectors */
        unsigned int nb_reserved;            /* number of reserved streams */
@@ -667,6 +668,7 @@ static int spop_init(struct connection *conn, struct proxy *px, struct session *
        spop_conn->state = SPOP_CS_HA_HELLO;
        spop_conn->errcode = SPOP_ERR_NONE;
        spop_conn->conn = conn;
+       spop_conn->max_frame_size = SPOP_MAX_FRAME_SIZE;
        spop_conn->streams_limit = 1;
        spop_conn->max_id = -1;
        spop_conn->nb_streams = 0;
@@ -702,6 +704,7 @@ static int spop_init(struct connection *conn, struct proxy *px, struct session *
        sdo = spop_strm_opposite_sd(spop_strm);
        if (sdo) {
                spop_conn->agent = spoe_appctx_agent(sc_appctx(sdo->sc));
+               spop_conn->max_frame_size = spop_conn->agent->max_frame_size;
                BUG_ON(!spop_conn->agent);
        }
 
@@ -1386,7 +1389,7 @@ static int spop_conn_send_hello(struct spop_conn *spop_conn)
                goto full;
 
        *p++ = SPOP_DATA_T_UINT32;
-       if (encode_varint(spop_conn->agent ? spop_conn->agent->max_frame_size : SPOP_MAX_FRAME_SIZE, &p, end) == -1)
+       if (encode_varint(spop_conn->max_frame_size, &p, end) == -1)
                goto full;
 
        /* "capabilities" K/V item */
@@ -1597,7 +1600,8 @@ static int spop_conn_handle_hello(struct spop_conn *spop_conn)
         * "capabilities" */
 
        /* Loop on K/V items */
-       vsn = max_frame_size = flags = 0;
+       vsn = flags = 0;
+       max_frame_size = spop_conn->max_frame_size;
        while (p < end) {
                char  *str;
                uint64_t sz;
@@ -1655,8 +1659,7 @@ static int spop_conn_handle_hello(struct spop_conn *spop_conn)
                                spop_conn_error(spop_conn, SPOP_ERR_INVALID);
                                goto fail;
                        }
-                       if (sz < SPOP_MIN_FRAME_SIZE ||
-                           sz > SPOP_MAX_FRAME_SIZE/* agent->max_frame_size */) {
+                       if (sz < SPOP_MIN_FRAME_SIZE || sz > spop_conn->max_frame_size) {
                                spop_conn_error(spop_conn, SPOP_ERR_BAD_FRAME_SIZE);
                                goto fail;
                        }
@@ -1722,8 +1725,8 @@ static int spop_conn_handle_hello(struct spop_conn *spop_conn)
        /* } */
 
        /* SPOE_APPCTX(appctx)->version        = (unsigned int)vsn; */
-       /* SPOE_APPCTX(appctx)->max_frame_size = (unsigned int)max_frame_size; */
        /* SPOE_APPCTX(appctx)->flags         |= flags; */
+       spop_conn->max_frame_size = (unsigned int)max_frame_size;
 
 
        TRACE_PROTO("SPOP AGENT HELLO frame rcvd", SPOP_EV_RX_FRAME|SPOP_EV_RX_HELLO, spop_conn->conn, 0, 0, (size_t[]){spop_conn->dfl});
@@ -2034,7 +2037,7 @@ static void spop_process_demux(struct spop_conn *spop_conn)
                                goto done;
                        }
 
-                       if ((int)hdr.len < 0 || (int)hdr.len > SPOP_MAX_FRAME_SIZE) {
+                       if ((int)hdr.len < 0 || (int)hdr.len > spop_conn->max_frame_size) {
                                spop_conn_error(spop_conn, SPOP_ERR_BAD_FRAME_SIZE);
                                spop_conn->state = SPOP_CS_CLOSED;
                                TRACE_ERROR("invalid AGENT HELLO frame length", SPOP_EV_RX_FRAME|SPOP_EV_RX_FHDR|SPOP_EV_RX_HELLO|SPOP_EV_SPOP_CONN_ERR, spop_conn->conn);
@@ -2068,7 +2071,7 @@ static void spop_process_demux(struct spop_conn *spop_conn)
                                break;
                        }
 
-                       if ((int)hdr.len < 0 || (int)hdr.len > spop_conn->agent->max_frame_size) {
+                       if ((int)hdr.len < 0 || (int)hdr.len > spop_conn->max_frame_size) {
                                spop_conn_error(spop_conn, SPOP_ERR_BAD_FRAME_SIZE);
                                TRACE_ERROR("invalid SPOP frame length", SPOP_EV_RX_FRAME|SPOP_EV_RX_FHDR|SPOP_EV_SPOP_CONN_ERR, spop_conn->conn);
                                TRACE_STATE("switching to CLOSED", SPOP_EV_RX_FRAME|SPOP_EV_RX_FHDR|SPOP_EV_SPOP_CONN_ERR, spop_conn->conn);