[PR #4947] Add automatic WebSocket fallback for HTTP/1.1-only environments for Management and Signal Server Connection #21663

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

📋 Pull Request Information

Original PR: https://github.com/netbirdio/netbird/pull/4947
Author: @shyam0904a
Created: 12/13/2025
Status: 🔄 Open

Base: mainHead: main


📝 Commits (8)

  • e6e12b4 Add automatic WebSocket fallback for HTTP/1.1-only environments
  • 1ed8154 Add comment to empty EnableWebSocketFallback function for SonarQube
  • 4fffdbb Address CodeRabbit review comments
  • 33974ff Address additional CodeRabbit nitpicks
  • 44e9619 Merge branch 'netbirdio:main' into main
  • 22904ae Merge branch 'netbirdio:main' into main
  • b0525d8 Merge branch 'netbirdio:main' into main
  • c4e1c1c Merge branch 'netbirdio:main' into main

📊 Changes

5 files changed (+186 additions, -26 deletions)

View changed files

📝 client/grpc/dialer.go (+46 -4)
📝 client/grpc/dialer_generic.go (+53 -20)
📝 client/grpc/dialer_js.go (+15 -1)
client/grpc/fallback.go (+66 -0)
📝 flow/client/client.go (+6 -1)

📄 Description

Describe your changes

This PR adds automatic WebSocket fallback support to the NetBird client for environments where native gRPC (HTTP/2) connections fail due to ALPN stripping or HTTP/1.1-only proxies (e.g., SASE solutions, corporate proxies).

Changes:

  • client/grpc/dialer.go: Modified CreateConnection to first attempt native gRPC, then automatically fall back to WebSocket if specific errors are detected (ALPN issues, DeadlineExceeded, Unavailable, Internal)
  • client/grpc/dialer_generic.go: Added dialWebSocket and dialNative helper functions; WebSocket connections now use context.Background() to prevent premature connection closure
  • client/grpc/dialer_js.go: Updated to match new WithCustomDialer signature (JS/WASM always uses WebSocket)
  • client/grpc/fallback.go: New file managing fallback state with IsWebSocketFallbackEnabled(), EnableWebSocketFallback(), and ShouldFallbackToWebSocket(err) functions
  • flow/client/client.go: Updated to use the new dialer signature

Behavior:

  1. Client attempts native gRPC connection (5-10s timeout)
  2. If it fails with ALPN/HTTP2 errors, WebSocket fallback is enabled globally
  3. Subsequent connections automatically use WebSocket proxy (/ws-proxy/{management,signal})

N/A - Addresses connectivity issues for users behind restrictive proxies that strip ALPN or enforce HTTP/1.1

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)

The feature is automatic and transparent to users - no configuration flags or user action required. The client automatically detects HTTP/2 issues and falls back to WebSocket without user intervention.

Summary by CodeRabbit

  • New Features

    • Automatic WebSocket fallback for gRPC connections when native dialing fails.
    • Runtime controls to enable/query the fallback state; client creation respects the fallback flag.
    • Platform-aware transport selection with distinct native and WebSocket timeouts.
  • Bug Fixes / Reliability

    • TLS handling adjusted so native and WebSocket paths use appropriate TLS behavior.
    • WebSocket fallback disabled for browser builds to avoid unsupported behavior.

✏️ Tip: You can customize this high-level summary in your review settings.


🔄 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/4947 **Author:** [@shyam0904a](https://github.com/shyam0904a) **Created:** 12/13/2025 **Status:** 🔄 Open **Base:** `main` ← **Head:** `main` --- ### 📝 Commits (8) - [`e6e12b4`](https://github.com/netbirdio/netbird/commit/e6e12b423fbc78c13453381e5af51f2d43a7133d) Add automatic WebSocket fallback for HTTP/1.1-only environments - [`1ed8154`](https://github.com/netbirdio/netbird/commit/1ed81542ebf4e579b5ab4baffca28be4c6cd2716) Add comment to empty EnableWebSocketFallback function for SonarQube - [`4fffdbb`](https://github.com/netbirdio/netbird/commit/4fffdbbf771655c7886cd6cccb86835661130c38) Address CodeRabbit review comments - [`33974ff`](https://github.com/netbirdio/netbird/commit/33974ff50b89b999fa7d9fdf7d66ef02469eda5e) Address additional CodeRabbit nitpicks - [`44e9619`](https://github.com/netbirdio/netbird/commit/44e961965ae87ba74d83d1a0ff3c60bb08fa8ef2) Merge branch 'netbirdio:main' into main - [`22904ae`](https://github.com/netbirdio/netbird/commit/22904aef0fef1c24d61e520b44cd3646cdb4a3e8) Merge branch 'netbirdio:main' into main - [`b0525d8`](https://github.com/netbirdio/netbird/commit/b0525d8c710404193dc195e37bdd34a9c8949367) Merge branch 'netbirdio:main' into main - [`c4e1c1c`](https://github.com/netbirdio/netbird/commit/c4e1c1c71b5a5b5dbf8f347ba709927aef010f80) Merge branch 'netbirdio:main' into main ### 📊 Changes **5 files changed** (+186 additions, -26 deletions) <details> <summary>View changed files</summary> 📝 `client/grpc/dialer.go` (+46 -4) 📝 `client/grpc/dialer_generic.go` (+53 -20) 📝 `client/grpc/dialer_js.go` (+15 -1) ➕ `client/grpc/fallback.go` (+66 -0) 📝 `flow/client/client.go` (+6 -1) </details> ### 📄 Description ## Describe your changes This PR adds automatic WebSocket fallback support to the NetBird client for environments where native gRPC (HTTP/2) connections fail due to ALPN stripping or HTTP/1.1-only proxies (e.g., SASE solutions, corporate proxies). **Changes:** - client/grpc/dialer.go: Modified CreateConnection to first attempt native gRPC, then automatically fall back to WebSocket if specific errors are detected (ALPN issues, DeadlineExceeded, Unavailable, Internal) - client/grpc/dialer_generic.go: Added dialWebSocket and dialNative helper functions; WebSocket connections now use context.Background() to prevent premature connection closure - client/grpc/dialer_js.go: Updated to match new WithCustomDialer signature (JS/WASM always uses WebSocket) - client/grpc/fallback.go: New file managing fallback state with IsWebSocketFallbackEnabled(), EnableWebSocketFallback(), and ShouldFallbackToWebSocket(err) functions - flow/client/client.go: Updated to use the new dialer signature **Behavior:** 1. Client attempts native gRPC connection (5-10s timeout) 2. If it fails with ALPN/HTTP2 errors, WebSocket fallback is enabled globally 3. Subsequent connections automatically use WebSocket proxy (/ws-proxy/{management,signal}) ## Issue ticket number and link N/A - Addresses connectivity issues for users behind restrictive proxies that strip ALPN or enforce HTTP/1.1 ## Stack <!-- branch-stack --> ### Checklist - [ ] Is it a bug fix - [ ] Is a typo/documentation fix - [x] 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](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) The feature is automatic and transparent to users - no configuration flags or user action required. The client automatically detects HTTP/2 issues and falls back to WebSocket without user intervention. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Automatic WebSocket fallback for gRPC connections when native dialing fails. * Runtime controls to enable/query the fallback state; client creation respects the fallback flag. * Platform-aware transport selection with distinct native and WebSocket timeouts. * **Bug Fixes / Reliability** * TLS handling adjusted so native and WebSocket paths use appropriate TLS behavior. * WebSocket fallback disabled for browser builds to avoid unsupported behavior. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- 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 05:08:48 -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#21663