]>
git.ipfire.org Git - thirdparty/squid.git/blob - test-suite/tcp-banger2.c
4 * On some systems, FD_SETSIZE is set to something lower than the
5 * actual number of files which can be opened. IRIX is one case,
6 * NetBSD is another. So here we increase FD_SETSIZE to our
7 * configure-discovered maximum *before* any system includes.
9 #define CHANGE_FD_SETSIZE 1
11 /* Cannot increase FD_SETSIZE on Linux */
12 #if defined(_SQUID_LINUX_)
13 #undef CHANGE_FD_SETSIZE
14 #define CHANGE_FD_SETSIZE 0
17 /* Cannot increase FD_SETSIZE on FreeBSD before 2.2.0, causes select(2)
18 * to return EINVAL. */
19 /* Marian Durkovic <marian@svf.stuba.sk> */
20 /* Peter Wemm <peter@spinner.DIALix.COM> */
21 #if defined(_SQUID_FREEBSD_)
22 #include <osreldate.h>
23 #if __FreeBSD_version < 220000
24 #undef CHANGE_FD_SETSIZE
25 #define CHANGE_FD_SETSIZE 0
29 /* Increase FD_SETSIZE if SQUID_MAXFD is bigger */
30 #if CHANGE_FD_SETSIZE && SQUID_MAXFD > DEFAULT_FD_SETSIZE
31 #define FD_SETSIZE SQUID_MAXFD
53 #include <sys/types.h>
56 #include <sys/select.h>
68 #include <sys/socket.h>
71 #include <netinet/in.h>
74 #include <arpa/inet.h>
86 #define PROXY_PORT 3128
87 #define PROXY_ADDR "127.0.0.1"
89 #define READ_BUF_SZ 4096
91 static int proxy_port
= PROXY_PORT
;
92 static char *proxy_addr
= PROXY_ADDR
;
93 static char *progname
;
96 static int opt_ims
= 0;
97 static int opt_range
= 0;
98 static int max_connections
= 64;
99 static time_t lifetime
= 60;
100 static struct timeval now
;
101 static long total_bytes_written
= 0;
102 static long total_bytes_read
= 0;
103 static int opt_checksum
= 0;
104 FILE *trace_file
= NULL
;
106 typedef void (CB
) (int, void *);
118 char requestbodyfile
[256];
119 char buf
[READ_BUF_SZ
* 2 + 1];
128 struct _f FD
[MAX_FDS
];
137 static char buf
[128];
138 struct tm
*gmt
= gmtime(t
);
140 (void) strftime(buf
, 127, "%A, %d-%b-%y %H:%M:%S GMT", gmt
);
149 FD
[fd
].ccb(fd
, FD
[fd
].data
);
155 while (fd
> 0 && FD
[fd
].cb
== NULL
)
162 fd_open(int fd
, CB
* cb
, void *data
, CB
*ccb
)
167 FD
[fd
].start
= now
.tv_sec
;
178 printf("\rWaiting for open connections to finish...\n");
179 signal(sig
, SIG_DFL
);
183 read_reply(int fd
, void *data
)
185 struct _request
*r
= data
;
186 static unsigned char buf
[READ_BUF_SZ
];
188 if ((len
=read(fd
, buf
, READ_BUF_SZ
)) <= 0) {
194 total_bytes_read
+=len
;
195 if (r
->headfound
< 2) {
196 char *p
,*header
= NULL
;
197 int oldlen
= strlen(r
->buf
);
198 int newlen
= oldlen
+ len
;
199 assert(oldlen
<= READ_BUF_SZ
);
200 memcpy(r
->buf
+oldlen
, buf
, len
);
201 r
->buf
[newlen
+1]='\0';
202 for(p
=r
->buf
; r
->headfound
< 2 && used
<newlen
; p
++,used
++) {
208 if (strncasecmp(header
,"Content-Length:",15)==0)
209 r
->content_length
= atoi(header
+15);
210 if (strncasecmp(header
,"X-Request-URI:",14)==0) {
212 if (strncmp(r
->url
, header
+15, strcspn(header
+15,"\r\n"))) {
214 strncpy(url
, header
+15, strcspn(header
+15,"\r\n"));
215 url
[strcspn(header
+15, "\r\n")]='\n';
216 fprintf(stderr
,"ERROR: Sent %s received %s\n",
233 memmove(r
->buf
, header
, newlen
- (header
- r
->buf
) + 1);
236 r
->bodysize
+=len
-used
;
238 for (; used
<len
; used
++) {
246 reply_done(int fd
, void *data
)
248 struct _request
*r
= data
;
250 ; /* skip size checks for now */
252 if (r
->bodysize
!= r
->content_length
&& r
->content_length
> 0)
253 fprintf(stderr
,"ERROR: %s expected %d bytes got %d\n",
254 r
->url
, r
->content_length
, r
->bodysize
);
255 else if (r
->validsize
>= 0) {
256 if (r
->validsize
!= r
->bodysize
)
257 fprintf(stderr
,"WARNING: %s size mismatch wanted %d bytes got %d\n",
258 r
->url
, r
->validsize
, r
->bodysize
);
259 else if (opt_checksum
&& r
->validsum
!= r
->sum
)
260 fprintf(stderr
,"WARNING: %s invalid checksum wanted %d got %d\n",
261 r
->url
, r
->validsum
, r
->sum
);
264 fprintf(trace_file
,"%s %s %s %d %d\n",
265 r
->method
, r
->url
, r
->requestbodyfile
, r
->bodysize
, r
->sum
);
276 char *method
, *url
, *file
, *size
, *checksum
;
281 struct sockaddr_in S
;
283 if ((s
= socket(PF_INET
, SOCK_STREAM
, 0)) < 0) {
287 memset(&S
, '\0', sizeof(struct sockaddr_in
));
288 S
.sin_family
= AF_INET
;
289 S
.sin_port
= htons(proxy_port
);
290 S
.sin_addr
.s_addr
= inet_addr(proxy_addr
);
291 if (connect(s
, (struct sockaddr
*) &S
, sizeof(S
)) < 0) {
296 strcpy(urlbuf
,urlin
);
297 method
=strtok(urlbuf
," ");
298 url
=strtok(NULL
," ");
299 file
=strtok(NULL
," ");
300 size
=strtok(NULL
," ");
301 checksum
=strtok(NULL
," ");
312 r
=calloc(1,sizeof *r
);
315 strcpy(r
->method
, method
);
316 strcpy(r
->requestbodyfile
, file
);
318 if (size
&& strcmp(size
,"-")!=0)
319 r
->validsize
=atoi(size
);
321 r
->validsize
=-1; /* Unknown */
322 if (checksum
&& strcmp(checksum
,"-")!=0)
323 r
->validsum
=atoi(checksum
);
324 r
->content_length
=-1; /* Unknown */
326 sprintf(buf
,"%s %s HTTP/1.0\r\n", method
, url
);
328 strcat(msg
, "Accept: */*\r\n");
329 if (opt_ims
&& (lrand48() & 0x03) == 0) {
330 w
= time(NULL
) - (lrand48() & 0x3FFFF);
331 sprintf(buf
, "If-Modified-Since: %s\r\n", mkrfc850(&w
));
334 if (file
&& strcmp(file
, "-")!=0) {
335 f
= open(file
,O_RDONLY
);
341 sprintf(buf
,"Content-Length: %d\r\n", st
.st_size
);
344 if (opt_range
&& (lrand48() & 0x03) == 0) {
347 strcat(msg
, "Range: bytes=");
348 while (((len
= (int)lrand48()) & 0x03) == 0 || !count
) {
349 const int offset
= (int) lrand48();
352 switch (lrand48() & 0x03) {
354 sprintf(buf
, "-%d", len
);
357 sprintf(buf
, "%d-", offset
);
360 sprintf(buf
, "%d-%d", offset
, offset
+len
);
370 if ((len2
=write(s
, msg
, len
)) != len
) {
372 perror("write request");
376 total_bytes_written
+= len2
;
378 while ((len
= read(f
, buf
, sizeof(buf
)))>0) {
379 len2
= write(s
, buf
, len
);
381 perror("write body");
393 * if (fcntl(s, F_SETFL, O_NDELAY) < 0)
394 * perror("fcntl O_NDELAY");
400 read_url(int fd
, void *junk
)
403 static char buf
[8192];
405 if (fgets(buf
, 8191, stdin
) == NULL
) {
406 printf("Done Reading URLS\n");
411 if ((t
= strchr(buf
, '\n')))
415 max_connections
= nfds
- 1;
416 printf("NOTE: max_connections set at %d\n", max_connections
);
418 fd_open(r
->fd
, read_reply
, r
, reply_done
);
425 fprintf(stderr
, "usage: %s: -p port -h host -n max\n", progname
);
426 fprintf(stderr
, " -t <tracefile> Save request trace\n");
427 fprintf(stderr
, " -c Check checksum agains trace\n");
428 fprintf(stderr
, " -i Send random If-Modified-Since times\n");
429 fprintf(stderr
, " -l <seconds> Connection lifetime timeout (default 60)\n");
442 struct timeval start
;
445 setbuf(stdout
, NULL
);
446 setbuf(stderr
, NULL
);
447 progname
= strdup(argv
[0]);
448 gettimeofday(&now
, NULL
);
450 while ((c
= getopt(argc
, argv
, "p:h:n:icrl:t:")) != -1) {
453 proxy_port
= atoi(optarg
);
456 proxy_addr
= strdup(optarg
);
459 max_connections
= atoi(optarg
);
465 lifetime
= (time_t) atoi(optarg
);
471 opt_checksum
= 1; /* Tracing requires checksums */
472 trace_file
= fopen(optarg
,"w");
483 fd_open(0, read_url
, NULL
, NULL
);
485 signal(SIGINT
, sig_intr
);
486 signal(SIGPIPE
, SIG_IGN
);
488 while (nfds
|| FD
[0].cb
) {
492 if (nfds
< max_connections
&& FD
[0].cb
)
494 for (i
= 1; i
<= maxfd
; i
++) {
495 if (FD
[i
].cb
== NULL
)
497 if (now
.tv_sec
- FD
[i
].start
> lifetime
) {
498 fprintf(stderr
, "WARNING: fd %d lifetime timeout\n", i
);
504 if (select(maxfd
+ 1, &R
, NULL
, NULL
, &to
) < 0) {
505 fprintf(stderr
, "maxfd=%d\n", maxfd
);
510 gettimeofday(&now
, NULL
);
511 for (i
= 0; i
<= maxfd
; i
++) {
512 if (!FD_ISSET(i
, &R
))
514 FD
[i
].cb(i
, FD
[i
].data
);
515 if (nfds
< max_connections
&& FD
[0].cb
) {
520 if(select(1,&R2
,NULL
,NULL
,&to
) == 1)
521 FD
[0].cb(0, FD
[0].data
);
524 if (now
.tv_sec
> last
.tv_sec
) {
526 dt
= (int) (now
.tv_sec
- start
.tv_sec
);
527 printf("T+ %6d: %9d req (%+4d), %4d conn, %3d/sec avg, %dmb, %dkb/sec avg\n",
532 (int) (nrequests
/ dt
),
533 (int)total_bytes_read
/ 1024 / 1024,
534 (int)total_bytes_read
/ 1024 / dt
);