mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-05-07 18:28:01 +00:00
MEDIUM: tevt/muxes: Add dedicated termination events for muxc/se locations
Termination events dedicated to mux connection and stream-endpoint descriptors are added in this patch. Specific events to these locations are thus added. Changes for the H1 and H2 multiplexers are reviewed to be more accurate.
This commit is contained in:
parent
f2778ccc7d
commit
a58e650ad1
@ -584,6 +584,37 @@ enum xprt_term_event_type {
|
||||
xprt_tevt_type_snd_err = 4,
|
||||
};
|
||||
|
||||
enum muxc_term_event_type {
|
||||
muxc_tevt_type_shutw = 1,
|
||||
muxc_tevt_type_shutr = 2,
|
||||
muxc_tevt_type_rcv_err = 3,
|
||||
muxc_tevt_type_snd_err = 4,
|
||||
muxc_tevt_type_truncated_shutr = 5,
|
||||
muxc_tevt_type_truncated_rcv_err= 6,
|
||||
|
||||
muxc_tevt_type_tout = 7,
|
||||
muxc_tevt_type_goaway_rcvd = 8,
|
||||
muxc_tevt_type_proto_err = 9,
|
||||
muxc_tevt_type_internal_err = 10,
|
||||
muxc_tevt_type_other_err = 11,
|
||||
muxc_tevt_type_graceful_shut = 12,
|
||||
|
||||
};
|
||||
|
||||
enum se_term_event_type {
|
||||
se_tevt_type_shutw = 1,
|
||||
se_tevt_type_eos = 2,
|
||||
se_tevt_type_rcv_err = 3,
|
||||
se_tevt_type_snd_err = 4,
|
||||
se_tevt_type_truncated_eos = 5,
|
||||
se_tevt_type_truncated_rcv_err= 6,
|
||||
/* unused: 7 */
|
||||
se_tevt_type_rst_rcvd = 8,
|
||||
se_tevt_type_proto_err = 9,
|
||||
se_tevt_type_internal_err = 10,
|
||||
se_tevt_type_other_err = 11,
|
||||
se_tevt_type_cancelled = 12,
|
||||
};
|
||||
|
||||
enum term_event_type {
|
||||
/* Events emitted by haproxy */
|
||||
|
@ -565,7 +565,15 @@ static inline size_t se_done_ff(struct sedesc *se)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void sc_report_term_evt(struct stconn *sc, enum term_event_loc loc, enum term_event_type type)
|
||||
static inline void se_report_term_evt(struct sedesc *se, enum se_term_event_type type)
|
||||
{
|
||||
enum term_event_loc loc = tevt_loc_se;
|
||||
|
||||
if (se->sc && se->sc->flags & SC_FL_ISBACK)
|
||||
loc += 8;
|
||||
se->term_evts_log = tevt_report_event(se->term_evts_log, loc, type);
|
||||
}
|
||||
|
||||
{
|
||||
if (sc->flags & SC_FL_ISBACK)
|
||||
loc += 8;
|
||||
|
107
src/mux_h1.c
107
src/mux_h1.c
@ -650,7 +650,7 @@ static inline void h1_release_buf(struct h1c *h1c, struct buffer *bptr)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void h1c_report_term_evt(struct h1c *h1c, enum term_event_type type)
|
||||
static inline void h1c_report_term_evt(struct h1c *h1c, enum muxc_term_event_type type)
|
||||
{
|
||||
enum term_event_loc loc = tevt_loc_muxc;
|
||||
|
||||
@ -659,15 +659,6 @@ static inline void h1c_report_term_evt(struct h1c *h1c, enum term_event_type typ
|
||||
h1c->term_evts_log = tevt_report_event(h1c->term_evts_log, loc, type);
|
||||
}
|
||||
|
||||
static inline void h1s_report_term_evt(struct h1s *h1s, enum term_event_type type)
|
||||
{
|
||||
enum term_event_loc loc = tevt_loc_se;
|
||||
|
||||
if (h1s->h1c->flags & H1C_F_IS_BACK)
|
||||
loc += 8;
|
||||
h1s->sd->term_evts_log = tevt_report_event(h1s->sd->term_evts_log, loc, type);
|
||||
}
|
||||
|
||||
/* Returns 1 if the H1 connection is alive (IDLE, EMBRYONIC, RUNNING or
|
||||
* DRAINING). Ortherwise 0 is returned.
|
||||
*/
|
||||
@ -2232,6 +2223,22 @@ static size_t h1_process_demux(struct h1c *h1c, struct buffer *buf, size_t count
|
||||
|
||||
if (h1s->flags & H1S_F_DEMUX_ERROR) {
|
||||
TRACE_ERROR("parsing or not-implemented error", H1_EV_RX_DATA|H1_EV_H1S_ERR, h1c->conn, h1s);
|
||||
if (h1c->state < H1_CS_RUNNING) {
|
||||
if (h1s->flags & H1S_F_PARSING_ERROR)
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_proto_err);
|
||||
else if (h1s->flags & H1S_F_INTERNAL_ERROR)
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_internal_err);
|
||||
else
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_other_err);
|
||||
}
|
||||
else {
|
||||
if (h1s->flags & H1S_F_PARSING_ERROR)
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_proto_err);
|
||||
else if (h1s->flags & H1S_F_INTERNAL_ERROR)
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_internal_err);
|
||||
else
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_other_err);
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -2309,29 +2316,33 @@ static size_t h1_process_demux(struct h1c *h1c, struct buffer *buf, size_t count
|
||||
se_fl_clr(h1s->sd, SE_FL_RCV_MORE | SE_FL_WANT_ROOM);
|
||||
|
||||
if (h1c->flags & H1C_F_EOS) {
|
||||
if (!(h1c->flags & H1C_F_ERROR))
|
||||
h1c_report_term_evt(h1c, (se_fl_test(h1c->h1s->sd, SE_FL_EOI) ? tevt_type_shutr : tevt_type_truncated_shutr));
|
||||
|
||||
se_fl_set(h1s->sd, SE_FL_EOS);
|
||||
TRACE_STATE("report EOS to SE", H1_EV_RX_DATA, h1c->conn, h1s);
|
||||
if (h1m->state >= H1_MSG_DONE || (h1m->state > H1_MSG_LAST_LF && !(h1m->flags & H1_MF_XFER_LEN))) {
|
||||
/* DONE or TUNNEL or SHUTR without XFER_LEN, set
|
||||
* EOI on the stream connector */
|
||||
if (!(h1c->flags & H1C_F_ERROR))
|
||||
h1s_report_term_evt(h1s, tevt_type_shutr);
|
||||
se_fl_set(h1s->sd, SE_FL_EOI);
|
||||
TRACE_STATE("report EOI to SE", H1_EV_RX_DATA, h1c->conn, h1s);
|
||||
}
|
||||
else if (h1m->state < H1_MSG_DONE) {
|
||||
if (h1m->state <= H1_MSG_LAST_LF && b_data(&h1c->ibuf))
|
||||
htx->flags |= HTX_FL_PARSING_ERROR;
|
||||
if (!(h1c->flags & H1C_F_ERROR))
|
||||
h1s_report_term_evt(h1s, tevt_type_truncated_shutr);
|
||||
se_fl_set(h1s->sd, SE_FL_ERROR);
|
||||
COUNT_IF(1, "H1C EOS before the end of the message");
|
||||
TRACE_ERROR("message aborted, set error on SC", H1_EV_RX_DATA|H1_EV_H1S_ERR, h1c->conn, h1s);
|
||||
}
|
||||
|
||||
if (!(h1c->flags & H1C_F_ERROR)) {
|
||||
if (se_fl_test(h1c->h1s->sd, SE_FL_EOI)) {
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_eos);
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_shutr);
|
||||
}
|
||||
else {
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_truncated_eos);
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_truncated_shutr);
|
||||
}
|
||||
}
|
||||
|
||||
if (h1s->flags & H1S_F_TX_BLK) {
|
||||
h1s->flags &= ~H1S_F_TX_BLK;
|
||||
h1_wake_stream_for_send(h1s);
|
||||
@ -2340,10 +2351,17 @@ static size_t h1_process_demux(struct h1c *h1c, struct buffer *buf, size_t count
|
||||
}
|
||||
if (h1c->flags & H1C_F_ERROR) {
|
||||
/* Report a terminal error to the SE if a previous read error was detected */
|
||||
h1c_report_term_evt(h1c, (se_fl_test(h1c->h1s->sd, SE_FL_EOI) ? tevt_type_rcv_err : tevt_type_truncated_rcv_err));
|
||||
h1s_report_term_evt(h1s, (se_fl_test(h1c->h1s->sd, SE_FL_EOI) ? tevt_type_rcv_err : tevt_type_truncated_rcv_err));
|
||||
|
||||
se_fl_set(h1s->sd, SE_FL_ERROR);
|
||||
|
||||
if (se_fl_test(h1c->h1s->sd, SE_FL_EOI)) {
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_rcv_err);
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_rcv_err);
|
||||
}
|
||||
else {
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_truncated_rcv_err);
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_truncated_rcv_err);
|
||||
}
|
||||
|
||||
COUNT_IF(h1m->state < H1_MSG_DONE, "H1C ERROR before the end of the message");
|
||||
TRACE_STATE("report ERROR to SE", H1_EV_RX_DATA|H1_EV_H1S_ERR, h1c->conn, h1s);
|
||||
}
|
||||
@ -3558,6 +3576,12 @@ static size_t h1_process_mux(struct h1c *h1c, struct buffer *buf, size_t count)
|
||||
h1c->flags |= H1C_F_OUT_FULL;
|
||||
}
|
||||
|
||||
if (h1s->flags & H1S_F_MUX_ERROR) {
|
||||
if (h1s->flags & H1S_F_PROCESSING_ERROR)
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_proto_err);
|
||||
else
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_internal_err);
|
||||
}
|
||||
end:
|
||||
|
||||
/* Both the request and the response reached the DONE state. So set EOI
|
||||
@ -3571,6 +3595,7 @@ static size_t h1_process_mux(struct h1c *h1c, struct buffer *buf, size_t count)
|
||||
htx->flags |= HTX_FL_PROCESSING_ERROR;
|
||||
h1s->flags |= H1S_F_PROCESSING_ERROR;
|
||||
se_fl_set(h1s->sd, SE_FL_ERROR);
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_proto_err);
|
||||
TRACE_ERROR("txn done but data waiting to be sent, set error on h1c", H1_EV_H1C_ERR, h1c->conn, h1s);
|
||||
}
|
||||
}
|
||||
@ -3968,7 +3993,7 @@ static int h1_send(struct h1c *h1c)
|
||||
TRACE_DEVEL("connection error", H1_EV_H1C_SEND, h1c->conn);
|
||||
COUNT_IF(b_data(&h1c->obuf), "connection error (send) with pending output data");
|
||||
h1c->flags |= H1C_F_ERR_PENDING;
|
||||
h1c_report_term_evt(h1c, tevt_type_snd_err);
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_snd_err);
|
||||
if (h1c->flags & H1C_F_EOS)
|
||||
h1c->flags |= H1C_F_ERROR;
|
||||
else if (!(h1c->wait_event.events & SUB_RETRY_RECV)) {
|
||||
@ -4100,7 +4125,7 @@ static int h1_process(struct h1c * h1c)
|
||||
if (h1c->state != H1_CS_RUNNING) {
|
||||
/* No stream connector or upgrading */
|
||||
if (h1c->state == H1_CS_IDLE)
|
||||
h1c_report_term_evt(h1c, ((h1c->flags & H1C_F_ERROR) ? tevt_type_rcv_err : tevt_type_shutr));
|
||||
h1c_report_term_evt(h1c, ((h1c->flags & H1C_F_ERROR) ? muxc_tevt_type_rcv_err : muxc_tevt_type_shutr));
|
||||
|
||||
if (h1c->state < H1_CS_RUNNING && !(h1c->flags & (H1C_F_IS_BACK|H1C_F_ABRT_PENDING))) {
|
||||
/* shutdown for reads and no error on the frontend connection: Send an error */
|
||||
@ -4384,7 +4409,7 @@ struct task *h1_timeout_task(struct task *t, void *context, unsigned int state)
|
||||
|
||||
HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
|
||||
h1c_report_term_evt(h1c, tevt_type_tout);
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_tout);
|
||||
}
|
||||
|
||||
do_leave:
|
||||
@ -4482,6 +4507,7 @@ static void h1_detach(struct sedesc *sd)
|
||||
|
||||
if (h1c->state == H1_CS_RUNNING && !(h1c->flags & H1C_F_IS_BACK) && h1s->req.state != H1_MSG_DONE) {
|
||||
h1c->state = H1_CS_DRAINING;
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_graceful_shut);
|
||||
COUNT_IF(1, "Deferring H1S destroy to drain message");
|
||||
TRACE_DEVEL("Deferring H1S destroy to drain message", H1_EV_STRM_END, h1s->h1c->conn, h1s);
|
||||
/* If we have a pending data, process it immediately or
|
||||
@ -4521,7 +4547,7 @@ static void h1_shut(struct stconn *sc, unsigned int mode, struct se_abort_info *
|
||||
COUNT_IF((h1c->flags & H1C_F_IS_BACK) && (h1s->res.state < H1_MSG_DONE), "Abort sending of the response");
|
||||
COUNT_IF(!(h1c->flags & H1C_F_IS_BACK) && (h1s->req.state < H1_MSG_DONE), "Abort sending of the request");
|
||||
|
||||
h1c_report_term_evt(h1c, tevt_type_shutw);
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_shutw);
|
||||
h1_close(h1c);
|
||||
if (!(mode & SE_SHW_NORMAL))
|
||||
h1c->flags |= H1C_F_SILENT_SHUT;
|
||||
@ -4733,6 +4759,7 @@ static size_t h1_snd_buf(struct stconn *sc, struct buffer *buf, size_t count, in
|
||||
// FIXME: following test was removed :
|
||||
// ((h1c->conn->flags & CO_FL_ERROR) && (se_fl_test(h1s->sd, SE_FL_EOI | SE_FL_EOS) || !b_data(&h1c->ibuf)))) {
|
||||
se_fl_set_error(h1s->sd);
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_snd_err);
|
||||
TRACE_ERROR("reporting error to the app-layer stream", H1_EV_STRM_SEND|H1_EV_H1S_ERR|H1_EV_STRM_ERR, h1c->conn, h1s);
|
||||
}
|
||||
|
||||
@ -4948,6 +4975,7 @@ static size_t h1_done_ff(struct stconn *sc)
|
||||
// TODO: should we call h1_process() instead ?
|
||||
if (h1c->conn->flags & CO_FL_ERROR) {
|
||||
h1c->flags = (h1c->flags & ~H1C_F_WANT_FASTFWD) | H1C_F_ERR_PENDING;
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_snd_err);
|
||||
if (h1c->flags & H1C_F_EOS)
|
||||
h1c->flags |= H1C_F_ERROR;
|
||||
else if (!(h1c->wait_event.events & SUB_RETRY_RECV)) {
|
||||
@ -4959,6 +4987,7 @@ static size_t h1_done_ff(struct stconn *sc)
|
||||
}
|
||||
COUNT_IF(b_data(&h1c->obuf) || (sd->iobuf.pipe && sd->iobuf.pipe->data), "connection error (done_ff) with pending output data");
|
||||
se_fl_set_error(h1s->sd);
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_snd_err);
|
||||
if (sd->iobuf.pipe) {
|
||||
put_pipe(sd->iobuf.pipe);
|
||||
sd->iobuf.pipe = NULL;
|
||||
@ -5122,24 +5151,46 @@ static int h1_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags)
|
||||
/* DONE or TUNNEL or SHUTR without XFER_LEN, set
|
||||
* EOI on the stream connector */
|
||||
se_fl_set(h1s->sd, SE_FL_EOI);
|
||||
h1c_report_term_evt(h1c, tevt_type_shutr);
|
||||
if (!(h1c->conn->flags & CO_FL_ERROR))
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_eos);
|
||||
TRACE_STATE("report EOI to SE", H1_EV_STRM_RECV, h1c->conn, h1s);
|
||||
}
|
||||
else {
|
||||
se_fl_set(h1s->sd, SE_FL_ERROR);
|
||||
h1c->flags = (h1c->flags & ~H1C_F_WANT_FASTFWD) | H1C_F_ERROR;
|
||||
h1c_report_term_evt(h1c, tevt_type_truncated_shutr);
|
||||
if (!(h1c->conn->flags & CO_FL_ERROR))
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_truncated_eos);
|
||||
COUNT_IF(1, "H1C EOS before the end of the message");
|
||||
TRACE_ERROR("message aborted, set error on SC", H1_EV_STRM_RECV|H1_EV_H1S_ERR, h1c->conn, h1s);
|
||||
}
|
||||
h1c->flags = (h1c->flags & ~H1C_F_WANT_FASTFWD) | H1C_F_EOS;
|
||||
|
||||
if (!(h1c->conn->flags & CO_FL_ERROR)) {
|
||||
if (se_fl_test(h1c->h1s->sd, SE_FL_EOI)) {
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_eos);
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_shutr);
|
||||
}
|
||||
else {
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_truncated_eos);
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_truncated_shutr);
|
||||
}
|
||||
}
|
||||
|
||||
TRACE_STATE("Allow xprt rcv_buf on read0", H1_EV_STRM_RECV, h1c->conn, h1s);
|
||||
}
|
||||
if (h1c->conn->flags & CO_FL_ERROR) {
|
||||
se_fl_set(h1s->sd, SE_FL_ERROR);
|
||||
h1c->flags = (h1c->flags & ~H1C_F_WANT_FASTFWD) | H1C_F_ERROR;
|
||||
if (!(h1c->flags & H1C_F_EOS))
|
||||
h1c_report_term_evt(h1c, tevt_type_truncated_rcv_err);
|
||||
|
||||
if (se_fl_test(h1c->h1s->sd, SE_FL_EOI)) {
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_rcv_err);
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_rcv_err);
|
||||
}
|
||||
else {
|
||||
se_report_term_evt(h1s->sd, se_tevt_type_truncated_rcv_err);
|
||||
h1c_report_term_evt(h1c, muxc_tevt_type_truncated_rcv_err);
|
||||
}
|
||||
|
||||
COUNT_IF(h1m->state < H1_MSG_DONE, "H1C ERROR before the end of the message");
|
||||
COUNT_IF(b_data(&h1c->obuf) || (h1s->sd->iobuf.pipe && h1s->sd->iobuf.pipe->data), "connection error (fastfwd) with pending output data");
|
||||
TRACE_DEVEL("connection error", H1_EV_STRM_ERR|H1_EV_H1C_ERR|H1_EV_H1S_ERR, h1c->conn, h1s);
|
||||
|
65
src/mux_h2.c
65
src/mux_h2.c
@ -695,7 +695,7 @@ static void h2_trace_fill_ctx(struct trace_ctx *ctx, const struct trace_source *
|
||||
}
|
||||
}
|
||||
|
||||
static inline void h2c_report_term_evt(struct h2c *h2c, enum term_event_type type)
|
||||
static inline void h2c_report_term_evt(struct h2c *h2c, enum muxc_term_event_type type)
|
||||
{
|
||||
enum term_event_loc loc = tevt_loc_muxc;
|
||||
|
||||
@ -1441,7 +1441,7 @@ static void h2_release(struct h2c *h2c)
|
||||
if (h2c->wait_event.events != 0)
|
||||
conn->xprt->unsubscribe(conn, conn->xprt_ctx, h2c->wait_event.events,
|
||||
&h2c->wait_event);
|
||||
h2c_report_term_evt(h2c, tevt_type_shutw);
|
||||
h2c_report_term_evt(h2c, muxc_tevt_type_shutw);
|
||||
}
|
||||
|
||||
/* Rhttp connections are not accounted prior to their reverse. */
|
||||
@ -1819,13 +1819,19 @@ static inline void h2s_propagate_term_flags(struct h2c *h2c, struct h2s *h2s)
|
||||
if (h2s->flags & H2_SF_ES_RCVD) {
|
||||
se_fl_set(h2s->sd, SE_FL_EOI);
|
||||
/* Add EOS flag for tunnel */
|
||||
if (h2s->flags & H2_SF_BODY_TUNNEL)
|
||||
if (h2s->flags & H2_SF_BODY_TUNNEL) {
|
||||
se_fl_set(h2s->sd, SE_FL_EOS);
|
||||
se_report_term_evt(h2s->sd, (h2c->flags & H2_CF_ERROR ? se_tevt_type_rcv_err : se_tevt_type_eos));
|
||||
}
|
||||
}
|
||||
if (h2c_read0_pending(h2c) || h2s->st == H2_SS_CLOSED) {
|
||||
se_fl_set(h2s->sd, SE_FL_EOS);
|
||||
if (!se_fl_test(h2s->sd, SE_FL_EOI))
|
||||
if (!se_fl_test(h2s->sd, SE_FL_EOI)) {
|
||||
se_fl_set(h2s->sd, SE_FL_ERROR);
|
||||
se_report_term_evt(h2s->sd, (h2c->flags & H2_CF_ERROR ? se_tevt_type_rcv_err : se_tevt_type_eos));
|
||||
}
|
||||
else
|
||||
se_report_term_evt(h2s->sd, (h2c->flags & H2_CF_ERROR ? se_tevt_type_truncated_rcv_err : se_tevt_type_truncated_eos));
|
||||
}
|
||||
if (se_fl_test(h2s->sd, SE_FL_ERR_PENDING))
|
||||
se_fl_set(h2s->sd, SE_FL_ERROR);
|
||||
@ -2351,10 +2357,26 @@ static int h2c_send_goaway_error(struct h2c *h2c, struct h2s *h2s)
|
||||
switch (h2c->errcode) {
|
||||
case H2_ERR_NO_ERROR:
|
||||
case H2_ERR_ENHANCE_YOUR_CALM:
|
||||
h2c_report_term_evt(h2c, muxc_tevt_type_graceful_shut);
|
||||
__fallthrough;
|
||||
case H2_ERR_REFUSED_STREAM:
|
||||
case H2_ERR_CANCEL:
|
||||
break;
|
||||
|
||||
case H2_ERR_PROTOCOL_ERROR:
|
||||
case H2_ERR_FRAME_SIZE_ERROR:
|
||||
case H2_ERR_COMPRESSION_ERROR:
|
||||
h2c_report_term_evt(h2c, muxc_tevt_type_proto_err);
|
||||
HA_ATOMIC_INC(&h2c->px_counters->goaway_resp);
|
||||
break;
|
||||
|
||||
case H2_ERR_INTERNAL_ERROR:
|
||||
h2c_report_term_evt(h2c, muxc_tevt_type_internal_err);
|
||||
HA_ATOMIC_INC(&h2c->px_counters->goaway_resp);
|
||||
break;
|
||||
|
||||
default:
|
||||
h2c_report_term_evt(h2c, muxc_tevt_type_other_err);
|
||||
HA_ATOMIC_INC(&h2c->px_counters->goaway_resp);
|
||||
}
|
||||
out:
|
||||
@ -2487,6 +2509,26 @@ static int h2c_send_rst_stream(struct h2c *h2c, struct h2s *h2s)
|
||||
}
|
||||
}
|
||||
|
||||
if (h2s->id) {
|
||||
switch (h2s->errcode) {
|
||||
case H2_ERR_REFUSED_STREAM:
|
||||
break;
|
||||
|
||||
case H2_ERR_CANCEL:
|
||||
se_report_term_evt(h2s->sd, se_tevt_type_cancelled);
|
||||
break;
|
||||
|
||||
case H2_ERR_STREAM_CLOSED:
|
||||
case H2_ERR_PROTOCOL_ERROR:
|
||||
se_report_term_evt(h2s->sd, se_tevt_type_proto_err);
|
||||
break;
|
||||
case H2_ERR_INTERNAL_ERROR:
|
||||
se_report_term_evt(h2s->sd, se_tevt_type_internal_err);
|
||||
break;
|
||||
default:
|
||||
se_report_term_evt(h2s->sd, se_tevt_type_other_err);
|
||||
}
|
||||
}
|
||||
ignore:
|
||||
if (h2s->id) {
|
||||
h2s->flags |= H2_SF_RST_SENT;
|
||||
@ -3185,6 +3227,7 @@ static int h2c_handle_goaway(struct h2c *h2c)
|
||||
h2c->errcode = h2_get_n32(&h2c->dbuf, 4);
|
||||
if (h2c->last_sid < 0)
|
||||
h2c->last_sid = last;
|
||||
h2c_report_term_evt(h2c, muxc_tevt_type_goaway_rcvd);
|
||||
h2_wake_some_streams(h2c, last);
|
||||
TRACE_LEAVE(H2_EV_RX_FRAME|H2_EV_RX_GOAWAY, h2c->conn);
|
||||
return 1;
|
||||
@ -3245,6 +3288,7 @@ static int h2c_handle_rst_stream(struct h2c *h2c, struct h2s *h2s)
|
||||
|
||||
if (h2s_sc(h2s)) {
|
||||
se_fl_set_error(h2s->sd);
|
||||
se_report_term_evt(h2s->sd, se_tevt_type_rst_rcvd);
|
||||
if (!h2s->sd->abort_info.info) {
|
||||
h2s->sd->abort_info.info = (SE_ABRT_SRC_MUX_H2 << SE_ABRT_SRC_SHIFT);
|
||||
h2s->sd->abort_info.code = h2s->errcode;
|
||||
@ -4406,12 +4450,12 @@ static void h2_process_demux(struct h2c *h2c)
|
||||
|
||||
if (h2c->flags & H2_CF_ERROR)
|
||||
h2c_report_term_evt(h2c, ((eb_is_empty(&h2c->streams_by_id) && !(h2c->flags & H2_CF_DEM_IN_PROGRESS))
|
||||
? tevt_type_rcv_err
|
||||
: tevt_type_truncated_rcv_err));
|
||||
? muxc_tevt_type_rcv_err
|
||||
: muxc_tevt_type_truncated_rcv_err));
|
||||
else if (h2c->flags & H2_CF_END_REACHED)
|
||||
h2c_report_term_evt(h2c, ((eb_is_empty(&h2c->streams_by_id) && !(h2c->flags & H2_CF_DEM_IN_PROGRESS))
|
||||
? tevt_type_shutr
|
||||
: tevt_type_truncated_shutr));
|
||||
? muxc_tevt_type_shutr
|
||||
: muxc_tevt_type_truncated_shutr));
|
||||
|
||||
/* Make sure to clear DFULL if contents were deleted */
|
||||
if (!b_full(&h2c->dbuf))
|
||||
@ -4756,7 +4800,7 @@ static int h2_send(struct h2c *h2c)
|
||||
|
||||
if (conn->flags & CO_FL_ERROR) {
|
||||
h2c->flags |= H2_CF_ERR_PENDING;
|
||||
h2c_report_term_evt(h2c, tevt_type_snd_err);
|
||||
h2c_report_term_evt(h2c, muxc_tevt_type_snd_err);
|
||||
if (h2c->flags & H2_CF_END_REACHED)
|
||||
h2c->flags |= H2_CF_ERROR;
|
||||
b_reset(br_tail(h2c->mbuf));
|
||||
@ -5091,7 +5135,7 @@ struct task *h2_timeout_task(struct task *t, void *context, unsigned int state)
|
||||
return t;
|
||||
}
|
||||
|
||||
h2c_report_term_evt(h2c, tevt_type_tout);
|
||||
h2c_report_term_evt(h2c, muxc_tevt_type_tout);
|
||||
}
|
||||
|
||||
do_leave:
|
||||
@ -7726,6 +7770,7 @@ static size_t h2_snd_buf(struct stconn *sc, struct buffer *buf, size_t count, in
|
||||
if (h2s->st == H2_SS_ERROR || h2s->flags & H2_SF_RST_RCVD) {
|
||||
TRACE_DEVEL("reporting RST/error to the app-layer stream", H2_EV_H2S_SEND|H2_EV_H2S_ERR|H2_EV_STRM_ERR, h2s->h2c->conn, h2s);
|
||||
se_fl_set_error(h2s->sd);
|
||||
se_report_term_evt(h2s->sd, se_tevt_type_snd_err);
|
||||
if (h2s_send_rst_stream(h2s->h2c, h2s) > 0)
|
||||
h2s_close(h2s);
|
||||
}
|
||||
|
16
src/mux_pt.c
16
src/mux_pt.c
@ -201,7 +201,7 @@ static void pt_trace(enum trace_level level, uint64_t mask, const struct trace_s
|
||||
}
|
||||
}
|
||||
|
||||
static inline void mux_pt_report_term_evt(struct mux_pt_ctx *ctx, enum term_event_type type)
|
||||
static inline void mux_pt_report_term_evt(struct mux_pt_ctx *ctx, enum muxc_term_event_type type)
|
||||
{
|
||||
struct connection *conn = ctx->conn;
|
||||
enum term_event_loc loc = tevt_loc_muxc;
|
||||
@ -480,7 +480,7 @@ static void mux_pt_shut(struct stconn *sc, unsigned int mode, struct se_abort_in
|
||||
|
||||
TRACE_ENTER(PT_EV_STRM_SHUT, conn, sc);
|
||||
if (mode & (SE_SHW_SILENT|SE_SHW_NORMAL)) {
|
||||
mux_pt_report_term_evt(ctx, tevt_type_shutw);
|
||||
mux_pt_report_term_evt(ctx, muxc_tevt_type_shutw);
|
||||
|
||||
if (conn_xprt_ready(conn) && conn->xprt->shutw)
|
||||
conn->xprt->shutw(conn, conn->xprt_ctx, (mode & SE_SHW_NORMAL));
|
||||
@ -527,7 +527,7 @@ static size_t mux_pt_rcv_buf(struct stconn *sc, struct buffer *buf, size_t count
|
||||
b_realign_if_empty(buf);
|
||||
ret = conn->xprt->rcv_buf(conn, conn->xprt_ctx, buf, count, flags);
|
||||
if (conn->flags & CO_FL_ERROR) {
|
||||
mux_pt_report_term_evt(ctx, tevt_type_rcv_err);
|
||||
mux_pt_report_term_evt(ctx, muxc_tevt_type_rcv_err);
|
||||
se_fl_clr(ctx->sd, SE_FL_RCV_MORE | SE_FL_WANT_ROOM);
|
||||
if (conn_xprt_read0_pending(conn))
|
||||
se_fl_set(ctx->sd, SE_FL_EOS);
|
||||
@ -535,7 +535,7 @@ static size_t mux_pt_rcv_buf(struct stconn *sc, struct buffer *buf, size_t count
|
||||
TRACE_DEVEL("error on connection", PT_EV_RX_DATA|PT_EV_CONN_ERR, conn, sc);
|
||||
}
|
||||
else if (conn_xprt_read0_pending(conn)) {
|
||||
mux_pt_report_term_evt(ctx, tevt_type_shutr);
|
||||
mux_pt_report_term_evt(ctx, muxc_tevt_type_shutr);
|
||||
se_fl_clr(ctx->sd, SE_FL_RCV_MORE | SE_FL_WANT_ROOM);
|
||||
se_fl_set(ctx->sd, (SE_FL_EOI|SE_FL_EOS));
|
||||
TRACE_DEVEL("read0 on connection", PT_EV_RX_DATA, conn, sc);
|
||||
@ -560,7 +560,7 @@ static size_t mux_pt_snd_buf(struct stconn *sc, struct buffer *buf, size_t count
|
||||
b_del(buf, ret);
|
||||
|
||||
if (conn->flags & CO_FL_ERROR) {
|
||||
mux_pt_report_term_evt(ctx, tevt_type_snd_err);
|
||||
mux_pt_report_term_evt(ctx, muxc_tevt_type_snd_err);
|
||||
if (conn_xprt_read0_pending(conn))
|
||||
se_fl_set(ctx->sd, SE_FL_EOS);
|
||||
se_fl_set_error(ctx->sd);
|
||||
@ -714,14 +714,14 @@ static int mux_pt_fastfwd(struct stconn *sc, unsigned int count, unsigned int fl
|
||||
|
||||
out:
|
||||
if (conn->flags & CO_FL_ERROR) {
|
||||
mux_pt_report_term_evt(ctx, tevt_type_rcv_err);
|
||||
mux_pt_report_term_evt(ctx, muxc_tevt_type_rcv_err);
|
||||
if (conn_xprt_read0_pending(conn))
|
||||
se_fl_set(ctx->sd, SE_FL_EOS);
|
||||
se_fl_set(ctx->sd, SE_FL_ERROR);
|
||||
TRACE_DEVEL("error on connection", PT_EV_RX_DATA|PT_EV_CONN_ERR, conn, sc);
|
||||
}
|
||||
else if (conn_xprt_read0_pending(conn)) {
|
||||
mux_pt_report_term_evt(ctx, tevt_type_shutr);
|
||||
mux_pt_report_term_evt(ctx, muxc_tevt_type_shutr);
|
||||
se_fl_set(ctx->sd, (SE_FL_EOS|SE_FL_EOI));
|
||||
TRACE_DEVEL("read0 on connection", PT_EV_RX_DATA, conn, sc);
|
||||
}
|
||||
@ -752,7 +752,7 @@ static int mux_pt_resume_fastfwd(struct stconn *sc, unsigned int flags)
|
||||
|
||||
out:
|
||||
if (conn->flags & CO_FL_ERROR) {
|
||||
mux_pt_report_term_evt(ctx, tevt_type_snd_err);
|
||||
mux_pt_report_term_evt(ctx, muxc_tevt_type_snd_err);
|
||||
if (conn_xprt_read0_pending(conn))
|
||||
se_fl_set(ctx->sd, SE_FL_EOS);
|
||||
se_fl_set_error(ctx->sd);
|
||||
|
Loading…
Reference in New Issue
Block a user