net: Automatically detect IPv4 and IPv6 reachability #36784

pull mzumsande wants to merge 3 commits into bitcoin:master from mzumsande:202611_reachability_detection changing 6 files +186 −1
  1. mzumsande commented at 6:17 PM on November 5, 2026: contributor

    In many network environments, IPv6 peers cannot be reached, which is currently not detected. As a result, IPv6 addresses take up spots in AddrMan, and we make futile attempts to connect to them (e.g. feelers or network-specific connections). The reverse (IPv6 is reachable, but IPv4 isn't) is much rarer, but also possible.

    This PR introduces an automatic check for IPv4/IPv6 reachability. The idea is to connect() a UDP socket to several well-known global unicast addresses. Because it's UDP, this only performs a local route lookup and source address selection, so no packets are sent out. Depending on specific error codes (e.g. ENETUNREACH), or if the selected source address is unusable (link-local, loopback), we decide that a network has no route. This is done conservatively to avoid false positives: in case of inconclusive evidence, the network stays reachable.

    If the check finds no route for either IPv4 or IPv6 (but not both, because then we most likely have no connectivity at all), the network is marked as unreachable. This means we won't make automatic outbound connections to it, won't add new addresses from it to AddrMan, and relay its addresses slightly less. The first check runs one minute after startup rather than immediately, so that short gaps at startup (e.g. addresses still being configured) don't cause us to drop anchors or fixed seeds. After that, the check is repeated every 10 minutes, so the node can adapt to changing network conditions.

    The check is disabled by any -onlynet setting, for networks reached through a proxy, and if automatic outbound connections are disabled (-connect).

    This is related to #35750, which addresses the same problem from the AddrMan side (not counting failures on networks we can't reach).

    I'll keep this PR in draft for a while, until I have more confidence that the check works on various systems and has no false positives. I also haven't explored the possibility of unit/functional tests for it yet.

    Test reports are very welcome, especially from more uncommon setups (e.g. IPv6-only, NAT64, containers, VPNs, Windows/BSD). Running with -debug=net shows the reason for each decision.

  2. DrahtBot added the label P2P on Nov 5, 2026
  3. DrahtBot commented at 6:17 PM on November 5, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    External sites

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process. A summary of reviews will appear here.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #31260 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/31260.svg"></sub> (scripted-diff: Type-safe settings retrieval by ryanofsky)
    • #30951 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/30951.svg"></sub> (net: option to disallow v1 connection on ipv4 and ipv6 peers by stratospher)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  4. mzumsande force-pushed on Nov 5, 2026
  5. DrahtBot added the label CI failed on Nov 5, 2026
  6. common: add HasGlobalRoute()
    Add a function that asks the OS whether there is a route to the global
    internet on IPv4 or IPv6, without sending any packets: connect()ing an
    unbound UDP socket only performs a route lookup and source address
    selection. Several well-known destinations are tried, and a route
    counts only if a usable (e.g. not link-local) source address is chosen.
    6b9903f39d
  7. net: automatically mark IPv4/IPv6 as unreachable if there is no route
    Check one minute after startup, and every 10 minutes afterwards,
    whether IPv4 and IPv6 have a route. Remove a network without one from
    g_reachable_nets to avoid futile outbound connection attempts, and add
    it back once a route appears.
    
    The first check is delayed to not react to short gaps at boot, which
    would drop anchors and fixed seeds of that network for the entire run.
    A network is only marked unreachable if another network has a route,
    since otherwise we are probably just offline.
    
    The check only runs if automatic outbound connections are made, -onlynet
    is not used (which serves as opt-out), and the network is not reached
    via a proxy.
    7ede503ba3
  8. doc: add release note for automatic IPv4/IPv6 reachability detection 0050627abd
  9. mzumsande force-pushed on Nov 5, 2026
  10. DrahtBot removed the label CI failed on Nov 5, 2026

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-11-15 02:51 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me