From owner-freebsd-bugs Fri Nov 14 22:40:05 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id WAA03778 for bugs-outgoing; Fri, 14 Nov 1997 22:40:05 -0800 (PST) (envelope-from owner-freebsd-bugs) Received: (from gnats@localhost) by hub.freebsd.org (8.8.7/8.8.7) id WAA03760; Fri, 14 Nov 1997 22:40:02 -0800 (PST) (envelope-from gnats) Resent-Date: Fri, 14 Nov 1997 22:40:02 -0800 (PST) Resent-Message-Id: <199711150640.WAA03760@hub.freebsd.org> Resent-From: gnats (GNATS Management) Resent-To: freebsd-bugs Resent-Reply-To: FreeBSD-gnats@FreeBSD.ORG, dillon@backplane.com Received: from apollo.backplane.com (root@apollo.backplane.com [207.33.240.2]) by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id WAA03587 for ; Fri, 14 Nov 1997 22:32:51 -0800 (PST) (envelope-from dillon@backplane.com) Received: (root@localhost) by apollo.backplane.com (8.8.5/8.6.5) id WAA23109; Fri, 14 Nov 1997 22:32:50 -0800 (PST) Message-Id: <199711150632.WAA23109@apollo.backplane.com> Date: Fri, 14 Nov 1997 22:32:50 -0800 (PST) From: Matthew Dillon Reply-To: dillon@backplane.com To: FreeBSD-gnats-submit@FreeBSD.ORG X-Send-Pr-Version: 3.2 Subject: kern/5048: if shutdown(fd,1) called twice on socket, pending input data is lost Sender: owner-freebsd-bugs@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk >Number: 5048 >Category: kern >Synopsis: Calling shutdown(fd,1) multiple times will blow up input data >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Nov 14 22:40:00 PST 1997 >Last-Modified: >Originator: Matthew Dillon >Organization: Best Internet Communications >Release: FreeBSD 2.2-STABLE i386 >Environment: FreeBSD 2.2.5 >Description: If you call shutdown(socket, 1) twice, pending input data on the socket may be lost. >How-To-Repeat: Open a TCP connection to some destination that sends you data (e.g. chargen), then call shutdown on the socket multiple times, the chargen will eventually stall. /* * TESTSHUTDOWN localhost chargen */ #include #include #include #include #include #include #include #include #include #include #include #include void goforit(int fd); int main(int ac, char **av) { int fd; int i; struct sockaddr_in sin; struct hostent *host; struct servent *serv; char *hostName = NULL; char *servName = NULL; for (i = 1; i < ac; ++i) { char *ptr = av[i]; if (*ptr != '-') { if (hostName == NULL) hostName = ptr; else servName = ptr; continue; } ptr += 2; switch(ptr[-1]) { case 'b': default: printf("bad option: %s\n", ptr - 2); exit(0); } } if (hostName == NULL) { puts("no hostname / ip address specified"); exit(0); } if (servName == NULL) { puts("no portname / port number specified"); exit(0); } bzero(&sin, sizeof(sin)); sin.sin_family = AF_INET; if ((fd = socket(AF_INET, SOCK_STREAM, 0)) > 0) { if ((host = gethostbyname(hostName)) != NULL) { sin.sin_family = host->h_addrtype; bcopy(host->h_addr, &sin.sin_addr, host->h_length); } else { sin.sin_addr.s_addr = inet_addr(hostName); } if ((serv = getservbyname(servName, "tcp")) != NULL) { sin.sin_port = serv->s_port; } else { sin.sin_port = htons(strtol(servName, NULL, 0)); } if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) == 0) { puts("connected"); goforit(fd); close(fd); } else { perror("connect"); } } return(0); } void goforit(int fd) { int pid; int n; char buf[256]; if ((pid = fork()) == 0) { int ttl = 0; while ((n = read(fd, buf, sizeof(buf))) > 0) { write(1, buf, n); ttl += n; if (ttl > 1024) { printf("\n****** (CALLING SHUTDOWN) *******\n"); shutdown(fd, 1); shutdown(fd, 1); ttl = 0; } } exit(0); } while ((n = read(0, buf, sizeof(buf))) > 0) { int i = 0; int r; while (i < n && (r = write(fd, buf + i, n - i)) > 0) { i += r; } } shutdown(fd, 1); while (wait(NULL) != pid) ; } >Fix: >Audit-Trail: >Unformatted: