Skip to content

[client] Supress ICE signaling in case of force relay setting#5820

Open
pappz wants to merge 3 commits intomainfrom
refactor/force-relay
Open

[client] Supress ICE signaling in case of force relay setting#5820
pappz wants to merge 3 commits intomainfrom
refactor/force-relay

Conversation

@pappz
Copy link
Copy Markdown
Contributor

@pappz pappz commented Apr 7, 2026

Describe your changes

Suppress ICE signaling and periodic offers in force-relay mode
When NB_FORCE_RELAY is enabled, skip WorkerICE creation entirely,
suppress ICE credentials in offer/answer messages, disable the
periodic ICE candidate monitor, and fix isConnectedOnAllWay to
only check relay status so the guard stops sending unnecessary offers.

Issue ticket number and link

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)

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

  • Bug Fixes
    • Improved connection reliability when forced relay mode is enabled by properly disabling ICE monitoring in relay-only scenarios.
    • Fixed potential issues with connection status evaluation when ICE is intentionally disabled.
    • Enhanced credential handling to correctly manage ICE state during peer handshaking.

pappz added 3 commits April 7, 2026 14:08
When NB_FORCE_RELAY is enabled, skip WorkerICE creation entirely,
suppress ICE credentials in offer/answer messages, disable the
periodic ICE candidate monitor, and fix isConnectedOnAllWay to
only check relay status so the guard stops sending unnecessary offers.
…tials

Track whether the remote peer includes ICE credentials in its
offers/answers. When remote stops sending ICE credentials, skip
ICE listener dispatch, suppress ICE credentials in responses, and
exclude ICE from the guard connectivity check. When remote resumes
sending ICE credentials, re-enable all ICE behavior.
… transition

Fix nil pointer dereference in signalOfferAnswer when SessionID is nil
(relay-only offers). Close stale ICE agent immediately when remote peer
stops sending ICE credentials to avoid traffic black-hole during the
ICE disconnect timeout.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 7, 2026

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly describes the main change: suppressing ICE signaling when force relay is enabled, which aligns with the changeset's core objective across multiple files.
Description check ✅ Passed PR description includes required sections: change description, checklist, and documentation decision. All critical template elements are filled with substantive content.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/force-relay

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
client/internal/peer/conn.go (1)

735-749: ⚠️ Potential issue | 🟠 Major

Require at least one transport when remote ICE is disabled.

Once RemoteICESupported() is false, this path skips the ICE gate. If relay is also unsupported for the peer, the function now falls through to true, so the guard stops re-offering even though there is no working transport.

💡 Suggested fix
 func (conn *Conn) isConnectedOnAllWay() (connected bool) {
@@
-	// For non-forced platforms: check ICE connection status only if remote peer supports ICE
-	if conn.handshaker.RemoteICESupported() {
+	relaySupported := conn.workerRelay.IsRelayConnectionSupportedWithPeer()
+
+	// For non-forced platforms: check ICE connection status only if remote peer supports ICE.
+	// If the remote disabled ICE, relay has to be available instead.
+	if conn.handshaker.RemoteICESupported() {
 		if conn.statusICE.Get() == worker.StatusDisconnected && !conn.workerICE.InProgress() {
 			return false
 		}
+	} else if !relaySupported {
+		return false
 	}
 
 	// If relay is supported with peer, it must also be connected
-	if conn.workerRelay.IsRelayConnectionSupportedWithPeer() {
+	if relaySupported {
 		if conn.statusRelay.Get() == worker.StatusDisconnected {
 			return false
 		}
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@client/internal/peer/conn.go` around lines 735 - 749, The current
transport-readiness check incorrectly returns true when RemoteICESupported() is
false and the peer also doesn't support relay; update the logic in the readiness
function that contains conn.handshaker.RemoteICESupported(), conn.statusICE, and
conn.workerRelay.IsRelayConnectionSupportedWithPeer() so that when
RemoteICESupported() is false you still require at least one working transport:
if relay is not supported with the peer
(workerRelay.IsRelayConnectionSupportedWithPeer() == false) then return false;
otherwise continue to validate the relay status as currently done (i.e., require
statusRelay != StatusDisconnected).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@client/internal/peer/conn.go`:
- Around line 735-749: The current transport-readiness check incorrectly returns
true when RemoteICESupported() is false and the peer also doesn't support relay;
update the logic in the readiness function that contains
conn.handshaker.RemoteICESupported(), conn.statusICE, and
conn.workerRelay.IsRelayConnectionSupportedWithPeer() so that when
RemoteICESupported() is false you still require at least one working transport:
if relay is not supported with the peer
(workerRelay.IsRelayConnectionSupportedWithPeer() == false) then return false;
otherwise continue to validate the relay status as currently done (i.e., require
statusRelay != StatusDisconnected).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 97653c97-31db-42e6-973f-df416c625882

📥 Commits

Reviewing files that changed from the base of the PR and between 0588d2d and 2734a33.

📒 Files selected for processing (6)
  • client/internal/engine.go
  • client/internal/peer/conn.go
  • client/internal/peer/env.go
  • client/internal/peer/guard/sr_watcher.go
  • client/internal/peer/handshaker.go
  • client/internal/peer/signaler.go

@pappz pappz marked this pull request as ready for review April 7, 2026 15:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant