xref: /iperf/src/main.c (revision 6a3cd13e)
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 
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 	    if (test->daemon) {
108 		int rc = daemon(0, 0);
109 		if (rc < 0) {
110 		    i_errno = IEDAEMON;
111 		    iperf_errexit(test, "error - %s", iperf_strerror(i_errno));
112 		}
113 	    }
114 	    consecutive_errors = 0;
115 	    if (iperf_create_pidfile(test) < 0) {
116 		i_errno = IEPIDFILE;
117 		iperf_errexit(test, "error - %s", iperf_strerror(i_errno));
118 	    }
119             for (;;) {
120                 if (iperf_run_server(test) < 0) {
121 		    iperf_err(test, "error - %s", iperf_strerror(i_errno));
122                     fprintf(stderr, "\n");
123 		    ++consecutive_errors;
124 		    if (consecutive_errors >= 5) {
125 		        fprintf(stderr, "too many errors, exiting\n");
126 			break;
127 		    }
128                 } else
129 		    consecutive_errors = 0;
130                 iperf_reset_test(test);
131             }
132 	    iperf_delete_pidfile(test);
133             break;
134         case 'c':
135             if (iperf_run_client(test) < 0)
136 		iperf_errexit(test, "error - %s", iperf_strerror(i_errno));
137             break;
138         default:
139             usage();
140             break;
141     }
142 
143     return 0;
144 }
145