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