Created attachment 207828 [details] ftp.patch Of course this problem depends on network environment, I can see this problem in my home network only. In my home network, the bandwidth of the internet connection is 100Mbps. Fetch(1) downloads in mostly full speed of the bandwidth. But ftp(1) seems about half speed of fetch(1). I have tried to download FreeBSD iso image file from the fastest mirror from my home. The results are shown below. ``` $ fetch ftp://ftp.jp.freebsd.org/pub/FreeBSD/releases/ISO-IMAGES/12.0/FreeBSD-12.0-RELEASE-amd64-disc1.iso FreeBSD-12.0-RELEASE-amd64-disc1.iso 851 MB 10 MBps 01m20s ``` ``` $ ftp ftp://ftp.jp.freebsd.org/pub/FreeBSD/releases/ISO-IMAGES/12.0/FreeBSD-12.0-RELEASE-amd64-disc1.iso Trying 2405:f000:202:2598:210:231:212:2:21 ... Connected to ftp.lab.bbtower.net. 220- Welcome to ftp.lab.BBTower.net, 220- Located in Tokyo, Japan. 220- 220- This server maintenanced by BroadBand Tower, Inc. 220- 220- BBTower Web site is at 220- http://www.bbtower.co.jp/ 220- 220- If you have any problem, please contact ftp-contact@bbtower.co.jp. 220 FTP server ready. 331 Guest login ok, send your email address as password. 230 Guest login ok, access restrictions apply. Remote system type is UNKNOWN. 200 Type set to I. 250 CWD command successful. 250 CWD command successful. 250 CWD command successful. 250 CWD command successful. 250 CWD command successful. local: FreeBSD-12.0-RELEASE-amd64-disc1.iso remote: FreeBSD-12.0-RELEASE-amd64-disc1.iso 229 Entering Extended Passive Mode (|||63019|) 150 Opening BINARY mode data connection for 'FreeBSD-12.0-RELEASE-amd64-disc1.iso' (892467200 bytes). 100% |***********************************| 851 MiB 5.14 MiB/s 00:00 ETA 226 Transfer complete. 892467200 bytes received in 02:45 (5.14 MiB/s) 221 Goodbye. ``` This is because socket buffer size is not large enough to ftp(1). Ftp(1) always set the buffer size to the default value. It prevents FreeBSD kernel from increasing socket buffer size automatically. So setting `sysctl net.inet.tcp.recvspace=131072` speeds up the ftp download for workaround. ``` $ sudo sysctl net.inet.tcp.recvspace=131072 Password: net.inet.tcp.recvspace: 65536 -> 131072 $ ftp ftp://ftp.jp.freebsd.org/pub/FreeBSD/releases/ISO-IMAGES/12.0/FreeBSD-12.0-RELEASE-amd64-disc1.iso Trying 2405:f000:202:2598:210:231:212:2:21 ... Connected to ftp.lab.bbtower.net. 220- Welcome to ftp.lab.BBTower.net, 220- Located in Tokyo, Japan. 220- 220- This server maintenanced by BroadBand Tower, Inc. 220- 220- BBTower Web site is at 220- http://www.bbtower.co.jp/ 220- 220- If you have any problem, please contact ftp-contact@bbtower.co.jp. 220 FTP server ready. 331 Guest login ok, send your email address as password. 230 Guest login ok, access restrictions apply. Remote system type is UNKNOWN. 200 Type set to I. 250 CWD command successful. 250 CWD command successful. 250 CWD command successful. 250 CWD command successful. 250 CWD command successful. local: FreeBSD-12.0-RELEASE-amd64-disc1.iso remote: FreeBSD-12.0-RELEASE-amd64-disc1.iso 229 Entering Extended Passive Mode (|||59743|) 150 Opening BINARY mode data connection for 'FreeBSD-12.0-RELEASE-amd64-disc1.iso' (892467200 bytes). 100% |***********************************| 851 MiB 9.67 MiB/s 00:00 ETA 226 Transfer complete. 892467200 bytes received in 01:27 (9.67 MiB/s) 221 Goodbye. ``` Basically ftp(1) should allow FreeBSD kernel to adjust socket buffer size. I suggest the attached patch that prevents ftp(1) from setting socket buffer size unless user input 'rcvbuf' or 'sndbuf' command.
Take.
Two weeks have been passed. Are there any problem in my patch? Or are you busy now?
Created attachment 209950 [details] Patch to prevent SO_SNDBUF and SO_RCVBUF from configuring when auto tuning enabled Sorry for the delay getting back to you. I created a modified patch to check net.inet.tcp.{send,recv}buf_auto sysctls because they are knobs where one can change this behavior. Please try it and see if it works as expected.
(In reply to Hiroki Sato from comment #3) Thanks for your patch. I confirmed that your patch solved this problem. I can see that your patch follows kernel mode explicitly. I think it's good way to record what I'm trying to do. But I have one question. You patched about auto_sendbuf in following lines. ^^^^ ``` +#ifdef __FreeBSD__ + DPRINTF("auto_rcvbuf = %d\n", auto_rcvbuf); + if (auto_sndbuf == 0) +#endif ``` DRPINTF message shows auto_rcvbuf value. ^^^ Is it typo?
(In reply to Yuichiro NAITO from comment #4) Yes, it was a typo. I thought I fixed it in my local tree but I mistakenly sent a previous version. I will send this patch for review and commit it if there is no big objection.
(In reply to Hiroki Sato from comment #5) >I will send this patch for review and commit it if there is no big objection. No problem to me. Thank you.
Sorry for the delay. Staged at https://reviews.freebsd.org/D23732
A commit references this bug: Author: hrs Date: Thu Feb 27 19:50:00 UTC 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 Changes: 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
Thanks for committing. I think this PR can be closed.