mirror of
https://github.com/haproxy/haproxy.git
synced 2026-04-22 14:49:45 -04:00
MEDIUM: mux-quic: implement STOP_SENDING handling
Implement support for STOP_SENDING frame parsing. The stream is resetted as specified by RFC 9000. This will automatically interrupt all future send operation in qc_send(). A RESET_STREAM will be sent with the code extracted from the original STOP_SENDING frame.
This commit is contained in:
parent
843a1196b3
commit
a5b5075211
3 changed files with 60 additions and 1 deletions
|
|
@ -27,6 +27,7 @@ int qcc_recv(struct qcc *qcc, uint64_t id, uint64_t len, uint64_t offset,
|
|||
char fin, char *data);
|
||||
int qcc_recv_max_data(struct qcc *qcc, uint64_t max);
|
||||
int qcc_recv_max_stream_data(struct qcc *qcc, uint64_t id, uint64_t max);
|
||||
int qcc_recv_stop_sending(struct qcc *qcc, uint64_t id, uint64_t err);
|
||||
void qcc_streams_sent_done(struct qcs *qcs, uint64_t data, uint64_t offset);
|
||||
|
||||
/* Bit shift to get the stream sub ID for internal use which is obtained
|
||||
|
|
|
|||
|
|
@ -888,6 +888,56 @@ int qcc_recv_max_stream_data(struct qcc *qcc, uint64_t id, uint64_t max)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Handle a new STOP_SENDING frame for stream ID <id>. The error code should be
|
||||
* specified in <err>.
|
||||
*
|
||||
* Returns 0 on success else non-zero. On error, the received frame should not
|
||||
* be acknowledged.
|
||||
*/
|
||||
int qcc_recv_stop_sending(struct qcc *qcc, uint64_t id, uint64_t err)
|
||||
{
|
||||
struct qcs *qcs;
|
||||
|
||||
TRACE_ENTER(QMUX_EV_QCC_RECV, qcc->conn);
|
||||
|
||||
/* RFC 9000 19.5. STOP_SENDING Frames
|
||||
*
|
||||
* Receiving a STOP_SENDING frame for a
|
||||
* locally initiated stream that has not yet been created MUST be
|
||||
* treated as a connection error of type STREAM_STATE_ERROR. An
|
||||
* endpoint that receives a STOP_SENDING frame for a receive-only stream
|
||||
* MUST terminate the connection with error STREAM_STATE_ERROR.
|
||||
*/
|
||||
if (qcc_get_qcs(qcc, id, 0, 1, &qcs)) {
|
||||
TRACE_LEAVE(QMUX_EV_QCC_RECV, qcc->conn);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!qcs)
|
||||
goto out;
|
||||
|
||||
/* RFC 9000 3.5. Solicited State Transitions
|
||||
*
|
||||
* An endpoint that receives a STOP_SENDING frame
|
||||
* MUST send a RESET_STREAM frame if the stream is in the "Ready" or
|
||||
* "Send" state. If the stream is in the "Data Sent" state, the
|
||||
* endpoint MAY defer sending the RESET_STREAM frame until the packets
|
||||
* containing outstanding data are acknowledged or declared lost. If
|
||||
* any outstanding data is declared lost, the endpoint SHOULD send a
|
||||
* RESET_STREAM frame instead of retransmitting the data.
|
||||
*
|
||||
* An endpoint SHOULD copy the error code from the STOP_SENDING frame to
|
||||
* the RESET_STREAM frame it sends, but it can use any application error
|
||||
* code.
|
||||
*/
|
||||
TRACE_DEVEL("receiving STOP_SENDING on stream", QMUX_EV_QCC_RECV|QMUX_EV_QCS_RECV, qcc->conn, qcs);
|
||||
qcc_reset_stream(qcs, err);
|
||||
|
||||
out:
|
||||
TRACE_LEAVE(QMUX_EV_QCC_RECV, qcc->conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Signal the closing of remote stream with id <id>. Flow-control for new
|
||||
* streams may be allocated for the peer if needed.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2412,8 +2412,16 @@ static int qc_parse_pkt_frms(struct quic_rx_packet *pkt, struct ssl_sock_ctx *ct
|
|||
/* TODO: handle this frame at STREAM level */
|
||||
break;
|
||||
case QUIC_FT_STOP_SENDING:
|
||||
/* TODO: handle this frame at STREAM level */
|
||||
{
|
||||
struct quic_stop_sending *stop_sending = &frm.stop_sending;
|
||||
if (qc->mux_state == QC_MUX_READY) {
|
||||
if (qcc_recv_stop_sending(qc->qcc, stop_sending->id,
|
||||
stop_sending->app_error_code)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QUIC_FT_CRYPTO:
|
||||
{
|
||||
struct quic_rx_crypto_frm *cf;
|
||||
|
|
|
|||
Loading…
Reference in a new issue