diff --git a/src/socket-proxy/socket-proxyd.c b/src/socket-proxy/socket-proxyd.c index ad56ac72b2..0928f7ad52 100644 --- a/src/socket-proxy/socket-proxyd.c +++ b/src/socket-proxy/socket-proxyd.c @@ -409,7 +409,7 @@ static int context_add_connection(Context *context, int fd) { log_debug("New connection from %s", strna(peer)); } - if (set_size(context->connections) > arg_connections_max) + if (set_size(context->connections) >= arg_connections_max) return log_warning_errno(SYNTHETIC_ERRNO(EBUSY), "Hit connection limit, refusing connection."); r = sd_event_source_set_enabled(context->idle_time, SD_EVENT_OFF); diff --git a/test/integration-tests/TEST-74-AUX-UTILS/TEST-74-AUX-UTILS.units/proxy-echo.py b/test/integration-tests/TEST-74-AUX-UTILS/TEST-74-AUX-UTILS.units/proxy-echo.py index f4a4b25ad4..094ea40713 100755 --- a/test/integration-tests/TEST-74-AUX-UTILS/TEST-74-AUX-UTILS.units/proxy-echo.py +++ b/test/integration-tests/TEST-74-AUX-UTILS/TEST-74-AUX-UTILS.units/proxy-echo.py @@ -7,12 +7,17 @@ import sys data = sys.stdin.buffer.read() s = socket.create_connection(('localhost', 12345), timeout=15) s.settimeout(15) -s.sendall(data) received = b'' -while len(received) < len(data): - chunk = s.recv(65536) - if not chunk: - break - received += chunk +try: + s.sendall(data) + while len(received) < len(data): + chunk = s.recv(65536) + if not chunk: + break + received += chunk +except (ConnectionResetError, BrokenPipeError): + # A proxy refusing the connection closes it, which may arrive as a reset rather than EOF + if received: + raise sys.stdout.buffer.write(received) s.close() diff --git a/test/units/TEST-74-AUX-UTILS.socket-proxyd.sh b/test/units/TEST-74-AUX-UTILS.socket-proxyd.sh index 0767e27268..ce3edeebb7 100755 --- a/test/units/TEST-74-AUX-UTILS.socket-proxyd.sh +++ b/test/units/TEST-74-AUX-UTILS.socket-proxyd.sh @@ -65,3 +65,26 @@ PROXY_PID="$(systemctl show -P MainPID test-proxyd.service)" read -r _ _ _ SOFT HARD _ < <(grep '^Max open files' "/proc/$PROXY_PID/limits") assert_eq "$SOFT" 4096 assert_eq "$HARD" 4096 + +# --connections-max= is a hard cap: while one connection is held open, the next one is closed unserved +systemctl stop test-proxyd.socket test-proxyd.service +cat >/run/systemd/system/test-proxyd.service </dev/tcp/127.0.0.1/12345 +echo -n held >&"$HELD" +read -r -N 4 -t 15 REPLY <&"$HELD" +assert_eq "$REPLY" "held" +# Assigned rather than passed to assert_eq, so that set -e fails the test when the client errors out +REFUSED="$(echo -n refused | proxy_echo)" +assert_eq "$REFUSED" "" +journalctl --sync +journalctl -b -u test-proxyd.service --grep "Hit connection limit" >/dev/null +echo -n still >&"$HELD" +read -r -N 5 -t 15 REPLY <&"$HELD" +assert_eq "$REPLY" "still" +exec {HELD}>&-