Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get_pingtime: set a lower value for preferred host #351

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

laggardkernel
Copy link

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.

  1. When a DIRECT rule is matched, the local proxy client help us finish this HTTP request, reusing the IP resolved by the local DNS server.
  2. But when a ProxyServer rule 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

@neverpanic
Copy link
Member

This probably needs a rebase on top of #353 for CI to pass.

@jmroot
Copy link
Member

jmroot commented Oct 14, 2024

We should probably use values that are clearly not valid ping times to represent these special cases.

to make it work under a fake-ip proxy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants