xref: /iperf/src/main.c (revision a57bcc2d)
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     /* This main program doesn't use SIGALRM, so the iperf API may use it. */
83     iperf_set_test_may_use_sigalrm(test, 1);
84 
85     if (iperf_parse_arguments(test, argc, argv) < 0) {
86         iperf_err(test, "parameter error - %s", iperf_strerror(i_errno));
87         fprintf(stderr, "\n");
88         usage_long();
89         exit(1);
90     }
91 
92     if (run(test) < 0)
93         iperf_errexit(test, "error - %s", iperf_strerror(i_errno));
94 
95     iperf_free_test(test);
96 
97     return 0;
98 }
99 
100 /**************************************************************************/
101 static int
102 run(struct iperf_test *test)
103 {
104     int consecutive_errors;
105 
106     switch (test->role) {
107         case 's':
108 	    if (test->daemon) {
109 		int rc = daemon(0, 0);
110 		if (rc < 0) {
111 		    i_errno = IEDAEMON;
112 		    iperf_errexit(test, "error - %s", iperf_strerror(i_errno));
113 		}
114 	    }
115 	    consecutive_errors = 0;
116 	    if (iperf_create_pidfile(test) < 0) {
117 		i_errno = IEPIDFILE;
118 		iperf_errexit(test, "error - %s", iperf_strerror(i_errno));
119 	    }
120             for (;;) {
121 		if (iperf_run_server(test) < 0) {
122 		    iperf_err(test, "error - %s", iperf_strerror(i_errno));
123                     fprintf(stderr, "\n");
124 		    ++consecutive_errors;
125 		    if (consecutive_errors >= 5) {
126 		        fprintf(stderr, "too many errors, exiting\n");
127 			break;
128 		    }
129                 } else
130 		    consecutive_errors = 0;
131                 iperf_reset_test(test);
132             }
133 	    iperf_delete_pidfile(test);
134             break;
135 	case 'c':
136 	    if (iperf_run_client(test) < 0)
137 		iperf_errexit(test, "error - %s", iperf_strerror(i_errno));
138             break;
139         default:
140             usage();
141             break;
142     }
143 
144     return 0;
145 }
146