Download raw body.
iperf3: unbreak rcctl with IPv6 link-local bind/source addresses
iperf3: unbreak rcctl with IPv6 link-local bind/source addresses
iperf3: unbreak rcctl with IPv6 link-local bind/source addresses
On 2025/10/30 17:49, Klemens Nanni wrote:
> If the argument contains a '%', the code will modify argv[] in place,
> which causes rc.subr(8)'s pexp aka. pgrep(1) to mismatch and thus
> rcctl(8) to report failure despite the service running fine:
>
> $ rcctl get iperf3 flags
> -6 --bind fe80::1%vport0
> $ rcctl check iperf3
> iperf3(failed)
> $ pgrep -fl iperf3
> 33091 /usr/local/bin/iperf3 -s -D -6 --bind fe80::1
ok I guess.
> Funnily, the code knows that:
>
> * Modifies the string pointed to by spec in-place due to the use of
> * strtok(3). The caller should strdup(3) or otherwise copy the string
> * if an unmodified copy is needed.
suppose that comment should be removed too?
seems worth trying it upstream and see if they'll take it?
> */
> int
> iperf_parse_hostname(struct iperf_test *test, char *spec, char **p, char **p1) {
>
>
> Simply pass a copy to that function to keep scope identifies in argv[]:
>
> $ rcctl check iperf3
> iperf3(ok)
> $ pgrep -fl iperf3
> 98863 /usr/local/bin/iperf3 -s -D -6 --bind fe80::1%vport0
>
> --client works the same as --bind, so fix it as well.
>
> Feedback? OK?
>
>
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/net/iperf3/Makefile,v
> diff -u -p -r1.21 Makefile
> --- Makefile 26 Dec 2024 18:12:38 -0000 1.21
> +++ Makefile 30 Oct 2025 17:08:08 -0000
> @@ -3,6 +3,7 @@ COMMENT= tool to measure maximum achieva
> V= 3.18
> DISTNAME= iperf-${V}
> PKGNAME= iperf3-${V}
> +REVISION= 0
>
> SHARED_LIBS += iperf 5.0 # 0.0
>
> Index: patches/patch-src_iperf_api_c
> ===================================================================
> RCS file: /cvs/ports/net/iperf3/patches/patch-src_iperf_api_c,v
> diff -u -p -r1.12 patch-src_iperf_api_c
> --- patches/patch-src_iperf_api_c 26 Dec 2024 18:12:38 -0000 1.12
> +++ patches/patch-src_iperf_api_c 30 Oct 2025 17:31:59 -0000
> @@ -1,9 +1,64 @@
> -Default to IPv4.
> +- Pass a copy of argv[] to prevent changes by strtok(3),
> + otherwise rc.subr(8) pexp might not match and cause rcctl failure.
> +- Default to IPv4.
>
> Index: src/iperf_api.c
> --- src/iperf_api.c.orig
> +++ src/iperf_api.c
> -@@ -2998,7 +2998,7 @@ iperf_defaults(struct iperf_test *testp)
> +@@ -1243,7 +1243,7 @@ iperf_parse_arguments(struct iperf_test *test, int arg
> + }
> + iperf_set_test_role(test, 's');
> + break;
> +- case 'c':
> ++ case 'c': {
> + if (test->role == 's') {
> + i_errno = IESERVCLIENT;
> + return -1;
> +@@ -1251,7 +1251,8 @@ iperf_parse_arguments(struct iperf_test *test, int arg
> + iperf_set_test_role(test, 'c');
> + iperf_set_test_server_hostname(test, optarg);
> +
> +- if (iperf_parse_hostname(test, optarg, &p, &p1)) {
> ++ char *arg = strdup(optarg);
> ++ if (iperf_parse_hostname(test, arg, &p, &p1)) {
> + #if defined(HAVE_SO_BINDTODEVICE)
> + /* Get rid of the hostname we saved earlier. */
> + free(iperf_get_test_server_hostname(test));
> +@@ -1262,7 +1263,9 @@ iperf_parse_arguments(struct iperf_test *test, int arg
> + return -1;
> + #endif /* HAVE_SO_BINDTODEVICE */
> + }
> ++ free(arg);
> + break;
> ++ }
> + case 'u':
> + set_protocol(test, Pudp);
> + client_flag = 1;
> +@@ -1374,10 +1377,11 @@ iperf_parse_arguments(struct iperf_test *test, int arg
> + client_flag = 1;
> + break;
> +
> +- case 'B':
> ++ case 'B': {
> + iperf_set_test_bind_address(test, optarg);
> +
> +- if (iperf_parse_hostname(test, optarg, &p, &p1)) {
> ++ char *arg = strdup(optarg);
> ++ if (iperf_parse_hostname(test, arg, &p, &p1)) {
> + #if defined(HAVE_SO_BINDTODEVICE)
> + /* Get rid of the hostname we saved earlier. */
> + free(iperf_get_test_bind_address(test));
> +@@ -1388,7 +1392,9 @@ iperf_parse_arguments(struct iperf_test *test, int arg
> + return -1;
> + #endif /* HAVE_SO_BINDTODEVICE */
> + }
> ++ free(arg);
> + break;
> ++ }
> + #if defined (HAVE_SO_BINDTODEVICE)
> + case OPT_BIND_DEV:
> + iperf_set_test_bind_dev(test, optarg);
> +@@ -2998,7 +3004,7 @@ iperf_defaults(struct iperf_test *testp)
> testp->stats_interval = testp->reporter_interval = 1;
> testp->num_streams = 1;
>
>
iperf3: unbreak rcctl with IPv6 link-local bind/source addresses
iperf3: unbreak rcctl with IPv6 link-local bind/source addresses
iperf3: unbreak rcctl with IPv6 link-local bind/source addresses