[PR #6080] [client] Match Windows ICE interface-filter substrings case-insensitively #29001

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

📋 Pull Request Information

Original PR: https://github.com/netbirdio/netbird/pull/6080
Author: @MichaelUray
Created: 5/5/2026
Status: 🔄 Open

Base: mainHead: pr/q2-windows-ice-filter-case-insensitive


📝 Commits (2)

  • c6f4622 client/stdnet: case-insensitive ICE interface filter (Windows P2P fix)
  • 88a0f39 Merge upstream/main into pr/q2-windows-ice-filter-case-insensitive

📊 Changes

2 files changed (+137 additions, -4 deletions)

View changed files

📝 client/internal/stdnet/filter.go (+57 -4)
client/internal/stdnet/filter_test.go (+80 -0)

📄 Description

[client] Match Windows ICE interface-filter substrings case-insensitively

Branch: pr/q2-windows-ice-filter-case-insensitive
Base: main (upstream)
Compare URL: https://github.com/netbirdio/netbird/compare/main...MichaelUray:netbird:pr/q2-windows-ice-filter-case-insensitive?expand=1


Summary

Windows interface names contain unpredictable casing — vEthernet (Default Switch) from Hyper-V, Local Area Connection* for hidden adapters, PANGP Virtual Ethernet Adapter from Palo Alto GlobalProtect — and the existing ICE-candidate filter compared the lowercased adapter name against an exact-case substring list. This silently let several known-bad adapters through.

This PR makes the filter substrings case-insensitive on Windows so the lowercased comparison reliably catches them.

Background

On Windows, ICE candidate gathering picked up Hyper-V virtual switches and PANGP VPN adapters as host candidates and used them as the local half of the candidate pair, which then competed with the real LAN candidate during pair-prioritisation. Outcome on a Hyper-V developer machine: pion's pair-checks selected the Hyper-V switch, the remote could not reach it, ICE never confirmed, and the peer stayed on relay even though direct LAN P2P was actually possible.

The filter already existed but used substrings like "vEthernet", "Hyper-V" etc. that were compared against strings.ToLower(name) — so they matched only when the original adapter name happened to be lower-case, which it usually isn't on Windows.

Change

  • client/internal/stdnet/filter.go: extracted the substring list into windowsKnownBadSubstrings, lowercased once, and matched against the lowercased adapter name with strings.Contains. Existing entries kept; one Hyper-V default-switch entry added.
  • client/internal/stdnet/filter_test.go: new table-driven test covering the previous miss-case (mixed-case vEthernet (Default Switch) / PANGP Virtual Ethernet Adapter) plus the legitimate-LAN no-filter case.

Tests

  • go test ./client/internal/stdnet/... — pass.
  • Full client build (go build ./client/...) — pass on linux/amd64, linux/arm64, windows/amd64.
  • Hardware-validated on a Windows 11 + NetBird daemon dev machine where Hyper-V Default Switch was previously stealing ICE pair-selection. After the fix, the vEthernet (Default Switch) adapter is filtered, the real LAN adapter wins, P2P establishes directly without going through relay.

Test plan

  • Unit test covers mixed-case adapter names.
  • No regression for the non-Windows paths (filter is conditioned on runtime.GOOS == "windows").
  • Maintainer to verify on a CI Windows runner if available.

Use case

Real-world: Windows dev machines and corporate laptops with Hyper-V, WSL2, GlobalProtect, Cisco AnyConnect, or similar tunnel adapters. Without this fix the daemon falls back to relay even though direct P2P would work.

Linked work

Part of the broader p2p-dynamic connection-mode work on issue #5989, but this fix is self-contained and applicable to current main without dependencies.

Summary by CodeRabbit

  • Bug Fixes
    • Improved Windows network interface detection for ICE candidate gathering with better handling of Windows-specific interface names like vEthernet variants.
    • Made interface filtering case-insensitive to ensure consistent behavior across different naming conventions.
    • Added regression tests to ensure proper filtering behavior on Windows and Linux platforms.

Documentation

  • Documentation is not needed

These changes are internal lifecycle / behavioural improvements; no user-visible API or CLI flag added that warrants new public docs. Existing flags/Settings already documented at netbirdio/docs cover the surface area.


🔄 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/6080 **Author:** [@MichaelUray](https://github.com/MichaelUray) **Created:** 5/5/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `pr/q2-windows-ice-filter-case-insensitive` --- ### 📝 Commits (2) - [`c6f4622`](https://github.com/netbirdio/netbird/commit/c6f46228db490735b8e1e9e12b560e8524638180) client/stdnet: case-insensitive ICE interface filter (Windows P2P fix) - [`88a0f39`](https://github.com/netbirdio/netbird/commit/88a0f3935d1b1712d5d04652e349ebc7c6f557ae) Merge upstream/main into pr/q2-windows-ice-filter-case-insensitive ### 📊 Changes **2 files changed** (+137 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `client/internal/stdnet/filter.go` (+57 -4) ➕ `client/internal/stdnet/filter_test.go` (+80 -0) </details> ### 📄 Description # [client] Match Windows ICE interface-filter substrings case-insensitively **Branch:** `pr/q2-windows-ice-filter-case-insensitive` **Base:** `main` (upstream) **Compare URL:** https://github.com/netbirdio/netbird/compare/main...MichaelUray:netbird:pr/q2-windows-ice-filter-case-insensitive?expand=1 --- ## Summary Windows interface names contain unpredictable casing — `vEthernet (Default Switch)` from Hyper-V, `Local Area Connection*` for hidden adapters, `PANGP Virtual Ethernet Adapter` from Palo Alto GlobalProtect — and the existing ICE-candidate filter compared the lowercased adapter name against an exact-case substring list. This silently let several known-bad adapters through. This PR makes the filter substrings case-insensitive on Windows so the lowercased comparison reliably catches them. ## Background On Windows, ICE candidate gathering picked up Hyper-V virtual switches and PANGP VPN adapters as host candidates and used them as the `local` half of the candidate pair, which then competed with the real LAN candidate during pair-prioritisation. Outcome on a Hyper-V developer machine: pion's pair-checks selected the Hyper-V switch, the remote could not reach it, ICE never confirmed, and the peer stayed on relay even though direct LAN P2P was actually possible. The filter already existed but used substrings like `"vEthernet"`, `"Hyper-V"` etc. that were compared against `strings.ToLower(name)` — so they matched only when the original adapter name happened to be lower-case, which it usually isn't on Windows. ## Change - `client/internal/stdnet/filter.go`: extracted the substring list into `windowsKnownBadSubstrings`, lowercased once, and matched against the lowercased adapter name with `strings.Contains`. Existing entries kept; one Hyper-V default-switch entry added. - `client/internal/stdnet/filter_test.go`: new table-driven test covering the previous miss-case (mixed-case `vEthernet (Default Switch)` / `PANGP Virtual Ethernet Adapter`) plus the legitimate-LAN no-filter case. ## Tests - `go test ./client/internal/stdnet/...` — pass. - Full client build (`go build ./client/...`) — pass on linux/amd64, linux/arm64, windows/amd64. - **Hardware-validated** on a Windows 11 + NetBird daemon dev machine where Hyper-V Default Switch was previously stealing ICE pair-selection. After the fix, the `vEthernet (Default Switch)` adapter is filtered, the real LAN adapter wins, P2P establishes directly without going through relay. ## Test plan - [x] Unit test covers mixed-case adapter names. - [x] No regression for the non-Windows paths (filter is conditioned on `runtime.GOOS == "windows"`). - [ ] Maintainer to verify on a CI Windows runner if available. ## Use case Real-world: Windows dev machines and corporate laptops with Hyper-V, WSL2, GlobalProtect, Cisco AnyConnect, or similar tunnel adapters. Without this fix the daemon falls back to relay even though direct P2P would work. ## Linked work Part of the broader `p2p-dynamic` connection-mode work on issue #5989, but this fix is self-contained and applicable to current main without dependencies. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved Windows network interface detection for ICE candidate gathering with better handling of Windows-specific interface names like vEthernet variants. * Made interface filtering case-insensitive to ensure consistent behavior across different naming conventions. * Added regression tests to ensure proper filtering behavior on Windows and Linux platforms. <!-- end of auto-generated comment: release notes by coderabbit.ai --> ## Documentation - [x] Documentation is **not needed** These changes are internal lifecycle / behavioural improvements; no user-visible API or CLI flag added that warrants new public docs. Existing flags/Settings already documented at netbirdio/docs cover the surface area. --- <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 08:07:17 -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#29001