The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=2039fe8ea421a93c466657485ba83b4b055f81dd
commit 2039fe8ea421a93c466657485ba83b4b055f81dd Author: KUROSAWA Takahiro <[email protected]> AuthorDate: 2026-07-07 19:11:19 +0000 Commit: Kristof Provost <[email protected]> CommitDate: 2026-07-08 07:23:16 +0000 tests/sendfile_helper: support remote connection In order to use the sendfile_helper program in a pf test script that requires non-loopback interfaces, add functionality to sendfile with a TCP socket that is connected to a remote host. The behavior for unix sockets and TCP loopback sockets is unchanged. Reviewed by: glebius Differential Revision: https://reviews.freebsd.org/D58041 --- tests/sys/common/sendfile_helper.c | 70 ++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 6 deletions(-) diff --git a/tests/sys/common/sendfile_helper.c b/tests/sys/common/sendfile_helper.c index c92a194bff2d..a6181d96892e 100644 --- a/tests/sys/common/sendfile_helper.c +++ b/tests/sys/common/sendfile_helper.c @@ -31,6 +31,7 @@ #include <sys/uio.h> #include <netinet/in.h> +#include <netdb.h> #include <err.h> #include <errno.h> @@ -101,6 +102,44 @@ tcp_socketpair(int *sv) return (0); } +static int +tcp_client_socket(const char *host, const char *port) +{ + struct addrinfo hints, *res, *res0; + int error; + int s; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + if ((error = getaddrinfo(host, port, &hints, &res0)) != 0) + errx(1, "host %s port %s: %s.", + host, port, gai_strerror(error)); + s = -1; + for (res = res0; res != NULL; res = res->ai_next) { + s = socket(res->ai_family, res->ai_socktype, + res->ai_protocol); + if (s < 0) { + warn("socket(pf:%d, type:%d, proto:%d)", + res->ai_family, res->ai_socktype, + res->ai_protocol); + continue; + } + if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { + warn("connect(%s, %s)", host, port); + close(s); + s = -1; + continue; + } else + break; + } + if (s < 0) + exit(1); + freeaddrinfo(res0); + + return s; +} + static void * receiver(void *arg) { @@ -124,7 +163,8 @@ receiver(void *arg) static void usage(void) { - errx(1, "usage: %s [-u] <file> <start> <len> <flags>", getprogname()); + errx(1, "usage: %s [-u] [-c host] [-p port] " + "<file> <start> <len> <flags>", getprogname()); } int @@ -134,9 +174,19 @@ main(int argc, char **argv) off_t start; int ch, fd, ss[2], flags, error; bool pf_unix = false; + bool tcp_client = false; + const char *host, *port; - while ((ch = getopt(argc, argv, "u")) != -1) + while ((ch = getopt(argc, argv, "c:p:u")) != -1) switch (ch) { + case 'c': + host = optarg; + tcp_client = true; + break; + case 'p': + port = optarg; + tcp_client = true; + break; case 'u': pf_unix = true; break; @@ -148,6 +198,8 @@ main(int argc, char **argv) if (argc != 4) usage(); + if (tcp_client && (host == NULL || port == NULL)) + errx(1, "Need to specify host and port."); start = strtoull(argv[1], NULL, 0); readlen = strtoull(argv[2], NULL, 0); @@ -160,12 +212,18 @@ main(int argc, char **argv) if (pf_unix) { if (socketpair(PF_LOCAL, SOCK_STREAM, 0, ss) != 0) err(1, "socketpair"); - } else + } else if (tcp_client) + ss[0] = tcp_client_socket(host, port); + else tcp_socketpair(ss); - error = pthread_create(&pt, NULL, receiver, &ss[1]); - if (error) - errc(1, error, "pthread_create"); + if (tcp_client) + read_done = true; /* The receiver is another process. */ + else { + error = pthread_create(&pt, NULL, receiver, &ss[1]); + if (error) + errc(1, error, "pthread_create"); + } if (sendfile(fd, ss[0], start, readlen, NULL, NULL, flags) < 0) err(3, "sendfile");
