This is a multi-part message in MIME format.
--------------2CFF1B1D14F41B9A5DA44F7F
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Here is a polished and updated test suite a bit..
* pconn-banger reports a throughtput report, like tcp-banger2
* both tools include support to validate size and a simple checksum
* A couple of pconn-banger bugs fixed.
* Wrote a small perl script that joins a URL list, and a size-checksum
report from tcp-banger to a combined list (needed to use the validation
feature).
Syntax for URL lists is eiter plain 1 URL/line, or
METHOD URL [Request-File|-] [size checksum]
The tools can send HTTP requests with any method or request-body, but
they do not (yet) support HEAD replies.
Both read the list of requests from stdin.
pconn-banger options:
-p port Port of proxy/server (default 3128)
-h serveraddr IP address of proxy/server (default 127.0.0.1)
-n max_outstanding Number of outstanding pipelined requests
-i Use IMS (random times)
-t tracefile Save all replies to a trace file
-r Don't reopen the connection when closed
-c Validate checksum
tcp-banger2 options:
-p port Port of proxy/server (default 3128)
-h serveraddr IP address of proxy/server (default 127.0.0.1)
-n max_connections Number simoultaneous requests/connections
-i Use IMS (random times)
-c Validate checksum
-l lifetime Connection lifetime
/Henrik
--------------2CFF1B1D14F41B9A5DA44F7F
Content-Type: text/plain; charset=us-ascii; name="squid-1.2.beta20-1.test_suite.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="squid-1.2.beta20-1.test_suite.patch"
Index: squid/test-suite/Makefile
diff -u squid/test-suite/Makefile:1.1.1.1 squid/test-suite/Makefile:1.1.1.1.10.1
--- squid/test-suite/Makefile:1.1.1.1 Sun Mar 8 15:46:55 1998
+++ squid/test-suite/Makefile Wed Apr 29 22:18:25 1998
@@ -1,5 +1,5 @@
CC = gcc
-CFLAGS = -O3 -DWITH_LIB
+CFLAGS = -O3 -I../include -I../src
OBJS = membanger.o hash.o SizeToPool.o
LIB = -L. -lMem
TARGLIB = libMem.a
Index: squid/test-suite/pconn-banger.c
diff -u squid/test-suite/pconn-banger.c:1.1.1.5 squid/test-suite/pconn-banger.c:1.1.1.5.16.3
--- squid/test-suite/pconn-banger.c:1.1.1.5 Thu Feb 5 22:45:12 1998
+++ squid/test-suite/pconn-banger.c Mon May 4 21:19:52 1998
@@ -86,6 +86,9 @@
#if HAVE_ASSERT_H
#include <assert.h>
#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
#define PROXY_PORT 3128
#define PROXY_ADDR "127.0.0.1"
@@ -99,20 +102,27 @@
static int noutstanding = 0;
static int done_reading_urls = 0;
static int opt_ims = 0;
-static int max_connections = 64;
+static int opt_checksum = 0;
+static int opt_reopen = 1;
+static int max_outstanding = 10;
static time_t lifetime = 60;
static const char *const crlf = "\r\n";
+static int trace_fd = -1;
+static int total_bytes_read = 0;
#define REPLY_HDR_SZ 8192
struct _r {
- char *url;
+ char url[1024];
int content_length;
int hdr_length;
int hdr_offset;
int bytes_read;
char reply_hdrs[REPLY_HDR_SZ];
struct _r *next;
+ long sum;
+ long validsize;
+ long validsum;
};
static struct _r *Requests;
@@ -151,11 +161,13 @@
void
sig_intr(int sig)
{
- printf("\rWaiting for open connections to finish...\n");
+ fprintf(stderr, "\rWaiting for open connections to finish...\n");
signal(sig, SIG_DFL);
+ done_reading_urls = 1;
}
int
+
open_http_socket(void)
{
int s;
@@ -177,37 +189,90 @@
}
int
-send_request(int fd, const char *url)
+send_request(int fd, const char *data)
{
- char buf[4096];
+ char msg[4096],buf[4096];
int len;
time_t w;
struct _r *r;
struct _r **R;
- buf[0] = '\0';
- strcat(buf, "GET ");
- strcat(buf, url);
- strcat(buf, " HTTP/1.0\r\n");
- strcat(buf, "Accept: */*\r\n");
- strcat(buf, "Proxy-Connection: Keep-Alive\r\n");
+ char *method, *url, *file, *size, *checksum;
+ char *tmp = strdup(data);
+ struct stat st;
+ int file_fd = -1;
+ method=strtok(tmp, " ");
+ url=strtok(NULL, " ");
+ file=strtok(NULL, " ");
+ size=strtok(NULL, " ");
+ checksum=strtok(NULL, " ");
+ if (!url) {
+ url=method;
+ method="GET";
+ }
+ if (file && strcmp(file,"-")==0)
+ file=NULL;
+ if (size && strcmp(size,"-")==0)
+ size=NULL;
+ if (checksum && strcmp(checksum,"-")==0)
+ checksum=NULL;
+ msg[0] = '\0';
+ sprintf(buf, "%s %s HTTP/1.0\r\n", method, url);
+ strcat(msg,buf);
+ strcat(msg, "Accept: */*\r\n");
+ strcat(msg, "Proxy-Connection: Keep-Alive\r\n");
if (opt_ims && (lrand48() & 0x03) == 0) {
w = time(NULL) - (lrand48() & 0x3FFFF);
- strcat(buf, "If-Modified-Since: ");
- strcat(buf, mkrfc850(&w));
- strcat(buf, "\r\n");
- }
- strcat(buf, "\r\n");
- len = strlen(buf);
- if (write(fd, buf, len) < 0) {
+ sprintf(buf, "If-Modified-Since: %s\r\n", mkrfc850(&w));
+ strcat(msg, buf);
+ }
+ if (file) {
+ if ( (file_fd = open(file,O_RDONLY)) < 0) {
+ perror("open");
+ return -1;
+ }
+ if ( fstat(file_fd, &st) ) {
+ perror("fstat");
+ close(file_fd);
+ return -1;
+ }
+ sprintf(buf, "Content-length: %d\r\n", st.st_size);
+ strcat(msg, buf);
+ }
+ strcat(msg, "\r\n");
+ len = strlen(msg);
+ if (write(fd, msg, len) < 0) {
close(fd);
- perror("write");
+ perror("request write");
+ close(file_fd);
return -1;
}
+ if (file) {
+ while((len=read(file_fd, buf, sizeof buf)) > 0) {
+ if (write(fd, buf, len) < 0) {
+ close(fd);
+ perror("body write");
+ close(file_fd);
+ return -1;
+ }
+ }
+ if (len < 0) {
+ perror("file read");
+ close(file_fd);
+ return -1;
+ }
+ close(file_fd);
+ }
r = calloc(1, sizeof(struct _r));
- r->url = strdup(url);
+ strcpy(r->url, url);
+ if (size)
+ r->validsize = atoi(size);
+ else
+ r->validsize = -1;
+ if (checksum)
+ r->validsum = atoi(checksum);
for (R = &Requests; *R; R = &(*R)->next);
*R = r;
- fprintf(stderr, "REQUESTED %s\n", url);
+/* fprintf(stderr, "REQUESTED %s\n", url); */
noutstanding++;
return 0;
}
@@ -224,63 +289,153 @@
return atoi(t);
}
}
- return 0;
+ return -1;
+}
+
+static const char *
+get_header_string_value(const char *hdr, const char *buf, const char *end)
+{
+ const char *t;
+ static char result[8192];
+ for (t = buf; t < end; t += strcspn(t, crlf), t += strspn(t, crlf)) {
+ if (strncasecmp(t, hdr, strlen(hdr)) == 0) {
+ t += strlen(hdr);
+ while (isspace(*t))
+ t++;
+ strcpy(result,"");
+ strncat(result,t,strcspn(t, crlf));
+ return result;
+ }
+ }
+ return NULL;
}
+void
+request_done(struct _r *r)
+{
+#if 0
+ fprintf(stderr, "DONE: %s, (%d+%d)\n",
+ r->url,
+ r->hdr_length,
+ r->content_length);
+#endif
+ if (r->content_length != r->bytes_read)
+ fprintf(stderr, "ERROR! Short reply, expected %d bytes got %d\n",
+ r->content_length, r->bytes_read);
+ else if (r->validsize >= 0) {
+ if (r->validsize != r->bytes_read)
+ fprintf(stderr, "WARNING: %s Object size mismatch, expected %d got %d\n",
+ r->url, r->validsize, r->bytes_read);
+ else if (opt_checksum && r->sum != r->validsum)
+ fprintf(stderr, "WARNING: %s Checksum error. Expected %d got %d\n",
+ r->url, r->validsum, r->sum);
+ }
+}
int
-handle_read(char *buf, int len)
+handle_read(char *inbuf, int len)
{
struct _r *r = Requests;
const char *end;
- int hlen;
- if (len < 0) {
+ const char *url;
+ static char buf[READ_BUF_SZ];
+ int hlen,blen;
+ if (len < 0 ) {
perror("read");
Requests = r->next;
+ request_done(r);
free(r);
noutstanding--;
+ if (trace_fd >= 0)
+ write(trace_fd,"\n[CLOSED]\n",10);
return -1;
}
+ total_bytes_read += len;
+ xmemcpy(buf,inbuf,len);
if (len == 0) {
- fprintf(stderr, "DONE: %s, server closed socket, read %d bytes\n", r->url, r->bytes_read);
+ fprintf(stderr, "WARNING: %s, server closed socket after %d+%d bytes\n", r->url, r->hdr_offset, r->bytes_read);
+ /* XXX, If no data was received and it isn't the first request on this
+ * connection then the request should be restarted rather than aborted
+ * but this is a simple test program an not a full blown HTTP client.
+ */
+ request_done(r);
Requests = r->next;
free(r);
noutstanding--;
return -1;
}
- if (r->hdr_length == 0) {
- hlen = min(len, REPLY_HDR_SZ - r->hdr_length);
- strncpy(r->reply_hdrs + r->hdr_length, buf, hlen);
- r->hdr_offset += hlen;
- *(r->reply_hdrs + REPLY_HDR_SZ - 1) = '\0';
- }
- if (r->hdr_length == 0 && (end = mime_headers_end(r->reply_hdrs)) != NULL) {
- fprintf(stderr, "FOUND EOH FOR %s\n", r->url);
- r->hdr_length = end - r->reply_hdrs;
- fprintf(stderr, "HDR_LENGTH = %d\n", r->hdr_length);
- r->content_length = get_header_int_value("content-length:", r->reply_hdrs, end);
- fprintf(stderr, "CONTENT_LENGTH = %d\n", r->content_length);
- }
- if (r->content_length && r->hdr_length) {
- int bytes_left = r->content_length + r->hdr_length - r->bytes_read;
- int bytes_used = len > bytes_left ? bytes_left : len;
- r->bytes_read += bytes_used;
- len -= bytes_used;
- if (r->bytes_read == r->content_length + r->hdr_length) {
- fprintf(stderr, "DONE: %s, (%d == %d+%d)\n",
- r->url,
- r->bytes_read,
- r->hdr_length,
- r->content_length);
- Requests = r->next;
- free(r);
- noutstanding--;
- } else {
- assert(r->bytes_read < r->content_length + r->hdr_length);
+ if (trace_fd > 0)
+ write(trace_fd, buf, len);
+ while (len > 0) {
+ /* Build headers */
+ if (r->hdr_length == 0) {
+ hlen = min(len, REPLY_HDR_SZ - r->hdr_offset - 1);
+ xmemcpy(r->reply_hdrs + r->hdr_offset, buf, hlen);
+ r->hdr_offset += hlen;
+ r->reply_hdrs[r->hdr_offset] = '\0';
+ len -= hlen;
+ /* Save any remaining read data */
+ xmemmove(buf, buf + hlen, len);
+ }
+ /* Process headers */
+ if (r->hdr_length == 0 && (end = mime_headers_end(r->reply_hdrs)) != NULL) {
+#if 0
+ fprintf(stderr, "FOUND EOH FOR %s\n", r->url); */
+#endif
+ r->hdr_length = end - r->reply_hdrs;
+#if 0
+ fprintf(stderr, "HDR_LENGTH = %d\n", r->hdr_length);
+#endif
+ /* "unread" any body contents received */
+ blen = r->hdr_offset - r->hdr_length;
+ assert(blen >= 0);
+ if (blen > 0) {
+ xmemmove(buf + blen, buf, len);
+ xmemcpy(buf, r->reply_hdrs + r->hdr_length, blen);
+ len += blen;
+ }
+ r->reply_hdrs[r->hdr_length]='\0'; /* Null terminate headers */
+ /* Parse headers */
+ r->content_length = get_header_int_value("content-length:", r->reply_hdrs, end);
+/* fprintf(stderr, "CONTENT_LENGTH = %d\n", r->content_length); */
+ url = get_header_string_value("X-Request-URI:", r->reply_hdrs, end);
+ if (url != NULL && strcmp(r->url, url) != 0)
+ fprintf(stderr, "WARNING: %s got reply %s\n", r->url, url);
+#if XREQUESTURI || 0
+ fprintf(stderr, "LOCATION = %s\n", get_header_string_value("X-Request-URI:", r->reply_hdrs, end));
+#endif
}
- if (len) {
- assert(bytes_used > 0);
+ if ( !(len==0 || r->hdr_length > 0) ) {
+ fprintf(stderr, "ERROR!!!\n");
+ assert((len==0 || r->hdr_length > 0));
+ }
+ /* Process body */
+ if (r->hdr_length != 0) {
+ int i;
+ int bytes_left, bytes_used;
+ if (r->content_length >= 0) {
+ bytes_left = r->content_length - r->bytes_read;
+ assert(bytes_left >= 0);
+ bytes_used = len < bytes_left ? len : bytes_left;
+ } else {
+ bytes_left = len + 1; /* Unknown end... */
+ bytes_used = len;
+ }
+ if (opt_checksum) {
+ for(i=0; i<bytes_used; i++)
+ r->sum += (int)buf[i] & 0xFF;
+ }
+ r->bytes_read += bytes_used;
+ len -= bytes_used;
+ if (bytes_left == bytes_used) {
+ request_done(r);
+ Requests = r->next;
+ free(r);
+ noutstanding--;
+ r = Requests;
+ } else {
+ assert(r->bytes_read < r->content_length);
+ }
xmemmove(buf, buf + bytes_used, len);
- return handle_read(buf, len);
}
}
return 0;
@@ -294,8 +449,10 @@
int x;
len = read(fd, buf, READ_BUF_SZ);
x = handle_read(buf, len);
- if (x < 0)
+ if (x < 0) {
+ perror("read reply");
close(fd);
+ }
return x;
}
@@ -305,21 +462,28 @@
static int pconn_fd = -1;
static char buf[8192];
struct timeval to;
+ struct timeval now,last,start;
fd_set R;
struct _r *r;
struct _r *nextr;
int x;
int timeouts;
+ int nrequests = 0, rrequests = 0, reqpersec = 0;
+
+ gettimeofday(&start, NULL);
+ last = start;
+
+ pconn_fd = open_http_socket();
+ if (pconn_fd < 0) {
+ perror("socket");
+ exit(1);
+ }
while (!done_reading_urls || noutstanding) {
- if (timeouts == 20) {
- close(pconn_fd);
- pconn_fd = -1;
- r = Requests;
- Requests = Requests->next;
- free(r);
- noutstanding--;
+ if (!opt_reopen && pconn_fd < 0) {
+ fprintf(stderr,"TERMINATED: Connection closed\n");
+ break;
}
- if (pconn_fd < 0) {
+ if (pconn_fd<0) {
pconn_fd = open_http_socket();
if (pconn_fd < 0) {
perror("socket");
@@ -327,24 +491,52 @@
}
nextr = Requests;
Requests = NULL;
+ noutstanding=0;
while ((r = nextr) != NULL) {
nextr = r->next;
- send_request(pconn_fd, r->url);
+ if (send_request(pconn_fd, r->url) != 0) {
+ close(pconn_fd);
+ pconn_fd=-1;
+ nextr = r;
+ for (r = Requests; r!=NULL && r->next; r=r->next);
+ if (r != NULL)
+ r->next = nextr;
+ else
+ Requests = nextr;
+ break;
+ }
free(r);
- noutstanding--;
}
timeouts = 0;
+ if (pconn_fd <0)
+ continue;
}
- if (noutstanding < 10 && !done_reading_urls) {
+ if (timeouts == 200) {
+ close(pconn_fd);
+ pconn_fd = -1;
+ r = Requests;
+ Requests = Requests->next;
+ fprintf(stderr, "ABORT %s\n", Requests->url);
+ free(r);
+ noutstanding--;
+ }
+ if (pconn_fd>=0 && noutstanding < max_outstanding && !done_reading_urls) {
char *t;
if (fgets(buf, 8191, stdin) == NULL) {
- printf("Done Reading URLS\n");
+ fprintf(stderr, "Done Reading URLS\n");
done_reading_urls = 1;
- break;
+ continue;
}
+ rrequests++;
if ((t = strchr(buf, '\n')))
*t = '\0';
- send_request(pconn_fd, buf);
+ if (send_request(pconn_fd, buf) != 0) {
+ close(pconn_fd);
+ pconn_fd=-1;
+ continue;
+ }
+ nrequests++;
+ reqpersec++;
timeouts = 0;
}
FD_ZERO(&R);
@@ -367,13 +559,31 @@
if (read_reply(pconn_fd) != 0)
pconn_fd = -1;
}
+ gettimeofday(&now, NULL);
+ if (now.tv_sec > last.tv_sec) {
+ int dt;
+ int nreq;
+ last = now;
+ dt = (int) (now.tv_sec - start.tv_sec);
+ nreq=0;
+ for (r=Requests; r ; r=r->next) nreq++;
+ printf("T+ %6d: %9d req (%+4d), %4d pend, %3d/sec avg, %dmb, %dkb/sec avg\n",
+ dt,
+ nrequests,
+ reqpersec,
+ nreq,
+ (int) (nrequests / dt),
+ (int)total_bytes_read / 1024 / 1024,
+ (int)total_bytes_read / 1024 / dt);
+ reqpersec = 0;
+ }
}
}
void
usage(void)
{
- fprintf(stderr, "usage: %s: -p port -h host -n max\n", progname);
+ fprintf(stderr, "usage: %s: -p port -h host -n max -t tracefile -i -c -l lifetime\n", progname);
}
int
@@ -385,7 +595,7 @@
setbuf(stdout, NULL);
setbuf(stderr, NULL);
progname = strdup(argv[0]);
- while ((c = getopt(argc, argv, "p:h:n:il:")) != -1) {
+ while ((c = getopt(argc, argv, "p:h:n:t:icl:r")) != -1) {
switch (c) {
case 'p':
proxy_port = atoi(optarg);
@@ -394,13 +604,22 @@
proxy_addr = strdup(optarg);
break;
case 'n':
- max_connections = atoi(optarg);
+ max_outstanding = atoi(optarg);
break;
case 'i':
opt_ims = 1;
break;
+ case 'c':
+ opt_checksum = 1;
+ break;
case 'l':
lifetime = (time_t) atoi(optarg);
+ break;
+ case 't':
+ trace_fd = open(optarg,O_WRONLY|O_CREAT|O_TRUNC,0666);
+ break;
+ case 'r':
+ opt_reopen = !opt_reopen;
break;
default:
usage();
Index: squid/test-suite/tcp-banger2.c
diff -u squid/test-suite/tcp-banger2.c:1.1.1.3 squid/test-suite/tcp-banger2.c:1.1.1.3.22.2
--- squid/test-suite/tcp-banger2.c:1.1.1.3 Fri Jan 2 11:58:15 1998
+++ squid/test-suite/tcp-banger2.c Mon May 4 21:19:53 1998
@@ -76,6 +76,12 @@
#if HAVE_ERRNO_H
#include <errno.h>
#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_ASSERT_H
+#include <assert.h>
+#endif
#define PROXY_PORT 3128
#define PROXY_ADDR "127.0.0.1"
@@ -91,14 +97,29 @@
static int max_connections = 64;
static time_t lifetime = 60;
static struct timeval now;
+static long total_bytes_written = 0;
+static long total_bytes_read = 0;
+static int opt_checksum = 0;
typedef void (CB) (int, void *);
struct _f {
CB *cb;
+ CB *ccb;
void *data;
time_t start;
};
+struct _request {
+ int fd;
+ char url[8192];
+ char buf[READ_BUF_SZ * 2 + 1];
+ int headfound;
+ long validsize;
+ long validsum;
+ long bodysize;
+ long sum;
+ int content_length;
+};
struct _f FD[MAX_FDS];
int nfds = 0;
@@ -120,6 +141,9 @@
fd_close(int fd)
{
close(fd);
+ if (FD[fd].ccb)
+ FD[fd].ccb(fd, FD[fd].data);
+ FD[fd].ccb = NULL;
FD[fd].cb = NULL;
FD[fd].data = NULL;
nfds--;
@@ -131,9 +155,10 @@
}
void
-fd_open(int fd, CB * cb, void *data)
+fd_open(int fd, CB * cb, void *data, CB *ccb)
{
FD[fd].cb = cb;
+ FD[fd].ccb = ccb;
FD[fd].data = data;
FD[fd].start = now.tv_sec;
if (fd > maxfd)
@@ -145,6 +170,7 @@
sig_intr(int sig)
{
fd_close(0);
+ nfds++;
printf("\rWaiting for open connections to finish...\n");
signal(sig, SIG_DFL);
}
@@ -152,26 +178,104 @@
void
read_reply(int fd, void *data)
{
- static char buf[READ_BUF_SZ];
- if (read(fd, buf, READ_BUF_SZ) <= 0) {
+ struct _request *r = data;
+ static unsigned char buf[READ_BUF_SZ];
+ int len;
+ char *p;
+ if ((len=read(fd, buf, READ_BUF_SZ)) <= 0) {
fd_close(fd);
reqpersec++;
nrequests++;
+ } else {
+ int used=0;
+ total_bytes_read+=len;
+ if (r->headfound < 2) {
+ char *p,*header = NULL;
+ int oldlen = strlen(r->buf);
+ int newlen = oldlen + len;
+ assert(oldlen <= READ_BUF_SZ);
+ memcpy(r->buf+oldlen, buf, len);
+ r->buf[newlen+1]='\0';
+ for(p=r->buf; r->headfound < 2 && used<newlen; p++,used++) {
+ switch(*p) {
+ case '\n':
+ r->headfound++;
+ if (header) {
+ /* Decode header */
+ if (strncasecmp(header,"Content-Length:",15)==0)
+ r->content_length = atoi(header+15);
+ if (strncasecmp(header,"X-Request-URI:",14)==0) {
+ /* Check URI */
+ if (strncmp(r->url, header+15, strcspn(header+15,"\r\n"))) {
+ char url[8192];
+ strncpy(url, header+15, strcspn(header+15,"\r\n"));
+ url[strcspn(header+15, "\r\n")]='\n';
+ fprintf(stderr,"ERROR: Sent %s received %s\n",
+ r->url, url);
+ }
+ }
+ header=NULL;
+ }
+ break;
+ case '\r':
+ break;
+ default:
+ r->headfound=0;
+ if (!header)
+ header = p;
+ break;
+ }
+ }
+ if (header) {
+ memmove(r->buf, header, newlen - (header - r->buf) + 1);
+ }
+ }
+ r->bodysize+=len-used;
+ if (opt_checksum) {
+ for (; used<len ; used++) {
+ r->sum += buf[used];
+ }
+ }
}
}
-int
-request(url)
- char *url;
+void
+reply_done(int fd, void *data)
{
- int s;
+ struct _request *r = data;
+ if (r->bodysize != r->content_length)
+ fprintf(stderr,"ERROR: %s expected %d bytes got %d\n",
+ r->url, r->content_length, r->bodysize);
+ else if (r->validsize >= 0) {
+ if (r->validsize != r->bodysize)
+ fprintf(stderr,"WARNING: %s size mismatch wanted %d bytes got %d\n",
+ r->url, r->validsize, r->bodysize);
+ else if (opt_checksum && r->validsum != r->sum)
+ fprintf(stderr,"WARNING: %s invalid checksum wanted %d got %d\n",
+ r->url, r->validsum, r->sum);
+ } else if (opt_checksum) {
+ fprintf(stderr,"DONE: %s checksum %d size %d\n",
+ r->url, r->sum, r->bodysize);
+ }
+ free(r);
+}
+
+struct _request *
+request(char *urlin)
+{
+ int s=-1,f=-1;
char buf[4096];
- int len;
+ char msg[8192];
+ char *method, *url, *file, *size, *checksum;
+ char urlbuf[8192];
+ int len,len2;
time_t w;
+ struct stat st;
struct sockaddr_in S;
+ struct _request *r;
if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
- return -1;
+ return NULL;
}
memset(&S, '\0', sizeof(struct sockaddr_in));
S.sin_family = AF_INET;
@@ -180,52 +284,100 @@
if (connect(s, (struct sockaddr *) &S, sizeof(S)) < 0) {
close(s);
perror("connect");
- return -1;
+ return NULL;
}
- buf[0] = '\0';
- strcat(buf, "GET ");
- strcat(buf, url);
- strcat(buf, " HTTP/1.0\r\n");
- strcat(buf, "Accept: */*\r\n");
+ strcpy(urlbuf,urlin);
+ method=strtok(urlbuf," ");
+ url=strtok(NULL," ");
+ file=strtok(NULL," ");
+ size=strtok(NULL," ");
+ checksum=strtok(NULL," ");
+ if (!url) {
+ url=method;
+ method="GET";
+ }
+ r=calloc(1,sizeof *r);
+ assert(r!=NULL);
+ strcpy(r->url, url);
+ r->fd = s;
+ if (size && strcmp(size,"-")!=0)
+ r->validsize=atoi(size);
+ else
+ r->validsize=-1; /* Unknown */
+ if (checksum && strcmp(checksum,"-")!=0)
+ r->validsum=atoi(checksum);
+ msg[0] = '\0';
+ sprintf(buf,"%s %s HTTP/1.0\r\n", method, url);
+ strcat(msg, buf);
+ strcat(msg, "Accept: */*\r\n");
if (opt_ims && (lrand48() & 0x03) == 0) {
w = time(NULL) - (lrand48() & 0x3FFFF);
- strcat(buf, "If-Modified-Since: ");
- strcat(buf, mkrfc850(&w));
- strcat(buf, "\r\n");
- }
- strcat(buf, "\r\n");
- len = strlen(buf);
- if (write(s, buf, len) < 0) {
+ sprintf(buf, "If-Modified-Since: %s\r\n", mkrfc850(&w));
+ strcat(msg,buf);
+ }
+ if (file && strcmp(file, "-")!=0) {
+ f = open(file,O_RDONLY);
+ if (f < 0) {
+ perror("open file");
+ exit(1);
+ }
+ fstat(f, &st);
+ sprintf(buf,"Content-Length: %d\r\n", st.st_size);
+ strcat(msg,buf);
+ }
+ strcat(msg, "\r\n");
+ len = strlen(msg);
+ if ((len2=write(s, msg, len)) != len) {
close(s);
- perror("write");
- return -1;
+ perror("write request");
+ free(r);
+ return NULL;
+ } else
+ total_bytes_written += len2;
+ if (f>=0) {
+ while ((len = read(f, buf, sizeof(buf)))>0) {
+ len2 = write(s, buf, len);
+ if (len2 < 0) {
+ perror("write body");
+ close(s);
+ free(r);
+ }
+ }
+ if (len < 0) {
+ perror("read body");
+ exit(1);
+ }
}
+
/*
* if (fcntl(s, F_SETFL, O_NDELAY) < 0)
* perror("fcntl O_NDELAY");
*/
- return s;
+ return r;
}
void
read_url(int fd, void *junk)
{
+ struct _request *r;
static char buf[8192];
char *t;
int s;
if (fgets(buf, 8191, stdin) == NULL) {
printf("Done Reading URLS\n");
fd_close(0);
+ nfds++;
return;
}
if ((t = strchr(buf, '\n')))
*t = '\0';
- s = request(buf);
- if (s < 0) {
+ r = request(buf);
+ if (!r) {
max_connections = nfds - 1;
printf("NOTE: max_connections set at %d\n", max_connections);
+ } else {
+ fd_open(r->fd, read_reply, r, reply_done);
}
- fd_open(s, read_reply, NULL);
}
void
@@ -242,16 +394,17 @@
int i;
int c;
int dt;
- fd_set R;
+ int j;
+ fd_set R,R2;
struct timeval start;
struct timeval last;
struct timeval to;
setbuf(stdout, NULL);
setbuf(stderr, NULL);
progname = strdup(argv[0]);
- gettimeofday(&start, NULL);
- last = start;
- while ((c = getopt(argc, argv, "p:h:n:il:")) != -1) {
+ gettimeofday(&now, NULL);
+ start = last = now;
+ while ((c = getopt(argc, argv, "p:h:n:icl:")) != -1) {
switch (c) {
case 'p':
proxy_port = atoi(optarg);
@@ -268,15 +421,20 @@
case 'l':
lifetime = (time_t) atoi(optarg);
break;
+ case 'c':
+ opt_checksum = 1;
+ break;
default:
usage();
return 1;
}
}
- fd_open(0, read_url, NULL);
+ fd_open(0, read_url, NULL, NULL);
+ nfds--;
signal(SIGINT, sig_intr);
signal(SIGPIPE, SIG_IGN);
- while (nfds) {
+ FD_ZERO(&R2);
+ while (nfds || FD[0].cb) {
FD_ZERO(&R);
to.tv_sec = 0;
to.tv_usec = 100000;
@@ -292,26 +450,36 @@
FD_SET(i, &R);
}
if (select(maxfd + 1, &R, NULL, NULL, &to) < 0) {
- printf("maxfd=%d\n", maxfd);
+ fprintf(stderr, "maxfd=%d\n", maxfd);
if (errno != EINTR)
perror("select");
continue;
}
+ gettimeofday(&now, NULL);
for (i = 0; i <= maxfd; i++) {
if (!FD_ISSET(i, &R))
continue;
FD[i].cb(i, FD[i].data);
+ if (nfds < max_connections && FD[0].cb) {
+ j=0;
+ FD_SET(0,&R2);
+ to.tv_sec=0;
+ to.tv_usec=0;
+ if(select(1,&R2,NULL,NULL,&to) == 1)
+ FD[0].cb(0, FD[0].data);
+ }
}
- gettimeofday(&now, NULL);
if (now.tv_sec > last.tv_sec) {
last = now;
dt = (int) (now.tv_sec - start.tv_sec);
- printf("T+ %6d: %9d req (%+4d), %4d conn, %3d/sec avg\n",
+ printf("T+ %6d: %9d req (%+4d), %4d conn, %3d/sec avg, %dmb, %dkb/sec avg\n",
dt,
nrequests,
reqpersec,
nfds,
- (int) (nrequests / dt));
+ (int) (nrequests / dt),
+ (int)total_bytes_read / 1024 / 1024,
+ (int)total_bytes_read / 1024 / dt);
reqpersec = 0;
}
}
--------------2CFF1B1D14F41B9A5DA44F7F
Content-Type: application/x-perl; name="build_file_list.pl"
Content-Transfer-Encoding: base64
Content-Disposition: inline; filename="build_file_list.pl"
IyEvdXNyL2Jpbi9wZXJsIC13CgpkaWUgIlVzYWdlOiBidWlsZF9maWxlX2xpc3QgdXJsX2Zp
bGUgdGNwLWJhbmdlci10cmFjZVxuIgogICAgaWYgKEBBUkdWICE9IDIpOwoKJHVybF9maWxl
PXNoaWZ0IEBBUkdWOwokdHJhY2U9c2hpZnQgQEFSR1Y7Cgolc2l6ZT0oKTsKJWNoZWNrc3Vt
PSgpOwoKb3BlbihUUkFDRSwiPCR0cmFjZSIpIHx8IGRpZSgib3BlbiAkdHJhY2UiKTsKd2hp
bGUoPFRSQUNFPikgewogICAgbmV4dCBpZiAhL15ET05FOi87CiAgICBteSgkdXJsLCRjaGVj
a3N1bSwkc2l6ZSkgPSBtL15ET05FOiAoXFMqKSBjaGVja3N1bSAoXGQrKSBzaXplIChcZCsp
LzsKICAgIGRpZSBpZiAhZGVmaW5lZCAkY2hlY2tzdW07CiAgICAkc2l6ZXskdXJsfT0kc2l6
ZTsKICAgICRjaGVja3N1bXskdXJsfT0kY2hlY2tzdW07Cn0KY2xvc2UoVFJBQ0UpOwoKb3Bl
bihVUkxTLCI8JHVybF9maWxlIikgfHwgZGllKCJvcGVuICR1cmxfZmlsZSIpOwp3aGlsZSg8
VVJMUz4pIHsKICAgIG15ICgkbWV0aG9kLCAkdXJsLCAkZmlsZSwgJHNpemUsICRjaGVja3N1
bSkgPSBzcGxpdDsKCiAgICBpZiAoJHVybCBlcSAiIikgewoJJHVybCA9ICRtZXRob2Q7Cgkk
bWV0aG9kID0gIkdFVCI7CgkkZmlsZSA9ICItIjsKCSRzaXplID0gIi0iOwoJJGNoZWNrc3Vt
ID0gIi0iOwogICAgfQogICAgJHNpemUgPSAkc2l6ZXskdXJsfSBpZiBkZWZpbmVkICRzaXpl
eyR1cmx9OwogICAgJGNoZWNrc3VtID0gJGNoZWNrc3VteyR1cmx9IGlmIGRlZmluZWQgJGNo
ZWNrc3VteyR1cmx9OwogICAgCiAgICBwcmludCAiJG1ldGhvZCAkdXJsICRmaWxlICRzaXpl
ICRjaGVja3N1bVxuIjsKfQpjbG9zZShVUkxTKTsK
--------------2CFF1B1D14F41B9A5DA44F7F
Content-Type: text/plain; charset=us-ascii; name="pconn-banger.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="pconn-banger.c"
#include "config.h"
/*
* On some systems, FD_SETSIZE is set to something lower than the
* actual number of files which can be opened. IRIX is one case,
* NetBSD is another. So here we increase FD_SETSIZE to our
* configure-discovered maximum *before* any system includes.
*/
#define CHANGE_FD_SETSIZE 1
/* Cannot increase FD_SETSIZE on Linux */
#if defined(_SQUID_LINUX_)
#undef CHANGE_FD_SETSIZE
#define CHANGE_FD_SETSIZE 0
#endif
/* Cannot increase FD_SETSIZE on FreeBSD before 2.2.0, causes select(2)
* to return EINVAL. */
/* Marian Durkovic <marian@svf.stuba.sk> */
/* Peter Wemm <peter@spinner.DIALix.COM> */
#if defined(_SQUID_FREEBSD_)
#include <osreldate.h>
#if __FreeBSD_version < 220000
#undef CHANGE_FD_SETSIZE
#define CHANGE_FD_SETSIZE 0
#endif
#endif
/* Increase FD_SETSIZE if SQUID_MAXFD is bigger */
#if CHANGE_FD_SETSIZE && SQUID_MAXFD > DEFAULT_FD_SETSIZE
#define FD_SETSIZE SQUID_MAXFD
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_STDIO_H
#include <stdio.h>
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#ifdef HAVE_BSTRING_H
#include <bstring.h>
#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#if HAVE_SIGNAL_H
#include <signal.h>
#endif
#if HAVE_TIME_H
#include <time.h>
#endif
#if HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_CTYPE_H
#include <ctype.h>
#endif
#if HAVE_ASSERT_H
#include <assert.h>
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#define PROXY_PORT 3128
#define PROXY_ADDR "127.0.0.1"
#define MAX_FDS 1024
#define READ_BUF_SZ 4096
#define min(x,y) ((x)<(y)? (x) : (y))
static int proxy_port = PROXY_PORT;
static char *proxy_addr = PROXY_ADDR;
static char *progname;
static int noutstanding = 0;
static int done_reading_urls = 0;
static int opt_ims = 0;
static int opt_checksum = 0;
static int opt_reopen = 1;
static int max_outstanding = 10;
static time_t lifetime = 60;
static const char *const crlf = "\r\n";
static int trace_fd = -1;
static int total_bytes_read = 0;
#define REPLY_HDR_SZ 8192
struct _r {
char url[1024];
int content_length;
int hdr_length;
int hdr_offset;
int bytes_read;
char reply_hdrs[REPLY_HDR_SZ];
struct _r *next;
long sum;
long validsize;
long validsum;
};
static struct _r *Requests;
char *
mkrfc850(t)
time_t *t;
{
static char buf[128];
struct tm *gmt = gmtime(t);
buf[0] = '\0';
(void) strftime(buf, 127, "%A, %d-%b-%y %H:%M:%S GMT", gmt);
return buf;
}
char *
mime_headers_end(const char *mime)
{
const char *p1, *p2;
const char *end = NULL;
p1 = strstr(mime, "\n\r\n");
p2 = strstr(mime, "\n\n");
if (p1 && p2)
end = p1 < p2 ? p1 : p2;
else
end = p1 ? p1 : p2;
if (end)
end += (end == p1 ? 3 : 2);
return (char *) end;
}
void
sig_intr(int sig)
{
fprintf(stderr, "\rWaiting for open connections to finish...\n");
signal(sig, SIG_DFL);
done_reading_urls = 1;
}
int
open_http_socket(void)
{
int s;
struct sockaddr_in S;
if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
return -1;
}
memset(&S, '\0', sizeof(struct sockaddr_in));
S.sin_family = AF_INET;
S.sin_port = htons(proxy_port);
S.sin_addr.s_addr = inet_addr(proxy_addr);
if (connect(s, (struct sockaddr *) &S, sizeof(S)) < 0) {
close(s);
perror("connect");
return -1;
}
return s;
}
int
send_request(int fd, const char *data)
{
char msg[4096],buf[4096];
int len;
time_t w;
struct _r *r;
struct _r **R;
char *method, *url, *file, *size, *checksum;
char *tmp = strdup(data);
struct stat st;
int file_fd = -1;
method=strtok(tmp, " ");
url=strtok(NULL, " ");
file=strtok(NULL, " ");
size=strtok(NULL, " ");
checksum=strtok(NULL, " ");
if (!url) {
url=method;
method="GET";
}
if (file && strcmp(file,"-")==0)
file=NULL;
if (size && strcmp(size,"-")==0)
size=NULL;
if (checksum && strcmp(checksum,"-")==0)
checksum=NULL;
msg[0] = '\0';
sprintf(buf, "%s %s HTTP/1.0\r\n", method, url);
strcat(msg,buf);
strcat(msg, "Accept: */*\r\n");
strcat(msg, "Proxy-Connection: Keep-Alive\r\n");
if (opt_ims && (lrand48() & 0x03) == 0) {
w = time(NULL) - (lrand48() & 0x3FFFF);
sprintf(buf, "If-Modified-Since: %s\r\n", mkrfc850(&w));
strcat(msg, buf);
}
if (file) {
if ( (file_fd = open(file,O_RDONLY)) < 0) {
perror("open");
return -1;
}
if ( fstat(file_fd, &st) ) {
perror("fstat");
close(file_fd);
return -1;
}
sprintf(buf, "Content-length: %d\r\n", st.st_size);
strcat(msg, buf);
}
strcat(msg, "\r\n");
len = strlen(msg);
if (write(fd, msg, len) < 0) {
close(fd);
perror("request write");
close(file_fd);
return -1;
}
if (file) {
while((len=read(file_fd, buf, sizeof buf)) > 0) {
if (write(fd, buf, len) < 0) {
close(fd);
perror("body write");
close(file_fd);
return -1;
}
}
if (len < 0) {
perror("file read");
close(file_fd);
return -1;
}
close(file_fd);
}
r = calloc(1, sizeof(struct _r));
strcpy(r->url, url);
if (size)
r->validsize = atoi(size);
else
r->validsize = -1;
if (checksum)
r->validsum = atoi(checksum);
for (R = &Requests; *R; R = &(*R)->next);
*R = r;
/* fprintf(stderr, "REQUESTED %s\n", url); */
noutstanding++;
return 0;
}
static int
get_header_int_value(const char *hdr, const char *buf, const char *end)
{
const char *t;
for (t = buf; t < end; t += strcspn(t, crlf), t += strspn(t, crlf)) {
if (strncasecmp(t, hdr, strlen(hdr)) == 0) {
t += strlen(hdr);
while (isspace(*t))
t++;
return atoi(t);
}
}
return -1;
}
static const char *
get_header_string_value(const char *hdr, const char *buf, const char *end)
{
const char *t;
static char result[8192];
for (t = buf; t < end; t += strcspn(t, crlf), t += strspn(t, crlf)) {
if (strncasecmp(t, hdr, strlen(hdr)) == 0) {
t += strlen(hdr);
while (isspace(*t))
t++;
strcpy(result,"");
strncat(result,t,strcspn(t, crlf));
return result;
}
}
return NULL;
}
void
request_done(struct _r *r)
{
#if 0
fprintf(stderr, "DONE: %s, (%d+%d)\n",
r->url,
r->hdr_length,
r->content_length);
#endif
if (r->content_length != r->bytes_read)
fprintf(stderr, "ERROR! Short reply, expected %d bytes got %d\n",
r->content_length, r->bytes_read);
else if (r->validsize >= 0) {
if (r->validsize != r->bytes_read)
fprintf(stderr, "WARNING: %s Object size mismatch, expected %d got %d\n",
r->url, r->validsize, r->bytes_read);
else if (opt_checksum && r->sum != r->validsum)
fprintf(stderr, "WARNING: %s Checksum error. Expected %d got %d\n",
r->url, r->validsum, r->sum);
}
}
int
handle_read(char *inbuf, int len)
{
struct _r *r = Requests;
const char *end;
const char *url;
static char buf[READ_BUF_SZ];
int hlen,blen;
if (len < 0 ) {
perror("read");
Requests = r->next;
request_done(r);
free(r);
noutstanding--;
if (trace_fd >= 0)
write(trace_fd,"\n[CLOSED]\n",10);
return -1;
}
total_bytes_read += len;
xmemcpy(buf,inbuf,len);
if (len == 0) {
fprintf(stderr, "WARNING: %s, server closed socket after %d+%d bytes\n", r->url, r->hdr_offset, r->bytes_read);
/* XXX, If no data was received and it isn't the first request on this
* connection then the request should be restarted rather than aborted
* but this is a simple test program an not a full blown HTTP client.
*/
request_done(r);
Requests = r->next;
free(r);
noutstanding--;
return -1;
}
if (trace_fd > 0)
write(trace_fd, buf, len);
while (len > 0) {
/* Build headers */
if (r->hdr_length == 0) {
hlen = min(len, REPLY_HDR_SZ - r->hdr_offset - 1);
xmemcpy(r->reply_hdrs + r->hdr_offset, buf, hlen);
r->hdr_offset += hlen;
r->reply_hdrs[r->hdr_offset] = '\0';
len -= hlen;
/* Save any remaining read data */
xmemmove(buf, buf + hlen, len);
}
/* Process headers */
if (r->hdr_length == 0 && (end = mime_headers_end(r->reply_hdrs)) != NULL) {
#if 0
fprintf(stderr, "FOUND EOH FOR %s\n", r->url); */
#endif
r->hdr_length = end - r->reply_hdrs;
#if 0
fprintf(stderr, "HDR_LENGTH = %d\n", r->hdr_length);
#endif
/* "unread" any body contents received */
blen = r->hdr_offset - r->hdr_length;
assert(blen >= 0);
if (blen > 0) {
xmemmove(buf + blen, buf, len);
xmemcpy(buf, r->reply_hdrs + r->hdr_length, blen);
len += blen;
}
r->reply_hdrs[r->hdr_length]='\0'; /* Null terminate headers */
/* Parse headers */
r->content_length = get_header_int_value("content-length:", r->reply_hdrs, end);
/* fprintf(stderr, "CONTENT_LENGTH = %d\n", r->content_length); */
url = get_header_string_value("X-Request-URI:", r->reply_hdrs, end);
if (url != NULL && strcmp(r->url, url) != 0)
fprintf(stderr, "WARNING: %s got reply %s\n", r->url, url);
#if XREQUESTURI || 0
fprintf(stderr, "LOCATION = %s\n", get_header_string_value("X-Request-URI:", r->reply_hdrs, end));
#endif
}
if ( !(len==0 || r->hdr_length > 0) ) {
fprintf(stderr, "ERROR!!!\n");
assert((len==0 || r->hdr_length > 0));
}
/* Process body */
if (r->hdr_length != 0) {
int i;
int bytes_left, bytes_used;
if (r->content_length >= 0) {
bytes_left = r->content_length - r->bytes_read;
assert(bytes_left >= 0);
bytes_used = len < bytes_left ? len : bytes_left;
} else {
bytes_left = len + 1; /* Unknown end... */
bytes_used = len;
}
if (opt_checksum) {
for(i=0; i<bytes_used; i++)
r->sum += (int)buf[i] & 0xFF;
}
r->bytes_read += bytes_used;
len -= bytes_used;
if (bytes_left == bytes_used) {
request_done(r);
Requests = r->next;
free(r);
noutstanding--;
r = Requests;
} else {
assert(r->bytes_read < r->content_length);
}
xmemmove(buf, buf + bytes_used, len);
}
}
return 0;
}
int
read_reply(int fd)
{
static char buf[READ_BUF_SZ];
int len;
int x;
len = read(fd, buf, READ_BUF_SZ);
x = handle_read(buf, len);
if (x < 0) {
perror("read reply");
close(fd);
}
return x;
}
void
main_loop(void)
{
static int pconn_fd = -1;
static char buf[8192];
struct timeval to;
struct timeval now,last,start;
fd_set R;
struct _r *r;
struct _r *nextr;
int x;
int timeouts;
int nrequests = 0, rrequests = 0, reqpersec = 0;
gettimeofday(&start, NULL);
last = start;
pconn_fd = open_http_socket();
if (pconn_fd < 0) {
perror("socket");
exit(1);
}
while (!done_reading_urls || noutstanding) {
if (!opt_reopen && pconn_fd < 0) {
fprintf(stderr,"TERMINATED: Connection closed\n");
break;
}
if (pconn_fd<0) {
pconn_fd = open_http_socket();
if (pconn_fd < 0) {
perror("socket");
exit(1);
}
nextr = Requests;
Requests = NULL;
noutstanding=0;
while ((r = nextr) != NULL) {
nextr = r->next;
if (send_request(pconn_fd, r->url) != 0) {
close(pconn_fd);
pconn_fd=-1;
nextr = r;
for (r = Requests; r!=NULL && r->next; r=r->next);
if (r != NULL)
r->next = nextr;
else
Requests = nextr;
break;
}
free(r);
}
timeouts = 0;
if (pconn_fd <0)
continue;
}
if (timeouts == 200) {
close(pconn_fd);
pconn_fd = -1;
r = Requests;
Requests = Requests->next;
fprintf(stderr, "ABORT %s\n", Requests->url);
free(r);
noutstanding--;
}
if (pconn_fd>=0 && noutstanding < max_outstanding && !done_reading_urls) {
char *t;
if (fgets(buf, 8191, stdin) == NULL) {
fprintf(stderr, "Done Reading URLS\n");
done_reading_urls = 1;
continue;
}
rrequests++;
if ((t = strchr(buf, '\n')))
*t = '\0';
if (send_request(pconn_fd, buf) != 0) {
close(pconn_fd);
pconn_fd=-1;
continue;
}
nrequests++;
reqpersec++;
timeouts = 0;
}
FD_ZERO(&R);
to.tv_sec = 1;
to.tv_usec = 0;
FD_SET(pconn_fd, &R);
x = select(pconn_fd + 1, &R, NULL, NULL, &to);
if (x < 0) {
if (errno != EINTR)
perror("select");
continue;
} else if (x == 0) {
assert(Requests != NULL);
fprintf(stderr, "TIMEOUT %s; %d, %d\n", Requests->url,
++timeouts, noutstanding);
continue;
}
if (FD_ISSET(pconn_fd, &R)) {
timeouts = 0;
if (read_reply(pconn_fd) != 0)
pconn_fd = -1;
}
gettimeofday(&now, NULL);
if (now.tv_sec > last.tv_sec) {
int dt;
int nreq;
last = now;
dt = (int) (now.tv_sec - start.tv_sec);
nreq=0;
for (r=Requests; r ; r=r->next) nreq++;
printf("T+ %6d: %9d req (%+4d), %4d pend, %3d/sec avg, %dmb, %dkb/sec avg\n",
dt,
nrequests,
reqpersec,
nreq,
(int) (nrequests / dt),
(int)total_bytes_read / 1024 / 1024,
(int)total_bytes_read / 1024 / dt);
reqpersec = 0;
}
}
}
void
usage(void)
{
fprintf(stderr, "usage: %s: -p port -h host -n max -t tracefile -i -c -l lifetime\n", progname);
}
int
main(argc, argv)
int argc;
char *argv[];
{
int c;
setbuf(stdout, NULL);
setbuf(stderr, NULL);
progname = strdup(argv[0]);
while ((c = getopt(argc, argv, "p:h:n:t:icl:r")) != -1) {
switch (c) {
case 'p':
proxy_port = atoi(optarg);
break;
case 'h':
proxy_addr = strdup(optarg);
break;
case 'n':
max_outstanding = atoi(optarg);
break;
case 'i':
opt_ims = 1;
break;
case 'c':
opt_checksum = 1;
break;
case 'l':
lifetime = (time_t) atoi(optarg);
break;
case 't':
trace_fd = open(optarg,O_WRONLY|O_CREAT|O_TRUNC,0666);
break;
case 'r':
opt_reopen = !opt_reopen;
break;
default:
usage();
return 1;
}
}
signal(SIGINT, sig_intr);
signal(SIGPIPE, SIG_IGN);
main_loop();
return 0;
}
--------------2CFF1B1D14F41B9A5DA44F7F
Content-Type: text/plain; charset=us-ascii; name="tcp-banger2.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="tcp-banger2.c"
#include "config.h"
/*
* On some systems, FD_SETSIZE is set to something lower than the
* actual number of files which can be opened. IRIX is one case,
* NetBSD is another. So here we increase FD_SETSIZE to our
* configure-discovered maximum *before* any system includes.
*/
#define CHANGE_FD_SETSIZE 1
/* Cannot increase FD_SETSIZE on Linux */
#if defined(_SQUID_LINUX_)
#undef CHANGE_FD_SETSIZE
#define CHANGE_FD_SETSIZE 0
#endif
/* Cannot increase FD_SETSIZE on FreeBSD before 2.2.0, causes select(2)
* to return EINVAL. */
/* Marian Durkovic <marian@svf.stuba.sk> */
/* Peter Wemm <peter@spinner.DIALix.COM> */
#if defined(_SQUID_FREEBSD_)
#include <osreldate.h>
#if __FreeBSD_version < 220000
#undef CHANGE_FD_SETSIZE
#define CHANGE_FD_SETSIZE 0
#endif
#endif
/* Increase FD_SETSIZE if SQUID_MAXFD is bigger */
#if CHANGE_FD_SETSIZE && SQUID_MAXFD > DEFAULT_FD_SETSIZE
#define FD_SETSIZE SQUID_MAXFD
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_STDIO_H
#include <stdio.h>
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#if HAVE_SIGNAL_H
#include <signal.h>
#endif
#if HAVE_TIME_H
#include <time.h>
#endif
#if HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_ASSERT_H
#include <assert.h>
#endif
#define PROXY_PORT 3128
#define PROXY_ADDR "127.0.0.1"
#define MAX_FDS 1024
#define READ_BUF_SZ 4096
static int proxy_port = PROXY_PORT;
static char *proxy_addr = PROXY_ADDR;
static char *progname;
static int reqpersec;
static int nrequests;
static int opt_ims = 0;
static int max_connections = 64;
static time_t lifetime = 60;
static struct timeval now;
static long total_bytes_written = 0;
static long total_bytes_read = 0;
static int opt_checksum = 0;
typedef void (CB) (int, void *);
struct _f {
CB *cb;
CB *ccb;
void *data;
time_t start;
};
struct _request {
int fd;
char url[8192];
char buf[READ_BUF_SZ * 2 + 1];
int headfound;
long validsize;
long validsum;
long bodysize;
long sum;
int content_length;
};
struct _f FD[MAX_FDS];
int nfds = 0;
int maxfd = 0;
char *
mkrfc850(t)
time_t *t;
{
static char buf[128];
struct tm *gmt = gmtime(t);
buf[0] = '\0';
(void) strftime(buf, 127, "%A, %d-%b-%y %H:%M:%S GMT", gmt);
return buf;
}
void
fd_close(int fd)
{
close(fd);
if (FD[fd].ccb)
FD[fd].ccb(fd, FD[fd].data);
FD[fd].ccb = NULL;
FD[fd].cb = NULL;
FD[fd].data = NULL;
nfds--;
if (fd == maxfd) {
while (fd > 0 && FD[fd].cb == NULL)
fd--;
maxfd = fd;
}
}
void
fd_open(int fd, CB * cb, void *data, CB *ccb)
{
FD[fd].cb = cb;
FD[fd].ccb = ccb;
FD[fd].data = data;
FD[fd].start = now.tv_sec;
if (fd > maxfd)
maxfd = fd;
nfds++;
}
void
sig_intr(int sig)
{
fd_close(0);
nfds++;
printf("\rWaiting for open connections to finish...\n");
signal(sig, SIG_DFL);
}
void
read_reply(int fd, void *data)
{
struct _request *r = data;
static unsigned char buf[READ_BUF_SZ];
int len;
char *p;
if ((len=read(fd, buf, READ_BUF_SZ)) <= 0) {
fd_close(fd);
reqpersec++;
nrequests++;
} else {
int used=0;
total_bytes_read+=len;
if (r->headfound < 2) {
char *p,*header = NULL;
int oldlen = strlen(r->buf);
int newlen = oldlen + len;
assert(oldlen <= READ_BUF_SZ);
memcpy(r->buf+oldlen, buf, len);
r->buf[newlen+1]='\0';
for(p=r->buf; r->headfound < 2 && used<newlen; p++,used++) {
switch(*p) {
case '\n':
r->headfound++;
if (header) {
/* Decode header */
if (strncasecmp(header,"Content-Length:",15)==0)
r->content_length = atoi(header+15);
if (strncasecmp(header,"X-Request-URI:",14)==0) {
/* Check URI */
if (strncmp(r->url, header+15, strcspn(header+15,"\r\n"))) {
char url[8192];
strncpy(url, header+15, strcspn(header+15,"\r\n"));
url[strcspn(header+15, "\r\n")]='\n';
fprintf(stderr,"ERROR: Sent %s received %s\n",
r->url, url);
}
}
header=NULL;
}
break;
case '\r':
break;
default:
r->headfound=0;
if (!header)
header = p;
break;
}
}
if (header) {
memmove(r->buf, header, newlen - (header - r->buf) + 1);
}
}
r->bodysize+=len-used;
if (opt_checksum) {
for (; used<len ; used++) {
r->sum += buf[used];
}
}
}
}
void
reply_done(int fd, void *data)
{
struct _request *r = data;
if (r->bodysize != r->content_length)
fprintf(stderr,"ERROR: %s expected %d bytes got %d\n",
r->url, r->content_length, r->bodysize);
else if (r->validsize >= 0) {
if (r->validsize != r->bodysize)
fprintf(stderr,"WARNING: %s size mismatch wanted %d bytes got %d\n",
r->url, r->validsize, r->bodysize);
else if (opt_checksum && r->validsum != r->sum)
fprintf(stderr,"WARNING: %s invalid checksum wanted %d got %d\n",
r->url, r->validsum, r->sum);
} else if (opt_checksum) {
fprintf(stderr,"DONE: %s checksum %d size %d\n",
r->url, r->sum, r->bodysize);
}
free(r);
}
struct _request *
request(char *urlin)
{
int s=-1,f=-1;
char buf[4096];
char msg[8192];
char *method, *url, *file, *size, *checksum;
char urlbuf[8192];
int len,len2;
time_t w;
struct stat st;
struct sockaddr_in S;
struct _request *r;
if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
return NULL;
}
memset(&S, '\0', sizeof(struct sockaddr_in));
S.sin_family = AF_INET;
S.sin_port = htons(proxy_port);
S.sin_addr.s_addr = inet_addr(proxy_addr);
if (connect(s, (struct sockaddr *) &S, sizeof(S)) < 0) {
close(s);
perror("connect");
return NULL;
}
strcpy(urlbuf,urlin);
method=strtok(urlbuf," ");
url=strtok(NULL," ");
file=strtok(NULL," ");
size=strtok(NULL," ");
checksum=strtok(NULL," ");
if (!url) {
url=method;
method="GET";
}
r=calloc(1,sizeof *r);
assert(r!=NULL);
strcpy(r->url, url);
r->fd = s;
if (size && strcmp(size,"-")!=0)
r->validsize=atoi(size);
else
r->validsize=-1; /* Unknown */
if (checksum && strcmp(checksum,"-")!=0)
r->validsum=atoi(checksum);
msg[0] = '\0';
sprintf(buf,"%s %s HTTP/1.0\r\n", method, url);
strcat(msg, buf);
strcat(msg, "Accept: */*\r\n");
if (opt_ims && (lrand48() & 0x03) == 0) {
w = time(NULL) - (lrand48() & 0x3FFFF);
sprintf(buf, "If-Modified-Since: %s\r\n", mkrfc850(&w));
strcat(msg,buf);
}
if (file && strcmp(file, "-")!=0) {
f = open(file,O_RDONLY);
if (f < 0) {
perror("open file");
exit(1);
}
fstat(f, &st);
sprintf(buf,"Content-Length: %d\r\n", st.st_size);
strcat(msg,buf);
}
strcat(msg, "\r\n");
len = strlen(msg);
if ((len2=write(s, msg, len)) != len) {
close(s);
perror("write request");
free(r);
return NULL;
} else
total_bytes_written += len2;
if (f>=0) {
while ((len = read(f, buf, sizeof(buf)))>0) {
len2 = write(s, buf, len);
if (len2 < 0) {
perror("write body");
close(s);
free(r);
}
}
if (len < 0) {
perror("read body");
exit(1);
}
}
/*
* if (fcntl(s, F_SETFL, O_NDELAY) < 0)
* perror("fcntl O_NDELAY");
*/
return r;
}
void
read_url(int fd, void *junk)
{
struct _request *r;
static char buf[8192];
char *t;
int s;
if (fgets(buf, 8191, stdin) == NULL) {
printf("Done Reading URLS\n");
fd_close(0);
nfds++;
return;
}
if ((t = strchr(buf, '\n')))
*t = '\0';
r = request(buf);
if (!r) {
max_connections = nfds - 1;
printf("NOTE: max_connections set at %d\n", max_connections);
} else {
fd_open(r->fd, read_reply, r, reply_done);
}
}
void
usage(void)
{
fprintf(stderr, "usage: %s: -p port -h host -n max\n", progname);
}
int
main(argc, argv)
int argc;
char *argv[];
{
int i;
int c;
int dt;
int j;
fd_set R,R2;
struct timeval start;
struct timeval last;
struct timeval to;
setbuf(stdout, NULL);
setbuf(stderr, NULL);
progname = strdup(argv[0]);
gettimeofday(&now, NULL);
start = last = now;
while ((c = getopt(argc, argv, "p:h:n:icl:")) != -1) {
switch (c) {
case 'p':
proxy_port = atoi(optarg);
break;
case 'h':
proxy_addr = strdup(optarg);
break;
case 'n':
max_connections = atoi(optarg);
break;
case 'i':
opt_ims = 1;
break;
case 'l':
lifetime = (time_t) atoi(optarg);
break;
case 'c':
opt_checksum = 1;
break;
default:
usage();
return 1;
}
}
fd_open(0, read_url, NULL, NULL);
nfds--;
signal(SIGINT, sig_intr);
signal(SIGPIPE, SIG_IGN);
FD_ZERO(&R2);
while (nfds || FD[0].cb) {
FD_ZERO(&R);
to.tv_sec = 0;
to.tv_usec = 100000;
if (nfds < max_connections && FD[0].cb)
FD_SET(0, &R);
for (i = 1; i <= maxfd; i++) {
if (FD[i].cb == NULL)
continue;
if (now.tv_sec - FD[i].start > lifetime) {
fd_close(i);
continue;
}
FD_SET(i, &R);
}
if (select(maxfd + 1, &R, NULL, NULL, &to) < 0) {
fprintf(stderr, "maxfd=%d\n", maxfd);
if (errno != EINTR)
perror("select");
continue;
}
gettimeofday(&now, NULL);
for (i = 0; i <= maxfd; i++) {
if (!FD_ISSET(i, &R))
continue;
FD[i].cb(i, FD[i].data);
#if 0
/* This is counterproductive. To maximize generated load we need
* utilize non-blocking transmission of requests..
*/
if (nfds < max_connections && FD[0].cb) {
j=0;
FD_SET(0,&R2);
to.tv_sec=0;
to.tv_usec=0;
if(select(1,&R2,NULL,NULL,&to) == 1)
FD[0].cb(0, FD[0].data);
}
#endif
}
if (now.tv_sec > last.tv_sec) {
last = now;
dt = (int) (now.tv_sec - start.tv_sec);
printf("T+ %6d: %9d req (%+4d), %4d conn, %3d/sec avg, %dmb, %dkb/sec avg\n",
dt,
nrequests,
reqpersec,
nfds,
(int) (nrequests / dt),
(int)total_bytes_read / 1024 / 1024,
(int)total_bytes_read / 1024 / dt);
reqpersec = 0;
}
}
return 0;
}
--------------2CFF1B1D14F41B9A5DA44F7F--
Received on Tue Jul 29 2003 - 13:15:48 MDT
This archive was generated by hypermail pre-2.1.9 : Tue Dec 09 2003 - 16:11:46 MST