5 #include <sys/socket.h>
6 #include <sys/sysctl.h>
10 #include <arpa/inet.h>
11 #include <netinet/in.h>
20 static void mainloop(const struct sockaddr_in *, int, int, long, u_long *,
24 usage(const char *cmd)
26 fprintf(stderr, "%s -4 inet4 [-4 inet4_1] -p port "
27 "[-i n_instance] [-c conn_max] [-l duration] [-u]\n", cmd);
32 main(int argc, char *argv[])
34 struct sockaddr_in *in, *tmp;
35 int opt, ninst, nconn, i, in_max, in_cnt, do_udp;
41 prm_len = sizeof(ninst);
42 if (sysctlbyname("hw.ncpu", &ninst, &prm_len, NULL, 0) != 0) {
43 fprintf(stderr, "sysctl hw.ncpu failed: %d\n", errno);
53 in = calloc(in_max, sizeof(struct sockaddr_in));
55 fprintf(stderr, "calloc failed\n");
60 while ((opt = getopt(argc, argv, "4:p:i:l:c:u")) != -1) {
63 if (in_cnt >= in_max) {
64 struct sockaddr_in *old_in = in;
65 int old_in_max = in_max;
68 in = calloc(in_max, sizeof(struct sockaddr_in));
70 fprintf(stderr, "calloc failed\n");
75 old_in_max * sizeof(struct sockaddr_in));
80 if (inet_pton(AF_INET, optarg, &tmp->sin_addr) <= 0) {
81 fprintf(stderr, "invalid inet address %s\n",
89 port = htons(atoi(optarg));
101 dur = strtol(optarg, NULL, 10);
113 if (ninst < 1 || dur < 1 || nconn < 1 || port == 0 || in_cnt == 0)
116 for (i = 0; i < in_cnt; ++i) {
118 tmp->sin_family = AF_INET;
119 tmp->sin_port = port;
122 result = mmap(NULL, ninst * sizeof(u_long), PROT_READ | PROT_WRITE,
123 MAP_ANON | MAP_SHARED, -1, 0);
124 if (result == MAP_FAILED) {
125 fprintf(stderr, "mmap failed: %d\n", errno);
128 memset(result, 0, ninst * sizeof(u_long));
130 for (i = 0; i < ninst; ++i) {
135 mainloop(in, in_cnt, nconn, dur, &result[i], do_udp);
137 } else if (pid < 0) {
138 fprintf(stderr, "fork failed: %d\n", errno);
142 for (i = 0; i < ninst; ++i) {
145 pid = waitpid(-1, NULL, 0);
147 fprintf(stderr, "waitpid failed: %d\n", errno);
153 for (i = 0; i < ninst; ++i)
155 printf("%.2f\n", (double)sum / (double)dur);
161 udp_send(const struct sockaddr_in *in)
166 s = socket(AF_INET, SOCK_DGRAM, 0);
168 fprintf(stderr, "socket DGRAM failed: %d\n", errno);
172 if (connect(s, (const struct sockaddr *)in, sizeof(*in)) < 0) {
173 fprintf(stderr, "connect DGRAM failed: %d\n", errno);
177 write(s, d, sizeof(d));
183 mainloop(const struct sockaddr_in *in, int in_cnt, int nconn_max,
184 long dur, u_long *res, int do_udp)
186 struct kevent *evt_change0, *evt;
187 int kq, nchange = 0, nconn = 0, nevt_max;
194 fprintf(stderr, "kqueue failed: %d\n", errno);
198 nevt_max = nconn_max + 1; /* timer */
200 evt_change0 = malloc(nevt_max * sizeof(struct kevent));
201 if (evt_change0 == NULL) {
202 fprintf(stderr, "malloc evt_change failed\n");
206 evt = malloc(nevt_max * sizeof(struct kevent));
208 fprintf(stderr, "malloc evt failed\n");
212 EV_SET(&evt_change0[0], 0, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0,
217 struct kevent *evt_change = NULL;
220 while (nconn < nconn_max) {
221 const struct sockaddr_in *tmp;
224 tmp = &in[in_idx % in_cnt];
230 s = socket(AF_INET, SOCK_STREAM, 0);
232 fprintf(stderr, "socket failed: %d\n", errno);
236 if (ioctl(s, FIONBIO, &nblock, sizeof(nblock)) < 0) {
237 fprintf(stderr, "ioctl failed: %d\n", errno);
241 n = connect(s, (const struct sockaddr *)tmp,
250 if (error != EINPROGRESS) {
251 fprintf(stderr, "connect failed: %d\n",
258 if (nchange >= nevt_max) {
259 fprintf(stderr, "invalid nchange %d, max %d\n",
263 EV_SET(&evt_change0[nchange], s, EVFILT_WRITE, EV_ADD,
269 evt_change = evt_change0;
271 n = kevent(kq, evt_change, nchange, evt, nevt_max, NULL);
273 fprintf(stderr, "kevent failed: %d\n", errno);
278 for (i = 0; i < n; ++i) {
279 struct kevent *e = &evt[i];
281 if (e->filter == EVFILT_TIMER) {
286 if ((e->flags & EV_EOF) && e->fflags) {
287 /* Error, don't count */