unsigned int stream_cnt; /* total number of streams seen */
int glitches; /* total number of glitches on this connection */
+ uint32_t term_evts_log; /* Termination events log: first 4 events reported */
+
struct proxy *proxy; /* the proxy this connection was created for */
struct task *task; /* timeout management task */
struct h2_counters *px_counters; /* h2 counters attached to proxy */
}
}
+static inline void h2c_report_term_evt(struct h2c *h2c, enum term_event_type type)
+{
+ enum term_event_loc loc = tevt_loc_muxc;
+
+ if (h2c->flags & H2_CF_IS_BACK)
+ loc += 8;
+ h2c->term_evts_log = tevt_report_event(h2c->term_evts_log, loc, type);
+}
/* Detect a pending read0 for a H2 connection. It happens if a read0 was
* already reported on a previous xprt->rcvbuf() AND a frame parser failed
h2c->stream_cnt = 0;
h2c->receiving_streams = 0;
h2c->glitches = 0;
+ h2c->term_evts_log = 0;
h2c->dbuf = *input;
h2c->dsi = -1;
h2c->task = NULL;
}
tasklet_free(h2c->wait_event.tasklet);
- if (conn && h2c->wait_event.events != 0)
- conn->xprt->unsubscribe(conn, conn->xprt_ctx, h2c->wait_event.events,
- &h2c->wait_event);
+ if (conn) {
+ 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);
+ }
/* Rhttp connections are not accounted prior to their reverse. */
if (!conn || !conn_is_reverse(conn))
h2c->flags |= H2_CF_END_REACHED;
}
+ 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));
+ 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));
+
/* Make sure to clear DFULL if contents were deleted */
if (!b_full(&h2c->dbuf))
h2c->flags &= ~H2_CF_DEM_DFULL;
if (conn->flags & CO_FL_ERROR) {
h2c->flags |= H2_CF_ERR_PENDING;
+ h2c_report_term_evt(h2c, tevt_type_snd_err);
if (h2c->flags & H2_CF_END_REACHED)
h2c->flags |= H2_CF_ERROR;
b_reset(br_tail(h2c->mbuf));
t->expire = tick_add_ifset(now_ms, h2c->timeout);
return t;
}
+
+ h2c_report_term_evt(h2c, tevt_type_tout);
}
do_leave: