Run bind(2) and connect(2) in parallel also for TCP and Raw IP.
authorbluhm <bluhm@openbsd.org>
Tue, 2 Jan 2024 15:06:48 +0000 (15:06 +0000)
committerbluhm <bluhm@openbsd.org>
Tue, 2 Jan 2024 15:06:48 +0000 (15:06 +0000)
Before only UDP was tested.

regress/sys/netinet/bindconnect/Makefile
regress/sys/netinet/bindconnect/bindconnect.c

index e2cb329..50e1261 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.3 2023/12/07 23:47:48 bluhm Exp $
+#      $OpenBSD: Makefile,v 1.4 2024/01/02 15:06:48 bluhm Exp $
 
 PROG=          bindconnect
 LDADD=         -lpthread
@@ -10,8 +10,6 @@ CLEANFILES=   ktrace.out
 LOCAL_NET ?=
 LOCAL_NET6 ?=
 
-REGRESS_ROOT_TARGETS +=        setup-maxfiles run-100000 run-localnet-connect-delete
-
 REGRESS_SETUP_ONCE +=  setup-maxfiles
 setup-maxfiles:
        [[ $$(sysctl -n kern.maxfiles) -ge 110000 ]] || \
@@ -35,52 +33,64 @@ cleanup-${af}-delete:
        -${SUDO} time ./${PROG} \
            -f ${af} -s 0 -o 0 -b 0 -c 0 -d 1 -N ${NET_${af}} -t 1
 
-REGRESS_TARGETS +=     run-${af}-bind
-run-${af}-bind:
-       time ${KTRACE} ./${PROG} \
-           -f ${af} -n 16 -s 2 -o 1 -b 6 -c 0
+.for proto in udp tcp any
+
+.if "${proto}" != udp && "${proto}" != tcp
+SUDO_${proto} = ${SUDO}
+.else
+SUDO_${proto} =
+.endif
+
+REGRESS_TARGETS +=     run-${af}-${proto}-bind
+run-${af}-${proto}-bind:
+       ${SUDO_${proto}} time ${KTRACE} ./${PROG} \
+           -f ${af} -p ${proto} -n 16 -s 2 -o 1 -b 6 -c 0
 
-REGRESS_TARGETS +=     run-${af}-connect
-run-${af}-connect:
-       time ${KTRACE} ./${PROG} \
-           -f ${af} -n 16 -s 2 -o 1 -b 0 -c 6
+REGRESS_TARGETS +=     run-${af}-${proto}-connect
+run-${af}-${proto}-connect:
+       ${SUDO_${proto}} time ${KTRACE} ./${PROG} \
+           -f ${af} -p ${proto} -n 16 -s 2 -o 1 -b 0 -c 6
 
-REGRESS_TARGETS +=     run-${af}-bind-connect
-run-${af}-bind-connect:
-       time ${KTRACE} ./${PROG} \
-           -f ${af} -n 16 -s 2 -o 1 -b 3 -c 3
+REGRESS_TARGETS +=     run-${af}-${proto}-bind-connect
+run-${af}-${proto}-bind-connect:
+       ${SUDO_${proto}} time ${KTRACE} ./${PROG} \
+           -f ${af} -p ${proto} -n 16 -s 2 -o 1 -b 3 -c 3
 
-REGRESS_TARGETS +=     run-${af}-100000
-run-${af}-100000:
+REGRESS_TARGETS +=     run-${af}-${proto}-100000
+run-${af}-${proto}-100000:
        ${SUDO} time ${KTRACE} ./${PROG} \
-           -f ${af} -n 100000 -s 2 -o 1 -b 3 -c 3
+           -f ${af} -p ${proto} -n 100000 -s 2 -o 1 -b 3 -c 3
 
-REGRESS_TARGETS +=     run-${af}-reuseport
-run-${af}-reuseport:
-       time ${KTRACE} ./${PROG} \
-           -f ${af} -n 16 -s 2 -o 1 -b 3 -c 3 -r
+REGRESS_TARGETS +=     run-${af}-${proto}-reuseport
+run-${af}-${proto}-reuseport:
+       ${SUDO_${proto}} time ${KTRACE} ./${PROG} \
+           -f ${af} -p ${proto} -n 16 -s 2 -o 1 -b 3 -c 3 -r
 
 .if empty(NET_${af})
-REGRESS_SKIP_TARGETS +=        run-${af}-localnet-connect \
-                       run-${af}-localnet-bind-connect \
-                       run-${af}-localnet-connect-delete
+REGRESS_SKIP_TARGETS +=        run-${af}-${proto}-localnet-connect \
+                       run-${af}-${proto}-localnet-bind-connect \
+                       run-${af}-${proto}-localnet-connect-delete
 .endif
 
-REGRESS_TARGETS +=     run-${af}-localnet-connect
-run-${af}-localnet-connect:
-       time ${KTRACE} ./${PROG} \
-           -f ${af} -n 16 -s 2 -o 1 -c 6 -N ${NET_${af}}
+REGRESS_TARGETS +=     run-${af}-${proto}-localnet-connect
+run-${af}-${proto}-localnet-connect:
+       ${SUDO_${proto}} time ${KTRACE} ./${PROG} \
+           -f ${af} -p ${proto} -n 16 -s 2 -o 1 -c 6 -N ${NET_${af}}
 
-REGRESS_TARGETS +=     run-${af}-localnet-bind-connect
-run-${af}-localnet-bind-connect:
-       time ${KTRACE} ./${PROG} \
-           -f ${af} -n 16 -s 2 -o 1 -b 3 -c 3 -N ${NET_${af}}
+REGRESS_TARGETS +=     run-${af}-${proto}-localnet-bind-connect
+run-${af}-${proto}-localnet-bind-connect:
+       ${SUDO_${proto}} time ${KTRACE} ./${PROG} \
+           -f ${af} -p ${proto} -n 16 -s 2 -o 1 -b 3 -c 3 -N ${NET_${af}}
 
-REGRESS_TARGETS +=     run-${af}-localnet-connect-delete
-run-${af}-localnet-connect-delete:
+REGRESS_TARGETS +=     run-${af}-${proto}-localnet-connect-delete
+run-${af}-${proto}-localnet-connect-delete:
        ${SUDO} time ${KTRACE} ./${PROG} \
-           -f ${af} -n 16 -s 2 -o 1 -b 0 -c 6 -d 3 -N ${NET_${af}}
+           -f ${af} -p ${proto} -n 16 -s 2 -o 1 -b 0 -c 6 -d 3 -N ${NET_${af}}
 
 .endfor
+.endfor
+
+REGRESS_ROOT_TARGETS +=        setup-maxfiles run-100000 run-localnet-connect-delete
+REGRESS_ROOT_TARGETS +=        ${REGRESS_TARGETS:N*-udp-*:N*-tcp-*}
 
 .include <bsd.regress.mk>
index 7ed5eaf..f2830e9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bindconnect.c,v 1.3 2023/12/07 23:47:48 bluhm Exp $   */
+/*     $OpenBSD: bindconnect.c,v 1.4 2024/01/02 15:06:48 bluhm Exp $   */
 
 /*
  * Copyright (c) 2023 Alexander Bluhm <bluhm@openbsd.org>
 
 #include <err.h>
 #include <errno.h>
+#include <netdb.h>
 #include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
-#define MAX(a, b)      ((a) > (b) ? (a) : (b))
+#define MAXIMUM(a, b)  ((a) > (b) ? (a) : (b))
 
 #define s6_addr8       __u6_addr.__u6_addr8
 #define s6_addr16      __u6_addr.__u6_addr16
@@ -54,27 +55,28 @@ unsigned int run_time = 10;
 unsigned int socket_num = 1, close_num = 1, bind_num = 1, connect_num = 1,
     delroute_num = 0;
 int reuse_port = 0;
-const char *family = "inet";
 union inaddr_union addr, mask;
-int af, prefix = -1, route_sock = -1;
+int af = AF_INET, type, proto = IPPROTO_UDP, prefix = -1, route_sock = -1;
 
 static void __dead
 usage(void)
 {
        fprintf(stderr,
            "bindconnect [-r] [-b bind] [-c connect] [-d delroute]\n"
-           "[-N addr/net] [-n num] [-o close] [-s socket] [-t time]\n"
+           "[-f family] [-N addr/net] [-n num] [-o close] [-s socket]\n"
+           "[-t time]\n"
            "    -b bind      threads binding sockets, default %u\n"
            "    -c connect   threads connecting sockets, default %u\n"
            "    -d delroute  threads deleting cloned routes, default %u\n"
-           "    -f family    address family inet or inet6, default %s\n"
+           "    -f family    address family inet or inet6, default inet\n"
            "    -N addr/net  connect to any address within network\n"
            "    -n num       number of file descriptors, default %u\n"
            "    -o close     threads closing sockets, default %u\n"
+           "    -p proto     protocol udp, tcp, name or number, default udp\n"
            "    -r           set reuse port socket option\n"
            "    -s socket    threads creating sockets, default %u\n"
            "    -t time      run time in seconds, default %u\n",
-           bind_num, connect_num, delroute_num, family, fd_num, close_num,
+           bind_num, connect_num, delroute_num, fd_num, close_num,
            socket_num, run_time);
        exit(2);
 }
@@ -164,7 +166,7 @@ thread_socket(void *arg)
        for (count = 0; *run; count++) {
                int opt;
 
-               fd = socket(af, SOCK_DGRAM, IPPROTO_UDP);
+               fd = socket(af, type | SOCK_NONBLOCK, proto);
                if (fd < 0 || !reuse_port)
                        continue;
                opt = 1;
@@ -286,6 +288,7 @@ int
 main(int argc, char *argv[])
 {
        struct rlimit rlim;
+       struct protoent *pent;
        pthread_t *tsocket, *tclose, *tbind, *tconnect, *tdelroute;
        const char *errstr, *addr_net = NULL;
        char buf[128], *p;
@@ -295,7 +298,7 @@ main(int argc, char *argv[])
            delroute_count;
        union sockaddr_union su;
 
-       while ((ch = getopt(argc, argv, "b:c:d:f:N:n:o:rs:t:")) != -1) {
+       while ((ch = getopt(argc, argv, "b:c:d:f:N:n:o:p:rs:t:")) != -1) {
                switch (ch) {
                case 'b':
                        bind_num = strtonum(optarg, 0, UINT_MAX, &errstr);
@@ -313,7 +316,12 @@ main(int argc, char *argv[])
                                errx(1, "delroute is %s: %s", errstr, optarg);
                        break;
                case 'f':
-                       family = optarg;
+                       if (strcmp(optarg, "inet") == 0)
+                               af = AF_INET;
+                       else if (strcmp(optarg, "inet6") == 0)
+                               af = AF_INET6;
+                       else
+                               errx(1, "bad address family %s", optarg);
                        break;
                case 'N':
                        addr_net = optarg;
@@ -328,6 +336,16 @@ main(int argc, char *argv[])
                        if (errstr != NULL)
                                errx(1, "close is %s: %s", errstr, optarg);
                        break;
+               case 'p':
+                       pent = getprotobyname(optarg);
+                       if (pent != NULL) {
+                               proto = pent->p_proto;
+                               break;
+                       }
+                       proto = strtonum(optarg, 0, IPPROTO_MAX -1 , &errstr);
+                       if (errstr != NULL)
+                               errx(1, "proto is %s: %s", errstr, optarg);
+                       break;
                case 'r':
                        reuse_port = 1;
                        break;
@@ -350,13 +368,6 @@ main(int argc, char *argv[])
        if (argc > 0)
                usage();
 
-       if (strcmp(family, "inet") == 0)
-               af = AF_INET;
-       else if (strcmp(family, "inet6") == 0)
-               af = AF_INET6;
-       else
-               errx(1, "bad address family %s", family);
-
        /* split addr/net into addr, mask, prefix */
        if (addr_net != NULL) {
                prefix = inet_net_pton(af, addr_net, &addr, sizeof(addr));
@@ -394,7 +405,18 @@ main(int argc, char *argv[])
        }
 
        /* detect lowest file desciptor, test bind, close everything above */
-       fd_base = socket(af, SOCK_DGRAM, IPPROTO_UDP);
+       switch (proto) {
+       case IPPROTO_TCP:
+               type = SOCK_STREAM;
+               break;
+       case IPPROTO_UDP:
+               type = SOCK_DGRAM;
+               break;
+       default:
+               type = SOCK_RAW;
+               break;
+       }
+       fd_base = socket(af, type, proto);
        if (fd_base < 0)
                err(1, "socket fd_base");
        if (fd_base > INT_MAX - (int)fd_num)
@@ -407,7 +429,7 @@ main(int argc, char *argv[])
 
        if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
                err(1, "getrlimit");
-       rlim.rlim_max = MAX(rlim.rlim_max, fd_base + fd_num);
+       rlim.rlim_max = MAXIMUM(rlim.rlim_max, fd_base + fd_num);
        rlim.rlim_cur = fd_base + fd_num;
        if (setrlimit(RLIMIT_NOFILE, &rlim) < 0)
                err(1, "setrlimit %llu", rlim.rlim_cur);