1 /* 2 * Copyright (c) 2009-2014, The Regents of the University of California, 3 * through Lawrence Berkeley National Laboratory (subject to receipt of any 4 * required approvals from the U.S. Dept. of Energy). All rights reserved. 5 * 6 * This code is distributed under a BSD style license, see the LICENSE file 7 * for complete information. 8 */ 9 #include "iperf_config.h" 10 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <string.h> 14 #include <getopt.h> 15 #include <errno.h> 16 #include <signal.h> 17 #include <unistd.h> 18 #include <stdint.h> 19 #include <sys/socket.h> 20 #include <sys/types.h> 21 #include <netinet/in.h> 22 #include <arpa/inet.h> 23 #include <netdb.h> 24 #include <stdint.h> 25 #include <netinet/tcp.h> 26 27 #include "iperf.h" 28 #include "iperf_api.h" 29 #include "units.h" 30 #include "locale.h" 31 #include "net.h" 32 33 34 static int run(struct iperf_test *test); 35 36 37 /**************************************************************************/ 38 int 39 main(int argc, char **argv) 40 { 41 struct iperf_test *test; 42 43 // XXX: Setting the process affinity requires root on most systems. 44 // Is this a feature we really need? 45 #ifdef TEST_PROC_AFFINITY 46 /* didnt seem to work.... */ 47 /* 48 * increasing the priority of the process to minimise packet generation 49 * delay 50 */ 51 int rc = setpriority(PRIO_PROCESS, 0, -15); 52 53 if (rc < 0) { 54 perror("setpriority:"); 55 fprintf(stderr, "setting priority to valid level\n"); 56 rc = setpriority(PRIO_PROCESS, 0, 0); 57 } 58 59 /* setting the affinity of the process */ 60 cpu_set_t cpu_set; 61 int affinity = -1; 62 int ncores = 1; 63 64 sched_getaffinity(0, sizeof(cpu_set_t), &cpu_set); 65 if (errno) 66 perror("couldn't get affinity:"); 67 68 if ((ncores = sysconf(_SC_NPROCESSORS_CONF)) <= 0) 69 err("sysconf: couldn't get _SC_NPROCESSORS_CONF"); 70 71 CPU_ZERO(&cpu_set); 72 CPU_SET(affinity, &cpu_set); 73 if (sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set) != 0) 74 err("couldn't change CPU affinity"); 75 #endif 76 77 test = iperf_new_test(); 78 if (!test) 79 iperf_errexit(NULL, "create new test error - %s", iperf_strerror(i_errno)); 80 iperf_defaults(test); /* sets defaults */ 81 82 if (iperf_parse_arguments(test, argc, argv) < 0) { 83 iperf_err(test, "parameter error - %s", iperf_strerror(i_errno)); 84 fprintf(stderr, "\n"); 85 usage_long(); 86 exit(1); 87 } 88 89 if (run(test) < 0) 90 iperf_errexit(test, "error - %s", iperf_strerror(i_errno)); 91 92 iperf_free_test(test); 93 94 return 0; 95 } 96 97 /**************************************************************************/ 98 static int 99 run(struct iperf_test *test) 100 { 101 int consecutive_errors; 102 103 switch (test->role) { 104 case 's': 105 if (test->daemon) { 106 int rc = daemon(0, 0); 107 if (rc < 0) { 108 i_errno = IEDAEMON; 109 iperf_errexit(test, "error - %s", iperf_strerror(i_errno)); 110 } 111 } 112 consecutive_errors = 0; 113 if (iperf_create_pidfile(test) < 0) { 114 i_errno = IEPIDFILE; 115 iperf_errexit(test, "error - %s", iperf_strerror(i_errno)); 116 } 117 for (;;) { 118 if (iperf_run_server(test) < 0) { 119 iperf_err(test, "error - %s", iperf_strerror(i_errno)); 120 fprintf(stderr, "\n"); 121 ++consecutive_errors; 122 if (consecutive_errors >= 5) { 123 fprintf(stderr, "too many errors, exiting\n"); 124 break; 125 } 126 } else 127 consecutive_errors = 0; 128 iperf_reset_test(test); 129 } 130 iperf_delete_pidfile(test); 131 break; 132 case 'c': 133 if (iperf_run_client(test) < 0) 134 iperf_errexit(test, "error - %s", iperf_strerror(i_errno)); 135 break; 136 default: 137 usage(); 138 break; 139 } 140 141 return 0; 142 } 143