2015-10-27 10:37:03 +00:00
// Copyright (C) 2014 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
2017-02-09 06:52:18 +00:00
// You can obtain one at https://mozilla.org/MPL/2.0/.
2015-10-27 10:37:03 +00:00
package config
2017-02-06 10:27:11 +00:00
import (
"fmt"
2020-01-27 16:31:17 +00:00
"runtime"
2017-12-07 08:33:32 +00:00
2020-02-01 07:02:18 +00:00
"github.com/syncthing/syncthing/lib/protocol"
2019-11-26 16:07:25 +00:00
"github.com/syncthing/syncthing/lib/rand"
2017-12-07 08:33:32 +00:00
"github.com/syncthing/syncthing/lib/util"
2017-02-06 10:27:11 +00:00
)
2015-10-27 10:37:03 +00:00
type OptionsConfiguration struct {
2019-11-26 16:07:25 +00:00
RawListenAddresses [ ] string ` xml:"listenAddress" json:"listenAddresses" default:"default" `
2020-08-18 07:26:33 +00:00
RawGlobalAnnServers [ ] string ` xml:"globalAnnounceServer" json:"globalAnnounceServers" default:"default" `
GlobalAnnEnabled bool ` xml:"globalAnnounceEnabled" json:"globalAnnounceEnabled" default:"true" `
LocalAnnEnabled bool ` xml:"localAnnounceEnabled" json:"localAnnounceEnabled" default:"true" `
LocalAnnPort int ` xml:"localAnnouncePort" json:"localAnnouncePort" default:"21027" `
LocalAnnMCAddr string ` xml:"localAnnounceMCAddr" json:"localAnnounceMCAddr" default:"[ff12::8384]:21027" `
2018-05-05 08:24:44 +00:00
MaxSendKbps int ` xml:"maxSendKbps" json:"maxSendKbps" `
MaxRecvKbps int ` xml:"maxRecvKbps" json:"maxRecvKbps" `
ReconnectIntervalS int ` xml:"reconnectionIntervalS" json:"reconnectionIntervalS" default:"60" `
RelaysEnabled bool ` xml:"relaysEnabled" json:"relaysEnabled" default:"true" `
RelayReconnectIntervalM int ` xml:"relayReconnectIntervalM" json:"relayReconnectIntervalM" default:"10" `
StartBrowser bool ` xml:"startBrowser" json:"startBrowser" default:"true" `
NATEnabled bool ` xml:"natEnabled" json:"natEnabled" default:"true" `
NATLeaseM int ` xml:"natLeaseMinutes" json:"natLeaseMinutes" default:"60" `
NATRenewalM int ` xml:"natRenewalMinutes" json:"natRenewalMinutes" default:"30" `
NATTimeoutS int ` xml:"natTimeoutSeconds" json:"natTimeoutSeconds" default:"10" `
2019-06-11 06:19:11 +00:00
URAccepted int ` xml:"urAccepted" json:"urAccepted" ` // Accepted usage reporting version; 0 for off (undecided), -1 for off (permanently)
URSeen int ` xml:"urSeen" json:"urSeen" ` // Report which the user has been prompted for.
URUniqueID string ` xml:"urUniqueID" json:"urUniqueId" ` // Unique ID for reporting purposes, regenerated when UR is turned on.
URURL string ` xml:"urURL" json:"urURL" default:"https://data.syncthing.net/newdata" ` // usage reporting URL
URPostInsecurely bool ` xml:"urPostInsecurely" json:"urPostInsecurely" default:"false" ` // For testing
2018-05-05 08:24:44 +00:00
URInitialDelayS int ` xml:"urInitialDelayS" json:"urInitialDelayS" default:"1800" `
2020-08-18 07:26:33 +00:00
RestartOnWakeup bool ` xml:"restartOnWakeup" json:"restartOnWakeup" default:"true" `
AutoUpgradeIntervalH int ` xml:"autoUpgradeIntervalH" json:"autoUpgradeIntervalH" default:"12" ` // 0 for off
UpgradeToPreReleases bool ` xml:"upgradeToPreReleases" json:"upgradeToPreReleases" ` // when auto upgrades are enabled
KeepTemporariesH int ` xml:"keepTemporariesH" json:"keepTemporariesH" default:"24" ` // 0 for off
CacheIgnoredFiles bool ` xml:"cacheIgnoredFiles" json:"cacheIgnoredFiles" default:"false" `
2018-05-05 08:24:44 +00:00
ProgressUpdateIntervalS int ` xml:"progressUpdateIntervalS" json:"progressUpdateIntervalS" default:"5" `
LimitBandwidthInLan bool ` xml:"limitBandwidthInLan" json:"limitBandwidthInLan" default:"false" `
MinHomeDiskFree Size ` xml:"minHomeDiskFree" json:"minHomeDiskFree" default:"1 %" `
2020-08-18 07:26:33 +00:00
ReleasesURL string ` xml:"releasesURL" json:"releasesURL" default:"https://upgrades.syncthing.net/meta.json" `
2018-05-05 08:24:44 +00:00
AlwaysLocalNets [ ] string ` xml:"alwaysLocalNet" json:"alwaysLocalNets" `
OverwriteRemoteDevNames bool ` xml:"overwriteRemoteDeviceNamesOnConnect" json:"overwriteRemoteDeviceNamesOnConnect" default:"false" `
TempIndexMinBlocks int ` xml:"tempIndexMinBlocks" json:"tempIndexMinBlocks" default:"10" `
UnackedNotificationIDs [ ] string ` xml:"unackedNotificationID" json:"unackedNotificationIDs" `
TrafficClass int ` xml:"trafficClass" json:"trafficClass" `
DefaultFolderPath string ` xml:"defaultFolderPath" json:"defaultFolderPath" default:"~" `
SetLowPriority bool ` xml:"setLowPriority" json:"setLowPriority" default:"true" `
2020-01-27 16:31:17 +00:00
RawMaxFolderConcurrency int ` xml:"maxFolderConcurrency" json:"maxFolderConcurrency" `
2019-06-11 06:19:11 +00:00
CRURL string ` xml:"crashReportingURL" json:"crURL" default:"https://crash.syncthing.net/newcrash" ` // crash reporting URL
2020-08-18 07:26:33 +00:00
CREnabled bool ` xml:"crashReportingEnabled" json:"crashReportingEnabled" default:"true" ` // Read in the monitor, but it's read before every attempt to report stuff, so does not require a restart.
StunKeepaliveStartS int ` xml:"stunKeepaliveStartS" json:"stunKeepaliveStartS" default:"180" ` // 0 for off
StunKeepaliveMinS int ` xml:"stunKeepaliveMinS" json:"stunKeepaliveMinS" default:"20" ` // 0 for off
2019-11-26 16:07:25 +00:00
RawStunServers [ ] string ` xml:"stunServer" json:"stunServers" default:"default" `
2020-08-18 07:26:33 +00:00
DatabaseTuning Tuning ` xml:"databaseTuning" json:"databaseTuning" restart:"true" ` // Can't be adjusted once the database has been opened
2020-02-01 07:02:18 +00:00
RawMaxCIRequestKiB int ` xml:"maxConcurrentIncomingRequestKiB" json:"maxConcurrentIncomingRequestKiB" `
2016-04-10 19:36:38 +00:00
2017-04-12 09:01:19 +00:00
DeprecatedUPnPEnabled bool ` xml:"upnpEnabled,omitempty" json:"-" `
DeprecatedUPnPLeaseM int ` xml:"upnpLeaseMinutes,omitempty" json:"-" `
DeprecatedUPnPRenewalM int ` xml:"upnpRenewalMinutes,omitempty" json:"-" `
DeprecatedUPnPTimeoutS int ` xml:"upnpTimeoutSeconds,omitempty" json:"-" `
DeprecatedRelayServers [ ] string ` xml:"relayServer,omitempty" json:"-" `
2019-01-28 10:46:28 +00:00
DeprecatedMinHomeDiskFreePct float64 ` xml:"minHomeDiskFreePct,omitempty" json:"-" `
2020-01-27 16:31:17 +00:00
DeprecatedMaxConcurrentScans int ` xml:"maxConcurrentScans,omitempty" json:"-" `
2015-10-27 10:37:03 +00:00
}
2019-05-29 07:56:40 +00:00
func ( opts OptionsConfiguration ) Copy ( ) OptionsConfiguration {
optsCopy := opts
2019-11-26 16:07:25 +00:00
optsCopy . RawListenAddresses = make ( [ ] string , len ( opts . RawListenAddresses ) )
copy ( optsCopy . RawListenAddresses , opts . RawListenAddresses )
optsCopy . RawGlobalAnnServers = make ( [ ] string , len ( opts . RawGlobalAnnServers ) )
copy ( optsCopy . RawGlobalAnnServers , opts . RawGlobalAnnServers )
2019-05-29 07:56:40 +00:00
optsCopy . AlwaysLocalNets = make ( [ ] string , len ( opts . AlwaysLocalNets ) )
copy ( optsCopy . AlwaysLocalNets , opts . AlwaysLocalNets )
optsCopy . UnackedNotificationIDs = make ( [ ] string , len ( opts . UnackedNotificationIDs ) )
copy ( optsCopy . UnackedNotificationIDs , opts . UnackedNotificationIDs )
return optsCopy
2015-10-27 10:37:03 +00:00
}
2017-12-07 08:33:32 +00:00
// RequiresRestartOnly returns a copy with only the attributes that require
// restart on change.
2019-05-29 07:56:40 +00:00
func ( opts OptionsConfiguration ) RequiresRestartOnly ( ) OptionsConfiguration {
optsCopy := opts
2017-12-07 08:33:32 +00:00
blank := OptionsConfiguration { }
2019-05-29 07:56:40 +00:00
util . CopyMatchingTag ( & blank , & optsCopy , "restart" , func ( v string ) bool {
2017-12-07 08:33:32 +00:00
if len ( v ) > 0 && v != "true" {
2019-05-29 07:56:40 +00:00
panic ( fmt . Sprintf ( ` unexpected tag value: %s. Expected untagged or "true" ` , v ) )
2017-12-07 08:33:32 +00:00
}
return v != "true"
} )
2019-05-29 07:56:40 +00:00
return optsCopy
}
func ( opts OptionsConfiguration ) IsStunDisabled ( ) bool {
return opts . StunKeepaliveMinS < 1 || opts . StunKeepaliveStartS < 1 || ! opts . NATEnabled
2017-12-07 08:33:32 +00:00
}
2019-11-26 16:07:25 +00:00
func ( opts OptionsConfiguration ) ListenAddresses ( ) [ ] string {
var addresses [ ] string
for _ , addr := range opts . RawListenAddresses {
switch addr {
case "default" :
addresses = append ( addresses , DefaultListenAddresses ... )
default :
addresses = append ( addresses , addr )
}
}
return util . UniqueTrimmedStrings ( addresses )
}
func ( opts OptionsConfiguration ) StunServers ( ) [ ] string {
var addresses [ ] string
for _ , addr := range opts . RawStunServers {
switch addr {
case "default" :
defaultPrimaryAddresses := make ( [ ] string , len ( DefaultPrimaryStunServers ) )
copy ( defaultPrimaryAddresses , DefaultPrimaryStunServers )
rand . Shuffle ( defaultPrimaryAddresses )
addresses = append ( addresses , defaultPrimaryAddresses ... )
defaultSecondaryAddresses := make ( [ ] string , len ( DefaultSecondaryStunServers ) )
copy ( defaultSecondaryAddresses , DefaultSecondaryStunServers )
rand . Shuffle ( defaultSecondaryAddresses )
addresses = append ( addresses , defaultSecondaryAddresses ... )
default :
addresses = append ( addresses , addr )
}
}
addresses = util . UniqueTrimmedStrings ( addresses )
return addresses
}
func ( opts OptionsConfiguration ) GlobalDiscoveryServers ( ) [ ] string {
var servers [ ] string
for _ , srv := range opts . RawGlobalAnnServers {
switch srv {
case "default" :
servers = append ( servers , DefaultDiscoveryServers ... )
case "default-v4" :
servers = append ( servers , DefaultDiscoveryServersV4 ... )
case "default-v6" :
servers = append ( servers , DefaultDiscoveryServersV6 ... )
default :
servers = append ( servers , srv )
}
}
return util . UniqueTrimmedStrings ( servers )
}
2020-01-27 16:31:17 +00:00
func ( opts OptionsConfiguration ) MaxFolderConcurrency ( ) int {
// If a value is set, trust that.
if opts . RawMaxFolderConcurrency > 0 {
return opts . RawMaxFolderConcurrency
}
if opts . RawMaxFolderConcurrency < 0 {
// -1 etc means unlimited, which in the implementation means zero
return 0
}
// Otherwise default to the number of CPU cores in the system as a rough
// approximation of system powerfullness.
if n := runtime . GOMAXPROCS ( - 1 ) ; n > 0 {
return n
}
// We should never get here to begin with, but since we're here let's
// use some sort of reasonable compromise between the old "no limit" and
// getting nothing done... (Median number of folders out there at time
// of writing is two, 95-percentile at 12 folders.)
return 4 // https://xkcd.com/221/
}
2020-02-01 07:02:18 +00:00
func ( opts OptionsConfiguration ) MaxConcurrentIncomingRequestKiB ( ) int {
// Negative is disabled, which in limiter land is spelled zero
if opts . RawMaxCIRequestKiB < 0 {
return 0
}
if opts . RawMaxFolderConcurrency == 0 {
// The default is 256 MiB
return 256 * 1024 // KiB
}
// We can't really do less than a couple of concurrent blocks or we'll
// pretty much stall completely. Check that an explicit value is large
// enough.
const minAllowed = 2 * protocol . MaxBlockSize / 1024
if opts . RawMaxCIRequestKiB < minAllowed {
return minAllowed
}
// Roll with it.
return opts . RawMaxCIRequestKiB
}
2020-06-02 09:38:39 +00:00
2020-08-18 07:26:33 +00:00
func ( opts OptionsConfiguration ) AutoUpgradeEnabled ( ) bool {
2020-06-02 09:38:39 +00:00
return opts . AutoUpgradeIntervalH > 0
}