get_pingtime: set a lower value for preferred host
preferred_hosts doesn't work under a rare network condition called Fake-IP, used by TUN based proxies apps/clients, like Surge, Clash (one of clash's fork called mihomo, is in our macports-ports repo).
Please bear with me while I'm explaining this Fake-IP concept.
# snippet of a proxy rule file for Clash
rules:
- DOMAIN-SUFFIX,foo.com,DIRECT
- DOMAIN-SUFFIX,bar.com,ProxyServer
Proxy clients like Clash, set up a TUN to intercept all traffic. It also sets up a local (forwarding) DNS server and set it as the system DNS, to keep track of the DNS requests. So it can match the IP from a TCP connection to its domain, which makes the DOMAIN-SUFFIX rules above works both for HTTP and TCP connections.
When an HTTP request comes, the proxy client first resolves the IP for it to set up a TCP connection. Otherwise the HTTP client like a browser will tell the user IP not found and request stops.
- When a
DIRECTrule is matched, the local proxy client help us finish this HTTP request, reusing the IP resolved by the local DNS server. - But when a
ProxyServerrule is matched, the HTTP reuqest is wrapped and sent to the remote proxy server. The server doesn't use the IP resolved by the local DNS on our computure, but resolves it again by itself.
Fake-IP is introduced to optimize the workflow above, cuz for the 2nd situation, resolving an IP for the request at the local side, is redundant.
- when a HTTP request captured by the local proxy client, a fake ip is generate and returned immediately.
- only when the rule is matched, it decides whether to do a IP resolving.
So when this Fake-IP feature is enabled, every mirror host is resolved immediately, ping -noq -c3 -t3 and compare the cost time doens't work as expected.
Here is the pingtimes I printed out during debug.
❯ ping -noq -c3 -t3 jnb.za.distfiles.macports.org
PING jnb.za.distfiles.macports.org (198.18.0.141): 56 data bytes
--- jnb.za.distfiles.macports.org ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.098/0.098/0.098/0.000 ms
❯ sudo port -v fetch mysql8
---> Fetching distfiles for mysql8
---> mysql-8.4.2.tar.gz does not exist in /opt/local/var/macports/distfiles/mysql8
ping: mirror.fcix.net, 0.093
ping: pek.cn.distfiles.macports.org, 0.086
ping: aarnet.au.distfiles.macports.org, 0.108
ping: mirrors.mit.edu, 0.091
ping: fra.de.distfiles.macports.org, 0.084
ping: ywg.ca.distfiles.macports.org, 0.083
ping: kmq.jp.distfiles.macports.org, 0.071
ping: bos.us.distfiles.macports.org, 0.087
ping: jnb.za.distfiles.macports.org, 0.092
ping: fco.it.distfiles.macports.org, 0.085
ping: ykf.ca.distfiles.macports.org, 0.063
ping: vie.at.distfiles.macports.org, 0.073
ping: nue.de.distfiles.macports.org, 0.119
ping: atl.us.distfiles.macports.org, 0.100
ping: mirror.sjtu.edu.cn, 0.079
ping: cph.dk.distfiles.macports.org, 0.067
ping: lis.pt.distfiles.macports.org, 0.072
ping: distfiles.macports.org, 0.104
ping: cjj.kr.distfiles.macports.org, 0.089
ping: mse.uk.distfiles.macports.org, 0.075
ping: jog.id.distfiles.macports.org, 0.078
ping: cdn.mysql.com, 0.106
You can see every host gets a much lower time cost value. In fact, the 1 returned in get_pingtime for a preferred_hosts, make the preferred hosts rank last.
Since the value 0 is returned for local mirror starts with file://, i used 0.001 to put preferred_hosts in the front of the ranking result.
ref
This probably needs a rebase on top of #353 for CI to pass.
We should probably use values that are clearly not valid ping times to represent these special cases.