⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp-banger3.c

📁 -
💻 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#include <netdb.h>#include <sys/wait.h>#define READ_BUF_SZ 4096#define URL_BUF_SZ 4096struct _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 DEBUGstatic int debug = 1;#elsestatic int debug = 0;#endifinttvSubMsec(struct timeval t1, struct timeval t2){    return (t2.tv_sec - t1.tv_sec) * 1000 + (t2.tv_usec - t1.tv_usec) / 1000;}static intget_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 0    if ((int) port != 80)	return 0;#endif    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);    if (s < 0) {	perror("socket");	return -errno;    }    x = connect(s, (struct sockaddr *) &S, sizeof(S));    if (x < 0) {	perror(host);	return -errno;    }    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 -errno;    }    do {	x = read(s, reply, READ_BUF_SZ);	if (x > 0)	    nr += x;    } while (x > 0);    close(s);    return nr;}static voidchild_main_loop(void){    char buf[URL_BUF_SZ];    char *t;    int n;    struct timeval t1;    struct timeval t2;    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;	gettimeofday(&t1, NULL);	n = get_url(buf);	gettimeofday(&t2, NULL);	printf("%d %d\n", n, tvSubMsec(t1, t2));    }}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 voidcreate_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 voiddispatch(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 voidread_reply(thing * t){    char buf[128];    int i;    int x;    int j;    x = read(t->rfd, buf, 128);    if (x < 0) {	perror("read");    } else if (2 == sscanf(buf, "%d %d", &i, &j)) {	gettimeofday(&now, NULL);	printf("%d.%06d %9d %9d %s\n", (int) now.tv_sec, (int) now.tv_usec, i, j, t->url);    }    t->state = 0;    FD_CLR(t->rfd, &R1);}static voidparent_main_loop(void){    thing *t;    char *url;    fd_set R2;    int x;    struct timeval to;    FD_ZERO(&R1);    for (;;) {	while ((t = get_idle_thing()) && (url = parent_read_url()))	    dispatch(t, url);	R2 = R1;	to.tv_sec = 60;	to.tv_usec = 0;	x = select(maxfd + 1, &R2, NULL, NULL, &to);	if (x < 0) {	    perror("select");	    continue;	} else if (x == 0) {	    return;	}	for (t = things; t; t = t->next) {	    if (t->state != 1)		continue;	    if (!FD_ISSET(t->rfd, &R2))		continue;	    read_reply(t);	}    }}static voidsig_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);}intmain(int argc, char *argv[]){    int i;    signal(SIGCHLD, sig_child);    create_children(argv);    parent_main_loop();    for (i=3;i<=maxfd; i++)	close(i);    sleep(1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -