]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
adding
authorwessels <>
Wed, 16 Sep 1998 15:24:25 +0000 (15:24 +0000)
committerwessels <>
Wed, 16 Sep 1998 15:24:25 +0000 (15:24 +0000)
test-suite/tcp-banger3.c [new file with mode: 0644]

diff --git a/test-suite/tcp-banger3.c b/test-suite/tcp-banger3.c
new file mode 100644 (file)
index 0000000..5d00758
--- /dev/null
@@ -0,0 +1,364 @@
+#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
+#include <netdb.h>
+#include <sys/wait.h>
+
+#define READ_BUF_SZ 4096
+#define URL_BUF_SZ 4096
+
+struct _thing {
+    int rfd;
+    int wfd;
+    int state;
+    pid_t pid;
+    char url[URL_BUF_SZ];
+    struct _thing *next;
+};
+typedef struct _thing thing;
+
+static thing *things = NULL;
+static fd_set R1;
+static int maxfd = 0;
+static struct timeval now;
+#if DEBUG
+static int debug = 1;
+#else
+static int debug = 0;
+#endif
+
+static int
+get_url(const char *url)
+{
+    char host[URL_BUF_SZ];
+    char path[URL_BUF_SZ];
+    char request[URL_BUF_SZ];
+    char reply[READ_BUF_SZ];
+    char *t;
+    int x;
+    int s;
+    int nr = 0;
+    struct hostent *h;
+    struct sockaddr_in S;
+    unsigned short port = 80;
+    assert(!strncmp(url, "http://", 7));
+    strncpy(host, url + 7, URL_BUF_SZ);
+    if ((t = strchr(host, '/')))
+       *t = '\0';
+    if ((t = strchr(host, ':'))) {
+       *t = '\0';
+       port = (unsigned short) atoi(t + 1);
+    }
+    if ((int) port != 80)
+       return 0;
+    t = strchr(url + 7, '/');
+    strncpy(path, (t ? t : "/"), URL_BUF_SZ);
+    memset(&S, '\0', sizeof(S));
+    h = gethostbyname(host);
+    if (!h)
+       return 0;
+    memcpy(&S.sin_addr.s_addr, h->h_addr_list[0], sizeof(S.sin_addr.s_addr));
+    S.sin_port = htons(port);
+    S.sin_family = AF_INET;
+    if (debug)
+    fprintf(stderr, "%s (%s) %d %s\n", host, inet_ntoa(S.sin_addr), (int) port, path);
+    s = socket(PF_INET, SOCK_STREAM, 0);
+    x = connect(s, (struct sockaddr *) &S, sizeof(S));
+    if (x < 0) {
+       perror(host);
+       return 0;
+    }
+    snprintf(request, URL_BUF_SZ,
+       "GET %s HTTP/1.1\r\n"
+       "Accept: */*\r\n"
+       "Host: %s\r\n"
+       "Connection: close\r\n"
+       "\r\n",
+       path,
+       host);
+    x = write(s, request, strlen(request));
+    if (x < 0) {
+       perror("write");
+       return 0;
+    }
+    do {
+       x = read(s, reply, READ_BUF_SZ);
+       if (x > 0)
+           nr += x;
+    } while (x > 0);
+    close(s);
+    return nr;
+}
+
+static void
+child_main_loop(void)
+{
+    char buf[URL_BUF_SZ];
+    char *t;
+    int n;
+    if (debug)
+    fprintf(stderr, "Child PID %d entering child_main_loop\n", (int) getpid());
+    setbuf(stdin, NULL);
+    setbuf(stdout, NULL);
+    setbuf(stderr, NULL);
+    while (fgets(buf, URL_BUF_SZ, stdin)) {
+       t = strchr(buf, '\n');
+       if (t == NULL)
+           continue;
+       *t = '\0';
+       if (strncmp(buf, "http://", 7))
+           continue;
+       n = get_url(buf);
+       printf ("%d\n", n);
+    }
+}
+
+static thing *
+create_a_thing(char *argv[])
+{
+    int p2c[2];
+    int c2p[2];
+    int prfd, pwfd, crfd, cwfd;
+    pid_t pid;
+    thing *t;
+    if (pipe(p2c) < 0)
+       abort();
+    if (pipe(c2p) < 0)
+       abort();
+    prfd = p2c[0];
+    cwfd = p2c[1];
+    crfd = c2p[0];
+    pwfd = c2p[1];
+    if ((pid = fork()) < 0)
+       abort();
+    if (pid > 0) {             /* parent */
+       /* close shared socket with child */
+       close(crfd);
+       close(cwfd);
+       t = calloc(1, sizeof(*t));
+       t->wfd = pwfd;
+       t->rfd = prfd;
+       if (pwfd > maxfd)
+           maxfd = pwfd;
+       if (prfd > maxfd)
+           maxfd = prfd;
+       t->pid = pid;
+       return t;
+    }
+    /* child */
+    close(prfd);
+    close(pwfd);
+    dup2(crfd, 0);
+    dup2(cwfd, 1);
+    close(crfd);
+    close(cwfd);
+    child_main_loop();
+    exit(0);
+}
+
+static void
+create_children(char *argv[])
+{
+    thing *t;
+    thing **T = &things;
+    int i;
+    for (i = 0; i < 20; i++) {
+       t = create_a_thing(argv);
+       assert(t);
+    if (debug)
+       fprintf(stderr, "Thing #%d on FD %d/%d\n",
+           i, t->rfd, t->wfd);
+       *T = t;
+       T = &t->next;
+    }
+}
+
+char *
+parent_read_url(void)
+{
+    static char buf[URL_BUF_SZ];
+    while (fgets(buf, URL_BUF_SZ, stdin)) {
+       if (strncmp(buf, "http://", 7))
+           continue;
+       return buf;
+    }
+    return NULL;
+}
+
+static thing *
+get_idle_thing(void)
+{
+    thing *t;
+    thing *n = things;
+    while ((t = n)) {
+       n = t->next;
+       if (t->state == 0)
+           break;
+    }
+    return t;
+}
+
+static void
+dispatch(thing * t, char *url)
+{
+    int x;
+    char *s;
+    assert(t->state == 0);
+    x = write(t->wfd, url, strlen(url));
+    if (x < 0)
+       perror("write");
+    if (debug)
+    fprintf(stderr, "dispatched URL to thing PID %d, %d bytes\n", (int) t->pid, x);
+    strncpy(t->url, url, URL_BUF_SZ);
+    if ((s = strchr(t->url, '\n')))
+       *s = '\0';
+    t->state = 1;
+    FD_SET(t->rfd, &R1);
+}
+
+static void
+read_reply(thing * t)
+{
+    char buf[128];
+    int i;
+    int x;
+    x = read(t->rfd, buf, 128);
+    if (x < 0) {
+       perror("read");
+    } else {
+       i = atoi(buf);
+       gettimeofday(&now, NULL);
+       printf("%d.%06d %9d %s\n", (int) now.tv_sec, (int) now.tv_usec, i, t->url);
+    }
+    t->state = 0;
+    FD_CLR(t->rfd, &R1);
+}
+
+static void
+parent_main_loop(void)
+{
+    thing *t;
+    char *url;
+    fd_set R2;
+    int x;
+    FD_ZERO(&R1);
+    for (;;) {
+       while ((t = get_idle_thing()) && (url = parent_read_url()))
+           dispatch(t, url);
+       R2 = R1;
+       x = select(maxfd + 1, &R2, NULL, NULL, NULL);
+       if (x < 0) {
+           perror("select");
+           continue;
+       }
+       for (t = things; t; t = t->next) {
+           if (t->state != 1)
+               continue;
+           if (!FD_ISSET(t->rfd, &R2))
+               continue;
+           read_reply(t);
+       }
+    }
+}
+
+static void
+sig_child(int sig)
+{
+    int status;
+    pid_t pid;
+    do {
+       pid = waitpid(-1, &status, WNOHANG);
+    } while (pid > 0 || (pid < 0 && errno == EINTR));
+    signal(sig, sig_child);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+    signal(SIGCHLD, sig_child);
+    create_children(argv);
+    parent_main_loop();
+    return 0;
+}