const char *name;
/* functor used to generate the stats module using counters provided through data parameter */
- void (*fill_stats)(void *data, struct field *);
+ int (*fill_stats)(void *data, struct field *, unsigned int *);
struct name_desc *stats; /* name/description of stats provided by the module */
void *counters; /* initial values of allocated counters */
long long qpack_decoder_stream_error; /* total number of QPACK_DECODER_STREAM_ERROR errors received */
} h3_counters;
-static void h3_fill_stats(void *data, struct field *stats)
+static int h3_fill_stats(void *data, struct field *stats, unsigned int *selected_field)
{
struct h3_counters *counters = data;
+ unsigned int current_field = (selected_field != NULL ? *selected_field : 0);
- /* h3 frame type counters */
- stats[H3_ST_DATA] = mkf_u64(FN_COUNTER, counters->h3_data);
- stats[H3_ST_HEADERS] = mkf_u64(FN_COUNTER, counters->h3_headers);
- stats[H3_ST_CANCEL_PUSH] = mkf_u64(FN_COUNTER, counters->h3_cancel_push);
- stats[H3_ST_PUSH_PROMISE] = mkf_u64(FN_COUNTER, counters->h3_push_promise);
- stats[H3_ST_MAX_PUSH_ID] = mkf_u64(FN_COUNTER, counters->h3_max_push_id);
- stats[H3_ST_GOAWAY] = mkf_u64(FN_COUNTER, counters->h3_goaway);
- stats[H3_ST_SETTINGS] = mkf_u64(FN_COUNTER, counters->h3_settings);
- /* h3 error counters */
- stats[H3_ST_H3_NO_ERROR] = mkf_u64(FN_COUNTER, counters->h3_no_error);
- stats[H3_ST_H3_GENERAL_PROTOCOL_ERROR] = mkf_u64(FN_COUNTER, counters->h3_general_protocol_error);
- stats[H3_ST_H3_INTERNAL_ERROR] = mkf_u64(FN_COUNTER, counters->h3_internal_error);
- stats[H3_ST_H3_STREAM_CREATION_ERROR] = mkf_u64(FN_COUNTER, counters->h3_stream_creation_error);
- stats[H3_ST_H3_CLOSED_CRITICAL_STREAM] = mkf_u64(FN_COUNTER, counters->h3_closed_critical_stream);
- stats[H3_ST_H3_FRAME_UNEXPECTED] = mkf_u64(FN_COUNTER, counters->h3_frame_unexpected);
- stats[H3_ST_H3_FRAME_ERROR] = mkf_u64(FN_COUNTER, counters->h3_frame_error);
- stats[H3_ST_H3_EXCESSIVE_LOAD] = mkf_u64(FN_COUNTER, counters->h3_excessive_load);
- stats[H3_ST_H3_ID_ERROR] = mkf_u64(FN_COUNTER, counters->h3_id_error);
- stats[H3_ST_H3_SETTINGS_ERROR] = mkf_u64(FN_COUNTER, counters->h3_settings_error);
- stats[H3_ST_H3_MISSING_SETTINGS] = mkf_u64(FN_COUNTER, counters->h3_missing_settings);
- stats[H3_ST_H3_REQUEST_REJECTED] = mkf_u64(FN_COUNTER, counters->h3_request_rejected);
- stats[H3_ST_H3_REQUEST_CANCELLED] = mkf_u64(FN_COUNTER, counters->h3_request_cancelled);
- stats[H3_ST_H3_REQUEST_INCOMPLETE] = mkf_u64(FN_COUNTER, counters->h3_request_incomplete);
- stats[H3_ST_H3_MESSAGE_ERROR] = mkf_u64(FN_COUNTER, counters->h3_message_error);
- stats[H3_ST_H3_CONNECT_ERROR] = mkf_u64(FN_COUNTER, counters->h3_connect_error);
- stats[H3_ST_H3_VERSION_FALLBACK] = mkf_u64(FN_COUNTER, counters->h3_version_fallback);
- /* QPACK error counters */
- stats[H3_ST_QPACK_DECOMPRESSION_FAILED] = mkf_u64(FN_COUNTER, counters->qpack_decompression_failed);
- stats[H3_ST_QPACK_ENCODER_STREAM_ERROR] = mkf_u64(FN_COUNTER, counters->qpack_encoder_stream_error);
- stats[H3_ST_QPACK_DECODER_STREAM_ERROR] = mkf_u64(FN_COUNTER, counters->qpack_decoder_stream_error);
+ for (; current_field < H3_STATS_COUNT; current_field++) {
+ struct field metric = { 0 };
+
+ switch (current_field) {
+ /* h3 frame type counters */
+ case H3_ST_DATA:
+ metric = mkf_u64(FN_COUNTER, counters->h3_data);
+ break;
+ case H3_ST_HEADERS:
+ metric = mkf_u64(FN_COUNTER, counters->h3_headers);
+ break;
+ case H3_ST_CANCEL_PUSH:
+ metric = mkf_u64(FN_COUNTER, counters->h3_cancel_push);
+ break;
+ case H3_ST_PUSH_PROMISE:
+ metric = mkf_u64(FN_COUNTER, counters->h3_push_promise);
+ break;
+ case H3_ST_MAX_PUSH_ID:
+ metric = mkf_u64(FN_COUNTER, counters->h3_max_push_id);
+ break;
+ case H3_ST_GOAWAY:
+ metric = mkf_u64(FN_COUNTER, counters->h3_goaway);
+ break;
+ case H3_ST_SETTINGS:
+ metric = mkf_u64(FN_COUNTER, counters->h3_settings);
+ break;
+
+ /* h3 error counters */
+ case H3_ST_H3_NO_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->h3_no_error);
+ break;
+ case H3_ST_H3_GENERAL_PROTOCOL_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->h3_general_protocol_error);
+ break;
+ case H3_ST_H3_INTERNAL_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->h3_internal_error);
+ break;
+ case H3_ST_H3_STREAM_CREATION_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->h3_stream_creation_error);
+ break;
+ case H3_ST_H3_CLOSED_CRITICAL_STREAM:
+ metric = mkf_u64(FN_COUNTER, counters->h3_closed_critical_stream);
+ break;
+ case H3_ST_H3_FRAME_UNEXPECTED:
+ metric = mkf_u64(FN_COUNTER, counters->h3_frame_unexpected);
+ break;
+ case H3_ST_H3_FRAME_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->h3_frame_error);
+ break;
+ case H3_ST_H3_EXCESSIVE_LOAD:
+ metric = mkf_u64(FN_COUNTER, counters->h3_excessive_load);
+ break;
+ case H3_ST_H3_ID_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->h3_id_error);
+ break;
+ case H3_ST_H3_SETTINGS_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->h3_settings_error);
+ break;
+ case H3_ST_H3_MISSING_SETTINGS:
+ metric = mkf_u64(FN_COUNTER, counters->h3_missing_settings);
+ break;
+ case H3_ST_H3_REQUEST_REJECTED:
+ metric = mkf_u64(FN_COUNTER, counters->h3_request_rejected);
+ break;
+ case H3_ST_H3_REQUEST_CANCELLED:
+ metric = mkf_u64(FN_COUNTER, counters->h3_request_cancelled);
+ break;
+ case H3_ST_H3_REQUEST_INCOMPLETE:
+ metric = mkf_u64(FN_COUNTER, counters->h3_request_incomplete);
+ break;
+ case H3_ST_H3_MESSAGE_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->h3_message_error);
+ break;
+ case H3_ST_H3_CONNECT_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->h3_connect_error);
+ break;
+ case H3_ST_H3_VERSION_FALLBACK:
+ metric = mkf_u64(FN_COUNTER, counters->h3_version_fallback);
+ break;
+
+ /* QPACK error counters */
+ case H3_ST_QPACK_DECOMPRESSION_FAILED:
+ metric = mkf_u64(FN_COUNTER, counters->qpack_decompression_failed);
+ break;
+ case H3_ST_QPACK_ENCODER_STREAM_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->qpack_encoder_stream_error);
+ break;
+ case H3_ST_QPACK_DECODER_STREAM_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->qpack_decoder_stream_error);
+ break;
+ default:
+ /* not used for frontends. If a specific metric
+ * is requested, return an error. Otherwise continue.
+ */
+ if (selected_field != NULL)
+ return 0;
+ continue;
+ }
+ stats[current_field] = metric;
+ if (selected_field != NULL)
+ break;
+ }
+ return 1;
}
struct stats_module h3_stats_module = {
#endif
} h1_counters;
-static void h1_fill_stats(void *data, struct field *stats)
+static int h1_fill_stats(void *data, struct field *stats, unsigned int *selected_field)
{
struct h1_counters *counters = data;
+ unsigned int current_field = (selected_field != NULL ? *selected_field : 0);
- stats[H1_ST_OPEN_CONN] = mkf_u64(FN_GAUGE, counters->open_conns);
- stats[H1_ST_OPEN_STREAM] = mkf_u64(FN_GAUGE, counters->open_streams);
- stats[H1_ST_TOTAL_CONN] = mkf_u64(FN_COUNTER, counters->total_conns);
- stats[H1_ST_TOTAL_STREAM] = mkf_u64(FN_COUNTER, counters->total_streams);
+ for (; current_field < H1_STATS_COUNT; current_field++) {
+ struct field metric = { 0 };
- stats[H1_ST_BYTES_IN] = mkf_u64(FN_COUNTER, counters->bytes_in);
- stats[H1_ST_BYTES_OUT] = mkf_u64(FN_COUNTER, counters->bytes_out);
+ switch (current_field) {
+ case H1_ST_OPEN_CONN:
+ metric = mkf_u64(FN_GAUGE, counters->open_conns);
+ break;
+ case H1_ST_OPEN_STREAM:
+ metric = mkf_u64(FN_GAUGE, counters->open_streams);
+ break;
+ case H1_ST_TOTAL_CONN:
+ metric = mkf_u64(FN_COUNTER, counters->total_conns);
+ break;
+ case H1_ST_TOTAL_STREAM:
+ metric = mkf_u64(FN_COUNTER, counters->total_streams);
+ break;
+ case H1_ST_BYTES_IN:
+ metric = mkf_u64(FN_COUNTER, counters->bytes_in);
+ break;
+ case H1_ST_BYTES_OUT:
+ metric = mkf_u64(FN_COUNTER, counters->bytes_out);
+ break;
#if defined(USE_LINUX_SPLICE)
- stats[H1_ST_SPLICED_BYTES_IN] = mkf_u64(FN_COUNTER, counters->spliced_bytes_in);
- stats[H1_ST_SPLICED_BYTES_OUT] = mkf_u64(FN_COUNTER, counters->spliced_bytes_out);
+ case H1_ST_SPLICED_BYTES_IN:
+ metric = mkf_u64(FN_COUNTER, counters->spliced_bytes_in);
+ break;
+ case H1_ST_SPLICED_BYTES_OUT:
+ metric = mkf_u64(FN_COUNTER, counters->spliced_bytes_out);
+ break;
#endif
+ default:
+ /* not used for frontends. If a specific metric
+ * is requested, return an error. Otherwise continue.
+ */
+ if (selected_field != NULL)
+ return 0;
+ continue;
+ }
+ stats[current_field] = metric;
+ if (selected_field != NULL)
+ break;
+ }
+ return 1;
}
static struct stats_module h1_stats_module = {
long long total_streams; /* total number of streams */
} h2_counters;
-static void h2_fill_stats(void *data, struct field *stats)
+static int h2_fill_stats(void *data, struct field *stats, unsigned int *selected_field)
{
struct h2_counters *counters = data;
+ unsigned int current_field = (selected_field != NULL ? *selected_field : 0);
- stats[H2_ST_HEADERS_RCVD] = mkf_u64(FN_COUNTER, counters->headers_rcvd);
- stats[H2_ST_DATA_RCVD] = mkf_u64(FN_COUNTER, counters->data_rcvd);
- stats[H2_ST_SETTINGS_RCVD] = mkf_u64(FN_COUNTER, counters->settings_rcvd);
- stats[H2_ST_RST_STREAM_RCVD] = mkf_u64(FN_COUNTER, counters->rst_stream_rcvd);
- stats[H2_ST_GOAWAY_RCVD] = mkf_u64(FN_COUNTER, counters->goaway_rcvd);
-
- stats[H2_ST_CONN_PROTO_ERR] = mkf_u64(FN_COUNTER, counters->conn_proto_err);
- stats[H2_ST_STRM_PROTO_ERR] = mkf_u64(FN_COUNTER, counters->strm_proto_err);
- stats[H2_ST_RST_STREAM_RESP] = mkf_u64(FN_COUNTER, counters->rst_stream_resp);
- stats[H2_ST_GOAWAY_RESP] = mkf_u64(FN_COUNTER, counters->goaway_resp);
-
- stats[H2_ST_OPEN_CONN] = mkf_u64(FN_GAUGE, counters->open_conns);
- stats[H2_ST_OPEN_STREAM] = mkf_u64(FN_GAUGE, counters->open_streams);
- stats[H2_ST_TOTAL_CONN] = mkf_u64(FN_COUNTER, counters->total_conns);
- stats[H2_ST_TOTAL_STREAM] = mkf_u64(FN_COUNTER, counters->total_streams);
+ for (; current_field < H2_STATS_COUNT; current_field++) {
+ struct field metric = { 0 };
+
+ switch (current_field) {
+ case H2_ST_HEADERS_RCVD:
+ metric = mkf_u64(FN_COUNTER, counters->headers_rcvd);
+ break;
+ case H2_ST_DATA_RCVD:
+ metric = mkf_u64(FN_COUNTER, counters->data_rcvd);
+ break;
+ case H2_ST_SETTINGS_RCVD:
+ metric = mkf_u64(FN_COUNTER, counters->settings_rcvd);
+ break;
+ case H2_ST_RST_STREAM_RCVD:
+ metric = mkf_u64(FN_COUNTER, counters->rst_stream_rcvd);
+ break;
+ case H2_ST_GOAWAY_RCVD:
+ metric = mkf_u64(FN_COUNTER, counters->goaway_rcvd);
+ break;
+ case H2_ST_CONN_PROTO_ERR:
+ metric = mkf_u64(FN_COUNTER, counters->conn_proto_err);
+ break;
+ case H2_ST_STRM_PROTO_ERR:
+ metric = mkf_u64(FN_COUNTER, counters->strm_proto_err);
+ break;
+ case H2_ST_RST_STREAM_RESP:
+ metric = mkf_u64(FN_COUNTER, counters->rst_stream_resp);
+ break;
+ case H2_ST_GOAWAY_RESP:
+ metric = mkf_u64(FN_COUNTER, counters->goaway_resp);
+ break;
+ case H2_ST_OPEN_CONN:
+ metric = mkf_u64(FN_GAUGE, counters->open_conns);
+ break;
+ case H2_ST_OPEN_STREAM:
+ metric = mkf_u64(FN_GAUGE, counters->open_streams);
+ break;
+ case H2_ST_TOTAL_CONN:
+ metric = mkf_u64(FN_COUNTER, counters->total_conns);
+ break;
+ case H2_ST_TOTAL_STREAM:
+ metric = mkf_u64(FN_COUNTER, counters->total_streams);
+ break;
+ default:
+ /* not used for frontends. If a specific metric
+ * is requested, return an error. Otherwise continue.
+ */
+ if (selected_field != NULL)
+ return 0;
+ continue;
+ }
+ stats[current_field] = metric;
+ if (selected_field != NULL)
+ break;
+ }
+ return 1;
}
static struct stats_module h2_stats_module = {
struct quic_counters quic_counters;
-static void quic_fill_stats(void *data, struct field *stats)
+static int quic_fill_stats(void *data, struct field *stats, unsigned int *selected_field)
{
struct quic_counters *counters = data;
+ unsigned int current_field = (selected_field != NULL ? *selected_field : 0);
- stats[QUIC_ST_RXBUF_FULL] = mkf_u64(FN_COUNTER, counters->rxbuf_full);
- stats[QUIC_ST_DROPPED_PACKET] = mkf_u64(FN_COUNTER, counters->dropped_pkt);
- stats[QUIC_ST_DROPPED_PACKET_BUFOVERRUN] = mkf_u64(FN_COUNTER, counters->dropped_pkt_bufoverrun);
- stats[QUIC_ST_DROPPED_PARSING] = mkf_u64(FN_COUNTER, counters->dropped_parsing);
- stats[QUIC_ST_SOCKET_FULL] = mkf_u64(FN_COUNTER, counters->socket_full);
- stats[QUIC_ST_SENDTO_ERR] = mkf_u64(FN_COUNTER, counters->sendto_err);
- stats[QUIC_ST_SENDTO_ERR_UNKNWN] = mkf_u64(FN_COUNTER, counters->sendto_err_unknown);
- stats[QUIC_ST_SENT_PACKET] = mkf_u64(FN_COUNTER, counters->sent_pkt);
- stats[QUIC_ST_LOST_PACKET] = mkf_u64(FN_COUNTER, counters->lost_pkt);
- stats[QUIC_ST_TOO_SHORT_INITIAL_DGRAM] = mkf_u64(FN_COUNTER, counters->too_short_initial_dgram);
- stats[QUIC_ST_RETRY_SENT] = mkf_u64(FN_COUNTER, counters->retry_sent);
- stats[QUIC_ST_RETRY_VALIDATED] = mkf_u64(FN_COUNTER, counters->retry_validated);
- stats[QUIC_ST_RETRY_ERRORS] = mkf_u64(FN_COUNTER, counters->retry_error);
- stats[QUIC_ST_HALF_OPEN_CONN] = mkf_u64(FN_GAUGE, counters->half_open_conn);
- stats[QUIC_ST_HDSHK_FAIL] = mkf_u64(FN_COUNTER, counters->hdshk_fail);
- stats[QUIC_ST_STATELESS_RESET_SENT] = mkf_u64(FN_COUNTER, counters->stateless_reset_sent);
- /* Special events of interest */
- stats[QUIC_ST_CONN_MIGRATION_DONE] = mkf_u64(FN_COUNTER, counters->conn_migration_done);
- /* Transport errors */
- stats[QUIC_ST_TRANSP_ERR_NO_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_no_error);
- stats[QUIC_ST_TRANSP_ERR_INTERNAL_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_internal_error);
- stats[QUIC_ST_TRANSP_ERR_CONNECTION_REFUSED] = mkf_u64(FN_COUNTER, counters->quic_transp_err_connection_refused);
- stats[QUIC_ST_TRANSP_ERR_FLOW_CONTROL_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_flow_control_error);
- stats[QUIC_ST_TRANSP_ERR_STREAM_LIMIT_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_stream_limit_error);
- stats[QUIC_ST_TRANSP_ERR_STREAM_STATE_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_stream_state_error);
- stats[QUIC_ST_TRANSP_ERR_FINAL_SIZE_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_final_size_error);
- stats[QUIC_ST_TRANSP_ERR_FRAME_ENCODING_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_frame_encoding_error);
- stats[QUIC_ST_TRANSP_ERR_TRANSPORT_PARAMETER_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_transport_parameter_error);
- stats[QUIC_ST_TRANSP_ERR_CONNECTION_ID_LIMIT_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_connection_id_limit);
- stats[QUIC_ST_TRANSP_ERR_PROTOCOL_VIOLATION] = mkf_u64(FN_COUNTER, counters->quic_transp_err_protocol_violation);
- stats[QUIC_ST_TRANSP_ERR_INVALID_TOKEN] = mkf_u64(FN_COUNTER, counters->quic_transp_err_invalid_token);
- stats[QUIC_ST_TRANSP_ERR_APPLICATION_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_application_error);
- stats[QUIC_ST_TRANSP_ERR_CRYPTO_BUFFER_EXCEEDED] = mkf_u64(FN_COUNTER, counters->quic_transp_err_crypto_buffer_exceeded);
- stats[QUIC_ST_TRANSP_ERR_KEY_UPDATE_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_key_update_error);
- stats[QUIC_ST_TRANSP_ERR_AEAD_LIMIT_REACHED] = mkf_u64(FN_COUNTER, counters->quic_transp_err_aead_limit_reached);
- stats[QUIC_ST_TRANSP_ERR_NO_VIABLE_PATH] = mkf_u64(FN_COUNTER, counters->quic_transp_err_no_viable_path);
- stats[QUIC_ST_TRANSP_ERR_CRYPTO_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_crypto_error);
- stats[QUIC_ST_TRANSP_ERR_UNKNOWN_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_unknown_error);
- /* Streams related counters */
- stats[QUIC_ST_DATA_BLOCKED] = mkf_u64(FN_COUNTER, counters->data_blocked);
- stats[QUIC_ST_STREAM_DATA_BLOCKED] = mkf_u64(FN_COUNTER, counters->stream_data_blocked);
- stats[QUIC_ST_STREAMS_BLOCKED_BIDI] = mkf_u64(FN_COUNTER, counters->streams_blocked_bidi);
- stats[QUIC_ST_STREAMS_BLOCKED_UNI] = mkf_u64(FN_COUNTER, counters->streams_blocked_uni);
+ for (; current_field < QUIC_STATS_COUNT; current_field++) {
+ struct field metric = { 0 };
+
+ switch (current_field) {
+ case QUIC_ST_RXBUF_FULL:
+ metric = mkf_u64(FN_COUNTER, counters->rxbuf_full);
+ break;
+ case QUIC_ST_DROPPED_PACKET:
+ metric = mkf_u64(FN_COUNTER, counters->dropped_pkt);
+ break;
+ case QUIC_ST_DROPPED_PACKET_BUFOVERRUN:
+ metric = mkf_u64(FN_COUNTER, counters->dropped_pkt_bufoverrun);
+ break;
+ case QUIC_ST_DROPPED_PARSING:
+ metric = mkf_u64(FN_COUNTER, counters->dropped_parsing);
+ break;
+ case QUIC_ST_SOCKET_FULL:
+ metric = mkf_u64(FN_COUNTER, counters->socket_full);
+ break;
+ case QUIC_ST_SENDTO_ERR:
+ metric = mkf_u64(FN_COUNTER, counters->sendto_err);
+ break;
+ case QUIC_ST_SENDTO_ERR_UNKNWN:
+ metric = mkf_u64(FN_COUNTER, counters->sendto_err_unknown);
+ break;
+ case QUIC_ST_SENT_PACKET:
+ metric = mkf_u64(FN_COUNTER, counters->sent_pkt);
+ break;
+ case QUIC_ST_LOST_PACKET:
+ metric = mkf_u64(FN_COUNTER, counters->lost_pkt);
+ break;
+ case QUIC_ST_TOO_SHORT_INITIAL_DGRAM:
+ metric = mkf_u64(FN_COUNTER, counters->too_short_initial_dgram);
+ break;
+ case QUIC_ST_RETRY_SENT:
+ metric = mkf_u64(FN_COUNTER, counters->retry_sent);
+ break;
+ case QUIC_ST_RETRY_VALIDATED:
+ metric = mkf_u64(FN_COUNTER, counters->retry_validated);
+ break;
+ case QUIC_ST_RETRY_ERRORS:
+ metric = mkf_u64(FN_COUNTER, counters->retry_error);
+ break;
+ case QUIC_ST_HALF_OPEN_CONN:
+ metric = mkf_u64(FN_GAUGE, counters->half_open_conn);
+ break;
+ case QUIC_ST_HDSHK_FAIL:
+ metric = mkf_u64(FN_COUNTER, counters->hdshk_fail);
+ break;
+ case QUIC_ST_STATELESS_RESET_SENT:
+ metric = mkf_u64(FN_COUNTER, counters->stateless_reset_sent);
+ break;
+
+ /* Special events of interest */
+ case QUIC_ST_CONN_MIGRATION_DONE:
+ metric = mkf_u64(FN_COUNTER, counters->conn_migration_done);
+ break;
+
+ /* Transport errors */
+ case QUIC_ST_TRANSP_ERR_NO_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_no_error);
+ break;
+ case QUIC_ST_TRANSP_ERR_INTERNAL_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_internal_error);
+ break;
+ case QUIC_ST_TRANSP_ERR_CONNECTION_REFUSED:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_connection_refused);
+ break;
+ case QUIC_ST_TRANSP_ERR_FLOW_CONTROL_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_flow_control_error);
+ break;
+ case QUIC_ST_TRANSP_ERR_STREAM_LIMIT_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_stream_limit_error);
+ break;
+ case QUIC_ST_TRANSP_ERR_STREAM_STATE_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_stream_state_error);
+ break;
+ case QUIC_ST_TRANSP_ERR_FINAL_SIZE_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_final_size_error);
+ break;
+ case QUIC_ST_TRANSP_ERR_FRAME_ENCODING_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_frame_encoding_error);
+ break;
+ case QUIC_ST_TRANSP_ERR_TRANSPORT_PARAMETER_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_transport_parameter_error);
+ break;
+ case QUIC_ST_TRANSP_ERR_CONNECTION_ID_LIMIT_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_connection_id_limit);
+ break;
+ case QUIC_ST_TRANSP_ERR_PROTOCOL_VIOLATION:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_protocol_violation);
+ break;
+ case QUIC_ST_TRANSP_ERR_INVALID_TOKEN:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_invalid_token);
+ break;
+ case QUIC_ST_TRANSP_ERR_APPLICATION_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_application_error);
+ break;
+ case QUIC_ST_TRANSP_ERR_CRYPTO_BUFFER_EXCEEDED:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_crypto_buffer_exceeded);
+ break;
+ case QUIC_ST_TRANSP_ERR_KEY_UPDATE_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_key_update_error);
+ break;
+ case QUIC_ST_TRANSP_ERR_AEAD_LIMIT_REACHED:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_aead_limit_reached);
+ break;
+ case QUIC_ST_TRANSP_ERR_NO_VIABLE_PATH:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_no_viable_path);
+ break;
+ case QUIC_ST_TRANSP_ERR_CRYPTO_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_crypto_error);
+ break;
+ case QUIC_ST_TRANSP_ERR_UNKNOWN_ERROR:
+ metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_unknown_error);
+ break;
+
+ /* Streams related counters */
+ case QUIC_ST_DATA_BLOCKED:
+ metric = mkf_u64(FN_COUNTER, counters->data_blocked);
+ break;
+ case QUIC_ST_STREAM_DATA_BLOCKED:
+ metric = mkf_u64(FN_COUNTER, counters->stream_data_blocked);
+ break;
+ case QUIC_ST_STREAMS_BLOCKED_BIDI:
+ metric = mkf_u64(FN_COUNTER, counters->streams_blocked_bidi);
+ break;
+ case QUIC_ST_STREAMS_BLOCKED_UNI:
+ metric = mkf_u64(FN_COUNTER, counters->streams_blocked_uni);
+ break;
+ default:
+ /* not used for frontends. If a specific metric
+ * is requested, return an error. Otherwise continue.
+ */
+ if (selected_field != NULL)
+ return 0;
+ continue;
+ }
+ stats[current_field] = metric;
+ if (selected_field != NULL)
+ break;
+ }
+ return 1;
}
struct stats_module quic_stats_module = {
static struct dns_counters dns_counters;
-static void resolv_fill_stats(void *d, struct field *stats)
+static int resolv_fill_stats(void *d, struct field *stats, unsigned int *selected_field)
{
struct dns_counters *counters = d;
- stats[RSLV_STAT_ID] = mkf_str(FO_CONFIG, counters->id);
- stats[RSLV_STAT_PID] = mkf_str(FO_CONFIG, counters->pid);
- stats[RSLV_STAT_SENT] = mkf_u64(FN_GAUGE, counters->sent);
- stats[RSLV_STAT_SND_ERROR] = mkf_u64(FN_GAUGE, counters->snd_error);
- stats[RSLV_STAT_VALID] = mkf_u64(FN_GAUGE, counters->app.resolver.valid);
- stats[RSLV_STAT_UPDATE] = mkf_u64(FN_GAUGE, counters->app.resolver.update);
- stats[RSLV_STAT_CNAME] = mkf_u64(FN_GAUGE, counters->app.resolver.cname);
- stats[RSLV_STAT_CNAME_ERROR] = mkf_u64(FN_GAUGE, counters->app.resolver.cname_error);
- stats[RSLV_STAT_ANY_ERR] = mkf_u64(FN_GAUGE, counters->app.resolver.any_err);
- stats[RSLV_STAT_NX] = mkf_u64(FN_GAUGE, counters->app.resolver.nx);
- stats[RSLV_STAT_TIMEOUT] = mkf_u64(FN_GAUGE, counters->app.resolver.timeout);
- stats[RSLV_STAT_REFUSED] = mkf_u64(FN_GAUGE, counters->app.resolver.refused);
- stats[RSLV_STAT_OTHER] = mkf_u64(FN_GAUGE, counters->app.resolver.other);
- stats[RSLV_STAT_INVALID] = mkf_u64(FN_GAUGE, counters->app.resolver.invalid);
- stats[RSLV_STAT_TOO_BIG] = mkf_u64(FN_GAUGE, counters->app.resolver.too_big);
- stats[RSLV_STAT_TRUNCATED] = mkf_u64(FN_GAUGE, counters->app.resolver.truncated);
- stats[RSLV_STAT_OUTDATED] = mkf_u64(FN_GAUGE, counters->app.resolver.outdated);
+ unsigned int current_field = (selected_field != NULL ? *selected_field : 0);
+
+ for (; current_field < RSLV_STAT_END; current_field++) {
+ struct field metric = { 0 };
+
+ switch (current_field) {
+ case RSLV_STAT_ID:
+ metric = mkf_str(FO_CONFIG, counters->id);
+ break;
+ case RSLV_STAT_PID:
+ metric = mkf_str(FO_CONFIG, counters->pid);
+ break;
+ case RSLV_STAT_SENT:
+ metric = mkf_u64(FN_GAUGE, counters->sent);
+ break;
+ case RSLV_STAT_SND_ERROR:
+ metric = mkf_u64(FN_GAUGE, counters->snd_error);
+ break;
+ case RSLV_STAT_VALID:
+ metric = mkf_u64(FN_GAUGE, counters->app.resolver.valid);
+ break;
+ case RSLV_STAT_UPDATE:
+ metric = mkf_u64(FN_GAUGE, counters->app.resolver.update);
+ break;
+ case RSLV_STAT_CNAME:
+ metric = mkf_u64(FN_GAUGE, counters->app.resolver.cname);
+ break;
+ case RSLV_STAT_CNAME_ERROR:
+ metric = mkf_u64(FN_GAUGE, counters->app.resolver.cname_error);
+ break;
+ case RSLV_STAT_ANY_ERR:
+ metric = mkf_u64(FN_GAUGE, counters->app.resolver.any_err);
+ break;
+ case RSLV_STAT_NX:
+ metric = mkf_u64(FN_GAUGE, counters->app.resolver.nx);
+ break;
+ case RSLV_STAT_TIMEOUT:
+ metric = mkf_u64(FN_GAUGE, counters->app.resolver.timeout);
+ break;
+ case RSLV_STAT_REFUSED:
+ metric = mkf_u64(FN_GAUGE, counters->app.resolver.refused);
+ break;
+ case RSLV_STAT_OTHER:
+ metric = mkf_u64(FN_GAUGE, counters->app.resolver.other);
+ break;
+ case RSLV_STAT_INVALID:
+ metric = mkf_u64(FN_GAUGE, counters->app.resolver.invalid);
+ break;
+ case RSLV_STAT_TOO_BIG:
+ metric = mkf_u64(FN_GAUGE, counters->app.resolver.too_big);
+ break;
+ case RSLV_STAT_TRUNCATED:
+ metric = mkf_u64(FN_GAUGE, counters->app.resolver.truncated);
+ break;
+ case RSLV_STAT_OUTDATED:
+ metric = mkf_u64(FN_GAUGE, counters->app.resolver.outdated);
+ break;
+ default:
+ /* not used for frontends. If a specific metric
+ * is requested, return an error. Otherwise continue.
+ */
+ if (selected_field != NULL)
+ return 0;
+ continue;
+ }
+ stats[current_field] = metric;
+ if (selected_field != NULL)
+ break;
+ }
+ return 1;
}
static struct stats_module rslv_stats_module = {
list_for_each_entry(mod, stat_modules, list) {
struct counters_node *counters = EXTRA_COUNTERS_GET(ns->extra_counters, mod);
- mod->fill_stats(counters, stats + idx);
+ if (!mod->fill_stats(counters, stats + idx, NULL))
+ continue;
idx += mod->stats_count;
}
long long failed_handshake;
} ssl_counters;
-static void ssl_fill_stats(void *data, struct field *stats)
+static int ssl_fill_stats(void *data, struct field *stats, unsigned int *selected_field)
{
struct ssl_counters *counters = data;
+ unsigned int current_field = (selected_field != NULL ? *selected_field : 0);
- stats[SSL_ST_SESS] = mkf_u64(FN_COUNTER, counters->sess);
- stats[SSL_ST_REUSED_SESS] = mkf_u64(FN_COUNTER, counters->reused_sess);
- stats[SSL_ST_FAILED_HANDSHAKE] = mkf_u64(FN_COUNTER, counters->failed_handshake);
+ for (; current_field < SSL_ST_STATS_COUNT; current_field++) {
+ struct field metric = { 0 };
+
+ switch (current_field) {
+ case SSL_ST_SESS:
+ metric = mkf_u64(FN_COUNTER, counters->sess);
+ break;
+ case SSL_ST_REUSED_SESS:
+ metric = mkf_u64(FN_COUNTER, counters->reused_sess);
+ break;
+ case SSL_ST_FAILED_HANDSHAKE:
+ metric = mkf_u64(FN_COUNTER, counters->failed_handshake);
+ break;
+ default:
+ /* not used for frontends. If a specific metric
+ * is requested, return an error. Otherwise continue.
+ */
+ if (selected_field != NULL)
+ return 0;
+ continue;
+ }
+ stats[current_field] = metric;
+ if (selected_field != NULL)
+ break;
+ }
+ return 1;
}
static struct stats_module ssl_stats_module = {
}
counters = EXTRA_COUNTERS_GET(px->extra_counters_fe, mod);
- mod->fill_stats(counters, stats + stats_count);
+ if (!mod->fill_stats(counters, stats + stats_count, NULL))
+ continue;
stats_count += mod->stats_count;
}
}
counters = EXTRA_COUNTERS_GET(l->extra_counters, mod);
- mod->fill_stats(counters, stats + stats_count);
+ if (!mod->fill_stats(counters, stats + stats_count, NULL))
+ continue;
stats_count += mod->stats_count;
}
}
counters = EXTRA_COUNTERS_GET(sv->extra_counters, mod);
- mod->fill_stats(counters, stats + stats_count);
+ if (!mod->fill_stats(counters, stats + stats_count, NULL))
+ continue;
stats_count += mod->stats_count;
}
}
counters = EXTRA_COUNTERS_GET(px->extra_counters_be, mod);
- mod->fill_stats(counters, stats + stats_count);
+ if (!mod->fill_stats(counters, stats + stats_count, NULL))
+ continue;
stats_count += mod->stats_count;
}
stat_count[domain] += m->stats_count;
}
+
static int allocate_stats_px_postcheck(void)
{
struct stats_module *mod;