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);