From a98f7575ae4edbf68f03cd4cfe0c003b3a455ce3 Mon Sep 17 00:00:00 2001 From: xginn8 Date: Mon, 11 Jun 2018 06:56:26 -0400 Subject: [PATCH] Add counter for socket unit refuse events (#9217) core: add counter for socket unit rejection events --- src/core/dbus-socket.c | 1 + src/core/socket.c | 30 +++++++++++++++++++----------- src/core/socket.h | 1 + src/systemctl/systemctl.c | 11 +++++++++-- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index aee81430bb..cb0884be13 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -125,6 +125,7 @@ const sd_bus_vtable bus_socket_vtable[] = { SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Socket, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("NConnections", "u", bus_property_get_unsigned, offsetof(Socket, n_connections), 0), SD_BUS_PROPERTY("NAccepted", "u", bus_property_get_unsigned, offsetof(Socket, n_accepted), 0), + SD_BUS_PROPERTY("NRefused", "u", bus_property_get_unsigned, offsetof(Socket, n_refused), 0), SD_BUS_PROPERTY("FileDescriptorName", "s", property_get_fdname, 0, 0), SD_BUS_PROPERTY("SocketProtocol", "i", bus_property_get_int, offsetof(Socket, socket_protocol), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("TriggerLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Socket, trigger_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/core/socket.c b/src/core/socket.c index f97ff64aa3..ee7428a126 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -2243,7 +2243,7 @@ static void socket_enter_running(Socket *s, int cfd) { log_unit_debug(UNIT(s), "Suppressing connection request since unit stop is scheduled."); if (cfd >= 0) - cfd = safe_close(cfd); + goto refuse; else flush_ports(s); @@ -2251,10 +2251,9 @@ static void socket_enter_running(Socket *s, int cfd) { } if (!ratelimit_below(&s->trigger_limit)) { - safe_close(cfd); log_unit_warning(UNIT(s), "Trigger limit hit, refusing further activation."); socket_enter_stop_pre(s, SOCKET_FAILURE_TRIGGER_LIMIT_HIT); - return; + goto refuse; } if (cfd < 0) { @@ -2292,15 +2291,13 @@ static void socket_enter_running(Socket *s, int cfd) { if (s->n_connections >= s->max_connections) { log_unit_warning(UNIT(s), "Too many incoming connections (%u), dropping connection.", s->n_connections); - safe_close(cfd); - return; + goto refuse; } if (s->max_connections_per_source > 0) { r = socket_acquire_peer(s, cfd, &p); if (r < 0) { - safe_close(cfd); - return; + goto refuse; } else if (r > 0 && p->n_ref > s->max_connections_per_source) { _cleanup_free_ char *t = NULL; @@ -2309,8 +2306,7 @@ static void socket_enter_running(Socket *s, int cfd) { log_unit_warning(UNIT(s), "Too many incoming connections (%u) from source %s, dropping connection.", p->n_ref, strnull(t)); - safe_close(cfd); - return; + goto refuse; } } @@ -2326,8 +2322,7 @@ static void socket_enter_running(Socket *s, int cfd) { /* ENOTCONN is legitimate if TCP RST was received. * This connection is over, but the socket unit lives on. */ log_unit_debug(UNIT(s), "Got ENOTCONN on incoming socket, assuming aborted connection attempt, ignoring."); - safe_close(cfd); - return; + goto refuse; } r = unit_name_to_prefix(UNIT(s)->id, &prefix); @@ -2371,6 +2366,11 @@ static void socket_enter_running(Socket *s, int cfd) { return; +refuse: + s->n_refused++; + safe_close(cfd); + return; + fail: log_unit_warning(UNIT(s), "Failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s", cfd >= 0 ? "template" : "non-template", @@ -2514,6 +2514,7 @@ static int socket_serialize(Unit *u, FILE *f, FDSet *fds) { unit_serialize_item(u, f, "state", socket_state_to_string(s->state)); unit_serialize_item(u, f, "result", socket_result_to_string(s->result)); unit_serialize_item_format(u, f, "n-accepted", "%u", s->n_accepted); + unit_serialize_item_format(u, f, "n-refused", "%u", s->n_refused); if (s->control_pid > 0) unit_serialize_item_format(u, f, "control-pid", PID_FMT, s->control_pid); @@ -2594,6 +2595,13 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value, log_unit_debug(u, "Failed to parse n-accepted value: %s", value); else s->n_accepted += k; + } else if (streq(key, "n-refused")) { + unsigned k; + + if (safe_atou(value, &k) < 0) + log_unit_debug(u, "Failed to parse n-refused value: %s", value); + else + s->n_refused += k; } else if (streq(key, "control-pid")) { pid_t pid; diff --git a/src/core/socket.h b/src/core/socket.h index 8a9559d5c6..ffee43cdc5 100644 --- a/src/core/socket.h +++ b/src/core/socket.h @@ -73,6 +73,7 @@ struct Socket { unsigned n_accepted; unsigned n_connections; + unsigned n_refused; unsigned max_connections; unsigned max_connections_per_source; diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 49b00a77ea..9e6d13a400 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3890,6 +3890,7 @@ typedef struct UnitStatusInfo { /* Socket */ unsigned n_accepted; unsigned n_connections; + unsigned n_refused; bool accept; /* Pairs of type, path */ @@ -4155,8 +4156,13 @@ static void print_status_info( STRV_FOREACH_PAIR(t, t2, i->listen) printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t); - if (i->accept) - printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections); + if (i->accept) { + printf(" Accepted: %u; Connected: %u;", i->n_accepted, i->n_connections); + if (i->n_refused) + printf(" Refused: %u", i->n_refused); + printf("\n"); + } + LIST_FOREACH(exec, p, i->exec) { _cleanup_free_ char *argv = NULL; @@ -4956,6 +4962,7 @@ static int show_one( { "NextElapseUSecMonotonic", "t", NULL, offsetof(UnitStatusInfo, next_elapse_monotonic) }, { "NAccepted", "u", NULL, offsetof(UnitStatusInfo, n_accepted) }, { "NConnections", "u", NULL, offsetof(UnitStatusInfo, n_connections) }, + { "NRefused", "u", NULL, offsetof(UnitStatusInfo, n_refused) }, { "Accept", "b", NULL, offsetof(UnitStatusInfo, accept) }, { "Listen", "a(ss)", map_listen, offsetof(UnitStatusInfo, listen) }, { "SysFSPath", "s", NULL, offsetof(UnitStatusInfo, sysfs_path) },