-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[client] Phase 3.5 + 3.7d-h of #5989: network-change ICE recovery + GUI mode tab (stack 2/4) #6082
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c4844cc
e0ed831
c71c951
7d90a5b
cc10c9f
dfd48e9
82877f0
cd0abe8
0022145
b22128e
3d8cc98
b53322d
f63e2a7
77852a9
0304dc2
ec2b46e
3528248
5c18a23
ad789e3
a9710d9
d662d9b
76e2d0b
efaa2b1
838702d
90c3d9f
74265f3
9f60f1a
37276ea
f9db3b0
f63852d
7928f05
4bb38b6
a49534f
68dd578
7349b95
75713b9
32c4efb
451872e
19fb079
b22143d
bfdc73e
7c1a7a1
701a20f
58eb4f8
6dd1e44
7c80838
b9a967f
8760fa1
6f86055
939d946
15c6d90
78d2fdc
90dba34
bcb30b9
9e444b5
67e7f36
ddd1f87
34300d5
b12be21
f4ff7c7
0b85cf5
672a9bc
abeecc6
3730df0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -307,6 +307,91 @@ func (p *Preferences) SetBlockInbound(block bool) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| p.configInput.BlockInbound = &block | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // GetConnectionMode returns the locally configured connection-mode override | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // (canonical lower-kebab-case: "relay-forced", "p2p", "p2p-lazy", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // "p2p-dynamic", "follow-server"), or empty string if no local override | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // is configured -- the daemon will then follow the server-pushed value. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (p *Preferences) GetConnectionMode() (string, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if p.configInput.ConnectionMode != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return *p.configInput.ConnectionMode, nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cfg, err := profilemanager.ReadConfig(p.configInput.ConfigPath) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "", err | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return cfg.ConnectionMode, nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // SetConnectionMode stores a local override for the connection mode. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Pass an empty string to clear the override (revert to following the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // server-pushed value). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (p *Preferences) SetConnectionMode(mode string) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| m := mode | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| p.configInput.ConnectionMode = &m | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // GetRelayTimeoutSeconds returns the locally configured relay-worker | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // inactivity timeout in seconds, or 0 if no override is set (follow | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // server-pushed value, or built-in default if the server has none). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (p *Preferences) GetRelayTimeoutSeconds() (int64, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if p.configInput.RelayTimeoutSeconds != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return int64(*p.configInput.RelayTimeoutSeconds), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cfg, err := profilemanager.ReadConfig(p.configInput.ConfigPath) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return 0, err | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return int64(cfg.RelayTimeoutSeconds), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // SetRelayTimeoutSeconds stores a local override for the relay timeout. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Pass 0 to clear the override. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (p *Preferences) SetRelayTimeoutSeconds(secs int64) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| v := uint32(secs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| p.configInput.RelayTimeoutSeconds = &v | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+325
to
+352
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Confirm there's no other "clear override" path that nils the pointer in apply() or elsewhere.
rg -nP --type=go -C2 'ConnectionMode|RelayTimeoutSeconds|P2pTimeoutSeconds|P2pRetryMaxSeconds' -g '!**/*_test.go' -g 'client/internal/profilemanager/**'Repository: netbirdio/netbird Length of output: 3375 🏁 Script executed: #!/bin/bash
# Check the actual SetConnectionMode, SetRelayTimeoutSeconds, SetP2pTimeoutSeconds, SetP2pRetryMaxSeconds implementations
cat -n client/android/preferences.go | head -400 | tail -100Repository: netbirdio/netbird Length of output: 4108 🏁 Script executed: #!/bin/bash
# Search for all occurrences of these four setter functions to ensure we catch all of them
rg -n 'func.*Set(ConnectionMode|RelayTimeoutSeconds|P2pTimeoutSeconds|P2pRetryMaxSeconds)' --type=go -g '!**/*_test.go'Repository: netbirdio/netbird Length of output: 426 🏁 Script executed: #!/bin/bash
# Check if there are any other code paths that might clear these overrides (e.g., by setting to nil)
rg -n 'ConnectionMode.*=.*nil|RelayTimeoutSeconds.*=.*nil|P2pTimeoutSeconds.*=.*nil|P2pRetryMaxSeconds.*=.*nil' --type=go -g '!**/*_test.go'Repository: netbirdio/netbird Length of output: 3062 Fix the "clear override" logic to set pointer to nil, not to zero value. The documented behaviour for To honour the documented semantics, set the pointer to Suggested fix pattern func (p *Preferences) SetConnectionMode(mode string) {
+ if mode == "" {
+ p.configInput.ConnectionMode = nil
+ return
+ }
m := mode
p.configInput.ConnectionMode = &m
}
@@
func (p *Preferences) SetRelayTimeoutSeconds(secs int64) {
+ if secs <= 0 {
+ p.configInput.RelayTimeoutSeconds = nil
+ return
+ }
v := uint32(secs)
p.configInput.RelayTimeoutSeconds = &v
}Apply the same pattern to 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // GetP2pTimeoutSeconds returns the locally configured ICE-worker | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // inactivity timeout in seconds (only effective in p2p-dynamic mode), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // or 0 if no override is set. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (p *Preferences) GetP2pTimeoutSeconds() (int64, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if p.configInput.P2pTimeoutSeconds != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return int64(*p.configInput.P2pTimeoutSeconds), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cfg, err := profilemanager.ReadConfig(p.configInput.ConfigPath) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return 0, err | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return int64(cfg.P2pTimeoutSeconds), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // SetP2pTimeoutSeconds stores a local override for the p2p timeout. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Pass 0 to clear the override. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (p *Preferences) SetP2pTimeoutSeconds(secs int64) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| v := uint32(secs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| p.configInput.P2pTimeoutSeconds = &v | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // GetP2pRetryMaxSeconds returns the locally configured cap on the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // per-peer ICE-failure backoff schedule, or 0 if no override is set. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (p *Preferences) GetP2pRetryMaxSeconds() (int64, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if p.configInput.P2pRetryMaxSeconds != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return int64(*p.configInput.P2pRetryMaxSeconds), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cfg, err := profilemanager.ReadConfig(p.configInput.ConfigPath) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return 0, err | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return int64(cfg.P2pRetryMaxSeconds), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // SetP2pRetryMaxSeconds stores a local override for the backoff cap. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Pass 0 to clear the override. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (p *Preferences) SetP2pRetryMaxSeconds(secs int64) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| v := uint32(secs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| p.configInput.P2pRetryMaxSeconds = &v | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Commit writes out the changes to the config file | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (p *Preferences) Commit() error { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _, err := profilemanager.UpdateOrCreateConfig(p.configInput) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ import ( | |
| "github.com/kardianos/service" | ||
| "github.com/spf13/cobra" | ||
|
|
||
| "github.com/netbirdio/netbird/client/internal/profilemanager" | ||
| "github.com/netbirdio/netbird/util" | ||
| ) | ||
|
|
||
|
|
@@ -131,6 +132,12 @@ var installCmd = &cobra.Command{ | |
| cmd.PrintErrf("Warning: failed to load saved service params: %v\n", err) | ||
| } | ||
|
|
||
| // Persist any profile-level connection-mode/timeout flags that | ||
| // were explicitly set so the daemon picks them up on first start. | ||
| if err := applyConnectionModeFlagsToProfile(cmd); err != nil { | ||
| cmd.PrintErrf("Warning: failed to persist connection-mode flags: %v\n", err) | ||
| } | ||
|
Comment on lines
+135
to
+139
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make connection-mode persistence failures abort the command. These flags are not passed through Suggested change- if err := applyConnectionModeFlagsToProfile(cmd); err != nil {
- cmd.PrintErrf("Warning: failed to persist connection-mode flags: %v\n", err)
- }
+ if err := applyConnectionModeFlagsToProfile(cmd); err != nil {
+ return fmt.Errorf("persist connection-mode flags: %w", err)
+ }Apply the same change in both the install and reconfigure paths. Based on learnings methods returning errors should be propagated early rather than continuing with partially applied state. Also applies to: 263-265 🤖 Prompt for AI Agents |
||
|
|
||
| svcConfig, err := createServiceConfigForInstall() | ||
| if err != nil { | ||
| return err | ||
|
|
@@ -157,6 +164,52 @@ var installCmd = &cobra.Command{ | |
| }, | ||
| } | ||
|
|
||
| // applyConnectionModeFlagsToProfile writes the connection-mode + | ||
| // timeout flags into the active profile's config file so the daemon | ||
| // will use them on its next startup. Only fields whose flag was | ||
| // explicitly set are touched; missing flags leave the existing | ||
| // profile values intact. Used by install + reconfigure so headless | ||
| // deployments can pre-seed everything in a single command. | ||
| func applyConnectionModeFlagsToProfile(cmd *cobra.Command) error { | ||
| anyChanged := false | ||
| for _, name := range []string{connectionModeFlag, relayTimeoutFlag, p2pTimeoutFlag, p2pRetryMaxFlag} { | ||
| if f := cmd.Flag(name); f != nil && f.Changed { | ||
| anyChanged = true | ||
| break | ||
| } | ||
| } | ||
| if !anyChanged { | ||
| return nil | ||
| } | ||
|
|
||
| cfgPath := profilemanager.DefaultConfigPath | ||
| if configPath != "" { | ||
| cfgPath = configPath | ||
| } | ||
| if cfgPath == "" { | ||
| return fmt.Errorf("default config path is not set on this platform; pass --config") | ||
| } | ||
|
|
||
| ic := profilemanager.ConfigInput{ConfigPath: cfgPath} | ||
| if cmd.Flag(connectionModeFlag).Changed { | ||
| ic.ConnectionMode = &connectionMode | ||
| } | ||
| if cmd.Flag(relayTimeoutFlag).Changed { | ||
| ic.RelayTimeoutSeconds = &relayTimeoutSecs | ||
| } | ||
| if cmd.Flag(p2pTimeoutFlag).Changed { | ||
| ic.P2pTimeoutSeconds = &p2pTimeoutSecs | ||
| } | ||
| if cmd.Flag(p2pRetryMaxFlag).Changed { | ||
| ic.P2pRetryMaxSeconds = &p2pRetryMaxSecs | ||
| } | ||
| if _, err := profilemanager.UpdateOrCreateConfig(ic); err != nil { | ||
| return fmt.Errorf("write profile %s: %w", cfgPath, err) | ||
| } | ||
| cmd.Println("connection-mode/timeout flags persisted to profile:", cfgPath) | ||
| return nil | ||
| } | ||
|
|
||
| var uninstallCmd = &cobra.Command{ | ||
| Use: "uninstall", | ||
| Short: "uninstalls NetBird service from system", | ||
|
|
@@ -207,6 +260,10 @@ This command will temporarily stop the service, update its configuration, and re | |
| cmd.PrintErrf("Warning: failed to load saved service params: %v\n", err) | ||
| } | ||
|
|
||
| if err := applyConnectionModeFlagsToProfile(cmd); err != nil { | ||
| cmd.PrintErrf("Warning: failed to persist connection-mode flags: %v\n", err) | ||
| } | ||
|
|
||
| wasRunning, err := isServiceRunning() | ||
| if err != nil && !errors.Is(err, ErrGetServiceStatus) { | ||
| return fmt.Errorf("check service status: %w", err) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -338,7 +338,7 @@ | |
| return nil | ||
| } | ||
|
|
||
| func setupSetConfigReq(customDNSAddressConverted []byte, cmd *cobra.Command, profileName, username string) *proto.SetConfigRequest { | ||
|
Check warning on line 341 in client/cmd/up.go
|
||
| var req proto.SetConfigRequest | ||
| req.ProfileName = profileName | ||
| req.Username = username | ||
|
|
@@ -439,10 +439,23 @@ | |
| req.LazyConnectionEnabled = &lazyConnEnabled | ||
| } | ||
|
|
||
| if cmd.Flag(connectionModeFlag).Changed { | ||
| req.ConnectionMode = &connectionMode | ||
| } | ||
| if cmd.Flag(relayTimeoutFlag).Changed { | ||
| req.RelayTimeoutSeconds = &relayTimeoutSecs | ||
| } | ||
| if cmd.Flag(p2pTimeoutFlag).Changed { | ||
| req.P2PTimeoutSeconds = &p2pTimeoutSecs | ||
| } | ||
| if cmd.Flag(p2pRetryMaxFlag).Changed { | ||
| req.P2PRetryMaxSeconds = &p2pRetryMaxSecs | ||
| } | ||
|
Comment on lines
+442
to
+453
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. New connection-mode flags are silently dropped in daemon mode.
The same applies to The fix is to extract and apply these fields inside 🐛 Proposed fix in server.go `SetConfig` if msg.Mtu != nil {
mtu := uint16(*msg.Mtu)
config.MTU = &mtu
}
+
+ if msg.ConnectionMode != nil {
+ config.ConnectionMode = *msg.ConnectionMode
+ }
+ if msg.RelayTimeoutSeconds != nil {
+ config.RelayTimeoutSeconds = *msg.RelayTimeoutSeconds
+ }
+ if msg.P2PTimeoutSeconds != nil {
+ config.P2pTimeoutSeconds = *msg.P2PTimeoutSeconds
+ }
+ if msg.P2PRetryMaxSeconds != nil {
+ config.P2pRetryMaxSeconds = *msg.P2PRetryMaxSeconds
+ }
if _, err := profilemanager.UpdateConfig(config); err != nil {
🤖 Prompt for AI Agents |
||
|
|
||
| return &req | ||
| } | ||
|
|
||
| func setupConfig(customDNSAddressConverted []byte, cmd *cobra.Command, configFilePath string) (*profilemanager.ConfigInput, error) { | ||
|
Check warning on line 458 in client/cmd/up.go
|
||
| ic := profilemanager.ConfigInput{ | ||
| ManagementURL: managementURL, | ||
| ConfigPath: configFilePath, | ||
|
|
@@ -555,10 +568,23 @@ | |
| if cmd.Flag(enableLazyConnectionFlag).Changed { | ||
| ic.LazyConnectionEnabled = &lazyConnEnabled | ||
| } | ||
|
|
||
| if cmd.Flag(connectionModeFlag).Changed { | ||
| ic.ConnectionMode = &connectionMode | ||
| } | ||
| if cmd.Flag(relayTimeoutFlag).Changed { | ||
| ic.RelayTimeoutSeconds = &relayTimeoutSecs | ||
| } | ||
| if cmd.Flag(p2pTimeoutFlag).Changed { | ||
| ic.P2pTimeoutSeconds = &p2pTimeoutSecs | ||
| } | ||
| if cmd.Flag(p2pRetryMaxFlag).Changed { | ||
| ic.P2pRetryMaxSeconds = &p2pRetryMaxSecs | ||
| } | ||
| return &ic, nil | ||
| } | ||
|
|
||
| func setupLoginRequest(providedSetupKey string, customDNSAddressConverted []byte, cmd *cobra.Command) (*proto.LoginRequest, error) { | ||
|
Check warning on line 587 in client/cmd/up.go
|
||
| loginRequest := proto.LoginRequest{ | ||
| SetupKey: providedSetupKey, | ||
| ManagementUrl: managementURL, | ||
|
|
@@ -669,6 +695,19 @@ | |
| if cmd.Flag(enableLazyConnectionFlag).Changed { | ||
| loginRequest.LazyConnectionEnabled = &lazyConnEnabled | ||
| } | ||
|
|
||
| if cmd.Flag(connectionModeFlag).Changed { | ||
| loginRequest.ConnectionMode = &connectionMode | ||
| } | ||
| if cmd.Flag(relayTimeoutFlag).Changed { | ||
| loginRequest.RelayTimeoutSeconds = &relayTimeoutSecs | ||
| } | ||
| if cmd.Flag(p2pTimeoutFlag).Changed { | ||
| loginRequest.P2PTimeoutSeconds = &p2pTimeoutSecs | ||
| } | ||
| if cmd.Flag(p2pRetryMaxFlag).Changed { | ||
| loginRequest.P2PRetryMaxSeconds = &p2pRetryMaxSecs | ||
| } | ||
| return &loginRequest, nil | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard negative timeout inputs before casting to
uint32.These setters currently turn negative Android values into huge positive timeouts (
-1becomes4294967295), which silently corrupts the persisted override instead of clearing/rejecting it. Clamp or reject< 0before the cast for all three setters.🛠️ Suggested fix
func (p *Preferences) SetRelayTimeoutSeconds(secs int64) { + if secs < 0 { + secs = 0 + } v := uint32(secs) p.configInput.RelayTimeoutSeconds = &v } @@ func (p *Preferences) SetP2pTimeoutSeconds(secs int64) { + if secs < 0 { + secs = 0 + } v := uint32(secs) p.configInput.P2pTimeoutSeconds = &v } @@ func (p *Preferences) SetP2pRetryMaxSeconds(secs int64) { + if secs < 0 { + secs = 0 + } v := uint32(secs) p.configInput.P2pRetryMaxSeconds = &v }Also applies to: 368-373, 388-393
🤖 Prompt for AI Agents