1 /* 2 * iperf, Copyright (c) 2014, 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 [email protected]. 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 #ifdef HAVE_STDINT_H 45 #include <stdint.h> 46 #endif 47 #include <netinet/tcp.h> 48 49 #include "iperf.h" 50 #include "iperf_api.h" 51 #include "units.h" 52 #include "iperf_locale.h" 53 #include "net.h" 54 55 56 static int run(struct iperf_test *test); 57 58 59 /**************************************************************************/ 60 int 61 main(int argc, char **argv) 62 { 63 struct iperf_test *test; 64 65 // XXX: Setting the process affinity requires root on most systems. 66 // Is this a feature we really need? 67 #ifdef TEST_PROC_AFFINITY 68 /* didnt seem to work.... */ 69 /* 70 * increasing the priority of the process to minimise packet generation 71 * delay 72 */ 73 int rc = setpriority(PRIO_PROCESS, 0, -15); 74 75 if (rc < 0) { 76 perror("setpriority:"); 77 fprintf(stderr, "setting priority to valid level\n"); 78 rc = setpriority(PRIO_PROCESS, 0, 0); 79 } 80 81 /* setting the affinity of the process */ 82 cpu_set_t cpu_set; 83 int affinity = -1; 84 int ncores = 1; 85 86 sched_getaffinity(0, sizeof(cpu_set_t), &cpu_set); 87 if (errno) 88 perror("couldn't get affinity:"); 89 90 if ((ncores = sysconf(_SC_NPROCESSORS_CONF)) <= 0) 91 err("sysconf: couldn't get _SC_NPROCESSORS_CONF"); 92 93 CPU_ZERO(&cpu_set); 94 CPU_SET(affinity, &cpu_set); 95 if (sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set) != 0) 96 err("couldn't change CPU affinity"); 97 #endif 98 99 test = iperf_new_test(); 100 if (!test) 101 iperf_errexit(NULL, "create new test error - %s", iperf_strerror(i_errno)); 102 iperf_defaults(test); /* sets defaults */ 103 104 if (iperf_parse_arguments(test, argc, argv) < 0) { 105 iperf_err(test, "parameter error - %s", iperf_strerror(i_errno)); 106 fprintf(stderr, "\n"); 107 usage_long(); 108 exit(1); 109 } 110 111 if (run(test) < 0) 112 iperf_errexit(test, "error - %s", iperf_strerror(i_errno)); 113 114 iperf_free_test(test); 115 116 return 0; 117 } 118 119 /**************************************************************************/ 120 static int 121 run(struct iperf_test *test) 122 { 123 int consecutive_errors; 124 125 switch (test->role) { 126 case 's': 127 if (test->daemon) { 128 int rc = daemon(0, 0); 129 if (rc < 0) { 130 i_errno = IEDAEMON; 131 iperf_errexit(test, "error - %s", iperf_strerror(i_errno)); 132 } 133 } 134 consecutive_errors = 0; 135 if (iperf_create_pidfile(test) < 0) { 136 i_errno = IEPIDFILE; 137 iperf_errexit(test, "error - %s", iperf_strerror(i_errno)); 138 } 139 for (;;) { 140 if (iperf_run_server(test) < 0) { 141 iperf_err(test, "error - %s", iperf_strerror(i_errno)); 142 fprintf(stderr, "\n"); 143 ++consecutive_errors; 144 if (consecutive_errors >= 5) { 145 fprintf(stderr, "too many errors, exiting\n"); 146 break; 147 } 148 } else 149 consecutive_errors = 0; 150 iperf_reset_test(test); 151 if (iperf_get_test_one_off(test)) 152 break; 153 } 154 iperf_delete_pidfile(test); 155 break; 156 case 'c': 157 if (iperf_run_client(test) < 0) 158 iperf_errexit(test, "error - %s", iperf_strerror(i_errno)); 159 break; 160 default: 161 usage(); 162 break; 163 } 164 165 return 0; 166 } 167