Check for errors on socket in send-only listen mode. Fixes #2827
Some checks are pending
nmap multiplatform autobuilds / build (arm64, gcc, ubuntu-latest-gcc-arm64, ubuntu-latest) (push) Waiting to run
nmap multiplatform autobuilds / build (clang, freebsd-15-clang, ubuntu-latest) (push) Waiting to run
nmap multiplatform autobuilds / build (clang, macos-15-clang, macos-15) (push) Waiting to run
nmap multiplatform autobuilds / build (clang, macos-26-clang, macos-26) (push) Waiting to run
nmap multiplatform autobuilds / build (clang, netbsd-10-clang, ubuntu-latest) (push) Waiting to run
nmap multiplatform autobuilds / build (clang, openbsd-7-clang, ubuntu-latest) (push) Waiting to run
nmap multiplatform autobuilds / build (clang, solaris-11-clang, ubuntu-latest) (push) Waiting to run
nmap multiplatform autobuilds / build (clang, ubuntu-latest-clang, ubuntu-latest) (push) Waiting to run
nmap multiplatform autobuilds / build (egcc, openbsd-7-gcc, ubuntu-latest) (push) Waiting to run
nmap multiplatform autobuilds / build (gcc, freebsd-15-gcc, ubuntu-latest) (push) Waiting to run
nmap multiplatform autobuilds / build (gcc, netbsd-10-gcc, ubuntu-latest) (push) Waiting to run
nmap multiplatform autobuilds / build (gcc, solaris-11-gcc, ubuntu-latest) (push) Waiting to run
nmap multiplatform autobuilds / build (gcc, ubuntu-latest-gcc, ubuntu-latest) (push) Waiting to run
nmap multiplatform autobuilds / build (msvc, windows-latest-msvc, windows-latest) (push) Waiting to run

This commit is contained in:
dmiller 2026-05-15 22:30:56 +00:00
parent b408fc243c
commit 5688bd25ed
3 changed files with 45 additions and 36 deletions

View file

@ -131,7 +131,7 @@ static int crlf_state = 0;
static void handle_connection(int socket_accept, int type, fd_set *listen_fds);
static int read_stdin(struct timeval *qtv);
static int read_socket(int recv_fd);
static int read_socket(int recv_fd, ssize_t (*writefunc)(int, const void *, size_t));
static void post_handle_connection(struct fdinfo *sinfo);
static void close_fd(struct fdinfo *fdn, int eof);
static void read_and_broadcast(int recv_socket);
@ -397,32 +397,26 @@ restart_fd_loop:
if (checked_fd_isset(cfd, &listen_fds)) {
/* we have a new connection request */
handle_connection(cfd, type, &listen_fds);
} else if (o.broker) {
read_and_broadcast(cfd);
} else if (cfd == STDIN_FILENO) {
if (o.broker) {
read_and_broadcast(cfd);
} else {
/* Read from stdin and write to all clients. */
rc = read_stdin(&qtv);
if (rc == 0 && (type == SOCK_STREAM || o.ssl)) {
if (!o.noshutdown) shutdown_sockets(SHUT_WR);
if (o.quitafter == 0 && (o.proto != IPPROTO_TCP || (o.proto == IPPROTO_TCP && o.sendonly))) {
/* There will be nothing more to send. If we're not
receiving anything, we can quit here. */
return 0;
}
/* Read from stdin and write to all clients. */
rc = read_stdin(&qtv);
if (rc == 0 && (type == SOCK_STREAM || o.ssl)) {
if (!o.noshutdown) shutdown_sockets(SHUT_WR);
if (o.quitafter == 0 && (o.proto != IPPROTO_TCP || (o.proto == IPPROTO_TCP && o.sendonly))) {
/* There will be nothing more to send. If we're not
receiving anything, we can quit here. */
return 0;
}
if (rc < 0)
return 1;
}
} else if (!o.sendonly) {
if (o.broker) {
read_and_broadcast(cfd);
} else {
/* Read from a client and write to stdout. */
rc = read_socket(cfd);
if (rc <= 0 && !o.keepopen)
return rc == 0 ? 0 : 1;
}
if (rc < 0)
return 1;
} else {
/* Read from a client and write to stdout. */
rc = read_socket(cfd, o.sendonly ? Ignore : Write);
if (rc <= 0 && !o.keepopen)
return rc == 0 ? 0 : 1;
}
fds_ready--;
@ -605,20 +599,18 @@ static void post_handle_connection(struct fdinfo *sinfo)
/* Now that a client is connected, pay attention to stdin. */
if (!stdin_eof && !o.recvonly)
checked_fd_set(STDIN_FILENO, &master_readfds);
if (!o.sendonly) {
/* add to our lists */
checked_fd_set(sinfo->fd, &master_readfds);
/* add it to our list of fds for maintaining maxfd */
/* add to our lists */
checked_fd_set(sinfo->fd, &master_readfds);
/* add it to our list of fds for maintaining maxfd */
#ifdef HAVE_OPENSSL
/* Don't add it twice (see handle_connection above) */
if (!o.ssl) {
/* Don't add it twice (see handle_connection above) */
if (!o.ssl) {
#endif
if (add_fdinfo(&client_fdlist, sinfo) < 0)
bye("add_fdinfo() failed.");
if (add_fdinfo(&client_fdlist, sinfo) < 0)
bye("add_fdinfo() failed.");
#ifdef HAVE_OPENSSL
}
#endif
}
#endif
checked_fd_set(sinfo->fd, &master_broadcastfds);
if (add_fdinfo(&broadcast_fdlist, sinfo) < 0)
bye("add_fdinfo() failed.");
@ -703,7 +695,7 @@ int read_stdin(struct timeval *qtv)
/* Read from a client socket and write to stdout. Return the number of bytes
read from the socket, or -1 on error. */
int read_socket(int recv_fd)
int read_socket(int recv_fd, ssize_t (*writefunc)(int, const void *, size_t))
{
char buf[DEFAULT_TCP_BUF_LEN];
struct fdinfo *fdn;
@ -728,7 +720,7 @@ int read_socket(int recv_fd)
return n;
}
else {
Write(STDOUT_FILENO, buf, n);
writefunc(STDOUT_FILENO, buf, n);
nbytes += n;
}
} while (pending);
@ -795,6 +787,10 @@ static void read_and_broadcast(int recv_fd)
close_fd(fdn, n == 0);
return;
}
/* Ignore any read data in sendonly mode */
if (o.sendonly) {
continue;
}
}
if (o.debug > 1)

View file

@ -189,3 +189,15 @@ ssize_t Write(int fd, const void *buf, size_t count)
return ret;
}
#ifndef UNUSED
#define UNUSED(x) ((void) x)
#endif
/* Like Write, but does nothing. */
ssize_t Ignore(int fd, const void *buf, size_t count)
{
UNUSED(fd);
UNUSED(buf);
UNUSED(count);
return 0;
}

View file

@ -108,5 +108,6 @@ sighandler_t Signal(int signum, sighandler_t handler);
int Socket(int domain, int type, int protocol);
char *Strdup(const char *s);
ssize_t Write(int fd, const void *buf, size_t count);
ssize_t Ignore(int fd, const void *buf, size_t count);
#endif