1 /* 2 * Copyright (c) 2009-2011, 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 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <getopt.h> 14 #include <errno.h> 15 #include <signal.h> 16 #include <unistd.h> 17 #include <stdint.h> 18 #include <sys/socket.h> 19 #include <sys/types.h> 20 #include <netinet/in.h> 21 #include <arpa/inet.h> 22 #include <netdb.h> 23 #include <stdint.h> 24 #include <netinet/tcp.h> 25 26 #include "iperf.h" 27 #include "iperf_api.h" 28 #include "units.h" 29 #include "locale.h" 30 #include "net.h" 31 32 33 static int run(struct iperf_test *test); 34 35 36 /**************************************************************************/ 37 int 38 main(int argc, char **argv) 39 { 40 struct iperf_test *test; 41 42 // XXX: Setting the process affinity requires root on most systems. 43 // Is this a feature we really need? 44 #ifdef TEST_PROC_AFFINITY 45 /* didnt seem to work.... */ 46 /* 47 * increasing the priority of the process to minimise packet generation 48 * delay 49 */ 50 int rc = setpriority(PRIO_PROCESS, 0, -15); 51 52 if (rc < 0) { 53 perror("setpriority:"); 54 fprintf(stderr, "setting priority to valid level\n"); 55 rc = setpriority(PRIO_PROCESS, 0, 0); 56 } 57 58 /* setting the affinity of the process */ 59 cpu_set_t cpu_set; 60 int affinity = -1; 61 int ncores = 1; 62 63 sched_getaffinity(0, sizeof(cpu_set_t), &cpu_set); 64 if (errno) 65 perror("couldn't get affinity:"); 66 67 if ((ncores = sysconf(_SC_NPROCESSORS_CONF)) <= 0) 68 err("sysconf: couldn't get _SC_NPROCESSORS_CONF"); 69 70 CPU_ZERO(&cpu_set); 71 CPU_SET(affinity, &cpu_set); 72 if (sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set) != 0) 73 err("couldn't change CPU affinity"); 74 #endif 75 76 test = iperf_new_test(); 77 if (!test) 78 iperf_errexit(NULL, "create new test error - %s", iperf_strerror(i_errno)); 79 iperf_defaults(test); /* sets defaults */ 80 81 /* This main program doesn't use SIGALRM, so the iperf API may use it. */ 82 iperf_set_test_may_use_sigalrm(test, 1); 83 84 if (iperf_parse_arguments(test, argc, argv) < 0) { 85 iperf_err(test, "parameter error - %s", iperf_strerror(i_errno)); 86 fprintf(stderr, "\n"); 87 usage_long(); 88 exit(1); 89 } 90 91 if (run(test) < 0) 92 iperf_errexit(test, "error - %s", iperf_strerror(i_errno)); 93 94 iperf_free_test(test); 95 96 return 0; 97 } 98 99 /**************************************************************************/ 100 static int 101 run(struct iperf_test *test) 102 { 103 int consecutive_errors; 104 105 switch (test->role) { 106 case 's': 107 consecutive_errors = 0; 108 for (;;) { 109 if (iperf_run_server(test) < 0) { 110 iperf_err(test, "error - %s", iperf_strerror(i_errno)); 111 fprintf(stderr, "\n"); 112 ++consecutive_errors; 113 if (consecutive_errors >= 5) { 114 fprintf(stderr, "too many errors, exitting\n"); 115 break; 116 } 117 } else 118 consecutive_errors = 0; 119 iperf_reset_test(test); 120 } 121 break; 122 case 'c': 123 if (iperf_run_client(test) < 0) 124 iperf_errexit(test, "error - %s", iperf_strerror(i_errno)); 125 break; 126 default: 127 usage(); 128 break; 129 } 130 131 return 0; 132 } 133