11 #include <sys/socket.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
16 #include <mLib/alloc.h>
17 #include <mLib/conn.h>
18 #include <mLib/mdwopt.h>
19 #include <mLib/quis.h>
20 #include <mLib/report.h>
24 typedef struct blast
{
29 static struct sockaddr_in sin
;
31 static struct timeval ctv
= { 0, 500000 };
33 static unsigned count
= 0;
35 static void timers(void);
37 static void stats(struct timeval
*tv
, void *p
)
39 static char baton
[5] = "/-\\|";
40 static char *bt
= baton
;
42 printf("\r%c %u connections/second", *bt
++, count
);
47 TV_ADDL(&ttv
, tv
, 1, 0);
48 sel_addtimer(&sel
, &sec
, &ttv
, stats
, p
);
51 static void newconn(blast
*b
);
53 static void retry(struct timeval
*tv
, void *p
)
59 static void backoff(blast
*b
)
63 double q
= RAND_MAX
/ 5;
65 TV_ADDL(&tv
, &tv
, r
/ q
, (r
% (unsigned)q
) * (MILLION
/ q
));
66 sel_addtimer(&sel
, &b
->t
, &tv
, retry
, b
);
69 static void connected(int fd
, void *p
)
82 static void timeout(struct timeval
*tv
, void *p
)
89 static void timers(void)
91 struct tab
{ void (*func
)(struct timeval
*tv
, void *p
); const char *name
; }
92 tab
[] = { { retry
, "retry" }, {timeout
, "timeout"}, { stats
, "stats" }, { 0,
94 sel_timer
*t
= sel
.timers
;
96 struct tab
*q
; for (q
= tab
; q
->func
!= t
->func
; q
++) ;
97 assert(t
->prev
->next
== t
);
98 printf("%i.%06i %p %s\n", t
->tv
.tv_sec
, t
->tv
.tv_usec
, t
->p
, q
->name
);
105 static void newconn(blast
*b
)
107 int fd
= socket(PF_INET
, SOCK_STREAM
, 0);
111 gettimeofday(&tv
, 0);
112 TV_ADD(&tv
, &tv
, &ctv
);
113 if (conn_init(&b
->c
, &sel
, fd
, (struct sockaddr
*)&sin
, sizeof(sin
),
116 sel_addtimer(&sel
, &b
->t
, &tv
, timeout
, b
);
123 int main(int argc
, char *argv
[])
131 int i
= getopt(argc
, argv
, "t:n:");
136 double t
= strtod(optarg
, 0);
137 double s
= modf(t
, &t
);
139 ctv
.tv_usec
= s
* MILLION
;
152 pquis(stderr
, "Usage: $ [-t time] [-n count] host port\n");
157 sin
.sin_family
= AF_INET
;
160 struct hostent
*h
= gethostbyname(argv
[0]);
162 die(1, "bad hostname `%s'", argv
[0]);
163 memcpy(&sin
.sin_addr
, h
->h_addr
, sizeof(struct in_addr
));
166 if (isdigit((unsigned char)argv
[1][0]))
167 sin
.sin_port
= htons(atoi(argv
[1]));
169 struct servent
*s
= getservbyname(argv
[1], "tcp");
171 die(1, "bad service name `%s'", argv
[1]);
172 sin
.sin_port
= s
->s_port
;
175 b
= xmalloc(n
* sizeof(blast
));
179 for (i
= 0; i
< n
; i
++)
185 gettimeofday(&tv
, 0);
187 sel_addtimer(&sel
, &sec
, &tv
, stats
, 0);