4 #include <sys/socket.h>
9 #include <netinet/in.h>
19 static void mainloop(const struct sockaddr_in *, int, int, long, u_long *);
22 usage(const char *cmd)
24 fprintf(stderr, "%s -4 inet4 [-4 inet4_1] -p port "
25 "[-i n_instance] [-c conn_max] [-l duration]\n", cmd);
30 main(int argc, char *argv[])
32 struct sockaddr_in *in, *tmp;
33 int opt, ninst, nconn, i, in_max, in_cnt;
44 in = calloc(in_max, sizeof(struct sockaddr_in));
46 fprintf(stderr, "calloc failed\n");
51 while ((opt = getopt(argc, argv, "4:p:i:l:c:")) != -1) {
54 if (in_cnt >= in_max) {
55 struct sockaddr_in *old_in = in;
56 int old_in_max = in_max;
59 in = calloc(in_max, sizeof(struct sockaddr_in));
61 fprintf(stderr, "calloc failed\n");
66 old_in_max * sizeof(struct sockaddr_in));
71 if (inet_pton(AF_INET, optarg, &tmp->sin_addr) <= 0) {
72 fprintf(stderr, "invalid inet address %s\n",
80 port = htons(atoi(optarg));
92 dur = strtol(optarg, NULL, 10);
100 if (ninst < 1 || dur < 1 || nconn < 1 || port == 0 || in_cnt == 0)
103 for (i = 0; i < in_cnt; ++i) {
105 tmp->sin_family = AF_INET;
106 tmp->sin_port = port;
109 result = mmap(NULL, ninst * sizeof(u_long), PROT_READ | PROT_WRITE,
110 MAP_ANON | MAP_SHARED, -1, 0);
111 if (result == MAP_FAILED) {
112 fprintf(stderr, "mmap failed: %d\n", errno);
115 memset(result, 0, ninst * sizeof(u_long));
117 for (i = 0; i < ninst; ++i) {
122 mainloop(in, in_cnt, nconn, dur, &result[i]);
124 } else if (pid < 0) {
125 fprintf(stderr, "fork failed: %d\n", errno);
129 for (i = 0; i < ninst; ++i) {
132 pid = waitpid(-1, NULL, 0);
134 fprintf(stderr, "waitpid failed: %d\n", errno);
140 for (i = 0; i < ninst; ++i)
142 printf("%.2f\n", (double)sum / (double)dur);
148 mainloop(const struct sockaddr_in *in, int in_cnt, int nconn_max,
149 long dur, u_long *res)
151 struct kevent *evt_change0, *evt;
152 int kq, nchange = 0, nconn = 0, nevt_max;
158 fprintf(stderr, "kqueue failed: %d\n", errno);
162 nevt_max = nconn_max + 1; /* timer */
164 evt_change0 = malloc(nevt_max * sizeof(struct kevent));
165 if (evt_change0 == NULL) {
166 fprintf(stderr, "malloc evt_change failed\n");
170 evt = malloc(nevt_max * sizeof(struct kevent));
172 fprintf(stderr, "malloc evt failed\n");
176 EV_SET(&evt_change0[0], 0, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0,
181 struct kevent *evt_change = NULL;
184 while (nconn < nconn_max) {
185 const struct sockaddr_in *tmp;
188 s = socket(AF_INET, SOCK_STREAM, 0);
190 fprintf(stderr, "socket failed: %d\n", errno);
194 flags = fcntl(s, F_GETFL, 0);
196 fprintf(stderr, "fcntl(GETFL) failed: %d\n",
200 if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
201 fprintf(stderr, "fcntl(SETFL) failed: %d\n",
206 tmp = &in[in_idx % in_cnt];
209 n = connect(s, (const struct sockaddr *)tmp,
218 if (error != EINPROGRESS) {
219 fprintf(stderr, "connect failed: %d\n",
226 if (nchange >= nevt_max) {
227 fprintf(stderr, "invalid nchange %d, max %d\n",
231 EV_SET(&evt_change0[nchange], s, EVFILT_WRITE, EV_ADD,
237 evt_change = evt_change0;
239 n = kevent(kq, evt_change, nchange, evt, nevt_max, NULL);
241 fprintf(stderr, "kevent failed: %d\n", errno);
246 for (i = 0; i < n; ++i) {
247 struct kevent *e = &evt[i];
249 if (e->filter == EVFILT_TIMER) {
254 if ((e->flags & EV_EOF) && e->fflags) {
255 /* Error, don't count */