lib/connections: Un-deprecate relaysEnabled (fixes #3074)

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3098
This commit is contained in:
Jakob Borg 2016-05-17 00:05:38 +00:00
parent adb7fb43cb
commit 2c1323ece6
13 changed files with 371 additions and 128 deletions

View File

@ -56,11 +56,24 @@
</div>
</div>
<div class="form-group">
<div class="checkbox">
<label>
<input id="GlobalAnnEnabled" type="checkbox" ng-model="tmpOptions.globalAnnounceEnabled"> <span translate>Global Discovery</span>
</label>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<div class="checkbox">
<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>

View File

@ -29,9 +29,9 @@ const (
var (
// DefaultListenAddresses should be substituted when the configuration
// contains <listenAddress>default</listenAddress>. This is
// done by the "consumer" of the configuration, as we don't want these
// saved to the config.
// contains <listenAddress>default</listenAddress>. This is done by the
// "consumer" of the configuration as we don't want these saved to the
// config.
DefaultListenAddresses = []string{
"tcp://0.0.0.0:22000",
"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
// configurations.
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) {
cfg.Options.ListenAddresses = append([]string{"default"}, newAddresses...)
// Migrate UPnP -> NAT options
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
// For consistency
sort.Strings(cfg.Options.ListenAddresses)
var newAddrs []string
for _, addr := range cfg.Options.GlobalAnnServers {
if addr != "default" {

View File

@ -12,7 +12,9 @@ import (
"fmt"
"os"
"path/filepath"
"reflect"
"runtime"
"sort"
"strings"
"testing"
@ -40,6 +42,7 @@ func TestDefaultValues(t *testing.T) {
MaxSendKbps: 0,
MaxRecvKbps: 0,
ReconnectIntervalS: 60,
RelaysEnabled: true,
RelayReconnectIntervalM: 10,
StartBrowser: true,
NATEnabled: true,
@ -169,6 +172,7 @@ func TestOverriddenValues(t *testing.T) {
MaxSendKbps: 1234,
MaxRecvKbps: 2341,
ReconnectIntervalS: 6000,
RelaysEnabled: false,
RelayReconnectIntervalM: 20,
StartBrowser: false,
NATEnabled: false,
@ -616,3 +620,61 @@ func TestRemoveDuplicateDevicesFolders(t *testing.T) {
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])
}
}
}

View File

@ -16,6 +16,7 @@ type OptionsConfiguration struct {
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"`
@ -40,12 +41,11 @@ type OptionsConfiguration struct {
OverwriteRemoteDevNames bool `xml:"overwriteRemoteDeviceNamesOnConnect" json:"overwriteRemoteDeviceNamesOnConnect" default:"false"`
TempIndexMinBlocks int `xml:"tempIndexMinBlocks" json:"tempIndexMinBlocks" default:"10"`
DeprecatedUPnPEnabled bool `xml:"upnpEnabled" json:"-"`
DeprecatedUPnPLeaseM int `xml:"upnpLeaseMinutes" json:"-"`
DeprecatedUPnPRenewalM int `xml:"upnpRenewalMinutes" json:"-"`
DeprecatedUPnPTimeoutS int `xml:"upnpTimeoutSeconds" json:"-"`
DeprecatedRelaysEnabled bool `xml:"relaysEnabled" json:"-"`
DeprecatedRelayServers []string `xml:"relayServer" json:"-"`
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:"-"`
}
func (orig OptionsConfiguration) Copy() OptionsConfiguration {

View File

@ -70,10 +70,6 @@ func (d *relayDialer) RedialFrequency() time.Duration {
return time.Duration(d.cfg.Options().RelayReconnectIntervalM) * time.Minute
}
func (d *relayDialer) String() string {
return "Relay Dialer"
}
type relayDialerFactory struct{}
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 {
return relayPriority
}
func (relayDialerFactory) Enabled(cfg config.Configuration) bool {
return cfg.Options.RelaysEnabled
}
func (relayDialerFactory) String() string {
return "Relay Dialer"
}

View File

@ -13,23 +13,26 @@ import (
"sync"
"time"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/dialer"
"github.com/syncthing/syncthing/lib/nat"
"github.com/syncthing/syncthing/lib/relay/client"
)
func init() {
listeners["relay"] = newRelayListener
listeners["dynamic+http"] = newRelayListener
listeners["dynamic+https"] = newRelayListener
factory := &relayListenerFactory{}
listeners["relay"] = factory
listeners["dynamic+http"] = factory
listeners["dynamic+https"] = factory
}
type relayListener struct {
onAddressesChangedNotifier
uri *url.URL
tlsCfg *tls.Config
conns chan IntermediateConnection
uri *url.URL
tlsCfg *tls.Config
conns chan IntermediateConnection
factory listenerFactory
err error
client client.RelayClient
@ -154,14 +157,25 @@ func (t *relayListener) Error() error {
return cerr
}
func (t *relayListener) Factory() listenerFactory {
return t.factory
}
func (t *relayListener) String() 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{
uri: uri,
tlsCfg: tlsCfg,
conns: conns,
uri: uri,
tlsCfg: tlsCfg,
conns: conns,
factory: f,
}
}
func (relayListenerFactory) Enabled(cfg config.Configuration) bool {
return cfg.Options.RelaysEnabled
}

View File

@ -9,6 +9,7 @@ package connections
import (
"crypto/tls"
"encoding/binary"
"errors"
"fmt"
"io"
"net"
@ -112,6 +113,10 @@ func NewService(cfg *config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg *
return service
}
var (
errDisabled = errors.New("disabled by configuration")
)
func (s *Service) handle() {
next:
for c := range s.conns {
@ -237,24 +242,35 @@ next:
func (s *Service) connect() {
nextDial := make(map[string]time.Time)
delay := time.Second
sleep := time.Second
bestDialerPrio := 1<<31 - 1 // worse prio won't build on 32 bit
for _, df := range dialers {
if prio := df.Priority(); prio < bestDialerPrio {
bestDialerPrio = prio
}
}
// Used as delay for the first few connection attempts, increases
// exponentially
initialRampup := time.Second
// Calculated from actual dialers reconnectInterval
var sleep time.Duration
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")
now := time.Now()
var seen []string
nextDevice:
for deviceID, deviceCfg := range s.cfg.Devices() {
for _, deviceCfg := range cfg.Devices {
deviceID := deviceCfg.DeviceID
if deviceID == s.myID {
continue
}
@ -292,35 +308,40 @@ func (s *Service) connect() {
seen = append(seen, 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)
if err != nil {
l.Infoln("Failed to parse connection url:", addr, err)
l.Infof("Dialer for %s: %v", addr, err)
continue
}
dialerFactory, ok := dialers[uri.Scheme]
if !ok {
l.Debugln("Unknown address schema", uri)
dialerFactory, err := s.getDialerFactory(cfg, uri)
if err == errDisabled {
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
}
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)
nextDial[addr] = now.Add(dialer.RedialFrequency())
conn, err := dialer.Dial(deviceID, uri)
if err != nil {
l.Debugln("dial failed", deviceCfg.DeviceID, uri, err)
@ -338,12 +359,12 @@ func (s *Service) connect() {
nextDial, sleep = filterAndFindSleepDuration(nextDial, seen, now)
// delay variable is used to trigger much more frequent dialing after
// initial startup, essentially causing redials every 1, 2, 4, 8... seconds
if delay < sleep {
time.Sleep(delay)
delay *= 2
if initialRampup < sleep {
l.Debugln("initial rampup; sleep", initialRampup, "and update to", initialRampup*2)
time.Sleep(initialRampup)
initialRampup *= 2
} else {
l.Debugln("sleep until next dial", sleep)
time.Sleep(sleep)
}
}
@ -366,24 +387,16 @@ func (s *Service) shouldLimit(addr net.Addr) bool {
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
uri, err := url.Parse(addr)
if err != nil {
l.Infoln("Failed to parse listen address:", addr, err)
return
}
listenerFactory, ok := listeners[uri.Scheme]
if !ok {
l.Infoln("Unknown listen address scheme:", uri.String())
return
}
l.Debugln("Starting listener", uri)
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)
s.listeners[addr] = listener
s.listenerTokens[addr] = s.Add(listener)
s.listeners[uri.String()] = listener
s.listenerTokens[uri.String()] = s.Add(listener)
return true
}
func (s *Service) logListenAddressesChangedEvent(l genericListener) {
@ -417,15 +430,33 @@ func (s *Service) CommitConfiguration(from, to config.Configuration) bool {
s.listenersMut.Lock()
seen := make(map[string]struct{})
for _, addr := range config.Wrap("", to).ListenAddresses() {
if _, ok := s.listeners[addr]; !ok {
l.Debugln("Staring listener", addr)
s.createListener(addr)
if _, ok := s.listeners[addr]; ok {
seen[addr] = struct{}{}
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{}{}
}
for addr := range s.listeners {
if _, ok := seen[addr]; !ok {
for addr, listener := range s.listeners {
if _, ok := seen[addr]; !ok || !listener.Factory().Enabled(to) {
l.Debugln("Stopping listener", addr)
s.Remove(s.listenerTokens[addr])
delete(s.listenerTokens, addr)
@ -494,6 +525,32 @@ func (s *Service) Status() map[string]interface{} {
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) {
if err := c.SetDeadline(time.Now().Add(2 * time.Second)); err != nil {
return protocol.HelloMessage{}, err

View File

@ -31,16 +31,19 @@ type Connection struct {
type dialerFactory interface {
New(*config.Wrapper, *tls.Config) genericDialer
Priority() int
Enabled(config.Configuration) bool
String() string
}
type genericDialer interface {
Dial(protocol.DeviceID, *url.URL) (IntermediateConnection, error)
Priority() int
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 {
Serve()
@ -58,6 +61,7 @@ type genericListener interface {
Error() error
OnAddressesChanged(func(genericListener))
String() string
Factory() listenerFactory
}
type Model interface {

View File

@ -20,8 +20,9 @@ import (
const tcpPriority = 10
func init() {
factory := &tcpDialerFactory{}
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
}
func (tcpDialer) Priority() int {
return tcpPriority
}
func (d *tcpDialer) RedialFrequency() time.Duration {
return time.Duration(d.cfg.Options().ReconnectIntervalS) * time.Second
}
func (d *tcpDialer) String() string {
return "TCP Dialer"
}
type tcpDialerFactory struct{}
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 {
return tcpPriority
}
func (tcpDialerFactory) Enabled(cfg config.Configuration) bool {
return true
}
func (tcpDialerFactory) String() string {
return "TCP Dialer"
}

View File

@ -14,23 +14,26 @@ import (
"sync"
"time"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/dialer"
"github.com/syncthing/syncthing/lib/nat"
)
func init() {
factory := &tcpListenerFactory{}
for _, scheme := range []string{"tcp", "tcp4", "tcp6"} {
listeners[scheme] = newTCPListener
listeners[scheme] = factory
}
}
type tcpListener struct {
onAddressesChangedNotifier
uri *url.URL
tlsCfg *tls.Config
stop chan struct{}
conns chan IntermediateConnection
uri *url.URL
tlsCfg *tls.Config
stop chan struct{}
conns chan IntermediateConnection
factory listenerFactory
natService *nat.Service
mapping *nat.Mapping
@ -63,6 +66,9 @@ func (t *tcpListener) Serve() {
}
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.OnChanged(func(_ *nat.Mapping, _, _ []nat.Address) {
t.notifyAddressesChanged(t)
@ -152,16 +158,61 @@ func (t *tcpListener) String() 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{
uri: fixupPort(uri),
tlsCfg: tlsCfg,
conns: conns,
natService: natService,
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 {
copyURI := *uri

View File

@ -2018,6 +2018,7 @@ func (m *Model) CommitConfiguration(from, to config.Configuration) bool {
from.Options.URAccepted = to.Options.URAccepted
from.Options.URUniqueID = to.Options.URUniqueID
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;
// removing this check requires going through those options carefully and
// making sure there are individual services that handle them correctly.

View File

@ -89,7 +89,8 @@ func (c *staticClient) Serve() {
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.connected = true

View File

@ -1,5 +1,5 @@
<configuration version="12">
<folder id="default" path="s1/" ro="false" rescanIntervalS="10" ignorePerms="false" autoNormalize="true">
<configuration version="14">
<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="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC"></device>
<device id="373HSRP-QLPNLIE-JYKZVQF-P4PKZ63-R2ZE6K3-YD442U2-JHBGBQG-WWXAHAU"></device>
@ -15,8 +15,10 @@
<pullerSleepS>0</pullerSleepS>
<pullerPauseS>0</pullerPauseS>
<maxConflicts>-1</maxConflicts>
<disableSparseFiles>false</disableSparseFiles>
<disableTempIndexes>false</disableTempIndexes>
</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="MRIW7OK-NETT3M4-N6SBWME-N25O76W-YJKVXPH-FUMQJ3S-P57B74J-GBITBAC"></device>
<minDiskFreePct>1</minDiskFreePct>
@ -30,6 +32,8 @@
<pullerSleepS>0</pullerSleepS>
<pullerPauseS>0</pullerPauseS>
<maxConflicts>-1</maxConflicts>
<disableSparseFiles>false</disableSparseFiles>
<disableTempIndexes>false</disableTempIndexes>
</folder>
<device id="EJHMPAQ-OGCVORE-ISB4IS3-SYYVJXF-TKJGLTU-66DIQPF-GJ5D2GX-GQ3OWQK" name="s4" compression="metadata" introducer="false">
<address>tcp://127.0.0.1:22004</address>
@ -51,26 +55,25 @@
<user>testuser</user>
<password>$2a$10$7tKL5uvLDGn5s2VLPM2yWOK/II45az0mTel8hxAUJDRQN1Tk2QYwu</password>
<apikey>abc123</apikey>
<theme>default</theme>
</gui>
<options>
<listenAddress>tcp://127.0.0.1:22001</listenAddress>
<listenAddress>dynamic+https://relays.syncthing.net/endpoint</listenAddress>
<globalAnnounceServer>default</globalAnnounceServer>
<globalAnnounceEnabled>false</globalAnnounceEnabled>
<localAnnounceEnabled>true</localAnnounceEnabled>
<localAnnouncePort>21027</localAnnouncePort>
<localAnnounceMCAddr>[ff12::8384]:21027</localAnnounceMCAddr>
<relayServer>dynamic+https://relays.syncthing.net/endpoint</relayServer>
<maxSendKbps>0</maxSendKbps>
<maxRecvKbps>0</maxRecvKbps>
<reconnectionIntervalS>5</reconnectionIntervalS>
<relaysEnabled>true</relaysEnabled>
<relayReconnectIntervalM>10</relayReconnectIntervalM>
<relayWithoutGlobalAnn>false</relayWithoutGlobalAnn>
<startBrowser>false</startBrowser>
<upnpEnabled>true</upnpEnabled>
<upnpLeaseMinutes>0</upnpLeaseMinutes>
<upnpRenewalMinutes>30</upnpRenewalMinutes>
<upnpTimeoutSeconds>10</upnpTimeoutSeconds>
<natEnabled>true</natEnabled>
<natLeaseMinutes>0</natLeaseMinutes>
<natRenewalMinutes>30</natRenewalMinutes>
<natTimeoutSeconds>10</natTimeoutSeconds>
<urAccepted>-1</urAccepted>
<urUniqueID></urUniqueID>
<urURL>https://data.syncthing.net/newdata</urURL>
@ -79,12 +82,18 @@
<restartOnWakeup>true</restartOnWakeup>
<autoUpgradeIntervalH>12</autoUpgradeIntervalH>
<keepTemporariesH>24</keepTemporariesH>
<cacheIgnoredFiles>true</cacheIgnoredFiles>
<cacheIgnoredFiles>false</cacheIgnoredFiles>
<progressUpdateIntervalS>5</progressUpdateIntervalS>
<symlinksEnabled>true</symlinksEnabled>
<limitBandwidthInLan>false</limitBandwidthInLan>
<databaseBlockCacheMiB>0</databaseBlockCacheMiB>
<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>
</configuration>