mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-30 00:22:06 +00:00
MEDIUM: mux-quic: implement shutw
Implement mux_ops shutw operation for QUIC mux. A RESET_STREAM is emitted unless the stream is already closed due to all data or RESET_STREAM already transmitted. This operation is notably useful when upper stream layer wants to close the connection early due to an error. This was tested by using a HTTP server which listens with PROXY protocol support. The corresponding server line on haproxy configuration deliberately not specify send-proxy. This causes the server to close abruptly the connection. Without this patch, nothing was done on the QUIC stream which was kept open until the whole connection is closed. Now, a proper RESET_STREAM is emitted to report the error. This should be backported up to 2.7.
This commit is contained in:
parent
be6a873096
commit
a473f196f1
@ -34,17 +34,19 @@ static const struct trace_event qmux_trace_events[] = {
|
||||
{ .mask = QMUX_EV_STRM_RECV, .name = "strm_recv", .desc = "receiving data for stream" },
|
||||
#define QMUX_EV_STRM_SEND (1ULL << 11)
|
||||
{ .mask = QMUX_EV_STRM_SEND, .name = "strm_send", .desc = "sending data for stream" },
|
||||
#define QMUX_EV_STRM_END (1ULL << 12)
|
||||
#define QMUX_EV_STRM_SHUT (1ULL << 12)
|
||||
{ .mask = QMUX_EV_STRM_SHUT, .name = "strm_shut", .desc = "stream shutdown" },
|
||||
#define QMUX_EV_STRM_END (1ULL << 13)
|
||||
{ .mask = QMUX_EV_STRM_END, .name = "strm_end", .desc = "detaching app-layer stream" },
|
||||
#define QMUX_EV_SEND_FRM (1ULL << 13)
|
||||
#define QMUX_EV_SEND_FRM (1ULL << 14)
|
||||
{ .mask = QMUX_EV_SEND_FRM, .name = "send_frm", .desc = "sending QUIC frame" },
|
||||
/* special event dedicated to qcs_xfer_data */
|
||||
#define QMUX_EV_QCS_XFER_DATA (1ULL << 14)
|
||||
#define QMUX_EV_QCS_XFER_DATA (1ULL << 15)
|
||||
{ .mask = QMUX_EV_QCS_XFER_DATA, .name = "qcs_xfer_data", .desc = "qcs_xfer_data" },
|
||||
/* special event dedicated to qcs_build_stream_frm */
|
||||
#define QMUX_EV_QCS_BUILD_STRM (1ULL << 15)
|
||||
#define QMUX_EV_QCS_BUILD_STRM (1ULL << 16)
|
||||
{ .mask = QMUX_EV_QCS_BUILD_STRM, .name = "qcs_build_stream_frm", .desc = "qcs_build_stream_frm" },
|
||||
#define QMUX_EV_PROTO_ERR (1ULL << 16)
|
||||
#define QMUX_EV_PROTO_ERR (1ULL << 17)
|
||||
{ .mask = QMUX_EV_PROTO_ERR, .name = "proto_err", .desc = "protocol error" },
|
||||
{ }
|
||||
};
|
||||
|
@ -2269,6 +2269,25 @@ static int qc_wake(struct connection *conn)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void qc_shutw(struct stconn *sc, enum co_shw_mode mode)
|
||||
{
|
||||
struct qcs *qcs = __sc_mux_strm(sc);
|
||||
|
||||
TRACE_ENTER(QMUX_EV_STRM_SHUT, qcs->qcc->conn, qcs);
|
||||
|
||||
/* If QC_SF_FIN_STREAM is not set and stream is not closed locally, it
|
||||
* means that upper layer reported an early closure. A RESET_STREAM is
|
||||
* necessary if not already scheduled.
|
||||
*/
|
||||
|
||||
if (!qcs_is_close_local(qcs) &&
|
||||
!(qcs->flags & (QC_SF_FIN_STREAM|QC_SF_TO_RESET))) {
|
||||
qcc_reset_stream(qcs, 0);
|
||||
se_fl_set_error(qcs->sd);
|
||||
}
|
||||
|
||||
TRACE_LEAVE(QMUX_EV_STRM_SHUT, qcs->qcc->conn, qcs);
|
||||
}
|
||||
|
||||
/* for debugging with CLI's "show sess" command. May emit multiple lines, each
|
||||
* new one being prefixed with <pfx>, if <pfx> is not NULL, otherwise a single
|
||||
@ -2306,6 +2325,7 @@ static const struct mux_ops qc_ops = {
|
||||
.subscribe = qc_subscribe,
|
||||
.unsubscribe = qc_unsubscribe,
|
||||
.wake = qc_wake,
|
||||
.shutw = qc_shutw,
|
||||
.show_sd = qc_show_sd,
|
||||
.flags = MX_FL_HTX|MX_FL_NO_UPG|MX_FL_FRAMED,
|
||||
.name = "QUIC",
|
||||
|
Loading…
Reference in New Issue
Block a user