[PR #6004] [client, relay] Advertise relay server IP via signal for foreign-relay fallback dial #24564

Closed
opened 2026-08-05 06:08:50 -04:00 by saavagebueno · 0 comments
Owner

Original Pull Request: https://github.com/netbirdio/netbird/pull/6004

State: closed
Merged: Yes


Describe your changes

Problem

When two peers are on different relays and P2P (ICE) cannot be established, each learns the other peer's relay address through signal as an FQDN. If that FQDN cannot be resolved on the receiving side, the foreign-relay dial fails and the peers never reach each other.

This deadlocks on first connect when the only configured exit-node peer is the one whose relay needs to be resolved: the overlay default route is installed before the exit-node WireGuard handshake completes, so DNS goes through wt0 and fails. Management's relay cache doesn't help here, the foreign peer's home relay is only learned through signal, not from management.

Fix

Peer B already knows the IP it is connected to on its relay. We add that IP to the signal Body so peer A can use it as a dial-time fallback when the FQDN cannot be resolved. SNI/cert validation still uses the FQDN, so TLS is unaffected.

  • Add relayServerIP (bytes, tag 11) to signal Body; reserve tag 9 (previously int64 sessionId) to avoid wire-type collisions
  • Surface the underlying TCP RemoteAddr from the websocket relay conn so ConnectedIP returns the resolved IP after an FQDN dial
  • Plumb the IP as netip.Addr through Manager.OpenConn and Client with a fallback dial path that substitutes the IP into the URL while keeping the original host as SNI
  • Add unit tests for the fallback dial, ConnectedIP after an FQDN dial, and substituteHost; add an end-to-end manager test exercising the foreign-relay path

Stack

Checklist

  • Is it a bug fix
  • Is a typo/documentation fix
  • Is a feature enhancement
  • It is a refactor
  • Created tests that fail without the change (if possible)

By submitting this pull request, you confirm that you have read and agree to the terms of the Contributor License Agreement.

Documentation

Select exactly one:

  • I added/updated documentation for this change
  • Documentation is not needed for this change (explain why)

Internal protocol field; no user-visible behavior change beyond reachability of foreign relays when DNS for the FQDN is unavailable.

Docs PR URL (required if "docs added" is checked)

Paste the PR link from https://github.com/netbirdio/docs here:

https://github.com/netbirdio/docs/pull/__

Summary by CodeRabbit

New Features

  • Added IP-based fallback mechanism for relay server connections when DNS resolution fails, improving resilience in connectivity scenarios
  • Relay servers now exchange their connected IP addresses to enable direct IP dialing as a fallback option

Tests

  • Added integration tests validating relay server IP recovery and fallback dialing behavior
**Original Pull Request:** https://github.com/netbirdio/netbird/pull/6004 **State:** closed **Merged:** Yes --- ## Describe your changes ### Problem When two peers are on different relays and P2P (ICE) cannot be established, each learns the other peer's relay address through signal as an FQDN. If that FQDN cannot be resolved on the receiving side, the foreign-relay dial fails and the peers never reach each other. This deadlocks on first connect when the only configured exit-node peer is the one whose relay needs to be resolved: the overlay default route is installed before the exit-node WireGuard handshake completes, so DNS goes through `wt0` and fails. Management's relay cache doesn't help here, the foreign peer's home relay is only learned through signal, not from management. ### Fix Peer B already knows the IP it is connected to on its relay. We add that IP to the signal `Body` so peer A can use it as a dial-time fallback when the FQDN cannot be resolved. SNI/cert validation still uses the FQDN, so TLS is unaffected. - Add `relayServerIP` (bytes, tag 11) to signal `Body`; reserve tag 9 (previously int64 sessionId) to avoid wire-type collisions - Surface the underlying TCP RemoteAddr from the websocket relay conn so `ConnectedIP` returns the resolved IP after an FQDN dial - Plumb the IP as `netip.Addr` through `Manager.OpenConn` and `Client` with a fallback dial path that substitutes the IP into the URL while keeping the original host as SNI - Add unit tests for the fallback dial, `ConnectedIP` after an FQDN dial, and `substituteHost`; add an end-to-end manager test exercising the foreign-relay path ## Issue ticket number and link ## Stack <!-- branch-stack --> ### Checklist - [ ] Is it a bug fix - [ ] Is a typo/documentation fix - [x] Is a feature enhancement - [ ] It is a refactor - [x] Created tests that fail without the change (if possible) > By submitting this pull request, you confirm that you have read and agree to the terms of the [Contributor License Agreement](https://github.com/netbirdio/netbird/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT.md). ## Documentation Select exactly one: - [ ] I added/updated documentation for this change - [x] Documentation is **not needed** for this change (explain why) Internal protocol field; no user-visible behavior change beyond reachability of foreign relays when DNS for the FQDN is unavailable. ### Docs PR URL (required if "docs added" is checked) Paste the PR link from https://github.com/netbirdio/docs here: https://github.com/netbirdio/docs/pull/__ <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## New Features * Added IP-based fallback mechanism for relay server connections when DNS resolution fails, improving resilience in connectivity scenarios * Relay servers now exchange their connected IP addresses to enable direct IP dialing as a fallback option ## Tests * Added integration tests validating relay server IP recovery and fallback dialing behavior <!-- end of auto-generated comment: release notes by coderabbit.ai -->
saavagebueno added the pull-request label 2026-08-05 06:08:50 -04:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#24564