From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202602 header.b=cuq03Htj; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 377D95A0624 for ; Wed, 13 May 2026 06:14:29 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202602; t=1778645665; bh=2L06U04tv4pYIsq9YStEDGqtvpaXJy7G659gL4QIjow=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cuq03HtjNnmmalfEFLQjF8ecbioL7BkbCBhov6/ywydko3/b9DLsK5TYR8rpR1ay9 6t/TCW2PwO2alJ9CaHQN2DyG4nWx7wv4HDZDOYGHlkwiOhImxoUNixDcDiK5/JEV6I u+pjJ7Fouiu1UigmJnEENqqRaadDyE1DnBjeQfNJEA92smxYoBIrqKUHOVUULv6D4U Uvh1+kg8Lwsui2tbwsKH0NdPQ7p20c++cNZmhiJ2UNVL0ZXFEYHhmPZwHqrhLp+8s4 i4QAj3HhJ3NIUC7l7AwKYpaYbVZ86dIRcJoTpVbihnK4Ey0+fcO2bLD4Zw2enKQ+yA 2yOcVn7zRoh9Q== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4gFg8K0MY7z4wKC; Wed, 13 May 2026 14:14:25 +1000 (AEST) From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH 2/3] conf, tap, repair: Uniformly use non-blocking accept() on Unix sockets Date: Wed, 13 May 2026 14:14:22 +1000 Message-ID: <20260513041423.2446716-3-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260513041423.2446716-1-david@gibson.dropbear.id.au> References: <20260513041423.2446716-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: IQSRJGDDZ43Z2THGHNKZHDQXDKSZX6M4 X-Message-ID-Hash: IQSRJGDDZ43Z2THGHNKZHDQXDKSZX6M4 X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: David Gibson X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: sock_unix(), which creates a listening Unix socket, doesn't set the SOCK_NONBLOCK flag, meaning that accept() will block if called with no pending connections. Generally, this doesn't matter because we only accept() once we've received an epoll event indicating there's a pending connection request. Control connections (pesto) are an exception, because the way we queue connections requires that we call accept() when we close one connection to see if there's another one waiting. We rely on an EAGAIN here to know that there's nothing waiting. To handle these we have an explicit fcntl() to enable NONBLOCK on the control listening socket. However, always using non-blocking accept() for Unix sockets would make things a bit more uniform, and should be a bit less fragile in the case that we ever somehow got a spurious connection event. So, alter sock_unix() to always use the SOCK_NONBLOCK flag. Remove the control socket's special case fcntl(), and adjust the error handling on each Unix socket accept() for the new behaviour. As a bonus the last adds reporting for accept() errors on tap socket connections. we will need non-blocking accept() for the upcoming control/configuration socket. Always add SOCK_NONBLOCK, which is more robust and in keeping with the normal non-blocking style of passt. Signed-off-by: David Gibson --- conf.c | 4 +--- repair.c | 4 ++-- tap.c | 5 +++++ util.c | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/conf.c b/conf.c index 029b9c7c..dec43fca 100644 --- a/conf.c +++ b/conf.c @@ -1091,8 +1091,6 @@ static void conf_open_files(struct ctx *c) die_perror("Couldn't open control socket %s", c->control_path); } - if (fcntl(c->fd_control_listen, F_SETFL, O_NONBLOCK)) - die_perror("Couldn't set O_NONBLOCK on control socket"); } else { c->fd_control_listen = -1; } @@ -2087,7 +2085,7 @@ retry: fd = accept4(c->fd_control_listen, NULL, NULL, SOCK_CLOEXEC); if (fd < 0) { if (errno != EAGAIN) - warn_perror("accept4() on configuration listening socket"); + warn_perror("Error accept()ing configuration socket"); return; } diff --git a/repair.c b/repair.c index 3e0e3e0a..42c4ae97 100644 --- a/repair.c +++ b/repair.c @@ -101,8 +101,8 @@ int repair_listen_handler(struct ctx *c, uint32_t events) if ((c->fd_repair = accept4(c->fd_repair_listen, NULL, NULL, SOCK_CLOEXEC)) < 0) { - rc = errno; - debug_perror("accept4() on TCP_REPAIR helper listening socket"); + if ((rc = errno) != EAGAIN) + warn_perror("Error accept()ing repair helper"); return rc; } diff --git a/tap.c b/tap.c index e7cac9df..fda2da9b 100644 --- a/tap.c +++ b/tap.c @@ -1491,6 +1491,11 @@ void tap_listen_handler(struct ctx *c, uint32_t events) } c->fd_tap = accept4(c->fd_tap_listen, NULL, NULL, SOCK_CLOEXEC); + if (c->fd_tap < 0) { + if (errno != EAGAIN) + warn_perror("Error accepting tap client"); + return; + } if (!getsockopt(c->fd_tap, SOL_SOCKET, SO_PEERCRED, &ucred, &len)) info("accepted connection from PID %i", ucred.pid); diff --git a/util.c b/util.c index 73c9d51d..204391c7 100644 --- a/util.c +++ b/util.c @@ -238,7 +238,7 @@ int sock_l4_dualstack_any(const struct ctx *c, enum epoll_type type, */ int sock_unix(char *sock_path) { - int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); struct sockaddr_un addr = { .sun_family = AF_UNIX, }; -- 2.54.0