Merge branch 'vendor/TNFTP'
[dragonfly.git] / tools / tools / netrate / accept_connect / connect_client / connect_client.c
1 #include <sys/types.h>
2 #include <sys/mman.h>
3 #include <sys/socket.h>
4 #include <sys/time.h>
5 #include <sys/wait.h>
6
7 #include <arpa/inet.h>
8 #include <netinet/in.h>
9
10 #include <errno.h>
11 #include <signal.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <unistd.h>
16
17 static void     mainloop(const struct sockaddr_in *, long, u_long *);
18
19 static int      global_stopped;
20
21 static void
22 usage(const char *cmd)
23 {
24         fprintf(stderr, "%s -4 inet4 -p port "
25             "[-i n_instance] [-l duration]\n", cmd);
26         exit(1);
27 }
28
29 int
30 main(int argc, char *argv[])
31 {
32         struct sockaddr_in in;
33         int opt, ninst, i;
34         long dur;
35         u_long *result, sum;
36
37         memset(&in, 0, sizeof(in));
38         in.sin_family = AF_INET;
39
40         ninst = 1;
41         dur = 10;
42
43         while ((opt = getopt(argc, argv, "4:p:i:l:")) != -1) {
44                 switch (opt) {
45                 case '4':
46                         if (inet_pton(AF_INET, optarg, &in.sin_addr) <= 0) {
47                                 fprintf(stderr, "invalid inet address %s\n",
48                                     optarg);
49                                 usage(argv[0]);
50                         }
51                         break;
52
53                 case 'p':
54                         in.sin_port = htons(atoi(optarg));
55                         break;
56
57                 case 'i':
58                         ninst = atoi(optarg);
59                         break;
60
61                 case 'l':
62                         dur = strtol(optarg, NULL, 10);
63                         break;
64
65                 default:
66                         usage(argv[0]);
67                 }
68         }
69
70         if (ninst < 1 || dur < 1 ||
71             in.sin_port == 0 || in.sin_addr.s_addr == INADDR_ANY)
72                 usage(argv[0]);
73
74         result = mmap(NULL, ninst * sizeof(u_long), PROT_READ | PROT_WRITE,
75             MAP_ANON | MAP_SHARED, -1, 0);
76         if (result == MAP_FAILED) {
77                 fprintf(stderr, "mmap failed: %d\n", errno);
78                 exit(1);
79         }
80         memset(result, 0, ninst * sizeof(u_long));
81
82         for (i = 0; i < ninst; ++i) {
83                 pid_t pid;
84
85                 pid = fork();
86                 if (pid == 0) {
87                         mainloop(&in, dur, &result[i]);
88                         exit(0);
89                 } else if (pid < 0) {
90                         fprintf(stderr, "fork failed: %d\n", errno);
91                 }
92         }
93
94         for (i = 0; i < ninst; ++i) {
95                 pid_t pid;
96
97                 pid = waitpid(-1, NULL, 0);
98                 if (pid < 0) {
99                         fprintf(stderr, "waitpid failed: %d\n", errno);
100                         exit(1);
101                 }
102         }
103
104         sum = 0;
105         for (i = 0; i < ninst; ++i)
106                 sum += result[i];
107         printf("%.2f\n", (double)sum / (double)dur);
108
109         exit(0);
110 }
111
112 static void
113 signal_handler(int signum __unused)
114 {
115         global_stopped = 1;
116 }
117
118
119 static void
120 mainloop(const struct sockaddr_in *in, long dur, u_long *res)
121 {
122         struct itimerval it;
123         u_long count = 0;
124
125         if (signal(SIGALRM, signal_handler) == SIG_ERR) {
126                 fprintf(stderr, "signal failed: %d\n", errno);
127                 return;
128         }
129
130         it.it_interval.tv_sec = 0;
131         it.it_interval.tv_usec = 0;
132         it.it_value.tv_sec = dur;
133         it.it_value.tv_usec = 0;
134
135         if (setitimer(ITIMER_REAL, &it, NULL) < 0) {
136                 fprintf(stderr, "setitimer failed: %d\n", errno);
137                 return;
138         }
139
140         while (!global_stopped) {
141                 int s;
142
143                 s = socket(AF_INET, SOCK_STREAM, 0);
144                 if (s < 0)
145                         continue;
146
147                 if (connect(s,
148                     (const struct sockaddr *)in, sizeof(*in)) == 0)
149                         ++count;
150                 close(s);
151         }
152         *res = count;
153 }