Repository: syncthing/syncthing (language: go)

Issue:
gui: Address override not respected in fresh default config
### What happened?

When generating a new `config.xml` file with default options, the GUI address is populated with a hard-coded default value of `127.0.0.1:8384`, except for a random free port if that default one is occupied.  This ignores any `STGUIADDRESS` override given via environment variable or command-line option, thus probing for the default port instead of the one specified via override.

When not probing for free ports (`--skip-port-probing`), the override should still be persisted rather than the default address.  Only when generating a fresh default `config.xml`, never on an existing one.

### Syncthing version

1.28.0

### Platform & operating system

Linux amd64

### Browser version

_No response_

### Relevant log output

_No response_


Discussion / hints:

Fix patch:
diff --git a/lib/config/config.go b/lib/config/config.go
index 550a485f3c6..44f8a3f95f4 100644
--- a/lib/config/config.go
+++ b/lib/config/config.go
@@ -49,7 +49,6 @@ var (
 		"dynamic+https://relays.syncthing.net/endpoint",
 		netutil.AddressURL("quic", net.JoinHostPort("0.0.0.0", strconv.Itoa(DefaultQUICPort))),
 	}
-	DefaultGUIPort = 8384
 	// DefaultDiscoveryServersV4 should be substituted when the configuration
 	// contains <globalAnnounceServer>default-v4</globalAnnounceServer>.
 	DefaultDiscoveryServersV4 = []string{
@@ -116,11 +115,19 @@ func New(myID protocol.DeviceID) Configuration {
 }
 
 func (cfg *Configuration) ProbeFreePorts() error {
-	port, err := getFreePort("127.0.0.1", DefaultGUIPort)
+	guiHost, guiPort, err := net.SplitHostPort(cfg.GUI.Address())
+	if err != nil {
+		return fmt.Errorf("get default port (GUI): %w", err)
+	}
+	port, err := strconv.Atoi(guiPort)
+	if err != nil {
+		return fmt.Errorf("convert default port (GUI): %w", err)
+	}
+	port, err = getFreePort(guiHost, port)
 	if err != nil {
 		return fmt.Errorf("get free port (GUI): %w", err)
 	}
-	cfg.GUI.RawAddress = fmt.Sprintf("127.0.0.1:%d", port)
+	cfg.GUI.RawAddress = net.JoinHostPort(guiHost, strconv.Itoa(port))
 
 	port, err = getFreePort("0.0.0.0", DefaultTCPPort)
 	if err != nil {
diff --git a/lib/syncthing/utils.go b/lib/syncthing/utils.go
index 4971da05072..15195c33444 100644
--- a/lib/syncthing/utils.go
+++ b/lib/syncthing/utils.go
@@ -63,6 +63,8 @@ func DefaultConfig(path string, myID protocol.DeviceID, evLogger events.Logger,
 
 	if skipPortProbing {
 		l.Infoln("Using default network port numbers instead of probing for free ports")
+		// Record address override initially
+		newCfg.GUI.RawAddress = newCfg.GUI.Address()
 	} else if err := newCfg.ProbeFreePorts(); err != nil {
 		return nil, err
 	}


Test patch: