BUG/MEDIUM: mux-spop: Respect the negociated max-frame-size value to send frames
When a SPOP connection is opened, the maximum size for frames is negociated. This negociated size is properly used when a frame is received and if a too big frame is detected, an error is triggered. However, the same was not performed on the sending path. No check was performed on frames sent to the agent. So it was possible to send frames bigger than the maximum size supported by the the SPOE agent. Now, the size of NOTIFY and DISCONNECT frames is checked before sending them to the agent. Thanks to Miroslav to have reported the issue. This patch must be backported to 3.1.
This commit is contained in:
parent
a56feffc6f
commit
ce8c2d359b
@ -1547,6 +1547,9 @@ static int spop_conn_send_disconnect(struct spop_conn *spop_conn)
|
||||
|
||||
outbuf.data += p - b_tail(&outbuf);
|
||||
|
||||
if (outbuf.data - 4 > spop_conn->max_frame_size)
|
||||
goto too_big;
|
||||
|
||||
/* update the frame's size now */
|
||||
TRACE_PROTO("SPOP HAPROXY DISCONNECT frame xferred", SPOP_EV_TX_FRAME|SPOP_EV_TX_DISCO, spop_conn->conn, 0, 0, (size_t[]){outbuf.data});
|
||||
spop_set_frame_size(outbuf.area, outbuf.data - 4);
|
||||
@ -1596,10 +1599,8 @@ static int spop_conn_send_disconnect(struct spop_conn *spop_conn)
|
||||
return ret;
|
||||
full:
|
||||
/* Too large to be encoded. For DISCONNECT frame, it is an error */
|
||||
if (!b_data(mbuf)) {
|
||||
TRACE_ERROR("SPOP HAPROXY DISCO frame too large", SPOP_EV_TX_FRAME|SPOP_EV_TX_DISCO|SPOP_EV_SPOP_CONN_ERR, spop_conn->conn);
|
||||
goto fail;
|
||||
}
|
||||
if (!b_data(mbuf))
|
||||
goto too_big;
|
||||
|
||||
if ((mbuf = br_tail_add(spop_conn->mbuf)) != NULL)
|
||||
goto retry;
|
||||
@ -1608,6 +1609,10 @@ static int spop_conn_send_disconnect(struct spop_conn *spop_conn)
|
||||
TRACE_STATE("mbuf ring full", SPOP_EV_TX_FRAME|SPOP_EV_SPOP_CONN_BLK, spop_conn->conn);
|
||||
ret = 0;
|
||||
goto end;
|
||||
|
||||
too_big:
|
||||
TRACE_ERROR("SPOP HAPROXY DISCO frame too large", SPOP_EV_TX_FRAME|SPOP_EV_TX_DISCO|SPOP_EV_SPOP_CONN_ERR, spop_conn->conn);
|
||||
|
||||
fail:
|
||||
spop_conn->state = SPOP_CS_CLOSED;
|
||||
TRACE_STATE("switching to CLOSED", SPOP_EV_TX_FRAME|SPOP_EV_TX_DISCO|SPOP_EV_SPOP_CONN_END, spop_conn->conn);
|
||||
@ -3215,6 +3220,9 @@ static size_t spop_strm_send_notify(struct spop_strm *spop_strm, struct buffer *
|
||||
|
||||
outbuf.data += p - b_tail(&outbuf);
|
||||
|
||||
if (outbuf.data - 4 > spop_conn->max_frame_size)
|
||||
goto too_big;
|
||||
|
||||
/* update the frame's size now */
|
||||
TRACE_PROTO("SPOP HAPROXY NOTIFY frame xferred", SPOP_EV_TX_FRAME|SPOP_EV_TX_NOTIFY, spop_conn->conn, spop_strm, 0, (size_t[]){outbuf.data});
|
||||
spop_set_frame_size(outbuf.area, outbuf.data - 4);
|
||||
@ -3228,11 +3236,8 @@ static size_t spop_strm_send_notify(struct spop_strm *spop_strm, struct buffer *
|
||||
return ret;
|
||||
full:
|
||||
/* Too large to be encoded. For NOTIFY frame, it is an error */
|
||||
if (!b_data(mbuf)) {
|
||||
TRACE_ERROR("SPOP HAPROXY NOTIFY frame too large", SPOP_EV_TX_FRAME|SPOP_EV_TX_NOTIFY|SPOP_EV_SPOP_STRM_ERR, spop_conn->conn, spop_strm);
|
||||
spop_strm_error(spop_strm, SPOP_ERR_TOO_BIG);
|
||||
goto fail;
|
||||
}
|
||||
if (!b_data(mbuf))
|
||||
goto too_big;
|
||||
|
||||
if ((mbuf = br_tail_add(spop_conn->mbuf)) != NULL)
|
||||
goto retry;
|
||||
@ -3241,6 +3246,11 @@ static size_t spop_strm_send_notify(struct spop_strm *spop_strm, struct buffer *
|
||||
TRACE_STATE("mbuf ring full", SPOP_EV_TX_FRAME|SPOP_EV_TX_NOTIFY|SPOP_EV_SPOP_STRM_BLK, spop_conn->conn, spop_strm);
|
||||
ret = 0;
|
||||
goto end;
|
||||
|
||||
too_big:
|
||||
TRACE_ERROR("SPOP HAPROXY NOTIFY frame too large", SPOP_EV_TX_FRAME|SPOP_EV_TX_NOTIFY|SPOP_EV_SPOP_STRM_ERR, spop_conn->conn, spop_strm);
|
||||
spop_strm_error(spop_strm, SPOP_ERR_TOO_BIG);
|
||||
|
||||
fail:
|
||||
TRACE_DEVEL("leaving on error", SPOP_EV_TX_FRAME|SPOP_EV_TX_NOTIFY|SPOP_EV_SPOP_STRM_ERR, spop_conn->conn, spop_strm);
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user