19a51510aSBrian Tierney /*
2*76bd67f6SSarah Larsen * iperf, Copyright (c) 2014-2022, The Regents of the University of
3da9f046fSBruce A. Mah * California, through Lawrence Berkeley National Laboratory (subject
4da9f046fSBruce A. Mah * to receipt of any required approvals from the U.S. Dept. of
5da9f046fSBruce A. Mah * Energy). All rights reserved.
67d375156SJon Dugan *
7da9f046fSBruce A. Mah * If you have questions about your rights to use or distribute this
8da9f046fSBruce A. Mah * software, please contact Berkeley Lab's Technology Transfer
9da9f046fSBruce A. Mah * Department at [email protected].
10da9f046fSBruce A. Mah *
11da9f046fSBruce A. Mah * NOTICE. This software is owned by the U.S. Department of Energy.
12da9f046fSBruce A. Mah * As such, the U.S. Government has been granted for itself and others
13da9f046fSBruce A. Mah * acting on its behalf a paid-up, nonexclusive, irrevocable,
14da9f046fSBruce A. Mah * worldwide license in the Software to reproduce, prepare derivative
15da9f046fSBruce A. Mah * works, and perform publicly and display publicly. Beginning five
16da9f046fSBruce A. Mah * (5) years after the date permission to assert copyright is obtained
17da9f046fSBruce A. Mah * from the U.S. Department of Energy, and subject to any subsequent
18da9f046fSBruce A. Mah * five (5) year renewals, the U.S. Government is granted for itself
19da9f046fSBruce A. Mah * and others acting on its behalf a paid-up, nonexclusive,
20da9f046fSBruce A. Mah * irrevocable, worldwide license in the Software to reproduce,
21da9f046fSBruce A. Mah * prepare derivative works, distribute copies to the public, perform
22da9f046fSBruce A. Mah * publicly and display publicly, and to permit others to do so.
23da9f046fSBruce A. Mah *
24da9f046fSBruce A. Mah * This code is distributed under a BSD style license, see the LICENSE
25da9f046fSBruce A. Mah * file for complete information.
269a51510aSBrian Tierney */
2740050b7bSBruce A. Mah #include "iperf_config.h"
289a51510aSBrian Tierney
299a51510aSBrian Tierney #include <stdio.h>
309a51510aSBrian Tierney #include <stdlib.h>
319a51510aSBrian Tierney #include <string.h>
329a51510aSBrian Tierney #include <getopt.h>
339a51510aSBrian Tierney #include <errno.h>
349a51510aSBrian Tierney #include <signal.h>
359a51510aSBrian Tierney #include <unistd.h>
36426221a3SBruce A. Mah #ifdef HAVE_STDINT_H
379a51510aSBrian Tierney #include <stdint.h>
38426221a3SBruce A. Mah #endif
399a51510aSBrian Tierney #include <sys/socket.h>
409a51510aSBrian Tierney #include <sys/types.h>
419a51510aSBrian Tierney #include <netinet/in.h>
429a51510aSBrian Tierney #include <arpa/inet.h>
439a51510aSBrian Tierney #include <netdb.h>
449a51510aSBrian Tierney
45a951c980SBrian Tierney #include "iperf.h"
469a51510aSBrian Tierney #include "iperf_api.h"
47120b7efeSTamir Duberstein #include "iperf_util.h"
48a1861d5fSBruce A. Mah #include "iperf_locale.h"
494559e27aSsethdelliott #include "net.h"
50120b7efeSTamir Duberstein #include "units.h"
519a51510aSBrian Tierney
52aebbe3a0Ssethdelliott
53afe6222aSJef Poskanzer static int run(struct iperf_test *test);
54afe6222aSJef Poskanzer
559a51510aSBrian Tierney
569a51510aSBrian Tierney /**************************************************************************/
579a51510aSBrian Tierney int
main(int argc,char ** argv)589a51510aSBrian Tierney main(int argc, char **argv)
599a51510aSBrian Tierney {
609a51510aSBrian Tierney struct iperf_test *test;
619a51510aSBrian Tierney
628430ad49Ssethdelliott // XXX: Setting the process affinity requires root on most systems.
638430ad49Ssethdelliott // Is this a feature we really need?
649a51510aSBrian Tierney #ifdef TEST_PROC_AFFINITY
6550d6cce6Sa1346054 /* didn't seem to work.... */
669a51510aSBrian Tierney /*
679a51510aSBrian Tierney * increasing the priority of the process to minimise packet generation
689a51510aSBrian Tierney * delay
699a51510aSBrian Tierney */
709a51510aSBrian Tierney int rc = setpriority(PRIO_PROCESS, 0, -15);
719a51510aSBrian Tierney
723e402adeSsethdelliott if (rc < 0) {
739a51510aSBrian Tierney perror("setpriority:");
749bfb54c0SJef Poskanzer fprintf(stderr, "setting priority to valid level\n");
759a51510aSBrian Tierney rc = setpriority(PRIO_PROCESS, 0, 0);
769a51510aSBrian Tierney }
773e402adeSsethdelliott
789a51510aSBrian Tierney /* setting the affinity of the process */
799a51510aSBrian Tierney cpu_set_t cpu_set;
809a51510aSBrian Tierney int affinity = -1;
819a51510aSBrian Tierney int ncores = 1;
829a51510aSBrian Tierney
839a51510aSBrian Tierney sched_getaffinity(0, sizeof(cpu_set_t), &cpu_set);
849a51510aSBrian Tierney if (errno)
859a51510aSBrian Tierney perror("couldn't get affinity:");
869a51510aSBrian Tierney
879a51510aSBrian Tierney if ((ncores = sysconf(_SC_NPROCESSORS_CONF)) <= 0)
889a51510aSBrian Tierney err("sysconf: couldn't get _SC_NPROCESSORS_CONF");
899a51510aSBrian Tierney
909a51510aSBrian Tierney CPU_ZERO(&cpu_set);
919a51510aSBrian Tierney CPU_SET(affinity, &cpu_set);
929a51510aSBrian Tierney if (sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set) != 0)
939a51510aSBrian Tierney err("couldn't change CPU affinity");
949a51510aSBrian Tierney #endif
959a51510aSBrian Tierney
969a51510aSBrian Tierney test = iperf_new_test();
97b5e0751fSJef Poskanzer if (!test)
98b5e0751fSJef Poskanzer iperf_errexit(NULL, "create new test error - %s", iperf_strerror(i_errno));
999a51510aSBrian Tierney iperf_defaults(test); /* sets defaults */
1009a51510aSBrian Tierney
1018430ad49Ssethdelliott if (iperf_parse_arguments(test, argc, argv) < 0) {
102b5e0751fSJef Poskanzer iperf_err(test, "parameter error - %s", iperf_strerror(i_errno));
1038430ad49Ssethdelliott fprintf(stderr, "\n");
1045ab2132cSGabriel Ganne usage_long(stdout);
105d44c04d4SBrian Tierney exit(1);
106d44c04d4SBrian Tierney }
10729e3ec74Ssethdelliott
108afe6222aSJef Poskanzer if (run(test) < 0)
109b5e0751fSJef Poskanzer iperf_errexit(test, "error - %s", iperf_strerror(i_errno));
110465b565cSsethdelliott
1119a51510aSBrian Tierney iperf_free_test(test);
1129a51510aSBrian Tierney
113ec2d0670SJef Poskanzer return 0;
1149a51510aSBrian Tierney }
115a951c980SBrian Tierney
1169293ec2cSManoj Joseph
1179293ec2cSManoj Joseph static jmp_buf sigend_jmp_buf;
1189293ec2cSManoj Joseph
1195ab2132cSGabriel Ganne static void __attribute__ ((noreturn))
sigend_handler(int sig)1209293ec2cSManoj Joseph sigend_handler(int sig)
1219293ec2cSManoj Joseph {
1229293ec2cSManoj Joseph longjmp(sigend_jmp_buf, 1);
1239293ec2cSManoj Joseph }
1249293ec2cSManoj Joseph
125a951c980SBrian Tierney /**************************************************************************/
126afe6222aSJef Poskanzer static int
run(struct iperf_test * test)127afe6222aSJef Poskanzer run(struct iperf_test *test)
128a951c980SBrian Tierney {
1299293ec2cSManoj Joseph /* Termination signals. */
1309293ec2cSManoj Joseph iperf_catch_sigend(sigend_handler);
1319293ec2cSManoj Joseph if (setjmp(sigend_jmp_buf))
1329293ec2cSManoj Joseph iperf_got_sigend(test);
1339293ec2cSManoj Joseph
1346f414a04SBruce A. Mah /* Ignore SIGPIPE to simplify error handling */
1356f414a04SBruce A. Mah signal(SIGPIPE, SIG_IGN);
1366f414a04SBruce A. Mah
1372d8bc019Ssethdelliott switch (test->role) {
138a951c980SBrian Tierney case 's':
139fe4a13abSBruce A. Mah if (test->daemon) {
14073b02f98SBruce A. Mah int rc;
14173b02f98SBruce A. Mah rc = daemon(0, 0);
142fe4a13abSBruce A. Mah if (rc < 0) {
143fe4a13abSBruce A. Mah i_errno = IEDAEMON;
144fe4a13abSBruce A. Mah iperf_errexit(test, "error - %s", iperf_strerror(i_errno));
145fe4a13abSBruce A. Mah }
146fe4a13abSBruce A. Mah }
147441d8b75SBruce A. Mah if (iperf_create_pidfile(test) < 0) {
148441d8b75SBruce A. Mah i_errno = IEPIDFILE;
149441d8b75SBruce A. Mah iperf_errexit(test, "error - %s", iperf_strerror(i_errno));
150441d8b75SBruce A. Mah }
1510bd8d9daSsethdelliott for (;;) {
152b7ab2b4bSBruce A. Mah int rc;
153b7ab2b4bSBruce A. Mah rc = iperf_run_server(test);
154be66b575SDavid Bar-On test->server_last_run_rc =rc;
155b7ab2b4bSBruce A. Mah if (rc < 0) {
156b5e0751fSJef Poskanzer iperf_err(test, "error - %s", iperf_strerror(i_errno));
15725f50c23SBruce A. Mah if (test->json_output) {
15825f50c23SBruce A. Mah if (iperf_json_finish(test) < 0)
15925f50c23SBruce A. Mah return -1;
16025f50c23SBruce A. Mah }
16125f50c23SBruce A. Mah iflush(test);
16225f50c23SBruce A. Mah
163b7ab2b4bSBruce A. Mah if (rc < -1) {
164b7ab2b4bSBruce A. Mah iperf_errexit(test, "exiting");
1650bd8d9daSsethdelliott }
166b7ab2b4bSBruce A. Mah }
1670bd8d9daSsethdelliott iperf_reset_test(test);
168be66b575SDavid Bar-On if (iperf_get_test_one_off(test) && rc != 2) {
169fd46367fSBruce A. Mah /* Authentication failure doesn't count for 1-off test */
170fd46367fSBruce A. Mah if (rc < 0 && i_errno == IEAUTHTEST) {
171fd46367fSBruce A. Mah continue;
172fd46367fSBruce A. Mah }
173dba611dbSBruce A. Mah break;
1740bd8d9daSsethdelliott }
175fd46367fSBruce A. Mah }
176441d8b75SBruce A. Mah iperf_delete_pidfile(test);
1770bd8d9daSsethdelliott break;
178a951c980SBrian Tierney case 'c':
179fab96c1dSWojciech Jowsa if (iperf_create_pidfile(test) < 0) {
180fab96c1dSWojciech Jowsa i_errno = IEPIDFILE;
181fab96c1dSWojciech Jowsa iperf_errexit(test, "error - %s", iperf_strerror(i_errno));
182fab96c1dSWojciech Jowsa }
183b5e0751fSJef Poskanzer if (iperf_run_client(test) < 0)
184b5e0751fSJef Poskanzer iperf_errexit(test, "error - %s", iperf_strerror(i_errno));
185fab96c1dSWojciech Jowsa iperf_delete_pidfile(test);
1860bd8d9daSsethdelliott break;
187a951c980SBrian Tierney default:
1881c9c053cSsethdelliott usage();
1890bd8d9daSsethdelliott break;
190a951c980SBrian Tierney }
1910bd8d9daSsethdelliott
1929293ec2cSManoj Joseph iperf_catch_sigend(SIG_DFL);
1936f414a04SBruce A. Mah signal(SIGPIPE, SIG_DFL);
1949293ec2cSManoj Joseph
195ec2d0670SJef Poskanzer return 0;
196a951c980SBrian Tierney }
197