mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-09 14:50:56 +00:00
lib/connections: Un-deprecate relaysEnabled (fixes #3074)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3098
This commit is contained in:
parent
adb7fb43cb
commit
2c1323ece6
@ -56,11 +56,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="row">
|
||||||
<div class="checkbox">
|
<div class="col-md-6">
|
||||||
<label>
|
<div class="form-group">
|
||||||
<input id="GlobalAnnEnabled" type="checkbox" ng-model="tmpOptions.globalAnnounceEnabled"> <span translate>Global Discovery</span>
|
<div class="checkbox">
|
||||||
</label>
|
<label>
|
||||||
|
<input id="GlobalAnnEnabled" type="checkbox" ng-model="tmpOptions.globalAnnounceEnabled"> <span translate>Global Discovery</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input id="RelaysEnabled" type="checkbox" ng-model="tmpOptions.relaysEnabled"> <span translate>Enable Relaying</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -29,9 +29,9 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// DefaultListenAddresses should be substituted when the configuration
|
// DefaultListenAddresses should be substituted when the configuration
|
||||||
// contains <listenAddress>default</listenAddress>. This is
|
// contains <listenAddress>default</listenAddress>. This is done by the
|
||||||
// done by the "consumer" of the configuration, as we don't want these
|
// "consumer" of the configuration as we don't want these saved to the
|
||||||
// saved to the config.
|
// config.
|
||||||
DefaultListenAddresses = []string{
|
DefaultListenAddresses = []string{
|
||||||
"tcp://0.0.0.0:22000",
|
"tcp://0.0.0.0:22000",
|
||||||
"dynamic+https://relays.syncthing.net/endpoint",
|
"dynamic+https://relays.syncthing.net/endpoint",
|
||||||
@ -258,27 +258,53 @@ func convertV13V14(cfg *Configuration) {
|
|||||||
// Not using the ignore cache is the new default. Disable it on existing
|
// Not using the ignore cache is the new default. Disable it on existing
|
||||||
// configurations.
|
// configurations.
|
||||||
cfg.Options.CacheIgnoredFiles = false
|
cfg.Options.CacheIgnoredFiles = false
|
||||||
cfg.Options.NATEnabled = cfg.Options.DeprecatedUPnPEnabled
|
|
||||||
cfg.Options.NATLeaseM = cfg.Options.DeprecatedUPnPLeaseM
|
|
||||||
cfg.Options.NATRenewalM = cfg.Options.DeprecatedUPnPRenewalM
|
|
||||||
cfg.Options.NATTimeoutS = cfg.Options.DeprecatedUPnPTimeoutS
|
|
||||||
if cfg.Options.DeprecatedRelaysEnabled {
|
|
||||||
cfg.Options.ListenAddresses = append(cfg.Options.ListenAddresses, cfg.Options.DeprecatedRelayServers...)
|
|
||||||
// Replace our two fairly long addresses with 'default' if both exist.
|
|
||||||
var newAddresses []string
|
|
||||||
for _, addr := range cfg.Options.ListenAddresses {
|
|
||||||
if addr != "tcp://0.0.0.0:22000" && addr != "dynamic+https://relays.syncthing.net/endpoint" {
|
|
||||||
newAddresses = append(newAddresses, addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(newAddresses)+2 == len(cfg.Options.ListenAddresses) {
|
// Migrate UPnP -> NAT options
|
||||||
cfg.Options.ListenAddresses = append([]string{"default"}, newAddresses...)
|
cfg.Options.NATEnabled = cfg.Options.DeprecatedUPnPEnabled
|
||||||
|
cfg.Options.DeprecatedUPnPEnabled = false
|
||||||
|
cfg.Options.NATLeaseM = cfg.Options.DeprecatedUPnPLeaseM
|
||||||
|
cfg.Options.DeprecatedUPnPLeaseM = 0
|
||||||
|
cfg.Options.NATRenewalM = cfg.Options.DeprecatedUPnPRenewalM
|
||||||
|
cfg.Options.DeprecatedUPnPRenewalM = 0
|
||||||
|
cfg.Options.NATTimeoutS = cfg.Options.DeprecatedUPnPTimeoutS
|
||||||
|
cfg.Options.DeprecatedUPnPTimeoutS = 0
|
||||||
|
|
||||||
|
// Replace the default listen address "tcp://0.0.0.0:22000" with the
|
||||||
|
// string "default", but only if we also have the default relay pool
|
||||||
|
// among the relay servers as this is implied by the new "default"
|
||||||
|
// entry.
|
||||||
|
hasDefault := false
|
||||||
|
for _, raddr := range cfg.Options.DeprecatedRelayServers {
|
||||||
|
if raddr == "dynamic+https://relays.syncthing.net/endpoint" {
|
||||||
|
for i, addr := range cfg.Options.ListenAddresses {
|
||||||
|
if addr == "tcp://0.0.0.0:22000" {
|
||||||
|
cfg.Options.ListenAddresses[i] = "default"
|
||||||
|
hasDefault = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cfg.Options.DeprecatedRelaysEnabled = false
|
|
||||||
|
// Copy relay addresses into listen addresses.
|
||||||
|
for _, addr := range cfg.Options.DeprecatedRelayServers {
|
||||||
|
if hasDefault && addr == "dynamic+https://relays.syncthing.net/endpoint" {
|
||||||
|
// Skip the default relay address if we already have the
|
||||||
|
// "default" entry in the list.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if addr == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
cfg.Options.ListenAddresses = append(cfg.Options.ListenAddresses, addr)
|
||||||
|
}
|
||||||
|
|
||||||
cfg.Options.DeprecatedRelayServers = nil
|
cfg.Options.DeprecatedRelayServers = nil
|
||||||
|
|
||||||
|
// For consistency
|
||||||
|
sort.Strings(cfg.Options.ListenAddresses)
|
||||||
|
|
||||||
var newAddrs []string
|
var newAddrs []string
|
||||||
for _, addr := range cfg.Options.GlobalAnnServers {
|
for _, addr := range cfg.Options.GlobalAnnServers {
|
||||||
if addr != "default" {
|
if addr != "default" {
|
||||||
|
@ -12,7 +12,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -40,6 +42,7 @@ func TestDefaultValues(t *testing.T) {
|
|||||||
MaxSendKbps: 0,
|
MaxSendKbps: 0,
|
||||||
MaxRecvKbps: 0,
|
MaxRecvKbps: 0,
|
||||||
ReconnectIntervalS: 60,
|
ReconnectIntervalS: 60,
|
||||||
|
RelaysEnabled: true,
|
||||||
RelayReconnectIntervalM: 10,
|
RelayReconnectIntervalM: 10,
|
||||||
StartBrowser: true,
|
StartBrowser: true,
|
||||||
NATEnabled: true,
|
NATEnabled: true,
|
||||||
@ -169,6 +172,7 @@ func TestOverriddenValues(t *testing.T) {
|
|||||||
MaxSendKbps: 1234,
|
MaxSendKbps: 1234,
|
||||||
MaxRecvKbps: 2341,
|
MaxRecvKbps: 2341,
|
||||||
ReconnectIntervalS: 6000,
|
ReconnectIntervalS: 6000,
|
||||||
|
RelaysEnabled: false,
|
||||||
RelayReconnectIntervalM: 20,
|
RelayReconnectIntervalM: 20,
|
||||||
StartBrowser: false,
|
StartBrowser: false,
|
||||||
NATEnabled: false,
|
NATEnabled: false,
|
||||||
@ -616,3 +620,61 @@ func TestRemoveDuplicateDevicesFolders(t *testing.T) {
|
|||||||
t.Errorf("Incorrect number of folder devices, %d != 2", l)
|
t.Errorf("Incorrect number of folder devices, %d != 2", l)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestV14ListenAddressesMigration(t *testing.T) {
|
||||||
|
tcs := [][3][]string{
|
||||||
|
|
||||||
|
// Default listen plus default relays is now "default"
|
||||||
|
{
|
||||||
|
{"tcp://0.0.0.0:22000"},
|
||||||
|
{"dynamic+https://relays.syncthing.net/endpoint"},
|
||||||
|
{"default"},
|
||||||
|
},
|
||||||
|
// Default listen address without any relay addresses gets converted
|
||||||
|
// to just the listen address. It's easier this way, and frankly the
|
||||||
|
// user has gone to some trouble to get the empty string in the
|
||||||
|
// config to start with...
|
||||||
|
{
|
||||||
|
{"tcp://0.0.0.0:22000"}, // old listen addrs
|
||||||
|
{""}, // old relay addrs
|
||||||
|
{"tcp://0.0.0.0:22000"}, // new listen addrs
|
||||||
|
},
|
||||||
|
// Default listen plus non-default relays gets copied verbatim
|
||||||
|
{
|
||||||
|
{"tcp://0.0.0.0:22000"},
|
||||||
|
{"dynamic+https://other.example.com"},
|
||||||
|
{"tcp://0.0.0.0:22000", "dynamic+https://other.example.com"},
|
||||||
|
},
|
||||||
|
// Non-default listen plus default relays gets copied verbatim
|
||||||
|
{
|
||||||
|
{"tcp://1.2.3.4:22000"},
|
||||||
|
{"dynamic+https://relays.syncthing.net/endpoint"},
|
||||||
|
{"tcp://1.2.3.4:22000", "dynamic+https://relays.syncthing.net/endpoint"},
|
||||||
|
},
|
||||||
|
// Default stuff gets sucked into "default", the rest gets copied
|
||||||
|
{
|
||||||
|
{"tcp://0.0.0.0:22000", "tcp://1.2.3.4:22000"},
|
||||||
|
{"dynamic+https://relays.syncthing.net/endpoint", "relay://other.example.com"},
|
||||||
|
{"default", "tcp://1.2.3.4:22000", "relay://other.example.com"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tcs {
|
||||||
|
cfg := Configuration{
|
||||||
|
Version: 13,
|
||||||
|
Options: OptionsConfiguration{
|
||||||
|
ListenAddresses: tc[0],
|
||||||
|
DeprecatedRelayServers: tc[1],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
convertV13V14(&cfg)
|
||||||
|
if cfg.Version != 14 {
|
||||||
|
t.Error("Configuration was not converted")
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(tc[2])
|
||||||
|
if !reflect.DeepEqual(cfg.Options.ListenAddresses, tc[2]) {
|
||||||
|
t.Errorf("Migration error; actual %#v != expected %#v", cfg.Options.ListenAddresses, tc[2])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -16,6 +16,7 @@ type OptionsConfiguration struct {
|
|||||||
MaxSendKbps int `xml:"maxSendKbps" json:"maxSendKbps"`
|
MaxSendKbps int `xml:"maxSendKbps" json:"maxSendKbps"`
|
||||||
MaxRecvKbps int `xml:"maxRecvKbps" json:"maxRecvKbps"`
|
MaxRecvKbps int `xml:"maxRecvKbps" json:"maxRecvKbps"`
|
||||||
ReconnectIntervalS int `xml:"reconnectionIntervalS" json:"reconnectionIntervalS" default:"60"`
|
ReconnectIntervalS int `xml:"reconnectionIntervalS" json:"reconnectionIntervalS" default:"60"`
|
||||||
|
RelaysEnabled bool `xml:"relaysEnabled" json:"relaysEnabled" default:"true"`
|
||||||
RelayReconnectIntervalM int `xml:"relayReconnectIntervalM" json:"relayReconnectIntervalM" default:"10"`
|
RelayReconnectIntervalM int `xml:"relayReconnectIntervalM" json:"relayReconnectIntervalM" default:"10"`
|
||||||
StartBrowser bool `xml:"startBrowser" json:"startBrowser" default:"true"`
|
StartBrowser bool `xml:"startBrowser" json:"startBrowser" default:"true"`
|
||||||
NATEnabled bool `xml:"natEnabled" json:"natEnabled" default:"true"`
|
NATEnabled bool `xml:"natEnabled" json:"natEnabled" default:"true"`
|
||||||
@ -40,12 +41,11 @@ type OptionsConfiguration struct {
|
|||||||
OverwriteRemoteDevNames bool `xml:"overwriteRemoteDeviceNamesOnConnect" json:"overwriteRemoteDeviceNamesOnConnect" default:"false"`
|
OverwriteRemoteDevNames bool `xml:"overwriteRemoteDeviceNamesOnConnect" json:"overwriteRemoteDeviceNamesOnConnect" default:"false"`
|
||||||
TempIndexMinBlocks int `xml:"tempIndexMinBlocks" json:"tempIndexMinBlocks" default:"10"`
|
TempIndexMinBlocks int `xml:"tempIndexMinBlocks" json:"tempIndexMinBlocks" default:"10"`
|
||||||
|
|
||||||
DeprecatedUPnPEnabled bool `xml:"upnpEnabled" json:"-"`
|
DeprecatedUPnPEnabled bool `xml:"upnpEnabled,omitempty" json:"-"`
|
||||||
DeprecatedUPnPLeaseM int `xml:"upnpLeaseMinutes" json:"-"`
|
DeprecatedUPnPLeaseM int `xml:"upnpLeaseMinutes,omitempty" json:"-"`
|
||||||
DeprecatedUPnPRenewalM int `xml:"upnpRenewalMinutes" json:"-"`
|
DeprecatedUPnPRenewalM int `xml:"upnpRenewalMinutes,omitempty" json:"-"`
|
||||||
DeprecatedUPnPTimeoutS int `xml:"upnpTimeoutSeconds" json:"-"`
|
DeprecatedUPnPTimeoutS int `xml:"upnpTimeoutSeconds,omitempty" json:"-"`
|
||||||
DeprecatedRelaysEnabled bool `xml:"relaysEnabled" json:"-"`
|
DeprecatedRelayServers []string `xml:"relayServer,omitempty" json:"-"`
|
||||||
DeprecatedRelayServers []string `xml:"relayServer" json:"-"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (orig OptionsConfiguration) Copy() OptionsConfiguration {
|
func (orig OptionsConfiguration) Copy() OptionsConfiguration {
|
||||||
|
@ -70,10 +70,6 @@ func (d *relayDialer) RedialFrequency() time.Duration {
|
|||||||
return time.Duration(d.cfg.Options().RelayReconnectIntervalM) * time.Minute
|
return time.Duration(d.cfg.Options().RelayReconnectIntervalM) * time.Minute
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *relayDialer) String() string {
|
|
||||||
return "Relay Dialer"
|
|
||||||
}
|
|
||||||
|
|
||||||
type relayDialerFactory struct{}
|
type relayDialerFactory struct{}
|
||||||
|
|
||||||
func (relayDialerFactory) New(cfg *config.Wrapper, tlsCfg *tls.Config) genericDialer {
|
func (relayDialerFactory) New(cfg *config.Wrapper, tlsCfg *tls.Config) genericDialer {
|
||||||
@ -86,3 +82,11 @@ func (relayDialerFactory) New(cfg *config.Wrapper, tlsCfg *tls.Config) genericDi
|
|||||||
func (relayDialerFactory) Priority() int {
|
func (relayDialerFactory) Priority() int {
|
||||||
return relayPriority
|
return relayPriority
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (relayDialerFactory) Enabled(cfg config.Configuration) bool {
|
||||||
|
return cfg.Options.RelaysEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
func (relayDialerFactory) String() string {
|
||||||
|
return "Relay Dialer"
|
||||||
|
}
|
||||||
|
@ -13,23 +13,26 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/syncthing/syncthing/lib/config"
|
||||||
"github.com/syncthing/syncthing/lib/dialer"
|
"github.com/syncthing/syncthing/lib/dialer"
|
||||||
"github.com/syncthing/syncthing/lib/nat"
|
"github.com/syncthing/syncthing/lib/nat"
|
||||||
"github.com/syncthing/syncthing/lib/relay/client"
|
"github.com/syncthing/syncthing/lib/relay/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
listeners["relay"] = newRelayListener
|
factory := &relayListenerFactory{}
|
||||||
listeners["dynamic+http"] = newRelayListener
|
listeners["relay"] = factory
|
||||||
listeners["dynamic+https"] = newRelayListener
|
listeners["dynamic+http"] = factory
|
||||||
|
listeners["dynamic+https"] = factory
|
||||||
}
|
}
|
||||||
|
|
||||||
type relayListener struct {
|
type relayListener struct {
|
||||||
onAddressesChangedNotifier
|
onAddressesChangedNotifier
|
||||||
|
|
||||||
uri *url.URL
|
uri *url.URL
|
||||||
tlsCfg *tls.Config
|
tlsCfg *tls.Config
|
||||||
conns chan IntermediateConnection
|
conns chan IntermediateConnection
|
||||||
|
factory listenerFactory
|
||||||
|
|
||||||
err error
|
err error
|
||||||
client client.RelayClient
|
client client.RelayClient
|
||||||
@ -154,14 +157,25 @@ func (t *relayListener) Error() error {
|
|||||||
return cerr
|
return cerr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *relayListener) Factory() listenerFactory {
|
||||||
|
return t.factory
|
||||||
|
}
|
||||||
|
|
||||||
func (t *relayListener) String() string {
|
func (t *relayListener) String() string {
|
||||||
return t.uri.String()
|
return t.uri.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRelayListener(uri *url.URL, tlsCfg *tls.Config, conns chan IntermediateConnection, natService *nat.Service) genericListener {
|
type relayListenerFactory struct{}
|
||||||
|
|
||||||
|
func (f *relayListenerFactory) New(uri *url.URL, cfg *config.Wrapper, tlsCfg *tls.Config, conns chan IntermediateConnection, natService *nat.Service) genericListener {
|
||||||
return &relayListener{
|
return &relayListener{
|
||||||
uri: uri,
|
uri: uri,
|
||||||
tlsCfg: tlsCfg,
|
tlsCfg: tlsCfg,
|
||||||
conns: conns,
|
conns: conns,
|
||||||
|
factory: f,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (relayListenerFactory) Enabled(cfg config.Configuration) bool {
|
||||||
|
return cfg.Options.RelaysEnabled
|
||||||
|
}
|
||||||
|
@ -9,6 +9,7 @@ package connections
|
|||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
@ -112,6 +113,10 @@ func NewService(cfg *config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg *
|
|||||||
return service
|
return service
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
errDisabled = errors.New("disabled by configuration")
|
||||||
|
)
|
||||||
|
|
||||||
func (s *Service) handle() {
|
func (s *Service) handle() {
|
||||||
next:
|
next:
|
||||||
for c := range s.conns {
|
for c := range s.conns {
|
||||||
@ -237,24 +242,35 @@ next:
|
|||||||
|
|
||||||
func (s *Service) connect() {
|
func (s *Service) connect() {
|
||||||
nextDial := make(map[string]time.Time)
|
nextDial := make(map[string]time.Time)
|
||||||
delay := time.Second
|
|
||||||
sleep := time.Second
|
|
||||||
|
|
||||||
bestDialerPrio := 1<<31 - 1 // worse prio won't build on 32 bit
|
// Used as delay for the first few connection attempts, increases
|
||||||
for _, df := range dialers {
|
// exponentially
|
||||||
if prio := df.Priority(); prio < bestDialerPrio {
|
initialRampup := time.Second
|
||||||
bestDialerPrio = prio
|
|
||||||
}
|
// Calculated from actual dialers reconnectInterval
|
||||||
}
|
var sleep time.Duration
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
cfg := s.cfg.Raw()
|
||||||
|
|
||||||
|
bestDialerPrio := 1<<31 - 1 // worse prio won't build on 32 bit
|
||||||
|
for _, df := range dialers {
|
||||||
|
if !df.Enabled(cfg) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if prio := df.Priority(); prio < bestDialerPrio {
|
||||||
|
bestDialerPrio = prio
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
l.Debugln("Reconnect loop")
|
l.Debugln("Reconnect loop")
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
var seen []string
|
var seen []string
|
||||||
|
|
||||||
nextDevice:
|
nextDevice:
|
||||||
for deviceID, deviceCfg := range s.cfg.Devices() {
|
for _, deviceCfg := range cfg.Devices {
|
||||||
|
deviceID := deviceCfg.DeviceID
|
||||||
if deviceID == s.myID {
|
if deviceID == s.myID {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -292,35 +308,40 @@ func (s *Service) connect() {
|
|||||||
seen = append(seen, addrs...)
|
seen = append(seen, addrs...)
|
||||||
|
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
|
nextDialAt, ok := nextDial[addr]
|
||||||
|
if ok && initialRampup >= sleep && nextDialAt.After(now) {
|
||||||
|
l.Debugf("Not dialing %v as sleep is %v, next dial is at %s and current time is %s", addr, sleep, nextDialAt, now)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// If we fail at any step before actually getting the dialer
|
||||||
|
// retry in a minute
|
||||||
|
nextDial[addr] = now.Add(time.Minute)
|
||||||
|
|
||||||
uri, err := url.Parse(addr)
|
uri, err := url.Parse(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Infoln("Failed to parse connection url:", addr, err)
|
l.Infof("Dialer for %s: %v", addr, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
dialerFactory, ok := dialers[uri.Scheme]
|
dialerFactory, err := s.getDialerFactory(cfg, uri)
|
||||||
if !ok {
|
if err == errDisabled {
|
||||||
l.Debugln("Unknown address schema", uri)
|
l.Debugln("Dialer for", uri, "is disabled")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
l.Infof("Dialer for %v: %v", uri, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if connected && dialerFactory.Priority() >= ct.Priority {
|
||||||
|
l.Debugf("Not dialing using %s as priorty is less than current connection (%d >= %d)", dialerFactory, dialerFactory.Priority(), ct.Priority)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
dialer := dialerFactory.New(s.cfg, s.tlsCfg)
|
dialer := dialerFactory.New(s.cfg, s.tlsCfg)
|
||||||
|
|
||||||
nextDialAt, ok := nextDial[uri.String()]
|
|
||||||
// See below for comments on this delay >= sleep check
|
|
||||||
if delay >= sleep && ok && nextDialAt.After(now) {
|
|
||||||
l.Debugf("Not dialing as next dial is at %s and current time is %s", nextDialAt, now)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
nextDial[uri.String()] = now.Add(dialer.RedialFrequency())
|
|
||||||
|
|
||||||
if connected && dialer.Priority() >= ct.Priority {
|
|
||||||
l.Debugf("Not dialing using %s as priorty is less than current connection (%d >= %d)", dialer, dialer.Priority(), ct.Priority)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
l.Debugln("dial", deviceCfg.DeviceID, uri)
|
l.Debugln("dial", deviceCfg.DeviceID, uri)
|
||||||
|
nextDial[addr] = now.Add(dialer.RedialFrequency())
|
||||||
|
|
||||||
conn, err := dialer.Dial(deviceID, uri)
|
conn, err := dialer.Dial(deviceID, uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Debugln("dial failed", deviceCfg.DeviceID, uri, err)
|
l.Debugln("dial failed", deviceCfg.DeviceID, uri, err)
|
||||||
@ -338,12 +359,12 @@ func (s *Service) connect() {
|
|||||||
|
|
||||||
nextDial, sleep = filterAndFindSleepDuration(nextDial, seen, now)
|
nextDial, sleep = filterAndFindSleepDuration(nextDial, seen, now)
|
||||||
|
|
||||||
// delay variable is used to trigger much more frequent dialing after
|
if initialRampup < sleep {
|
||||||
// initial startup, essentially causing redials every 1, 2, 4, 8... seconds
|
l.Debugln("initial rampup; sleep", initialRampup, "and update to", initialRampup*2)
|
||||||
if delay < sleep {
|
time.Sleep(initialRampup)
|
||||||
time.Sleep(delay)
|
initialRampup *= 2
|
||||||
delay *= 2
|
|
||||||
} else {
|
} else {
|
||||||
|
l.Debugln("sleep until next dial", sleep)
|
||||||
time.Sleep(sleep)
|
time.Sleep(sleep)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -366,24 +387,16 @@ func (s *Service) shouldLimit(addr net.Addr) bool {
|
|||||||
return !tcpaddr.IP.IsLoopback()
|
return !tcpaddr.IP.IsLoopback()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) createListener(addr string) {
|
func (s *Service) createListener(factory listenerFactory, uri *url.URL) bool {
|
||||||
// must be called with listenerMut held
|
// must be called with listenerMut held
|
||||||
uri, err := url.Parse(addr)
|
|
||||||
if err != nil {
|
|
||||||
l.Infoln("Failed to parse listen address:", addr, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
listenerFactory, ok := listeners[uri.Scheme]
|
l.Debugln("Starting listener", uri)
|
||||||
if !ok {
|
|
||||||
l.Infoln("Unknown listen address scheme:", uri.String())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
listener := listenerFactory(uri, s.tlsCfg, s.conns, s.natService)
|
listener := factory.New(uri, s.cfg, s.tlsCfg, s.conns, s.natService)
|
||||||
listener.OnAddressesChanged(s.logListenAddressesChangedEvent)
|
listener.OnAddressesChanged(s.logListenAddressesChangedEvent)
|
||||||
s.listeners[addr] = listener
|
s.listeners[uri.String()] = listener
|
||||||
s.listenerTokens[addr] = s.Add(listener)
|
s.listenerTokens[uri.String()] = s.Add(listener)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) logListenAddressesChangedEvent(l genericListener) {
|
func (s *Service) logListenAddressesChangedEvent(l genericListener) {
|
||||||
@ -417,15 +430,33 @@ func (s *Service) CommitConfiguration(from, to config.Configuration) bool {
|
|||||||
s.listenersMut.Lock()
|
s.listenersMut.Lock()
|
||||||
seen := make(map[string]struct{})
|
seen := make(map[string]struct{})
|
||||||
for _, addr := range config.Wrap("", to).ListenAddresses() {
|
for _, addr := range config.Wrap("", to).ListenAddresses() {
|
||||||
if _, ok := s.listeners[addr]; !ok {
|
if _, ok := s.listeners[addr]; ok {
|
||||||
l.Debugln("Staring listener", addr)
|
seen[addr] = struct{}{}
|
||||||
s.createListener(addr)
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uri, err := url.Parse(addr)
|
||||||
|
if err != nil {
|
||||||
|
l.Infof("Listener for %s: %v", addr, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
factory, err := s.getListenerFactory(to, uri)
|
||||||
|
if err == errDisabled {
|
||||||
|
l.Debugln("Listener for", uri, "is disabled")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
l.Infof("Listener for %v: %v", uri, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
s.createListener(factory, uri)
|
||||||
seen[addr] = struct{}{}
|
seen[addr] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
for addr := range s.listeners {
|
for addr, listener := range s.listeners {
|
||||||
if _, ok := seen[addr]; !ok {
|
if _, ok := seen[addr]; !ok || !listener.Factory().Enabled(to) {
|
||||||
l.Debugln("Stopping listener", addr)
|
l.Debugln("Stopping listener", addr)
|
||||||
s.Remove(s.listenerTokens[addr])
|
s.Remove(s.listenerTokens[addr])
|
||||||
delete(s.listenerTokens, addr)
|
delete(s.listenerTokens, addr)
|
||||||
@ -494,6 +525,32 @@ func (s *Service) Status() map[string]interface{} {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) getDialerFactory(cfg config.Configuration, uri *url.URL) (dialerFactory, error) {
|
||||||
|
dialerFactory, ok := dialers[uri.Scheme]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("unknown address scheme %q", uri.Scheme)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !dialerFactory.Enabled(cfg) {
|
||||||
|
return nil, errDisabled
|
||||||
|
}
|
||||||
|
|
||||||
|
return dialerFactory, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) getListenerFactory(cfg config.Configuration, uri *url.URL) (listenerFactory, error) {
|
||||||
|
listenerFactory, ok := listeners[uri.Scheme]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("unknown address scheme %q", uri.Scheme)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !listenerFactory.Enabled(cfg) {
|
||||||
|
return nil, errDisabled
|
||||||
|
}
|
||||||
|
|
||||||
|
return listenerFactory, nil
|
||||||
|
}
|
||||||
|
|
||||||
func exchangeHello(c net.Conn, h protocol.HelloMessage) (protocol.HelloMessage, error) {
|
func exchangeHello(c net.Conn, h protocol.HelloMessage) (protocol.HelloMessage, error) {
|
||||||
if err := c.SetDeadline(time.Now().Add(2 * time.Second)); err != nil {
|
if err := c.SetDeadline(time.Now().Add(2 * time.Second)); err != nil {
|
||||||
return protocol.HelloMessage{}, err
|
return protocol.HelloMessage{}, err
|
||||||
|
@ -31,16 +31,19 @@ type Connection struct {
|
|||||||
type dialerFactory interface {
|
type dialerFactory interface {
|
||||||
New(*config.Wrapper, *tls.Config) genericDialer
|
New(*config.Wrapper, *tls.Config) genericDialer
|
||||||
Priority() int
|
Priority() int
|
||||||
|
Enabled(config.Configuration) bool
|
||||||
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
type genericDialer interface {
|
type genericDialer interface {
|
||||||
Dial(protocol.DeviceID, *url.URL) (IntermediateConnection, error)
|
Dial(protocol.DeviceID, *url.URL) (IntermediateConnection, error)
|
||||||
Priority() int
|
|
||||||
RedialFrequency() time.Duration
|
RedialFrequency() time.Duration
|
||||||
String() string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type listenerFactory func(*url.URL, *tls.Config, chan IntermediateConnection, *nat.Service) genericListener
|
type listenerFactory interface {
|
||||||
|
New(*url.URL, *config.Wrapper, *tls.Config, chan IntermediateConnection, *nat.Service) genericListener
|
||||||
|
Enabled(config.Configuration) bool
|
||||||
|
}
|
||||||
|
|
||||||
type genericListener interface {
|
type genericListener interface {
|
||||||
Serve()
|
Serve()
|
||||||
@ -58,6 +61,7 @@ type genericListener interface {
|
|||||||
Error() error
|
Error() error
|
||||||
OnAddressesChanged(func(genericListener))
|
OnAddressesChanged(func(genericListener))
|
||||||
String() string
|
String() string
|
||||||
|
Factory() listenerFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
type Model interface {
|
type Model interface {
|
||||||
|
@ -20,8 +20,9 @@ import (
|
|||||||
const tcpPriority = 10
|
const tcpPriority = 10
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
factory := &tcpDialerFactory{}
|
||||||
for _, scheme := range []string{"tcp", "tcp4", "tcp6"} {
|
for _, scheme := range []string{"tcp", "tcp4", "tcp6"} {
|
||||||
dialers[scheme] = tcpDialerFactory{}
|
dialers[scheme] = factory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,18 +56,10 @@ func (d *tcpDialer) Dial(id protocol.DeviceID, uri *url.URL) (IntermediateConnec
|
|||||||
return IntermediateConnection{tc, "TCP (Client)", tcpPriority}, nil
|
return IntermediateConnection{tc, "TCP (Client)", tcpPriority}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tcpDialer) Priority() int {
|
|
||||||
return tcpPriority
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *tcpDialer) RedialFrequency() time.Duration {
|
func (d *tcpDialer) RedialFrequency() time.Duration {
|
||||||
return time.Duration(d.cfg.Options().ReconnectIntervalS) * time.Second
|
return time.Duration(d.cfg.Options().ReconnectIntervalS) * time.Second
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *tcpDialer) String() string {
|
|
||||||
return "TCP Dialer"
|
|
||||||
}
|
|
||||||
|
|
||||||
type tcpDialerFactory struct{}
|
type tcpDialerFactory struct{}
|
||||||
|
|
||||||
func (tcpDialerFactory) New(cfg *config.Wrapper, tlsCfg *tls.Config) genericDialer {
|
func (tcpDialerFactory) New(cfg *config.Wrapper, tlsCfg *tls.Config) genericDialer {
|
||||||
@ -79,3 +72,11 @@ func (tcpDialerFactory) New(cfg *config.Wrapper, tlsCfg *tls.Config) genericDial
|
|||||||
func (tcpDialerFactory) Priority() int {
|
func (tcpDialerFactory) Priority() int {
|
||||||
return tcpPriority
|
return tcpPriority
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tcpDialerFactory) Enabled(cfg config.Configuration) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tcpDialerFactory) String() string {
|
||||||
|
return "TCP Dialer"
|
||||||
|
}
|
||||||
|
@ -14,23 +14,26 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/syncthing/syncthing/lib/config"
|
||||||
"github.com/syncthing/syncthing/lib/dialer"
|
"github.com/syncthing/syncthing/lib/dialer"
|
||||||
"github.com/syncthing/syncthing/lib/nat"
|
"github.com/syncthing/syncthing/lib/nat"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
factory := &tcpListenerFactory{}
|
||||||
for _, scheme := range []string{"tcp", "tcp4", "tcp6"} {
|
for _, scheme := range []string{"tcp", "tcp4", "tcp6"} {
|
||||||
listeners[scheme] = newTCPListener
|
listeners[scheme] = factory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type tcpListener struct {
|
type tcpListener struct {
|
||||||
onAddressesChangedNotifier
|
onAddressesChangedNotifier
|
||||||
|
|
||||||
uri *url.URL
|
uri *url.URL
|
||||||
tlsCfg *tls.Config
|
tlsCfg *tls.Config
|
||||||
stop chan struct{}
|
stop chan struct{}
|
||||||
conns chan IntermediateConnection
|
conns chan IntermediateConnection
|
||||||
|
factory listenerFactory
|
||||||
|
|
||||||
natService *nat.Service
|
natService *nat.Service
|
||||||
mapping *nat.Mapping
|
mapping *nat.Mapping
|
||||||
@ -63,6 +66,9 @@ func (t *tcpListener) Serve() {
|
|||||||
}
|
}
|
||||||
defer listener.Close()
|
defer listener.Close()
|
||||||
|
|
||||||
|
l.Infof("TCP listener (%v) starting", listener.Addr())
|
||||||
|
defer l.Infof("TCP listener (%v) shutting down", listener.Addr())
|
||||||
|
|
||||||
mapping := t.natService.NewMapping(nat.TCP, tcaddr.IP, tcaddr.Port)
|
mapping := t.natService.NewMapping(nat.TCP, tcaddr.IP, tcaddr.Port)
|
||||||
mapping.OnChanged(func(_ *nat.Mapping, _, _ []nat.Address) {
|
mapping.OnChanged(func(_ *nat.Mapping, _, _ []nat.Address) {
|
||||||
t.notifyAddressesChanged(t)
|
t.notifyAddressesChanged(t)
|
||||||
@ -152,16 +158,61 @@ func (t *tcpListener) String() string {
|
|||||||
return t.uri.String()
|
return t.uri.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTCPListener(uri *url.URL, tlsCfg *tls.Config, conns chan IntermediateConnection, natService *nat.Service) genericListener {
|
func (t *tcpListener) Factory() listenerFactory {
|
||||||
|
return t.factory
|
||||||
|
}
|
||||||
|
|
||||||
|
type tcpListenerFactory struct{}
|
||||||
|
|
||||||
|
func (f *tcpListenerFactory) New(uri *url.URL, cfg *config.Wrapper, tlsCfg *tls.Config, conns chan IntermediateConnection, natService *nat.Service) genericListener {
|
||||||
return &tcpListener{
|
return &tcpListener{
|
||||||
uri: fixupPort(uri),
|
uri: fixupPort(uri),
|
||||||
tlsCfg: tlsCfg,
|
tlsCfg: tlsCfg,
|
||||||
conns: conns,
|
conns: conns,
|
||||||
natService: natService,
|
natService: natService,
|
||||||
stop: make(chan struct{}),
|
stop: make(chan struct{}),
|
||||||
|
factory: f,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tcpListenerFactory) Enabled(cfg config.Configuration) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func isPublicIPv4(ip net.IP) bool {
|
||||||
|
ip = ip.To4()
|
||||||
|
if ip == nil {
|
||||||
|
// Not an IPv4 address (IPv6)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsGlobalUnicast below only checks that it's not link local or
|
||||||
|
// multicast, and we want to exclude private (NAT:ed) addresses as well.
|
||||||
|
rfc1918 := []net.IPNet{
|
||||||
|
{IP: net.IP{10, 0, 0, 0}, Mask: net.IPMask{255, 0, 0, 0}},
|
||||||
|
{IP: net.IP{172, 16, 0, 0}, Mask: net.IPMask{255, 240, 0, 0}},
|
||||||
|
{IP: net.IP{192, 168, 0, 0}, Mask: net.IPMask{255, 255, 0, 0}},
|
||||||
|
}
|
||||||
|
for _, n := range rfc1918 {
|
||||||
|
if n.Contains(ip) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ip.IsGlobalUnicast()
|
||||||
|
}
|
||||||
|
|
||||||
|
func isPublicIPv6(ip net.IP) bool {
|
||||||
|
if ip.To4() != nil {
|
||||||
|
// Not an IPv6 address (IPv4)
|
||||||
|
// (To16() returns a v6 mapped v4 address so can't be used to check
|
||||||
|
// that it's an actual v6 address)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return ip.IsGlobalUnicast()
|
||||||
|
}
|
||||||
|
|
||||||
func fixupPort(uri *url.URL) *url.URL {
|
func fixupPort(uri *url.URL) *url.URL {
|
||||||
copyURI := *uri
|
copyURI := *uri
|
||||||
|
|
||||||
|
@ -2018,6 +2018,7 @@ func (m *Model) CommitConfiguration(from, to config.Configuration) bool {
|
|||||||
from.Options.URAccepted = to.Options.URAccepted
|
from.Options.URAccepted = to.Options.URAccepted
|
||||||
from.Options.URUniqueID = to.Options.URUniqueID
|
from.Options.URUniqueID = to.Options.URUniqueID
|
||||||
from.Options.ListenAddresses = to.Options.ListenAddresses
|
from.Options.ListenAddresses = to.Options.ListenAddresses
|
||||||
|
from.Options.RelaysEnabled = to.Options.RelaysEnabled
|
||||||
// All of the other generic options require restart. Or at least they may;
|
// All of the other generic options require restart. Or at least they may;
|
||||||
// removing this check requires going through those options carefully and
|
// removing this check requires going through those options carefully and
|
||||||
// making sure there are individual services that handle them correctly.
|
// making sure there are individual services that handle them correctly.
|
||||||
|
@ -89,7 +89,8 @@ func (c *staticClient) Serve() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
l.Infoln("Joined relay", c.uri)
|
l.Infof("Joined relay %s://%s", c.uri.Scheme, c.uri.Host)
|
||||||
|
defer l.Infof("Disconnected from relay %s://%s", c.uri.Scheme, c.uri.Host)
|
||||||
|
|
||||||
c.mut.Lock()
|
c.mut.Lock()
|
||||||
c.connected = true
|
c.connected = true
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<configuration version="12">
|
<configuration version="14">
|
||||||
<folder id="default" path="s1/" ro="false" rescanIntervalS="10" ignorePerms="false" autoNormalize="true">
|
<folder id="default" label="" path="s1/" type="readwrite" rescanIntervalS="10" ignorePerms="false" autoNormalize="true">
|
||||||
<device id="I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU"></device>
|
<device id="I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU"></device>
|
||||||
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC"></device>
|
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC"></device>
|
||||||
<device id="373HSRP-QLPNLIE-JYKZVQF-P4PKZ63-R2ZE6K3-YD442U2-JHBGBQG-WWXAHAU"></device>
|
<device id="373HSRP-QLPNLIE-JYKZVQF-P4PKZ63-R2ZE6K3-YD442U2-JHBGBQG-WWXAHAU"></device>
|
||||||
@ -15,8 +15,10 @@
|
|||||||
<pullerSleepS>0</pullerSleepS>
|
<pullerSleepS>0</pullerSleepS>
|
||||||
<pullerPauseS>0</pullerPauseS>
|
<pullerPauseS>0</pullerPauseS>
|
||||||
<maxConflicts>-1</maxConflicts>
|
<maxConflicts>-1</maxConflicts>
|
||||||
|
<disableSparseFiles>false</disableSparseFiles>
|
||||||
|
<disableTempIndexes>false</disableTempIndexes>
|
||||||
</folder>
|
</folder>
|
||||||
<folder id="¯\_(ツ)_/¯ Räksmörgås 动作 Адрес" path="s12-1/" ro="false" rescanIntervalS="10" ignorePerms="false" autoNormalize="true">
|
<folder id="¯\_(ツ)_/¯ Räksmörgås 动作 Адрес" label="" path="s12-1/" type="readwrite" rescanIntervalS="10" ignorePerms="false" autoNormalize="true">
|
||||||
<device id="I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU"></device>
|
<device id="I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU"></device>
|
||||||
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC"></device>
|
<device id="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC"></device>
|
||||||
<minDiskFreePct>1</minDiskFreePct>
|
<minDiskFreePct>1</minDiskFreePct>
|
||||||
@ -30,6 +32,8 @@
|
|||||||
<pullerSleepS>0</pullerSleepS>
|
<pullerSleepS>0</pullerSleepS>
|
||||||
<pullerPauseS>0</pullerPauseS>
|
<pullerPauseS>0</pullerPauseS>
|
||||||
<maxConflicts>-1</maxConflicts>
|
<maxConflicts>-1</maxConflicts>
|
||||||
|
<disableSparseFiles>false</disableSparseFiles>
|
||||||
|
<disableTempIndexes>false</disableTempIndexes>
|
||||||
</folder>
|
</folder>
|
||||||
<device id="EJHMPAQ-OGCVORE-ISB4IS3-SYYVJXF-TKJGLTU-66DIQPF-GJ5D2GX-GQ3OWQK" name="s4" compression="metadata" introducer="false">
|
<device id="EJHMPAQ-OGCVORE-ISB4IS3-SYYVJXF-TKJGLTU-66DIQPF-GJ5D2GX-GQ3OWQK" name="s4" compression="metadata" introducer="false">
|
||||||
<address>tcp://127.0.0.1:22004</address>
|
<address>tcp://127.0.0.1:22004</address>
|
||||||
@ -51,26 +55,25 @@
|
|||||||
<user>testuser</user>
|
<user>testuser</user>
|
||||||
<password>$2a$10$7tKL5uvLDGn5s2VLPM2yWOK/II45az0mTel8hxAUJDRQN1Tk2QYwu</password>
|
<password>$2a$10$7tKL5uvLDGn5s2VLPM2yWOK/II45az0mTel8hxAUJDRQN1Tk2QYwu</password>
|
||||||
<apikey>abc123</apikey>
|
<apikey>abc123</apikey>
|
||||||
|
<theme>default</theme>
|
||||||
</gui>
|
</gui>
|
||||||
<options>
|
<options>
|
||||||
<listenAddress>tcp://127.0.0.1:22001</listenAddress>
|
<listenAddress>tcp://127.0.0.1:22001</listenAddress>
|
||||||
|
<listenAddress>dynamic+https://relays.syncthing.net/endpoint</listenAddress>
|
||||||
<globalAnnounceServer>default</globalAnnounceServer>
|
<globalAnnounceServer>default</globalAnnounceServer>
|
||||||
<globalAnnounceEnabled>false</globalAnnounceEnabled>
|
<globalAnnounceEnabled>false</globalAnnounceEnabled>
|
||||||
<localAnnounceEnabled>true</localAnnounceEnabled>
|
<localAnnounceEnabled>true</localAnnounceEnabled>
|
||||||
<localAnnouncePort>21027</localAnnouncePort>
|
<localAnnouncePort>21027</localAnnouncePort>
|
||||||
<localAnnounceMCAddr>[ff12::8384]:21027</localAnnounceMCAddr>
|
<localAnnounceMCAddr>[ff12::8384]:21027</localAnnounceMCAddr>
|
||||||
<relayServer>dynamic+https://relays.syncthing.net/endpoint</relayServer>
|
|
||||||
<maxSendKbps>0</maxSendKbps>
|
<maxSendKbps>0</maxSendKbps>
|
||||||
<maxRecvKbps>0</maxRecvKbps>
|
<maxRecvKbps>0</maxRecvKbps>
|
||||||
<reconnectionIntervalS>5</reconnectionIntervalS>
|
<reconnectionIntervalS>5</reconnectionIntervalS>
|
||||||
<relaysEnabled>true</relaysEnabled>
|
|
||||||
<relayReconnectIntervalM>10</relayReconnectIntervalM>
|
<relayReconnectIntervalM>10</relayReconnectIntervalM>
|
||||||
<relayWithoutGlobalAnn>false</relayWithoutGlobalAnn>
|
|
||||||
<startBrowser>false</startBrowser>
|
<startBrowser>false</startBrowser>
|
||||||
<upnpEnabled>true</upnpEnabled>
|
<natEnabled>true</natEnabled>
|
||||||
<upnpLeaseMinutes>0</upnpLeaseMinutes>
|
<natLeaseMinutes>0</natLeaseMinutes>
|
||||||
<upnpRenewalMinutes>30</upnpRenewalMinutes>
|
<natRenewalMinutes>30</natRenewalMinutes>
|
||||||
<upnpTimeoutSeconds>10</upnpTimeoutSeconds>
|
<natTimeoutSeconds>10</natTimeoutSeconds>
|
||||||
<urAccepted>-1</urAccepted>
|
<urAccepted>-1</urAccepted>
|
||||||
<urUniqueID></urUniqueID>
|
<urUniqueID></urUniqueID>
|
||||||
<urURL>https://data.syncthing.net/newdata</urURL>
|
<urURL>https://data.syncthing.net/newdata</urURL>
|
||||||
@ -79,12 +82,18 @@
|
|||||||
<restartOnWakeup>true</restartOnWakeup>
|
<restartOnWakeup>true</restartOnWakeup>
|
||||||
<autoUpgradeIntervalH>12</autoUpgradeIntervalH>
|
<autoUpgradeIntervalH>12</autoUpgradeIntervalH>
|
||||||
<keepTemporariesH>24</keepTemporariesH>
|
<keepTemporariesH>24</keepTemporariesH>
|
||||||
<cacheIgnoredFiles>true</cacheIgnoredFiles>
|
<cacheIgnoredFiles>false</cacheIgnoredFiles>
|
||||||
<progressUpdateIntervalS>5</progressUpdateIntervalS>
|
<progressUpdateIntervalS>5</progressUpdateIntervalS>
|
||||||
<symlinksEnabled>true</symlinksEnabled>
|
<symlinksEnabled>true</symlinksEnabled>
|
||||||
<limitBandwidthInLan>false</limitBandwidthInLan>
|
<limitBandwidthInLan>false</limitBandwidthInLan>
|
||||||
<databaseBlockCacheMiB>0</databaseBlockCacheMiB>
|
|
||||||
<minHomeDiskFreePct>1</minHomeDiskFreePct>
|
<minHomeDiskFreePct>1</minHomeDiskFreePct>
|
||||||
<releasesURL>https://api.github.com/repos/syncthing/syncthing/releases?per_page=30</releasesURL>
|
<releasesURL>https://upgrades.syncthing.net/meta.json</releasesURL>
|
||||||
|
<overwriteRemoteDeviceNamesOnConnect>false</overwriteRemoteDeviceNamesOnConnect>
|
||||||
|
<tempIndexMinBlocks>10</tempIndexMinBlocks>
|
||||||
|
<upnpEnabled>true</upnpEnabled>
|
||||||
|
<upnpLeaseMinutes>0</upnpLeaseMinutes>
|
||||||
|
<upnpRenewalMinutes>30</upnpRenewalMinutes>
|
||||||
|
<upnpTimeoutSeconds>10</upnpTimeoutSeconds>
|
||||||
|
<relaysEnabled>false</relaysEnabled>
|
||||||
</options>
|
</options>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
Loading…
Reference in New Issue
Block a user