This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
commit 18e1307515bdb4f43d195b4a4354977d2bc3d9ad Author: Ricard Rosson <[email protected]> AuthorDate: Mon Oct 26 20:25:58 2026 +0000 netutils/telnetd: Keep serving after a failed connection. Any single failed connection made the daemon exit: - An accept4() error other than EINTR, such as ECONNABORTED from a peer that reset before the accept completed (e.g. "nc -z"), took the errout path and closed the listen socket. - The per-connection error paths after a successful accept (SO_LINGER, opening /dev/telnet, SIOCTELNET, opening the session device, spawning the session) likewise exited the daemon instead of dropping the one connection. After that the telnet console is gone until reboot. Treat all of these as per-connection failures: log, drop the connection and keep accepting. Also correct the SIOCTELNET error message, which reported the failing call as open(/dev/telnet). Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Ricard Rosson <[email protected]> --- netutils/telnetd/telnetd_daemon.c | 42 +++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/netutils/telnetd/telnetd_daemon.c b/netutils/telnetd/telnetd_daemon.c index 18dfbe5f7..dba57fdea 100644 --- a/netutils/telnetd/telnetd_daemon.c +++ b/netutils/telnetd/telnetd_daemon.c @@ -241,17 +241,17 @@ int telnetd_daemon(FAR const struct telnetd_config_s *config) acceptsd = accept4(listensd, &addr.generic, &addrlen, SOCK_CLOEXEC); if (acceptsd < 0) { - /* Just continue if a signal was received */ + /* A failed accept (a signal, or a peer that reset before the + * accept completed) only affects that one connection: keep + * serving. + */ - if (errno == EINTR) - { - continue; - } - else + if (errno != EINTR) { nerr("ERROR: accept failed: %d\n", errno); - goto errout_with_socket; } + + continue; } #ifdef CONFIG_NET_SOLINGER @@ -264,8 +264,13 @@ int telnetd_daemon(FAR const struct telnetd_config_s *config) if (setsockopt(acceptsd, SOL_SOCKET, SO_LINGER, &ling, sizeof(struct linger)) < 0) { + /* Per-connection failure (e.g. the peer already reset the + * connection): drop the connection and keep accepting. + */ + nerr("ERROR: setsockopt failed: %d\n", errno); - goto errout_with_acceptsd; + close(acceptsd); + continue; } #endif @@ -275,7 +280,8 @@ int telnetd_daemon(FAR const struct telnetd_config_s *config) if (drvrfd < 0) { nerr("ERROR: open(/dev/telnet) failed: %d\n", errno); - goto errout_with_acceptsd; + close(acceptsd); + continue; } /* Create a character device to "wrap" the accepted socket descriptor */ @@ -288,9 +294,10 @@ int telnetd_daemon(FAR const struct telnetd_config_s *config) if (ioctl(drvrfd, SIOCTELNET, (unsigned long)((uintptr_t)&session)) < 0) { - nerr("ERROR: open(/dev/telnet) failed: %d\n", errno); + nerr("ERROR: SIOCTELNET failed: %d\n", errno); close(drvrfd); - goto errout_with_acceptsd; + close(acceptsd); + continue; } close(drvrfd); @@ -301,8 +308,12 @@ int telnetd_daemon(FAR const struct telnetd_config_s *config) drvrfd = open(session.ts_devpath, O_RDWR); if (drvrfd < 0) { + /* The socket now belongs to the telnet driver instance; just + * keep accepting. + */ + nerr("ERROR: Failed to open %s: %d\n", session.ts_devpath, errno); - goto errout_with_socket; + continue; } /* Use this driver as stdin, stdout, and stderror */ @@ -330,6 +341,7 @@ int telnetd_daemon(FAR const struct telnetd_config_s *config) pid_t pid = task_create("Telnet session", config->t_priority, config->t_stacksize, config->t_entry, NULL); + if (pid >= 0) { continue; @@ -358,16 +370,12 @@ int telnetd_daemon(FAR const struct telnetd_config_s *config) if (ret > 0) { nerr("ERROR: Failed start the telnet session: %d\n", ret); - errno = ret; - goto errout_with_socket; + continue; } } #endif } -errout_with_acceptsd: - close(acceptsd); - errout_with_socket: close(listensd); errout:
