[PR #6826] [client] Fix data race on agentDialerCancel in ICE connect error paths #27193

Open
opened 2026-08-05 07:08:21 -04:00 by saavagebueno · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/netbirdio/netbird/pull/6826
Author: @MichaelUray
Created: 7/19/2026
Status: 🔄 Open

Base: mainHead: fix/ice-connect-own-dialer-cancel


📝 Commits (1)

  • 7714b56 [client] Fix data race on agentDialerCancel in ICE connect error paths

📊 Changes

2 files changed (+115 additions, -7 deletions)

View changed files

📝 client/internal/peer/worker_ice.go (+16 -7)
client/internal/peer/worker_ice_test.go (+99 -0)

📄 Description

Describe your changes

WorkerICE.connect() runs on its own goroutine (go w.connect(...) in
OnNewOffer) and read w.agentDialerCancel in its four error paths
(gather candidates failure, dial failure, selected-pair failure, nil pair)
without holding muxAgent, while a concurrent OnNewOffer replaces that
field under the lock.

Two consequences:

  1. A data race on the field (reported by go test -race).
  2. A functional bug: when a new offer has already re-created the agent,
    the stale error path invoked the successor's dialer cancel func,
    aborting the brand-new dial attempt instead of its own.

Fix: connect() now receives the cancel func belonging to its own dial
attempt as a parameter (created as a pair with dialerCtx in
OnNewOffer), mirroring how onConnectionStateChange already receives
dialerCancel. w.agentDialerCancel is now only accessed under
muxAgent (in OnNewOffer and Close).

Tests: a deterministic unit test pins that a failing connect attempt
cancels its own context and never touches the worker-level field, plus a
-race companion that exercises connect concurrently with the field
replacement.


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.

Summary by CodeRabbit

  • Bug Fixes

    • Improved connection cancellation handling to prevent one connection attempt from interrupting another.
    • Reduced the risk of connection setup issues during concurrent dialing and offer processing.
  • Tests

    • Added coverage for connection error handling and concurrent dial cancellation scenarios.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/netbirdio/netbird/pull/6826 **Author:** [@MichaelUray](https://github.com/MichaelUray) **Created:** 7/19/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `fix/ice-connect-own-dialer-cancel` --- ### 📝 Commits (1) - [`7714b56`](https://github.com/netbirdio/netbird/commit/7714b561a80e1d22cf0aedeb92f3ec1c3c440850) [client] Fix data race on agentDialerCancel in ICE connect error paths ### 📊 Changes **2 files changed** (+115 additions, -7 deletions) <details> <summary>View changed files</summary> 📝 `client/internal/peer/worker_ice.go` (+16 -7) ➕ `client/internal/peer/worker_ice_test.go` (+99 -0) </details> ### 📄 Description ## Describe your changes `WorkerICE.connect()` runs on its own goroutine (`go w.connect(...)` in `OnNewOffer`) and read `w.agentDialerCancel` in its four error paths (gather candidates failure, dial failure, selected-pair failure, nil pair) without holding `muxAgent`, while a concurrent `OnNewOffer` replaces that field under the lock. Two consequences: 1. A data race on the field (reported by `go test -race`). 2. A functional bug: when a new offer has already re-created the agent, the stale error path invoked the **successor's** dialer cancel func, aborting the brand-new dial attempt instead of its own. Fix: `connect()` now receives the cancel func belonging to its own dial attempt as a parameter (created as a pair with `dialerCtx` in `OnNewOffer`), mirroring how `onConnectionStateChange` already receives `dialerCancel`. `w.agentDialerCancel` is now only accessed under `muxAgent` (in `OnNewOffer` and `Close`). Tests: a deterministic unit test pins that a failing connect attempt cancels its own context and never touches the worker-level field, plus a `-race` companion that exercises `connect` concurrently with the field replacement. ## Issue ticket number and link - <!-- codesmith:footer --> --- <a href="https://app.blacksmith.sh/netbirdio/codesmith/netbird/pr/6826"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg"><img alt="View with Codesmith" src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"></picture></a> <a href="https://backend.blacksmith.sh/track/enable-autofix?expires=1787060577&installation_id=146802194&pr_number=6826&repository=netbirdio%2Fnetbird&return_to=https%3A%2F%2Fgithub.com%2Fnetbirdio%2Fnetbird%2Fpull%2F6826&signature=787e14aeca1aadf922f374a1fab42b8faf0971ae583cac6804749467a28eb4a8"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img alt="Autofix with Codesmith" src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"></picture></a> <sup>Need help on this PR? Tag <code>/codesmith</code> with what you need. Autofix is disabled.</sup> <!-- codesmith:autofix:disabled --> <!-- /codesmith:footer --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved connection cancellation handling to prevent one connection attempt from interrupting another. * Reduced the risk of connection setup issues during concurrent dialing and offer processing. * **Tests** * Added coverage for connection error handling and concurrent dial cancellation scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
saavagebueno added the pull-request label 2026-08-05 07:08:21 -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#27193