12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <arpa/inet.h>
17 #include <mLib/alloc.h>
18 #include <mLib/conn.h>
19 #include <mLib/mdwopt.h>
20 #include <mLib/quis.h>
21 #include <mLib/report.h>
25 typedef struct blast {
31 static struct sockaddr_in sin;
33 static struct timeval ctv = { 0, 500000 };
35 static unsigned count = 0;
37 static void timers(void);
39 static void stats(struct timeval *tv, void *p)
41 static char baton[5] = "/-\\|";
42 static char *bt = baton;
44 printf("\r%c %u connections/second", *bt++, count);
49 TV_ADDL(&ttv, tv, 1, 0);
50 sel_addtimer(&sel, &sec, &ttv, stats, p);
53 static void newconn(blast *b);
55 static void retry(struct timeval *tv, void *p)
61 static void backoff(blast *b)
65 double q = RAND_MAX / 5;
67 TV_ADDL(&tv, &tv, r / q, (r % (unsigned)q) * (MILLION / q));
68 sel_addtimer(&sel, &b->t, &tv, retry, b);
71 static void connected(int fd, void *p)
84 static void timeout(struct timeval *tv, void *p)
91 static void timers(void)
93 struct tab { void (*func)(struct timeval *tv, void *p); const char *name; }
94 tab[] = { { retry, "retry" }, {timeout, "timeout"}, { stats, "stats" }, { 0,
96 sel_timer *t = sel.timers;
98 struct tab *q; for (q = tab; q->func != t->func; q++) ;
99 /* assert(t->prev->next == t); */
100 printf("%lu.%06lu %p %s\n", t->tv.tv_sec, t->tv.tv_usec, t->p, q->name);
101 assert(t != t->next);
107 static void newconn(blast *b)
109 int fd = socket(PF_INET, SOCK_STREAM, 0);
113 gettimeofday(&tv, 0);
114 TV_ADD(&tv, &tv, &ctv);
115 sel_addtimer(&sel, &b->t, &tv, timeout, b);
116 if (conn_init(&b->c, &sel, fd, (struct sockaddr *)&sin, sizeof(sin),
126 int main(int argc, char *argv[])
134 int i = getopt(argc, argv, "t:n:");
139 double t = strtod(optarg, 0);
140 double s = modf(t, &t);
142 ctv.tv_usec = s * MILLION;
155 pquis(stderr, "Usage: $ [-t TIME] [-n COUNT] HOST PORT\n");
160 sin.sin_family = AF_INET;
163 struct hostent *h = gethostbyname(argv[0]);
165 die(1, "bad hostname `%s'", argv[0]);
166 memcpy(&sin.sin_addr, h->h_addr, sizeof(struct in_addr));
169 if (isdigit((unsigned char)argv[1][0]))
170 sin.sin_port = htons(atoi(argv[1]));
172 struct servent *s = getservbyname(argv[1], "tcp");
174 die(1, "bad service name `%s'", argv[1]);
175 sin.sin_port = s->s_port;
178 b = xmalloc(n * sizeof(blast));
182 for (i = 0; i < n; i++)
188 gettimeofday(&tv, 0);
190 sel_addtimer(&sel, &sec, &tv, stats, 0);