-
Notifications
You must be signed in to change notification settings - Fork 8
/
main.c
executable file
·120 lines (111 loc) · 3.53 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <getopt.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include "server.h"
#include "client.h"
static void usage(const char *cmd)
{
printf("Usage: %s [options]\n"
"\n"
"Options:\n"
" -c target run as client and connect to target server\n"
" --cc [reno,cubic] congestion control algorithm to use (default reno)\n"
" -e measure time for connection establishment and first byte only\n"
" -g enable UDP generic segmentation offload\n"
" --iw initial-window initial window to use (default 10)\n"
" -l log-file file to log tls secrets\n"
" -p port to listen on/connect to (default 18080)\n"
" -s run as server\n"
" -t time (s) run for X seconds (default 10s)\n"
" -h print this help\n"
"\n",
cmd);
}
static struct option long_options[] =
{
{"cc", required_argument, NULL, 0},
{"iw", required_argument, NULL, 1},
{NULL, 0, NULL, 0}
};
int main(int argc, char** argv)
{
int port = 18080;
bool server_mode = false;
const char *host = NULL;
int runtime_s = 10;
int ch;
bool ttfb_only = false;
bool gso = false;
const char *logfile = NULL;
const char *cc = "reno";
int iw = 10;
while ((ch = getopt_long(argc, argv, "c:egl:p:st:h", long_options, NULL)) != -1) {
switch (ch) {
case 0:
if(strcmp(optarg, "reno") != 0 && strcmp(optarg, "cubic") != 0) {
fprintf(stderr, "invalid argument passed to --cc\n");
exit(1);
}
cc = optarg;
break;
case 1:
iw = (intptr_t)optarg;
if (sscanf(optarg, "%" SCNu32, &iw) != 1) {
fprintf(stderr, "invalid argument passed to --iw\n");
exit(1);
}
break;
case 'c':
host = optarg;
break;
case 'e':
ttfb_only = true;
break;
case 'g':
#ifdef __linux__
gso = true;
printf("using UDP GSO, requires kernel >= 4.18\n");
#else
fprintf(stderr, "UDP GSO only supported on linux\n");
exit(1);
#endif
break;
case 'l':
logfile = optarg;
break;
case 'p':
port = (intptr_t)optarg;
if(sscanf(optarg, "%u", &port) < 0 || port > 65535) {
fprintf(stderr, "invalid argument passed to -p\n");
exit(1);
}
break;
case 's':
server_mode = true;
break;
case 't':
if(sscanf(optarg, "%u", &runtime_s) != 1 || runtime_s < 1) {
fprintf(stderr, "invalid argument passed to -t\n");
exit(1);
}
break;
default:
usage(argv[0]);
exit(1);
}
}
if(server_mode && host != NULL) {
printf("cannot use -c in server mode\n");
exit(1);
}
if(!server_mode && host == NULL) {
usage(argv[0]);
exit(1);
}
char port_char[16];
sprintf(port_char, "%d", port);
return server_mode ?
run_server(port_char, gso, logfile, cc, iw, "server.crt", "server.key") :
run_client(port_char, gso, logfile, cc, iw, host, runtime_s, ttfb_only);
}