Subject: Kernel lockups in tcp code
To: None <tech-kern@NetBSD.ORG>
From: Michael Graff <explorer@cygnus.com>
List: tech-kern
Date: 11/24/1996 16:08:12
The following code will lock up your kernel but good in the -current tcp
code. I have not had a lot of time to find out why, mostly because it locks
the machine and doesn't drop into the debugger, and does not respond to the
usual put-me-in-the-debugger key sequence.
This is on the i386, and I have not tested this on other archs.
Edit the hardcoded ip address to point to your machine in the following code,
compile it, sync, and run it for a while.
I suspect all ports 1024..5000 are in TIME_WAIT, and this causes something
to loose...
--Michael
/* $Id$ */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <err.h>
#define PORT 8844
int
main(int argc, char **argv)
{
pid_t pid;
pid = fork();
if (pid < 0)
err(1, "fork");
if (pid > 0) { /* in the parent */
fd_set ifds;
int ifd;
int nfd;
int fd;
ssize_t status;
int fds[FD_SETSIZE];
struct sockaddr_in isin;
struct sockaddr_in nsin;
int nsin_len;
char data[1024];
printf("In parent...\n");
memset(&isin, 0, sizeof(isin));
for (fd = 0 ; fd < FD_SETSIZE ; fd++)
fds[fd] = -1;
ifd = socket(AF_INET, SOCK_STREAM, 0);
isin.sin_family = AF_INET;
isin.sin_addr.s_addr = INADDR_ANY;
isin.sin_port = htons(PORT);
if (bind(ifd, (struct sockaddr *)&isin, sizeof(isin)) < 0)
err(1, "bind");
printf("Bound local port %d\n", ntohs(isin.sin_port));
fds[ifd] = ifd;
listen(ifd, 128);
for ( ; ; ) {
FD_ZERO(&ifds);
for (fd = 0 ; fd < FD_SETSIZE ; fd++)
if (fds[fd] != -1)
FD_SET(fd, &ifds);
if (select(FD_SETSIZE - 1, &ifds, NULL, NULL, NULL) < 0)
err(1, "select");
for (fd = 0 ; fd < FD_SETSIZE ; fd++)
if (FD_ISSET(fd, &ifds))
if (fd == ifd) {
nsin_len = sizeof(nsin);
memset(&nsin, 0, sizeof(nsin));
if ((nfd = accept(ifd, (struct sockaddr *)&nsin, &nsin_len)) < 0)
err(1, "accept");
printf("Accepted connection on port %d, fd %d... ",
ntohs(nsin.sin_port), nfd);
fflush(stdout);
fds[nfd] = nfd;
} else if (fds[fd] != -1) {
status = read(fd, data, sizeof(data));
if (status < 0)
err(1, "read");
if (status == 0) {
close(fd);
fds[fd] = -1;
}
} else {
errx(1, "attempted read from closed socket");
}
}
} else { /* in the child */
int lfd = -1;
int ofd;
struct sockaddr_in osin;
sleep(1);
printf("In child...\n");
for ( ; ; ) {
memset(&osin, 0, sizeof(osin));
ofd = socket(AF_INET, SOCK_STREAM, 0);
osin.sin_family = AF_INET;
osin.sin_addr.s_addr = inet_addr("192.80.44.41");
osin.sin_port = htons(PORT);
if (connect(ofd, (struct sockaddr *)&osin, sizeof(osin)) < 0)
err(1, "connect");
usleep(10000);
printf("Connected fd %d. Closing %d.\n", ofd, lfd);
fflush(stdout);
if (lfd != -1)
close(lfd);
lfd = ofd;
}
}
}