Date: Thu, 27 Feb 2020 19:49:59 +0000 (UTC) From: Hiroki Sato <hrs@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r358405 - head/contrib/tnftp/src Message-ID: <202002271949.01RJnx1H042269@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: hrs Date: Thu Feb 27 19:49:59 2020 New Revision: 358405 URL: https://svnweb.freebsd.org/changeset/base/358405 Log: Fix poor performance of ftp(1) due to small SO_SNDBUF and SO_RCVBUF. ftp(1) from vendor/tnftp always tried the following for every TCP connection: 1. Get the current buffer length of SO_SNDBUF and SO_RCVBUF by getsockopt(2). 2. Invoke setsockopt(2) to set them to the same values after checking if they are in a range between 8 KiB to 8 MiB. This behavior broke dynamic buffer sizing enabled by default (net.inet.tcp.{recv,send}buf_auto sysctls) and led to a very poor transfer rate. The fetch(1) utility does not have this problem. This change prevents SO_SNDBUF and SO_RCVBUF from configuring when the buffer auto-sizing is enabled unless the buffer sizes are explicitly specified. PR: 240827 Spotted by: Yuichiro NAITO MFC after: 3 days Differential Revision: https://reviews.freebsd.org/D23732 Modified: head/contrib/tnftp/src/cmds.c head/contrib/tnftp/src/ftp_var.h head/contrib/tnftp/src/main.c head/contrib/tnftp/src/util.c Modified: head/contrib/tnftp/src/cmds.c ============================================================================== --- head/contrib/tnftp/src/cmds.c Thu Feb 27 19:40:29 2020 (r358404) +++ head/contrib/tnftp/src/cmds.c Thu Feb 27 19:49:59 2020 (r358405) @@ -2653,10 +2653,14 @@ setxferbuf(int argc, char *argv[]) goto usage; } - if (dir & RATE_PUT) + if (dir & RATE_PUT) { sndbuf_size = size; - if (dir & RATE_GET) + auto_sndbuf = 0; + } + if (dir & RATE_GET) { rcvbuf_size = size; + auto_rcvbuf = 0; + } fprintf(ttyout, "Socket buffer sizes: send %d, receive %d.\n", sndbuf_size, rcvbuf_size); code = 0; Modified: head/contrib/tnftp/src/ftp_var.h ============================================================================== --- head/contrib/tnftp/src/ftp_var.h Thu Feb 27 19:40:29 2020 (r358404) +++ head/contrib/tnftp/src/ftp_var.h Thu Feb 27 19:49:59 2020 (r358405) @@ -298,6 +298,8 @@ GLOBAL int options; /* used during socket creation */ GLOBAL int sndbuf_size; /* socket send buffer size */ GLOBAL int rcvbuf_size; /* socket receive buffer size */ +GLOBAL int auto_sndbuf; /* flag: if != 0 then use auto sndbuf size */ +GLOBAL int auto_rcvbuf; /* flag: if != 0 then use auto rcvbuf size */ GLOBAL int macnum; /* number of defined macros */ GLOBAL struct macel macros[16]; Modified: head/contrib/tnftp/src/main.c ============================================================================== --- head/contrib/tnftp/src/main.c Thu Feb 27 19:40:29 2020 (r358404) +++ head/contrib/tnftp/src/main.c Thu Feb 27 19:49:59 2020 (r358405) @@ -127,6 +127,9 @@ __RCSID(" NetBSD: main.c,v 1.117 2009/07/13 19:05:41 r #include <locale.h> #endif /* tnftp */ +#ifdef __FreeBSD__ +#include <sys/sysctl.h> +#endif #define GLOBAL /* force GLOBAL decls in ftp_var.h to be declared */ #include "ftp_var.h" @@ -509,6 +512,13 @@ main(int volatile argc, char **volatile argv) (void)xsignal(SIGUSR1, crankrate); (void)xsignal(SIGUSR2, crankrate); (void)xsignal(SIGWINCH, setttywidth); + + auto_rcvbuf = ((sysctlbyname("net.inet.tcp.recvbuf_auto", + &auto_rcvbuf, &(size_t []){[0] = sizeof(int)}[0], NULL, 0) == 0) && + auto_rcvbuf == 1); + auto_sndbuf = ((sysctlbyname("net.inet.tcp.sendbuf_auto", + &auto_sndbuf, &(size_t []){[0] = sizeof(int)}[0], NULL, 0) == 0) && + auto_sndbuf == 1); if (argc > 0) { if (isupload) { Modified: head/contrib/tnftp/src/util.c ============================================================================== --- head/contrib/tnftp/src/util.c Thu Feb 27 19:40:29 2020 (r358404) +++ head/contrib/tnftp/src/util.c Thu Feb 27 19:49:59 2020 (r358405) @@ -1087,13 +1087,27 @@ setupsockbufsize(int sock) sndbuf_size); } +#ifdef __FreeBSD__ + DPRINTF("auto_rcvbuf = %d\n", auto_rcvbuf); + if (auto_sndbuf == 0) { +#endif if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void *)&sndbuf_size, sizeof(sndbuf_size)) == -1) warn("Unable to set sndbuf size %d", sndbuf_size); +#ifdef __FreeBSD__ + } +#endif +#ifdef __FreeBSD__ + DPRINTF("auto_sndbuf = %d\n", auto_sndbuf); + if (auto_rcvbuf == 0) { +#endif if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&rcvbuf_size, sizeof(rcvbuf_size)) == -1) warn("Unable to set rcvbuf size %d", rcvbuf_size); +#ifdef __FreeBSD__ + } +#endif } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202002271949.01RJnx1H042269>