Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 2 Sep 1999 02:33:13 -0700
From:      "Brian O'Shea" <boshea@ricochet.net>
To:        Dave Liebreich <davel@entera.com>
Cc:        freebsd-net@freebsd.org
Subject:   Re: TCP socket performance?
Message-ID:  <19990902023313.B57569@beastie.localdomain>
In-Reply-To: <199909020149.SAA02570@warhawk.entera.com>; from Dave Liebreich on Wed, Sep 01, 1999 at 06:49:11PM -0700
References:  <199909020149.SAA02570@warhawk.entera.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Maybe I'm losing it here, but did you actually get this to compile?
I started making modifications to get through the compiler errors, but
there's just too much wrong here.  I'd love to see the compiler that
this successfully built on.

For instance, this just isn't valid C syntax:

74 		int fd(socket(AF_INET, SOCK_STREAM, 0));
75 		if (fd < 0)
76 		{
77 			perror("socket.2");
78 			return 1;
79 		}

Where is 'fd' declared?  Is it an integer or a function?


On Wed, Sep 01, 1999 at 06:49:11PM -0700, Dave Liebreich wrote:
> The following program was written to demonstrate a problem with Solaris 7
> x86 networking.  I tried running it under FreeBSD 3.2-RELEASE (vanilla - no
> tuning).
> 
> The program runs for a bit, then the system interactive response "freezes"
>  - sending a HUP to the process restores the system to normal performace.
> 
> If anyone on this list has any ideas on why this program thrashes the system
> so badly, or any suggestions on how to tune the system to not thrash, please
> let me know.
> 
> Thanks
> 
> Dave Liebreich
> QA
> Entera, Inc.
> 
> 
> --------->% cut here %<---------
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <sys/wait.h>
> #include <sys/stat.h>
> #include <netinet/in.h>
> #include <sys/time.h>
> #include <fcntl.h>
> #include <stdio.h>
> #include <errno.h>
> #include <unistd.h>
> #include <stdlib.h>
> #include <memory.h>
> #include <signal.h>
> #include <time.h>
> 
> 
> #ifdef ONT_GET_ALARMED
> static int useAlarm = 0;
> #else
> static int useAlarm = 1;
> #endif
> 
> #ifdef ONT_USE_PIPES
> static int usePipes;
> #else
> static int usePipes = 1;
> #endif
> 
> static int numServProcs;
> static int numCliProcs;
> static int pipefds[2];
> 
> 
> static sockaddr_in sin[1];
> static pid_t startPid;
> 
> void pauseAnInstant(long num)
> {
> 	timeval tv[1];
> 	tv->tv_sec = 0;
> 	tv->tv_usec = num * 1000;
> 	if (select(0, 0, 0, 0, tv) < 0)
> 		perror("select");
> }
> 
> static void handler()
> {
> 	if (getpid() == startPid)
> 		kill(0, SIGHUP);
> }
> 
> static void sigHandler(int sig)
> {
> 	exit(0);
> }
> 
> int bite(int num)
> {
> 	char first[10];
> 	char pre[2];
> 	char post[2];
> 	long pid=getpid();
> 	pre[0] = 'C';
> 	pre[1] = ' ' + num;
> 	post[0] = 'c';
> 	post[1] = ' ' + num;
> 	first[0] = 'F';
> 	first[1] = ' ' + num;
> 	memcpy(first + 2, (char *)&pid, sizeof pid);
> 
> 	write(pipefds[1], first, sizeof pid + 2);
> 	for (;;)
> 	{
> 		char buf[2048];
> 		int fd(socket(AF_INET, SOCK_STREAM, 0));
> 		if (fd < 0)
> 		{
> 			perror("socket.2");
> 			return 1;
> 		}
> 		pauseAnInstant(10);
> 		write(pipefds[1], pre, 2);
> 		int r = connect(fd, (sockaddr*)sin, sizeof(sin));
> 		if (r < 0)
> 		{
> 			perror("connect");
> 			return 1;
> 		}
> 		write(pipefds[1], post, 2);
> 
> 		if (write(fd, buf, sizeof(buf)) != sizeof buf)
> 			perror("read.write.bite");
> 		pauseAnInstant(150);
> 		if (read(fd, buf, sizeof(buf)) != sizeof(buf))
> 			perror("read.read.bite");
> 		close(fd);
> 	}
> }
> 
> int attack()
> {
> 	for (int i = 0; i < numCliProcs; ++i)
> 	{
> 		switch(fork())
> 		{
> 		case 0:
> 			sleep(1);
> 			return bite(i);
> 		case -1:
> 			perror("fork.2");
> 			return 1;
> 		}
> 	}
> 	while (wait((int *)0) < 0)
> 	{
> 		sleep(1);
> 	}
> 	return 0;
> }
> 
> int block(int num, int bs)
> {
> 	char first[10];
> 	char pre[2];
> 	char post[2];
> 	long pid=getpid();
> 	ssize_t frump;
> 
> 	pre[0] = 'A';
> 	pre[1] = ' ' + num | 0x80;
> 	post[0] = 'a';
> 	post[1] = ' ' + num | 0x80;
> 	first[0] = 'F';
> 	first[1] = ' ' + num | 0x80;
> 	memcpy(first + 2, (char *)&pid, sizeof pid);
> 	write(pipefds[1], first, sizeof pid + 2);
> 	for (;;)
> 	{
> 		char buf[2048];
> 		int len = sizeof sin;
> 		pauseAnInstant(50);
> 		write(pipefds[1], pre, 2);
> 		if (useAlarm)
> 			alarm(100);
> 		int fd = accept(bs, (sockaddr *)sin, &len);
> 		if (useAlarm)
> 			alarm(0);
> 		if (fd < 0)
> 		{
> 			perror("accept");
> 			return 1;
> 		}
> 		write(pipefds[1], post, 2);
> 		if ((frump=read(fd, buf, sizeof(buf))) != sizeof(buf))
> 		  {
> 		    fprintf(stderr,"frump is %lu\n",frump);
> 		    perror("read.read.block");
> 		  }
> 		if (write(fd, buf, sizeof(buf)) != sizeof buf)
> 			perror("read.write.block");
> 		close(fd);
> 	}
> }
> 
> int defend(int bs)
> {
> 	for (int i = 0; i < numServProcs; ++i)
> 	{
> 		switch(fork())
> 		{
> 		case 0:
> 			sleep(1);
> 			return block(i, bs);
> 		case -1:
> 			perror("fork.3");
> 			return 1;
> 		}
> 	}
> 	while (wait((int *)0) < 0)
> 	{
> 		sleep(1);
> 	}
> 	return 0;
> }
> 
> int readStuff()
> {
> 	long counts[256];
> 	long ocounts[5][256];
> 	long marks[256];
> 	long pids[256];
> 	int phases[256];
> 	unsigned char buf[1 << 14];
> 	int ln(0); // int ln; BUG BUG BUG BWAHAHAHAHAA
> 	long strt = time((long *)0);
> 	long lasttim = 0;
> 	long nextReportTime = strt + 10;
> 	int leftover = 0;
> 	int i;
> 
> 	memset((char *)counts, 0, sizeof counts);
> 	memset((char *)marks, 0, sizeof marks);
> 	memset((char *)phases, 0, sizeof phases);
> 	memset((char *)ocounts, 0, sizeof ocounts);
> 	memset((char *)pids, 0, sizeof pids);
> 
> 	for(;;)
> 	{
> 		pauseAnInstant(450);
> 		if ((ln = read(pipefds[0], (char *)buf + leftover, sizeof(buf) - leftover)) < 0)
> 		{
> 			perror("read.readStuff");
> 			break;
> 		}
> 		if (ln == 0)
> 		{
> 			if (usePipes)
> 				break;
> 			continue;
> 		}
> 		ln += leftover;
> 		leftover = 0;
> 		if (ln & 1)
> 		{
> 			fprintf(stderr, "What the !?!?!?\n");
> 			ln &= ~1;
> 		}
> 		long tim = time((long *)0) - strt;
> 		for(i = 0; i < ln; i += 2)
> 		{
> 			int p = buf[i];
> 			int n = buf[i+1];
> 			if (p == 'F')
> 			{
> 				if (i + 2 + sizeof pids[0] > ln)
> 				{
> 					leftover = ln - i;
> 					memcpy(buf, buf + i, leftover);
> 					break;
> 				}
> 				memcpy((char *)&pids[n], buf + i + 2, sizeof *pids);
> 				i += sizeof *pids;
> 			}
> 			else
> 			{
> 				counts[p] += 1;
> 				ocounts[tim%5][p] += 1;
> 				phases[n] = p;
> 				marks[n] = tim;
> 			}
> 		}
> 		if (tim <= lasttim)
> 			continue;
> 		if (!(tim % 10) || tim >= nextReportTime)
> 		{
> 			nextReportTime = tim + 10;
> 
> 			int any(0);
> 			int anyany(0);
> 			for(i = 0; i < 256; ++i)
> 			{
> 				if (marks[i] < tim - 4 && phases[i] == 'A')
> 				{
> 					if (!any)
> 					{
> 						printf("ACCEPT:");
> 						anyany = any = 1;
> 					}
> 					printf(" %lu:%d", pids[i], tim - marks[i]);
> 				}
> 			}
> 			if (any)
> 				printf("\n");
> 
> 			any = 0;
> 			for(i = 0; i < 256; ++i)
> 			{
> 				if (marks[i] < tim - 4 && phases[i] == 'C')
> 				{
> 					if (!any)
> 					{
> 						printf("CONNECT:");
> 						anyany = any = 1;
> 					}
> 					printf(" %lu:%d", pids[i], tim - marks[i]);
> 				}
> 			}
> 			if (any)
> 				printf("\n");
> 
> 			any = 0;
> 			for(i = 0; i < 256; ++i)
> 			{
> 				if (marks[i] < tim - 4 && phases[i] == 'a')
> 				{
> 					if (!any)
> 					{
> 						printf("ACCEPTTRANS:");
> 						anyany = any = 1;
> 					}
> 					printf(" %lu:%d", pids[i], tim - marks[i]);
> 				}
> 			}
> 			if (any)
> 				printf("\n");
> 
> 			any = 0;
> 			for(i = 0; i < 256; ++i)
> 			{
> 				if (marks[i] < tim - 4 && phases[i] == 'c')
> 				{
> 					if (!any)
> 					{
> 						printf("CONNECTTRANS:");
> 						anyany = any = 1;
> 					}
> 					printf(" %lu:%d", pids[i], tim - marks[i]);
> 				}
> 			}
> 			if (any)
> 				printf("\n");
> 
> 			if (!anyany)
> 			{
> 				printf("CLEAN\n");
> 			}
> 			printf("SEC: CNT:ACP  AVGTOTAL.TIM AVG-FIVE.SEC\n");
> 		}
> 		long n = (counts['a'] * 1000) / tim;
> 		long n2 = 0;
> 		for (int i = 0; i < 5; ++i)
> 		{
> 			n2 += (ocounts[i]['a'] * 1000) / (tim - lasttim);
> 		}
> 		n2 /= 5;
> 		printf("%03.3ld: %03ld:%03ld  %8ld.%03.3ld %8ld.%03.03ld\n",
> 			tim,
> 			counts['C'] - counts['c'], counts['A'] - counts['a'],
> 			n / 1000, n % 1000, n2 / 1000, n2 % 1000);
> 		fflush(stdout);
> 		lasttim = tim;
> 		memset((char *)ocounts[(tim+1)%5], 0, sizeof ocounts[0]);
> 	}
> 	fprintf(stderr, "Sneaking away....\n");
> 	return 0;
> }
> 
> int main(int argc, char **argv)
> {
> 	startPid = getpid();
> 
> 	setpgrp(0, startPid);
> 
> 	atexit(handler);
> 	signal(SIGINT, sigHandler);
> 	signal(SIGPIPE, SIG_IGN);
> 
> 	if (usePipes)
> 	{
> 		if (pipe(pipefds))
> 		{
> 			perror("pipe");
> 			return 1;
> 		}
> 	}
> 	else
> 	{
> 		pipefds[1] = open("/tmp/incroyable", O_CREAT|O_TRUNC|O_WRONLY|O_APPEND, 0600);
> 		if (pipefds[1] < 0)
> 		{
> 			perror("open:O_CREAT|O_TRUNC|O_WRONLY|O_APPEND");
> 			return 1;
> 		}
> 		pipefds[0] = open("/tmp/incroyable", O_RDONLY, 0600);
> 		if (pipefds[0] < 0)
> 		{
> 			perror("open:O_RDONLY");
> 			return 1;
> 		}
> 		unlink("/tmp/incroyable");
> 	}
> 
> 	close(0);
> 
> 	switch(fork())
> 	{
> 	case -1:
> 		perror("fork.9");
> 		return 1;
> 	case 0:
> 		close(pipefds[1]);
> 		return readStuff();
> 	}
> 
> 	nice(20);
> 
> 	close(pipefds[0]);
> 
> 	if (argc > 1)
> 		numServProcs = atoi(argv[1]);
> 	if (!numServProcs)
> 		numServProcs = 70;
> 
> 	if (argc > 2)
> 		numCliProcs = atoi(argv[2]);
> 	if (!numCliProcs)
> 		numCliProcs = numServProcs;
> 
> 	unsigned short portNo;
> 	int bs(socket(AF_INET, SOCK_STREAM, 0));
> 	if (bs < 0)
> 	{
> 		perror("socket.inet");
> 		return 1;
> 	}
> 	memset((char* )sin, 0, sizeof(sin));
> 
> 	sin->sin_addr.s_addr = INADDR_ANY;
> 	sin->sin_port = htons(0);
> 
> 	if (bind(bs, (struct sockaddr* )sin, sizeof(sin)) < 0)
> 	{
> 		perror("bind");
> 		return 1;
> 	}
> 
> 	if (listen(bs, 100) < 0)
> 	{
> 		perror("listen");
> 		return 1;
> 	}
> 
> 	int ln(sizeof(sin));
> 	if (getsockname(bs, (struct sockaddr* )sin, &ln) < 0)
> 	{
> 		perror("getsockname");
> 		return 1;
> 	}
> 	portNo = ntohs(sin->sin_port);
> 
> 	printf("Listening on Port %u\n", portNo);
> 	fflush(stdout);
> 	close(1);
> 
> 	switch(fork())
> 	{
> 	case 0:
> 		close(bs);
> 		sleep(3);
> 		return attack();
> 	case -1:
> 		perror("fork");
> 		return 1;
> 	}
> 	return defend(bs);
> }
> 
> 
> To Unsubscribe: send mail to majordomo@FreeBSD.org
> with "unsubscribe freebsd-net" in the body of the message
> 

-- 
Brian O'Shea
boshea@ricochet.net


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990902023313.B57569>