xref: /iperf/src/main.c (revision ba7b91d2)
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