mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-22 19:08:58 +00:00
3c476542d2
There was a bug that the unique ID was not set when reporting was enabled, and thus the reports where rejected by the server. The unique ID got set only on startup, so next time Syncthing restarted. This makes sure to set the unique ID when blank.
218 lines
7.0 KiB
Go
218 lines
7.0 KiB
Go
// 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,
|
|
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
|
|
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"runtime"
|
|
|
|
"github.com/syncthing/syncthing/lib/protocol"
|
|
"github.com/syncthing/syncthing/lib/rand"
|
|
"github.com/syncthing/syncthing/lib/stringutil"
|
|
"github.com/syncthing/syncthing/lib/structutil"
|
|
)
|
|
|
|
func (opts OptionsConfiguration) Copy() OptionsConfiguration {
|
|
optsCopy := opts
|
|
optsCopy.RawListenAddresses = make([]string, len(opts.RawListenAddresses))
|
|
copy(optsCopy.RawListenAddresses, opts.RawListenAddresses)
|
|
optsCopy.RawGlobalAnnServers = make([]string, len(opts.RawGlobalAnnServers))
|
|
copy(optsCopy.RawGlobalAnnServers, opts.RawGlobalAnnServers)
|
|
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
|
|
}
|
|
|
|
func (opts *OptionsConfiguration) prepare(guiPWIsSet bool) {
|
|
structutil.FillNilSlices(opts)
|
|
|
|
opts.RawListenAddresses = stringutil.UniqueTrimmedStrings(opts.RawListenAddresses)
|
|
opts.RawGlobalAnnServers = stringutil.UniqueTrimmedStrings(opts.RawGlobalAnnServers)
|
|
|
|
// Very short reconnection intervals are annoying
|
|
if opts.ReconnectIntervalS < 5 {
|
|
opts.ReconnectIntervalS = 5
|
|
}
|
|
|
|
if guiPWIsSet && len(opts.UnackedNotificationIDs) > 0 {
|
|
for i, key := range opts.UnackedNotificationIDs {
|
|
if key == "authenticationUserAndPassword" {
|
|
opts.UnackedNotificationIDs = append(opts.UnackedNotificationIDs[:i], opts.UnackedNotificationIDs[i+1:]...)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// Negative limits are meaningless, zero means unlimited.
|
|
if opts.ConnectionLimitEnough < 0 {
|
|
opts.ConnectionLimitEnough = 0
|
|
}
|
|
if opts.ConnectionLimitMax < 0 {
|
|
opts.ConnectionLimitMax = 0
|
|
}
|
|
|
|
if opts.ConnectionPriorityQUICWAN <= opts.ConnectionPriorityQUICLAN {
|
|
l.Warnln("Connection priority number for QUIC over WAN must be worse (higher) than QUIC over LAN. Correcting.")
|
|
opts.ConnectionPriorityQUICWAN = opts.ConnectionPriorityQUICLAN + 1
|
|
}
|
|
if opts.ConnectionPriorityTCPWAN <= opts.ConnectionPriorityTCPLAN {
|
|
l.Warnln("Connection priority number for TCP over WAN must be worse (higher) than TCP over LAN. Correcting.")
|
|
opts.ConnectionPriorityTCPWAN = opts.ConnectionPriorityTCPLAN + 1
|
|
}
|
|
|
|
// If usage reporting is enabled we must have a unique ID.
|
|
if opts.URAccepted > 0 && opts.URUniqueID == "" {
|
|
opts.URUniqueID = rand.String(8)
|
|
}
|
|
}
|
|
|
|
// RequiresRestartOnly returns a copy with only the attributes that require
|
|
// restart on change.
|
|
func (opts OptionsConfiguration) RequiresRestartOnly() OptionsConfiguration {
|
|
optsCopy := opts
|
|
blank := OptionsConfiguration{}
|
|
copyMatchingTag(&blank, &optsCopy, "restart", func(v string) bool {
|
|
if len(v) > 0 && v != "true" {
|
|
panic(fmt.Sprintf(`unexpected tag value: %s. Expected untagged or "true"`, v))
|
|
}
|
|
return v != "true"
|
|
})
|
|
return optsCopy
|
|
}
|
|
|
|
func (opts OptionsConfiguration) IsStunDisabled() bool {
|
|
return opts.StunKeepaliveMinS < 1 || opts.StunKeepaliveStartS < 1 || !opts.NATEnabled
|
|
}
|
|
|
|
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 stringutil.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 = stringutil.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 stringutil.UniqueTrimmedStrings(servers)
|
|
}
|
|
|
|
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/
|
|
}
|
|
|
|
func (opts OptionsConfiguration) MaxConcurrentIncomingRequestKiB() int {
|
|
// Negative is disabled, which in limiter land is spelled zero
|
|
if opts.RawMaxCIRequestKiB < 0 {
|
|
return 0
|
|
}
|
|
|
|
if opts.RawMaxCIRequestKiB == 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
|
|
}
|
|
|
|
func (opts OptionsConfiguration) AutoUpgradeEnabled() bool {
|
|
return opts.AutoUpgradeIntervalH > 0
|
|
}
|
|
|
|
func (opts OptionsConfiguration) FeatureFlag(name string) bool {
|
|
for _, flag := range opts.FeatureFlags {
|
|
if flag == name {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// LowestConnectionLimit is the lower of ConnectionLimitEnough or
|
|
// ConnectionLimitMax, or whichever of them is actually set if only one of
|
|
// them is set. It's the point where we should stop dialing.
|
|
func (opts OptionsConfiguration) LowestConnectionLimit() int {
|
|
limit := opts.ConnectionLimitEnough
|
|
if limit == 0 || (opts.ConnectionLimitMax != 0 && opts.ConnectionLimitMax < limit) {
|
|
// It doesn't really make sense to set Max lower than Enough but
|
|
// someone might do it while experimenting and it's easy for us to
|
|
// do the right thing.
|
|
limit = opts.ConnectionLimitMax
|
|
}
|
|
return limit
|
|
}
|