1 /* 2 * iperf, Copyright (c) 2014, 2015, 2017, 2019, The Regents of the University of 3 * California, through Lawrence Berkeley National Laboratory (subject 4 * to receipt of any required approvals from the U.S. Dept. of 5 * Energy). All rights reserved. 6 * 7 * If you have questions about your rights to use or distribute this 8 * software, please contact Berkeley Lab's Technology Transfer 9 * Department at TTD@lbl.gov. 10 * 11 * NOTICE. This software is owned by the U.S. Department of Energy. 12 * As such, the U.S. Government has been granted for itself and others 13 * acting on its behalf a paid-up, nonexclusive, irrevocable, 14 * worldwide license in the Software to reproduce, prepare derivative 15 * works, and perform publicly and display publicly. Beginning five 16 * (5) years after the date permission to assert copyright is obtained 17 * from the U.S. Department of Energy, and subject to any subsequent 18 * five (5) year renewals, the U.S. Government is granted for itself 19 * and others acting on its behalf a paid-up, nonexclusive, 20 * irrevocable, worldwide license in the Software to reproduce, 21 * prepare derivative works, distribute copies to the public, perform 22 * publicly and display publicly, and to permit others to do so. 23 * 24 * This code is distributed under a BSD style license, see the LICENSE 25 * file for complete information. 26 */ 27 #include "iperf_config.h" 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <getopt.h> 33 #include <errno.h> 34 #include <signal.h> 35 #include <unistd.h> 36 #ifdef HAVE_STDINT_H 37 #include <stdint.h> 38 #endif 39 #include <sys/socket.h> 40 #include <sys/types.h> 41 #include <netinet/in.h> 42 #include <arpa/inet.h> 43 #include <netdb.h> 44 45 #include "iperf.h" 46 #include "iperf_api.h" 47 #include "units.h" 48 #include "iperf_locale.h" 49 #include "net.h" 50 51 52 static int run(struct iperf_test *test); 53 54 55 /**************************************************************************/ 56 int 57 main(int argc, char **argv) 58 { 59 struct iperf_test *test; 60 61 // XXX: Setting the process affinity requires root on most systems. 62 // Is this a feature we really need? 63 #ifdef TEST_PROC_AFFINITY 64 /* didnt seem to work.... */ 65 /* 66 * increasing the priority of the process to minimise packet generation 67 * delay 68 */ 69 int rc = setpriority(PRIO_PROCESS, 0, -15); 70 71 if (rc < 0) { 72 perror("setpriority:"); 73 fprintf(stderr, "setting priority to valid level\n"); 74 rc = setpriority(PRIO_PROCESS, 0, 0); 75 } 76 77 /* setting the affinity of the process */ 78 cpu_set_t cpu_set; 79 int affinity = -1; 80 int ncores = 1; 81 82 sched_getaffinity(0, sizeof(cpu_set_t), &cpu_set); 83 if (errno) 84 perror("couldn't get affinity:"); 85 86 if ((ncores = sysconf(_SC_NPROCESSORS_CONF)) <= 0) 87 err("sysconf: couldn't get _SC_NPROCESSORS_CONF"); 88 89 CPU_ZERO(&cpu_set); 90 CPU_SET(affinity, &cpu_set); 91 if (sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set) != 0) 92 err("couldn't change CPU affinity"); 93 #endif 94 95 test = iperf_new_test(); 96 if (!test) 97 iperf_errexit(NULL, "create new test error - %s", iperf_strerror(i_errno)); 98 iperf_defaults(test); /* sets defaults */ 99 100 if (iperf_parse_arguments(test, argc, argv) < 0) { 101 iperf_err(test, "parameter error - %s", iperf_strerror(i_errno)); 102 fprintf(stderr, "\n"); 103 usage_long(stdout); 104 exit(1); 105 } 106 107 if (run(test) < 0) 108 iperf_errexit(test, "error - %s", iperf_strerror(i_errno)); 109 110 iperf_free_test(test); 111 112 return 0; 113 } 114 115 116 static jmp_buf sigend_jmp_buf; 117 118 static void __attribute__ ((noreturn)) 119 sigend_handler(int sig) 120 { 121 longjmp(sigend_jmp_buf, 1); 122 } 123 124 /**************************************************************************/ 125 static int 126 run(struct iperf_test *test) 127 { 128 /* Termination signals. */ 129 iperf_catch_sigend(sigend_handler); 130 if (setjmp(sigend_jmp_buf)) 131 iperf_got_sigend(test); 132 133 /* Ignore SIGPIPE to simplify error handling */ 134 signal(SIGPIPE, SIG_IGN); 135 136 switch (test->role) { 137 case 's': 138 if (test->daemon) { 139 int rc; 140 rc = daemon(0, 0); 141 if (rc < 0) { 142 i_errno = IEDAEMON; 143 iperf_errexit(test, "error - %s", iperf_strerror(i_errno)); 144 } 145 } 146 if (iperf_create_pidfile(test) < 0) { 147 i_errno = IEPIDFILE; 148 iperf_errexit(test, "error - %s", iperf_strerror(i_errno)); 149 } 150 for (;;) { 151 int rc; 152 rc = iperf_run_server(test); 153 if (rc < 0) { 154 iperf_err(test, "error - %s", iperf_strerror(i_errno)); 155 if (rc < -1) { 156 iperf_errexit(test, "exiting"); 157 } 158 } 159 iperf_reset_test(test); 160 if (iperf_get_test_one_off(test)) { 161 /* Authentication failure doesn't count for 1-off test */ 162 if (rc < 0 && i_errno == IEAUTHTEST) { 163 continue; 164 } 165 break; 166 } 167 } 168 iperf_delete_pidfile(test); 169 break; 170 case 'c': 171 if (iperf_run_client(test) < 0) 172 iperf_errexit(test, "error - %s", iperf_strerror(i_errno)); 173 break; 174 default: 175 usage(); 176 break; 177 } 178 179 iperf_catch_sigend(SIG_DFL); 180 signal(SIGPIPE, SIG_DFL); 181 182 return 0; 183 } 184