From owner-freebsd-questions@FreeBSD.ORG Sat Mar 7 16:24:30 2015 Return-Path: Delivered-To: freebsd-questions@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id DF336A5B for ; Sat, 7 Mar 2015 16:24:30 +0000 (UTC) Received: from mx1.nybek.com (mx1.nybek.com [78.47.4.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 871FB3DC for ; Sat, 7 Mar 2015 16:24:30 +0000 (UTC) Received: by mx1.nybek.com (Postfix, from userid 1000) id 577F228074E; Sat, 7 Mar 2015 16:24:21 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nybek.com; s=mail; t=1425745461; bh=xEKgAESELBaygfVv5oyyq+iOLo/E0penYG4ERuklZjA=; h=Date:From:To:Subject:References:In-Reply-To:From; b=Go4fCGHKKFgUcGFUD7xOCwAyv1nFJVGHKGZ+PjcO+Nnshn+oCYpcTnqTgXL4a2fUi OV1YO+4QzHuoVerpdaLlYcfOYDZ8cLXasmwBsygsFPHLkskpcIlCLmHJ8XIkHrBSAy djvcb6HN1Nxpuz22jhW0jJ+3CZIIFCqBzPTjYQYQ= Date: Sat, 7 Mar 2015 16:24:21 +0000 From: Rory Byrne To: freebsd-questions@freebsd.org Subject: Re: TCP aborted from state FIN_WAIT1 after empty 60 secs Message-ID: <20150307162421.GB3060@nybek.com> Mail-Followup-To: freebsd-questions@freebsd.org References: <20150307154902.GA3060@nybek.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150307154902.GA3060@nybek.com> X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 07 Mar 2015 16:24:31 -0000 On Sat, Mar 07, 2015 at 03:49:02PM +0000, Rory Byrne wrote: > > See attached for test code and a tcpdump trace. The client and server must be > on different hosts: the TCP connection won't be aborted if you run it over lo0. Sorry, the test code got dropped. I'll include it inline. --- client.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ server.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 client.c create mode 100644 server.c diff --git a/client.c b/client.c new file mode 100644 index 0000000..e908289 --- /dev/null +++ b/client.c @@ -0,0 +1,90 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PORT 7777 +#define RCVBUF_SIZE 8192 +#define READ_SIZE 512 + +void die(const char *where) +{ + perror(where); + exit(EXIT_FAILURE); +} + +void usage_exit(const char *prog_name, const char *err_msg) +{ + if (err_msg != NULL) + fprintf(stderr, "%s\n", err_msg); + fprintf(stderr, + "usage: %s ip-address\n" + " -h Print usage and exit.\n", + prog_name); + exit(EXIT_FAILURE); +} + +void set_socket_options(int fd) +{ + int r, val; + + val = RCVBUF_SIZE, + r = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)); + if (r == -1) + die("setting SO_RCVBUF"); +} + +int main(int argc, char *argv[]) +{ + int sockfd, total, n, r; + char buf[READ_SIZE]; + struct sockaddr_in servaddr; + + if (argc != 2 || strcmp("-h", argv[1]) == 0) + usage_exit(argv[0], NULL); + + memset(&servaddr, 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(PORT); + + r = inet_pton(AF_INET, argv[1], &servaddr.sin_addr.s_addr); + if (r != 1) { + fprintf(stderr, "failed at inet_pton()\n"); + exit(EXIT_FAILURE); + } + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == -1) + die("socket()"); + + set_socket_options(sockfd); + + r = connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); + if (r == -1) + die("connect()"); + + /* Prompt user before reading next 512 byte block */ + total = 0; + while ((n = read(sockfd, buf, READ_SIZE)) != 0) { + if (n == -1) + die("socket read()"); + total += n; + printf("RECV: %d (%d)\n", n, total); + + printf("Press RETURN to read next %d bytes: ", READ_SIZE); + while (getchar() != '\n') + ; + } + puts("End of input stream"); + + close(sockfd); + puts("Connection closed"); + + exit(EXIT_SUCCESS); +} diff --git a/server.c b/server.c new file mode 100644 index 0000000..ffdee85 --- /dev/null +++ b/server.c @@ -0,0 +1,101 @@ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PORT 7777 +#define SNDBUF_SIZE (50 * 1024) +#define PAYLOAD_SIZE (20 * 1024) +#define BACKLOG 128 + +void die(const char *where) +{ + perror(where); + exit(EXIT_FAILURE); +} + +void get_payload(char *buf, int size) +{ + int i; + + for (i = 0; i < size; i++) { + buf[i] = '.'; + } +} + +void set_socket_options(int fd) +{ + int r, val; + + val = 1; + r = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); + if (r == -1) + die("setting SO_REUSEADDR"); + + val = SNDBUF_SIZE, + r = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, sizeof(val)); + if (r == -1) + die("setting SO_SNDBUF"); +} + +int main(void) +{ + int listenfd, connfd, r; + ssize_t n; + struct sockaddr_in servaddr; + char buf[PAYLOAD_SIZE]; + + memset(buf, 0, sizeof(buf)); + get_payload(buf, sizeof(buf)); + + listenfd = socket(AF_INET, SOCK_STREAM, 0); + if (listenfd == -1) + die("socket"); + + set_socket_options(listenfd); + + memset(&servaddr, 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(PORT); + + r = bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); + if (r == -1) + die("bind()"); + + r = listen(listenfd, BACKLOG); + if (r == -1) + die("listen()"); + + puts("-- waiting for client connection"); + connfd = accept(listenfd, (struct sockaddr *) NULL, NULL); + if (connfd == -1) + die("accept()"); + puts("-- client connected"); + + puts("-- closing listening socket"); + r = close(listenfd); + if (r == -1) + die("closing listenfd"); + + puts("-- writing payload"); + n = write(connfd, buf, sizeof(buf)); + if (n == -1) { + die("write()"); + } else if (n != sizeof(buf)) { + fprintf(stderr, "failed to write full buffer"); + exit(EXIT_FAILURE); + } + + puts("-- closing connected socket"); + r = close(connfd); + if (r == -1) + die("closing connfd"); + + exit(EXIT_SUCCESS); +} -- 1.7.10.4