net: retire ThreadGetMyExternalIP + HTTP path (after #7 lands) #5

Closed
opened 2026-06-03 19:18:48 +00:00 by dobbscoin · 2 comments
dobbscoin commented 2026-06-03 19:18:48 +00:00

Background

PR #4 (merged in 1439f4f) fixed the immediate breakage in GetMyExternalIP by swapping the dead hardcoded IPs for three modern services and switching to HTTP/1.0. That's the correct minimal fix for making it work.

The longer-term direction is to delete the HTTP path entirely — what upstream Bitcoin Core did in bitcoin/bitcoin#7028 (2016). Reasons:

  • Removes the cleartext-HTTP startup pings to AWS / Cloudflare / ipify (privacy hygiene; minor real-world impact since cluster nodes use -externalip= anyway).
  • Removes the MITM-can-poison-AddLocal attack surface (a hostile response on the HTTP path gets fed to AddLocal(addrLocalHost, LOCAL_HTTP) and gossipped via addr).
  • Deletes the hand-rolled HTTP-response parser in GetMyExternalIP2 — small piece of attack surface in its own right.
  • Aligns with modern Bitcoin Core architecture.
  • Removes a thread (ThreadGetMyExternalIP) and the address-discovery delay at startup.

Prerequisite: issue #7 must land first

This issue is now scoped to HTTP-path deletion only. The SeenLocal → AddLocal(LOCAL_PEER) swap that lets peer votes seed mapLocalHost — which is what makes deleting the HTTP path safe — has been split off to #7. Land #7 first; let peer-vote scores accumulate on a live node in -debug=net logs to confirm the replacement path is working; then do this deletion.

Proposed change (after #7)

Delete:

  • GetMyExternalIP (src/net.cpp:346-403)
  • GetMyExternalIP2 (src/net.cpp:300-344)
  • ThreadGetMyExternalIP (src/net.cpp:405-412)
  • The thread spawn at src/net.cpp:1711 (threadGroup.create_thread(... &ThreadGetMyExternalIP))
  • Any forward declarations in src/net.h

Untouched: UPnP path (src/net.cpp:1104), local-interface enumeration (src/net.cpp:1655-1701), LOCAL_HTTP enum value (left in src/net.h even though no path produces it anymore — leaving the slot avoids reshuffling other enum values' integer scores, which could affect on-disk peers.dat compatibility).

Net delta: roughly -110 lines, +0 lines, no new dependencies.

Trade-offs worth knowing

  • Outbound-only NAT'd nodes never learn their external IP. The pfrom->fInbound guard at main.cpp:3895 means only inbound peers feed addrMe in. A node behind NAT with no port forwarding gets nothing from peer votes. Acceptable because such a node is unreachable anyway — nothing useful to advertise. Same trade-off upstream accepted.
  • Startup timing. HTTP-fetch landed an address within seconds. addrMe-from-peer requires a completed inbound handshake. On a small chain like OFF this may take meaningfully longer, especially for a fresh-syncing node that's mostly making outbound connections during IBD. Cosmetic, but real.
  • Cluster impact: ~zero. All cluster nodes use -externalip= or are reachable by known IP; this code path is firing into the void today and will fire into the void tomorrow either way.

References

@9019x — same offer as before, no obligation. If #7 is the friendlier first contribution and this is the larger follow-up, that's an even cleaner split than I originally framed it.

## Background PR #4 (merged in `1439f4f`) fixed the immediate breakage in `GetMyExternalIP` by swapping the dead hardcoded IPs for three modern services and switching to HTTP/1.0. That's the correct minimal fix for *making it work*. The longer-term direction is to delete the HTTP path entirely — what upstream Bitcoin Core did in [bitcoin/bitcoin#7028](https://github.com/bitcoin/bitcoin/pull/7028) (2016). Reasons: - Removes the cleartext-HTTP startup pings to AWS / Cloudflare / ipify (privacy hygiene; minor real-world impact since cluster nodes use `-externalip=` anyway). - Removes the MITM-can-poison-`AddLocal` attack surface (a hostile response on the HTTP path gets fed to `AddLocal(addrLocalHost, LOCAL_HTTP)` and gossipped via `addr`). - Deletes the hand-rolled HTTP-response parser in `GetMyExternalIP2` — small piece of attack surface in its own right. - Aligns with modern Bitcoin Core architecture. - Removes a thread (`ThreadGetMyExternalIP`) and the address-discovery delay at startup. ## Prerequisite: issue #7 must land first This issue is now scoped to **HTTP-path deletion only**. The `SeenLocal → AddLocal(LOCAL_PEER)` swap that lets peer votes seed `mapLocalHost` — which is what makes deleting the HTTP path safe — has been split off to **#7**. Land #7 first; let peer-vote scores accumulate on a live node in `-debug=net` logs to confirm the replacement path is working; *then* do this deletion. ## Proposed change (after #7) Delete: - `GetMyExternalIP` (`src/net.cpp:346-403`) - `GetMyExternalIP2` (`src/net.cpp:300-344`) - `ThreadGetMyExternalIP` (`src/net.cpp:405-412`) - The thread spawn at `src/net.cpp:1711` (`threadGroup.create_thread(... &ThreadGetMyExternalIP)`) - Any forward declarations in `src/net.h` Untouched: UPnP path (`src/net.cpp:1104`), local-interface enumeration (`src/net.cpp:1655-1701`), `LOCAL_HTTP` enum value (left in `src/net.h` even though no path produces it anymore — leaving the slot avoids reshuffling other enum values' integer scores, which could affect on-disk peers.dat compatibility). Net delta: roughly -110 lines, +0 lines, no new dependencies. ## Trade-offs worth knowing - **Outbound-only NAT'd nodes never learn their external IP.** The `pfrom->fInbound` guard at `main.cpp:3895` means only inbound peers feed `addrMe` in. A node behind NAT with no port forwarding gets nothing from peer votes. Acceptable because such a node is unreachable anyway — nothing useful to advertise. Same trade-off upstream accepted. - **Startup timing.** HTTP-fetch landed an address within seconds. `addrMe`-from-peer requires a completed inbound handshake. On a small chain like OFF this may take meaningfully longer, especially for a fresh-syncing node that's mostly making outbound connections during IBD. Cosmetic, but real. - **Cluster impact: ~zero.** All cluster nodes use `-externalip=` or are reachable by known IP; this code path is firing into the void today and will fire into the void tomorrow either way. ## References - Upstream PR: [bitcoin/bitcoin#7028](https://github.com/bitcoin/bitcoin/pull/7028) — "Net: Remove getmyexternalip" (Pieter Wuille, 2016, merged into 0.13) - Issue #7 (prerequisite — peer-vote AddLocal swap): https://github.com/SubGeniusFinance/Offerings-to-Cthulhu/issues/7 - PR #4 (the interim HTTP fix this retirement supersedes): https://github.com/SubGeniusFinance/Offerings-to-Cthulhu/pull/4 @9019x — same offer as before, no obligation. If #7 is the friendlier first contribution and this is the larger follow-up, that's an even cleaner split than I originally framed it.
dobbscoin commented 2026-06-04 12:12:53 +00:00

Closed by PR #9 (merge commit 24196aa).

PR #9 deleted all five items from this issue's proposal:

  • GetMyExternalIP
  • GetMyExternalIP2
  • ThreadGetMyExternalIP
  • The thread spawn in Discover()
  • The forward declaration in net.h

One small divergence from what this issue specified: this issue suggested leaving the LOCAL_HTTP enum slot in place to preserve peers.dat integer-score compat. PR #9 actually removed it, shifting LOCAL_MANUAL from 6 → 5. Acceptable on OFF — peers.dat scores are advisory (not consensus), and post-Restoration most node operators are starting fresh anyway. Flagging for the record, not blocking.

Thanks @9019x.

Closed by PR #9 (merge commit `24196aa`). PR #9 deleted all five items from this issue's proposal: - `GetMyExternalIP` - `GetMyExternalIP2` - `ThreadGetMyExternalIP` - The thread spawn in `Discover()` - The forward declaration in `net.h` One small divergence from what this issue specified: this issue suggested leaving the `LOCAL_HTTP` enum slot in place to preserve `peers.dat` integer-score compat. PR #9 actually removed it, shifting `LOCAL_MANUAL` from 6 → 5. Acceptable on OFF — `peers.dat` scores are advisory (not consensus), and post-Restoration most node operators are starting fresh anyway. Flagging for the record, not blocking. Thanks @9019x.
dobbscoin closed this issue 2026-06-04 12:13:06 +00:00
dobbscoin commented 2026-06-04 12:15:06 +00:00

Self-correction on the comment above: I flagged the LOCAL_HTTP enum removal as a peers.dat compatibility risk. That's wrong — mapLocalHost is runtime-only memory (rebuilt every startup from -bind= / -externalip= / interface enum / UPnP), not persisted to peers.dat or anywhere else. The enum integer values are internal-runtime-only. PR #9's removal of LOCAL_HTTP has zero cross-version footprint.

The "preserve the slot" line in the original issue text was also wrong on the same point. No-op risk; correct decision in the PR to just remove it cleanly.

Self-correction on the comment above: I flagged the `LOCAL_HTTP` enum removal as a `peers.dat` compatibility risk. **That's wrong** — `mapLocalHost` is runtime-only memory (rebuilt every startup from `-bind=` / `-externalip=` / interface enum / UPnP), not persisted to `peers.dat` or anywhere else. The enum integer values are internal-runtime-only. PR #9's removal of `LOCAL_HTTP` has zero cross-version footprint. The "preserve the slot" line in the original issue text was also wrong on the same point. No-op risk; correct decision in the PR to just remove it cleanly.
Sign in to join this conversation.
No labels
enhancement
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
SubGeniusFinance/Offerings-to-Cthulhu#5
No description provided.