Date: Sat, 7 Mar 2015 16:24:21 +0000 From: Rory Byrne <rory@nybek.com> To: freebsd-questions@freebsd.org Subject: Re: TCP aborted from state FIN_WAIT1 after empty 60 secs Message-ID: <20150307162421.GB3060@nybek.com> In-Reply-To: <20150307154902.GA3060@nybek.com> References: <20150307154902.GA3060@nybek.com>
next in thread | previous in thread | raw e-mail | index | archive | help
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 <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <sys/socket.h> + +#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 <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <netinet/in.h> +#include <sys/socket.h> + +#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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150307162421.GB3060>