Messages in this thread | | | Date | Wed, 18 Oct 2000 21:20:40 -0700 | From | Brian Craft <> | Subject | Re: 2.2 generating odd TCP resets? |
| |
> Looks like the application on the Linux system is issuing a close() on > the socket before reading all of the available data. That always > causes a RST to be sent.
Here's some stripped down code to generate bogus (I think) TCP resets on 2.2.14-17.
The RST is generated when the server closes the socket, but there is NO data pending on the socket.
On linux run ./st
on windows run ./st 10.0.70.5
(or whatever).
The windows box should return an error on read after linux generates the RST. The code can be compiled with cygwin.
Is there any reason this should fail? It does not fail when talking to a linux host. The only obvious difference is windows generates two ACK's of the server's FIN.
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/socket.h> #include <netinet/in.h>
#define LEN 1000000 int main(int argc, char *argv[]) { struct sockaddr_in sin; int len, fd; char buff[LEN];
len = sizeof (sin); sin.sin_family = AF_INET; sin.sin_port = htons (5000);
if (argc > 1) { /* client side */ int n, count = 0; printf("client\n"); sin.sin_addr.s_addr = inet_addr(argv[1]); fd = socket (AF_INET, SOCK_STREAM, 0); if (fd < 1) { perror("socket"); exit(0); } while (connect (fd, (struct sockaddr *) &sin, len)) { usleep(10000); perror("connect"); } printf("connected to server\n"); shutdown(fd, 1); usleep(2000000); while (count < LEN) { n = read(fd, buff, 100); if (n < 0) { printf("error on read\n"); break; } count += n; }
if (count == LEN) printf("read ok\n"); /*printf("read %s\n", buff); */ close(fd); } else { /* server side */ int i, new_fd; int on = 1; printf("server\n"); sin.sin_addr.s_addr = INADDR_ANY; fd = socket (AF_INET, SOCK_STREAM, 0); setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on));
if (fd < 1) { perror("serv socket"); exit(0); } if (bind (fd, (struct sockaddr *)&sin, len) < 0 ||listen (fd, 1) < 0) { perror("bind/listen"); close(fd); exit(0); } new_fd = accept (fd, 0, 0); if (new_fd < 0) { perror("accept"); exit(0); } close(fd); usleep(1000000); shutdown (new_fd, 0); fcntl (new_fd, F_SETFL, 1); for (i = 0; i < LEN; ++i) buff[i] = i%256; write(new_fd, buff, LEN); close(new_fd); printf("socket closed\n"); usleep(10000000); printf("server exiting\n"); }
return 0; } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/
| |