I'm trying to teach ftp(1) to do something like gui web browsers do
and reduce the HTTP/HTTPS connection timeout from the default (75 seconds)
if there are multiple addresses behind a hostname.
There's an existing connection timeout mechanism that I thought it
might make sense to reuse...
-w seconds
For URL format connections to HTTP/HTTPS servers, abort a slow
connection after seconds.
So, I tried
Index: fetch.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.208
diff -u -p -r1.208 fetch.c
--- fetch.c 10 Nov 2021 07:32:55 -0000 1.208
+++ fetch.c 9 Jul 2022 11:39:29 -0000
@@ -570,6 +570,9 @@ noslash:
if (verbose)
setvbuf(ttyout, NULL, _IOLBF, 0);
+ if (res0->ai_next && connect_timeout == 0)
+ connect_timeout = 10;
+
fd = -1;
for (res = res0; res; res = res->ai_next) {
if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,
...but, what actually happens is, instead of aborting a slow connection
to a server (which is possibly one of many servers behind a hostname),
the SIGALRM handler aborts ftp(1) completely.
$ route -T 3 exec obj/ftp -o- http://firmware.openbsd.org/ 2>&1 | ts -s %.s
0.022289 Trying 145.238.169.11...
10.027972 ftp: connect taking too long
I also tried setsockopt SO_RCVTIMEO/SO_SNDTIMEO but these don't seem to do
anything for connect.
Does anyone have an idea if there's another way this might be done?
Is the inside of ftp(1) just too hairy for this?
The original problem I'm trying to mitigate is super-slow installs on
machines which have access to the install server but not most of the
internet;
| What timezone are you in? ('?' for list) [Canada/Mountain] Europe/London
| Saving configuration files... done.
| Making all device nodes... done.
|
< 7.5 minutes delay here; or would be 12.5 minutes if the machine had a v6
address >
| Cannot fetch http://firmware.openbsd.org/firmware/7.1/SHA256.sig (timed out)
| fw_update: added none; updated none; kept none
| Multiprocessor machine; using bsd.mp instead of bsd.
| Relinking to create unique kernel... done.
...in this particular situation I can workaround anyway ("block return"
instead of "block"), but there's still a naturally-occurring problem if
the first-returned host or hosts are temporarily unreachable; it takes
a lot longer than is reasonable to move on.