Skip to content

[client, management] Support per-peer lazy connection state and default proxy peers to lazy#6762

Open
lixmal wants to merge 5 commits into
mainfrom
lazy-conn-per-peer
Open

[client, management] Support per-peer lazy connection state and default proxy peers to lazy#6762
lixmal wants to merge 5 commits into
mainfrom
lazy-conn-per-peer

Conversation

@lixmal

@lixmal lixmal commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Describe your changes

Lazy connections were an all-or-nothing account setting. This makes laziness controllable per peer and runs the lazy connection manager continuously, so ephemeral proxy peers connect on-demand by default even when the account-wide flag is off.

  • Run the lazy connection manager whenever it is supported instead of gating it on the account-wide flag; the account flag and the local override now decide which peers default to lazy versus always-active.
  • Add a per-peer lazy override to the network map (default / lazy / eager) so management can steer individual peers in either direction.
  • Default ephemeral proxy peers to lazy on both endpoints, so shared proxy infrastructure is not kept permanently connected to every peer.
  • Keep a local NB_LAZY_CONN / MDM override authoritative over the per-peer state.
  • Reflect the resolved account-wide default in client status and update it when the flag changes at runtime.

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)
  • This change does not modify the public API, gRPC protocols, functionality behavior, CLI / service flags, or introduce a new feature — OR I have discussed it with the NetBird team beforehand (link the issue / Slack thread in the description). See CONTRIBUTING.md.

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)

No new user-facing configuration is introduced; the per-peer eager override has no admin-facing setting yet and the proxy-peer default is internal behavior.

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 per-peer lazy connection control (default/lazy/eager) via management configuration, including embedded proxy–aware lazy behavior.
    • Lazy peer eligibility and exclusions now incorporate ingress forwarding rules end-to-end.
  • Bug Fixes
    • Remote lazy feature-flag updates no longer restart or reconcile lazy peers unnecessarily.
    • Exclude-list updates avoid redundant recomputation when the effective set hasn’t changed.
  • Tests
    • Expanded coverage for per-peer lazy resolution and forwarding-rule-based exclusion behavior, plus updated engine lazy test setup.

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2f64ce33-2337-45f6-a02d-eca2bb53e6ec

📥 Commits

Reviewing files that changed from the base of the PR and between 99ceb9b and 75fb373.

📒 Files selected for processing (1)
  • client/internal/engine.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • client/internal/engine.go

📝 Walkthrough

Walkthrough

Management now emits per-peer lazy states, while ConnMgr resolves account-wide and per-peer policies. Engine reconciliation uses forwarding rules to classify permanent peers and update lazy exclusions.

Changes

Lazy connection policy

Layer / File(s) Summary
Management lazy-state contract
shared/management/proto/management.proto, management/internals/shared/grpc/conversion.go
Adds LazyStateDefault, LazyStateLazy, and LazyStateEager, and emits per-peer lazy state based on embedded proxy status.
Connection-manager lazy resolution
client/internal/conn_mgr.go, client/internal/conn_mgr_test.go
Caches the remote lazy flag, resolves per-peer defaults, changes manager lifecycle behavior, avoids redundant exclude-list reconciliation, and supports permanent connection decisions with corresponding tests.
Engine peer reconciliation
client/internal/engine.go, client/internal/conn_mgr_test.go, client/internal/engine_lazy_exclude_test.go, client/internal/engine_test.go
Passes forwarding rules through peer reconciliation, classifies permanent peers, updates lazy exclusions, and expands coverage for policy combinations, forward targets, and userspace interface setup.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Management
  participant Engine
  participant ConnMgr
  participant LazyConnectionManager
  Management->>Engine: emit RemotePeerConfig with LazyState
  Engine->>Engine: compute forwarding rules and permanent peers
  Engine->>ConnMgr: AddPeerConn with permanence
  ConnMgr->>LazyConnectionManager: route eligible connections
Loading

Possibly related PRs

  • netbirdio/netbird#6674: Updates related toExcludedLazyPeers forward-target detection and tests.
  • netbirdio/netbird#6767: Modifies the client lazy-connection startup flow by warming lazy peers after the connection manager starts.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: per-peer lazy connection state and lazy defaults for proxy peers.
Description check ✅ Passed The description covers the change summary, checklist, and docs note, but the issue ticket and stack sections are left empty.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ 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 lazy-conn-per-peer

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@client/internal/engine.go`:
- Line 1782: Update the AddPeerConn call sites in the connection-handling flow
and the corresponding later path to classify permanence from the incoming peer
configuration’s allowed IPs, rather than calling isPermanentPeer against the
not-yet-populated peer store. Ensure forward targets are registered as permanent
when their configured allowed IPs indicate forwarding, while preserving existing
behavior for other peers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 46ec3772-d86e-4d61-99a8-3163f66be388

📥 Commits

Reviewing files that changed from the base of the PR and between a48618c and 82ea626.

⛔ Files ignored due to path filters (1)
  • shared/management/proto/management.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (6)
  • client/internal/conn_mgr.go
  • client/internal/conn_mgr_test.go
  • client/internal/engine.go
  • client/internal/engine_lazy_exclude_test.go
  • management/internals/shared/grpc/conversion.go
  • shared/management/proto/management.proto

Comment thread client/internal/engine.go
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown

Release artifacts

Built for PR head 75fb373 in workflow run #16843.

Artifact Link
All release artifacts Download
Linux packages Download
Windows packages Download
macOS packages Download
UI artifacts Download
UI macOS artifacts Download

GHCR images (amd64)

This comment is updated by the Release workflow. Artifact links expire according to the workflow retention policy.

// Force a lazy (on-demand) connection regardless of the account flag.
LazyStateLazy = 1;
// Force an always-active connection regardless of the account flag.
LazyStateEager = 2;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this used?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It's used on the consumer (client), it's not produced by mgmt yet


e.initLazyManager(ctx)
e.statusRecorder.UpdateLazyConnection(true)
e.statusRecorder.UpdateLazyConnection(e.PeerLazyDefault(mgmProto.LazyState_LazyStateDefault))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is this capturing the fact that proxy peers are lazy when account flag is not set?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Nope, right now it reflects the account wide setting

return
}

e.initLazyManager(ctx)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We are starting the lazy manager even when account and local lazy flag say to not use lazy. (majority of customers today?)

By doing so, we are running toExcludedLazyPeers on every sync update potentially on a long slice of RemotePeerConfigs, even though the result will exactly the entire map of all peers.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I added a check to avoid running the expensive part when nothing has changed

Comment thread client/internal/engine.go Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

GetPeerConfig can be nil ( from line 1393 ). If so GetLazyConnectionEnabled is defaulted to false. Is it ok?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I've hardened it

@sonarqubecloud

Copy link
Copy Markdown

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.

2 participants