From b947056e624cccbc7f79f42a77fc54e95a58e850 Mon Sep 17 00:00:00 2001 From: Simon Frei Date: Sat, 9 Apr 2022 16:04:56 +0200 Subject: [PATCH] lib: Removal global connection registry (#8254) --- cmd/stfinddevice/main.go | 2 +- lib/connections/connections_test.go | 6 ++-- lib/connections/quic_dial.go | 16 ++++++---- lib/connections/quic_listen.go | 28 +++++++++-------- lib/connections/registry/registry.go | 16 ---------- lib/connections/relay_dial.go | 3 +- lib/connections/relay_listen.go | 3 +- lib/connections/service.go | 9 ++++-- lib/connections/structs.go | 5 +-- lib/connections/tcp_dial.go | 19 +++++++----- lib/connections/tcp_listen.go | 18 ++++++----- lib/dialer/public.go | 46 +++++++++++++++------------- lib/discover/cache_test.go | 3 +- lib/discover/global.go | 12 ++++++-- lib/discover/global_test.go | 13 +++++--- lib/discover/manager.go | 7 +++-- lib/syncthing/syncthing.go | 6 ++-- 17 files changed, 118 insertions(+), 94 deletions(-) diff --git a/cmd/stfinddevice/main.go b/cmd/stfinddevice/main.go index 688c29b2c..f6e94a3ba 100644 --- a/cmd/stfinddevice/main.go +++ b/cmd/stfinddevice/main.go @@ -84,7 +84,7 @@ func checkServers(deviceID protocol.DeviceID, servers ...string) { } func checkServer(deviceID protocol.DeviceID, server string) checkResult { - disco, err := discover.NewGlobal(server, tls.Certificate{}, nil, events.NoopLogger) + disco, err := discover.NewGlobal(server, tls.Certificate{}, nil, events.NoopLogger, nil) if err != nil { return checkResult{error: err} } diff --git a/lib/connections/connections_test.go b/lib/connections/connections_test.go index a7d4caf19..c1fc17a9f 100644 --- a/lib/connections/connections_test.go +++ b/lib/connections/connections_test.go @@ -21,6 +21,7 @@ import ( "github.com/thejerf/suture/v4" "github.com/syncthing/syncthing/lib/config" + "github.com/syncthing/syncthing/lib/connections/registry" "github.com/syncthing/syncthing/lib/events" "github.com/syncthing/syncthing/lib/nat" "github.com/syncthing/syncthing/lib/protocol" @@ -414,7 +415,7 @@ func withConnectionPair(b *testing.B, connUri string, h func(client, server inte } natSvc := nat.NewService(deviceId, wcfg) conns := make(chan internalConn, 1) - listenSvc := lf.New(uri, wcfg, tlsCfg, conns, natSvc) + listenSvc := lf.New(uri, wcfg, tlsCfg, conns, natSvc, registry.New()) supervisor.Add(listenSvc) var addr *url.URL @@ -433,7 +434,8 @@ func withConnectionPair(b *testing.B, connUri string, h func(client, server inte if err != nil { b.Fatal(err) } - dialer := df.New(cfg.Options, tlsCfg) + // Purposely using a different registry: Don't want to reuse port between dialer and listener on the same device + dialer := df.New(cfg.Options, tlsCfg, registry.New()) // Relays might take some time to register the device, so dial multiple times clientConn, err := dialer.Dial(ctx, deviceId, addr) diff --git a/lib/connections/quic_dial.go b/lib/connections/quic_dial.go index d47d3b84d..afe60c75e 100644 --- a/lib/connections/quic_dial.go +++ b/lib/connections/quic_dial.go @@ -41,6 +41,7 @@ func init() { type quicDialer struct { commonDialer + registry *registry.Registry } func (d *quicDialer) Dial(ctx context.Context, _ protocol.DeviceID, uri *url.URL) (internalConn, error) { @@ -58,7 +59,7 @@ func (d *quicDialer) Dial(ctx context.Context, _ protocol.DeviceID, uri *url.URL // Given we always pass the connection to quic, it assumes it's a remote connection it never closes it, // So our wrapper around it needs to close it, but it only needs to close it if it's not the listening connection. var createdConn net.PacketConn - listenConn := registry.Get(uri.Scheme, packetConnUnspecified) + listenConn := d.registry.Get(uri.Scheme, packetConnUnspecified) if listenConn != nil { conn = listenConn.(net.PacketConn) } else { @@ -96,7 +97,7 @@ func (d *quicDialer) Dial(ctx context.Context, _ protocol.DeviceID, uri *url.URL type quicDialerFactory struct{} -func (quicDialerFactory) New(opts config.OptionsConfiguration, tlsCfg *tls.Config) genericDialer { +func (quicDialerFactory) New(opts config.OptionsConfiguration, tlsCfg *tls.Config, registry *registry.Registry) genericDialer { // So the idea is that we should probably try dialing every 20 seconds. // However it would still be nice if this was adjustable/proportional to ReconnectIntervalS // But prevent something silly like 1/3 = 0 etc. @@ -104,10 +105,13 @@ func (quicDialerFactory) New(opts config.OptionsConfiguration, tlsCfg *tls.Confi if quicInterval < 10 { quicInterval = 10 } - return &quicDialer{commonDialer{ - reconnectInterval: time.Duration(quicInterval) * time.Second, - tlsCfg: tlsCfg, - }} + return &quicDialer{ + commonDialer: commonDialer{ + reconnectInterval: time.Duration(quicInterval) * time.Second, + tlsCfg: tlsCfg, + }, + registry: registry, + } } func (quicDialerFactory) Priority() int { diff --git a/lib/connections/quic_listen.go b/lib/connections/quic_listen.go index 4e5091f80..ed0eeae4e 100644 --- a/lib/connections/quic_listen.go +++ b/lib/connections/quic_listen.go @@ -40,11 +40,12 @@ type quicListener struct { onAddressesChangedNotifier - uri *url.URL - cfg config.Wrapper - tlsCfg *tls.Config - conns chan internalConn - factory listenerFactory + uri *url.URL + cfg config.Wrapper + tlsCfg *tls.Config + conns chan internalConn + factory listenerFactory + registry *registry.Registry address *url.URL laddr net.Addr @@ -100,8 +101,8 @@ func (t *quicListener) serve(ctx context.Context) error { go svc.Serve(ctx) - registry.Register(t.uri.Scheme, conn) - defer registry.Unregister(t.uri.Scheme, conn) + t.registry.Register(t.uri.Scheme, conn) + defer t.registry.Unregister(t.uri.Scheme, conn) listener, err := quic.Listen(conn, t.tlsCfg, quicConfig) if err != nil { @@ -217,13 +218,14 @@ func (f *quicListenerFactory) Valid(config.Configuration) error { return nil } -func (f *quicListenerFactory) New(uri *url.URL, cfg config.Wrapper, tlsCfg *tls.Config, conns chan internalConn, natService *nat.Service) genericListener { +func (f *quicListenerFactory) New(uri *url.URL, cfg config.Wrapper, tlsCfg *tls.Config, conns chan internalConn, natService *nat.Service, registry *registry.Registry) genericListener { l := &quicListener{ - uri: fixupPort(uri, config.DefaultQUICPort), - cfg: cfg, - tlsCfg: tlsCfg, - conns: conns, - factory: f, + uri: fixupPort(uri, config.DefaultQUICPort), + cfg: cfg, + tlsCfg: tlsCfg, + conns: conns, + factory: f, + registry: registry, } l.ServiceWithError = svcutil.AsService(l.serve, l.String()) l.nat.Store(stun.NATUnknown) diff --git a/lib/connections/registry/registry.go b/lib/connections/registry/registry.go index 4d9be9510..a262f2be8 100644 --- a/lib/connections/registry/registry.go +++ b/lib/connections/registry/registry.go @@ -15,10 +15,6 @@ import ( "github.com/syncthing/syncthing/lib/sync" ) -var ( - Default = New() -) - type Registry struct { mut sync.Mutex available map[string][]interface{} @@ -85,15 +81,3 @@ func (r *Registry) Get(scheme string, preferred func(interface{}) bool) interfac } return best } - -func Register(scheme string, item interface{}) { - Default.Register(scheme, item) -} - -func Unregister(scheme string, item interface{}) { - Default.Unregister(scheme, item) -} - -func Get(scheme string, preferred func(interface{}) bool) interface{} { - return Default.Get(scheme, preferred) -} diff --git a/lib/connections/relay_dial.go b/lib/connections/relay_dial.go index 51f2c6622..969229582 100644 --- a/lib/connections/relay_dial.go +++ b/lib/connections/relay_dial.go @@ -13,6 +13,7 @@ import ( "time" "github.com/syncthing/syncthing/lib/config" + "github.com/syncthing/syncthing/lib/connections/registry" "github.com/syncthing/syncthing/lib/dialer" "github.com/syncthing/syncthing/lib/protocol" "github.com/syncthing/syncthing/lib/relay/client" @@ -68,7 +69,7 @@ func (d *relayDialer) Dial(ctx context.Context, id protocol.DeviceID, uri *url.U type relayDialerFactory struct{} -func (relayDialerFactory) New(opts config.OptionsConfiguration, tlsCfg *tls.Config) genericDialer { +func (relayDialerFactory) New(opts config.OptionsConfiguration, tlsCfg *tls.Config, _ *registry.Registry) genericDialer { return &relayDialer{commonDialer{ trafficClass: opts.TrafficClass, reconnectInterval: time.Duration(opts.RelayReconnectIntervalM) * time.Minute, diff --git a/lib/connections/relay_listen.go b/lib/connections/relay_listen.go index 4b93d2c92..035ba787a 100644 --- a/lib/connections/relay_listen.go +++ b/lib/connections/relay_listen.go @@ -16,6 +16,7 @@ import ( "github.com/pkg/errors" "github.com/syncthing/syncthing/lib/config" + "github.com/syncthing/syncthing/lib/connections/registry" "github.com/syncthing/syncthing/lib/dialer" "github.com/syncthing/syncthing/lib/nat" "github.com/syncthing/syncthing/lib/relay/client" @@ -177,7 +178,7 @@ func (t *relayListener) NATType() string { type relayListenerFactory struct{} -func (f *relayListenerFactory) New(uri *url.URL, cfg config.Wrapper, tlsCfg *tls.Config, conns chan internalConn, natService *nat.Service) genericListener { +func (f *relayListenerFactory) New(uri *url.URL, cfg config.Wrapper, tlsCfg *tls.Config, conns chan internalConn, natService *nat.Service, _ *registry.Registry) genericListener { t := &relayListener{ uri: uri, cfg: cfg, diff --git a/lib/connections/service.go b/lib/connections/service.go index 4d394cd96..67d5c9654 100644 --- a/lib/connections/service.go +++ b/lib/connections/service.go @@ -23,6 +23,7 @@ import ( "time" "github.com/syncthing/syncthing/lib/config" + "github.com/syncthing/syncthing/lib/connections/registry" "github.com/syncthing/syncthing/lib/discover" "github.com/syncthing/syncthing/lib/events" "github.com/syncthing/syncthing/lib/nat" @@ -160,6 +161,7 @@ type service struct { limiter *limiter natService *nat.Service evLogger events.Logger + registry *registry.Registry dialNow chan struct{} dialNowDevices map[protocol.DeviceID]struct{} @@ -170,7 +172,7 @@ type service struct { listenerTokens map[string]suture.ServiceToken } -func NewService(cfg config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg *tls.Config, discoverer discover.Finder, bepProtocolName string, tlsDefaultCommonName string, evLogger events.Logger) Service { +func NewService(cfg config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg *tls.Config, discoverer discover.Finder, bepProtocolName string, tlsDefaultCommonName string, evLogger events.Logger, registry *registry.Registry) Service { spec := svcutil.SpecWithInfoLogger(l) service := &service{ Supervisor: suture.New("connections.Service", spec), @@ -187,6 +189,7 @@ func NewService(cfg config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg *t limiter: newLimiter(myID, cfg), natService: nat.NewService(myID, cfg), evLogger: evLogger, + registry: registry, dialNowDevicesMut: sync.NewMutex(), dialNow: make(chan struct{}, 1), @@ -655,7 +658,7 @@ func (s *service) resolveDialTargets(ctx context.Context, now time.Time, cfg con continue } - dialer := dialerFactory.New(s.cfg.Options(), s.tlsCfg) + dialer := dialerFactory.New(s.cfg.Options(), s.tlsCfg, s.registry) nextDialAt.set(deviceID, addr, now.Add(dialer.RedialFrequency())) // For LAN addresses, increase the priority so that we @@ -755,7 +758,7 @@ func (s *service) createListener(factory listenerFactory, uri *url.URL) bool { l.Debugln("Starting listener", uri) - listener := factory.New(uri, s.cfg, s.tlsCfg, s.conns, s.natService) + listener := factory.New(uri, s.cfg, s.tlsCfg, s.conns, s.natService, s.registry) listener.OnAddressesChanged(s.logListenAddressesChangedEvent) // Retrying a listener many times in rapid succession is unlikely to help, diff --git a/lib/connections/structs.go b/lib/connections/structs.go index 74ec65361..84cb47298 100644 --- a/lib/connections/structs.go +++ b/lib/connections/structs.go @@ -16,6 +16,7 @@ import ( "time" "github.com/syncthing/syncthing/lib/config" + "github.com/syncthing/syncthing/lib/connections/registry" "github.com/syncthing/syncthing/lib/nat" "github.com/syncthing/syncthing/lib/protocol" "github.com/syncthing/syncthing/lib/stats" @@ -139,7 +140,7 @@ func (c internalConn) String() string { } type dialerFactory interface { - New(config.OptionsConfiguration, *tls.Config) genericDialer + New(config.OptionsConfiguration, *tls.Config, *registry.Registry) genericDialer Priority() int AlwaysWAN() bool Valid(config.Configuration) error @@ -162,7 +163,7 @@ type genericDialer interface { } type listenerFactory interface { - New(*url.URL, config.Wrapper, *tls.Config, chan internalConn, *nat.Service) genericListener + New(*url.URL, config.Wrapper, *tls.Config, chan internalConn, *nat.Service, *registry.Registry) genericListener Valid(config.Configuration) error } diff --git a/lib/connections/tcp_dial.go b/lib/connections/tcp_dial.go index faa4611fc..9f87f4117 100644 --- a/lib/connections/tcp_dial.go +++ b/lib/connections/tcp_dial.go @@ -13,6 +13,7 @@ import ( "time" "github.com/syncthing/syncthing/lib/config" + "github.com/syncthing/syncthing/lib/connections/registry" "github.com/syncthing/syncthing/lib/dialer" "github.com/syncthing/syncthing/lib/protocol" ) @@ -28,6 +29,7 @@ func init() { type tcpDialer struct { commonDialer + registry *registry.Registry } func (d *tcpDialer) Dial(ctx context.Context, _ protocol.DeviceID, uri *url.URL) (internalConn, error) { @@ -35,7 +37,7 @@ func (d *tcpDialer) Dial(ctx context.Context, _ protocol.DeviceID, uri *url.URL) timeoutCtx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() - conn, err := dialer.DialContextReusePort(timeoutCtx, uri.Scheme, uri.Host) + conn, err := dialer.DialContextReusePortFunc(d.registry)(timeoutCtx, uri.Scheme, uri.Host) if err != nil { return internalConn{}, err } @@ -62,12 +64,15 @@ func (d *tcpDialer) Dial(ctx context.Context, _ protocol.DeviceID, uri *url.URL) type tcpDialerFactory struct{} -func (tcpDialerFactory) New(opts config.OptionsConfiguration, tlsCfg *tls.Config) genericDialer { - return &tcpDialer{commonDialer{ - trafficClass: opts.TrafficClass, - reconnectInterval: time.Duration(opts.ReconnectIntervalS) * time.Second, - tlsCfg: tlsCfg, - }} +func (tcpDialerFactory) New(opts config.OptionsConfiguration, tlsCfg *tls.Config, registry *registry.Registry) genericDialer { + return &tcpDialer{ + commonDialer: commonDialer{ + trafficClass: opts.TrafficClass, + reconnectInterval: time.Duration(opts.ReconnectIntervalS) * time.Second, + tlsCfg: tlsCfg, + }, + registry: registry, + } } func (tcpDialerFactory) Priority() int { diff --git a/lib/connections/tcp_listen.go b/lib/connections/tcp_listen.go index 13a071334..c2b4bb57f 100644 --- a/lib/connections/tcp_listen.go +++ b/lib/connections/tcp_listen.go @@ -32,11 +32,12 @@ type tcpListener struct { svcutil.ServiceWithError onAddressesChangedNotifier - uri *url.URL - cfg config.Wrapper - tlsCfg *tls.Config - conns chan internalConn - factory listenerFactory + uri *url.URL + cfg config.Wrapper + tlsCfg *tls.Config + conns chan internalConn + factory listenerFactory + registry *registry.Registry natService *nat.Service mapping *nat.Mapping @@ -69,8 +70,8 @@ func (t *tcpListener) serve(ctx context.Context) error { t.notifyAddressesChanged(t) defer t.clearAddresses(t) - registry.Register(t.uri.Scheme, tcaddr) - defer registry.Unregister(t.uri.Scheme, tcaddr) + t.registry.Register(t.uri.Scheme, tcaddr) + defer t.registry.Unregister(t.uri.Scheme, tcaddr) l.Infof("TCP listener (%v) starting", tcaddr) defer l.Infof("TCP listener (%v) shutting down", tcaddr) @@ -213,7 +214,7 @@ func (t *tcpListener) NATType() string { type tcpListenerFactory struct{} -func (f *tcpListenerFactory) New(uri *url.URL, cfg config.Wrapper, tlsCfg *tls.Config, conns chan internalConn, natService *nat.Service) genericListener { +func (f *tcpListenerFactory) New(uri *url.URL, cfg config.Wrapper, tlsCfg *tls.Config, conns chan internalConn, natService *nat.Service, registry *registry.Registry) genericListener { l := &tcpListener{ uri: fixupPort(uri, config.DefaultTCPPort), cfg: cfg, @@ -221,6 +222,7 @@ func (f *tcpListenerFactory) New(uri *url.URL, cfg config.Wrapper, tlsCfg *tls.C conns: conns, natService: natService, factory: f, + registry: registry, } l.ServiceWithError = svcutil.AsService(l.serve, l.String()) return l diff --git a/lib/dialer/public.go b/lib/dialer/public.go index cfd632ced..9310cca77 100644 --- a/lib/dialer/public.go +++ b/lib/dialer/public.go @@ -104,32 +104,34 @@ func DialContext(ctx context.Context, network, addr string) (net.Conn, error) { // DialContextReusePort tries dialing via proxy if a proxy is configured, and falls back to // a direct connection reusing the port from the connections registry, if no proxy is defined, or connecting via proxy // fails. It also in parallel dials without reusing the port, just in case reusing the port affects routing decisions badly. -func DialContextReusePort(ctx context.Context, network, addr string) (net.Conn, error) { - // If proxy is configured, there is no point trying to reuse listen addresses. - if proxy.FromEnvironment() != proxy.Direct { - return DialContext(ctx, network, addr) - } +func DialContextReusePortFunc(registry *registry.Registry) func(ctx context.Context, network, addr string) (net.Conn, error) { + return func(ctx context.Context, network, addr string) (net.Conn, error) { + // If proxy is configured, there is no point trying to reuse listen addresses. + if proxy.FromEnvironment() != proxy.Direct { + return DialContext(ctx, network, addr) + } - localAddrInterface := registry.Get(network, func(addr interface{}) bool { - return addr.(*net.TCPAddr).IP.IsUnspecified() - }) - if localAddrInterface == nil { - // Nothing listening, nothing to reuse. - return DialContext(ctx, network, addr) - } + localAddrInterface := registry.Get(network, func(addr interface{}) bool { + return addr.(*net.TCPAddr).IP.IsUnspecified() + }) + if localAddrInterface == nil { + // Nothing listening, nothing to reuse. + return DialContext(ctx, network, addr) + } - laddr, ok := localAddrInterface.(*net.TCPAddr) - if !ok { - return nil, errUnexpectedInterfaceType - } + laddr, ok := localAddrInterface.(*net.TCPAddr) + if !ok { + return nil, errUnexpectedInterfaceType + } - // Dial twice, once reusing the listen address, another time not reusing it, just in case reusing the address - // influences routing and we fail to reach our destination. - dialer := net.Dialer{ - Control: ReusePortControl, - LocalAddr: laddr, + // Dial twice, once reusing the listen address, another time not reusing it, just in case reusing the address + // influences routing and we fail to reach our destination. + dialer := net.Dialer{ + Control: ReusePortControl, + LocalAddr: laddr, + } + return dialTwicePreferFirst(ctx, dialer.DialContext, (&net.Dialer{}).DialContext, "reuse", "non-reuse", network, addr) } - return dialTwicePreferFirst(ctx, dialer.DialContext, (&net.Dialer{}).DialContext, "reuse", "non-reuse", network, addr) } type dialFunc func(ctx context.Context, network, address string) (net.Conn, error) diff --git a/lib/discover/cache_test.go b/lib/discover/cache_test.go index bcc571efd..130e7c97d 100644 --- a/lib/discover/cache_test.go +++ b/lib/discover/cache_test.go @@ -14,6 +14,7 @@ import ( "time" "github.com/syncthing/syncthing/lib/config" + "github.com/syncthing/syncthing/lib/connections/registry" "github.com/syncthing/syncthing/lib/events" "github.com/syncthing/syncthing/lib/protocol" ) @@ -23,7 +24,7 @@ func setupCache() *manager { cfg.Options.LocalAnnEnabled = false cfg.Options.GlobalAnnEnabled = false - return NewManager(protocol.LocalDeviceID, config.Wrap("", cfg, protocol.LocalDeviceID, events.NoopLogger), tls.Certificate{}, events.NoopLogger, nil).(*manager) + return NewManager(protocol.LocalDeviceID, config.Wrap("", cfg, protocol.LocalDeviceID, events.NoopLogger), tls.Certificate{}, events.NoopLogger, nil, registry.New()).(*manager) } func TestCacheUnique(t *testing.T) { diff --git a/lib/discover/global.go b/lib/discover/global.go index cd4b03b1b..8f3546e2a 100644 --- a/lib/discover/global.go +++ b/lib/discover/global.go @@ -14,12 +14,14 @@ import ( "errors" "fmt" "io" + "net" "net/http" "net/url" "strconv" stdsync "sync" "time" + "github.com/syncthing/syncthing/lib/connections/registry" "github.com/syncthing/syncthing/lib/dialer" "github.com/syncthing/syncthing/lib/events" "github.com/syncthing/syncthing/lib/protocol" @@ -71,7 +73,7 @@ func (e *lookupError) CacheFor() time.Duration { return e.cacheFor } -func NewGlobal(server string, cert tls.Certificate, addrList AddressLister, evLogger events.Logger) (FinderService, error) { +func NewGlobal(server string, cert tls.Certificate, addrList AddressLister, evLogger events.Logger, registry *registry.Registry) (FinderService, error) { server, opts, err := parseOptions(server) if err != nil { return nil, err @@ -88,10 +90,16 @@ func NewGlobal(server string, cert tls.Certificate, addrList AddressLister, evLo // The http.Client used for announcements. It needs to have our // certificate to prove our identity, and may or may not verify the server // certificate depending on the insecure setting. + var dialContext func(ctx context.Context, network, addr string) (net.Conn, error) + if registry != nil { + dialContext = dialer.DialContextReusePortFunc(registry) + } else { + dialContext = dialer.DialContext + } var announceClient httpClient = &contextClient{&http.Client{ Timeout: requestTimeout, Transport: &http.Transport{ - DialContext: dialer.DialContextReusePort, + DialContext: dialContext, Proxy: http.ProxyFromEnvironment, TLSClientConfig: &tls.Config{ InsecureSkipVerify: opts.insecure, diff --git a/lib/discover/global_test.go b/lib/discover/global_test.go index c8471460c..d7379cb59 100644 --- a/lib/discover/global_test.go +++ b/lib/discover/global_test.go @@ -16,6 +16,7 @@ import ( "testing" "time" + "github.com/syncthing/syncthing/lib/connections/registry" "github.com/syncthing/syncthing/lib/events" "github.com/syncthing/syncthing/lib/protocol" "github.com/syncthing/syncthing/lib/tlsutil" @@ -56,15 +57,17 @@ func TestGlobalOverHTTP(t *testing.T) { // is only allowed in combination with the "insecure" and "noannounce" // parameters. - if _, err := NewGlobal("http://192.0.2.42/", tls.Certificate{}, nil, events.NoopLogger); err == nil { + registry := registry.New() + + if _, err := NewGlobal("http://192.0.2.42/", tls.Certificate{}, nil, events.NoopLogger, registry); err == nil { t.Fatal("http is not allowed without insecure and noannounce") } - if _, err := NewGlobal("http://192.0.2.42/?insecure", tls.Certificate{}, nil, events.NoopLogger); err == nil { + if _, err := NewGlobal("http://192.0.2.42/?insecure", tls.Certificate{}, nil, events.NoopLogger, registry); err == nil { t.Fatal("http is not allowed without noannounce") } - if _, err := NewGlobal("http://192.0.2.42/?noannounce", tls.Certificate{}, nil, events.NoopLogger); err == nil { + if _, err := NewGlobal("http://192.0.2.42/?noannounce", tls.Certificate{}, nil, events.NoopLogger, registry); err == nil { t.Fatal("http is not allowed without insecure") } @@ -185,7 +188,7 @@ func TestGlobalAnnounce(t *testing.T) { go func() { _ = http.Serve(list, mux) }() url := "https://" + list.Addr().String() + "?insecure" - disco, err := NewGlobal(url, cert, new(fakeAddressLister), events.NoopLogger) + disco, err := NewGlobal(url, cert, new(fakeAddressLister), events.NoopLogger, registry.New()) if err != nil { t.Fatal(err) } @@ -210,7 +213,7 @@ func TestGlobalAnnounce(t *testing.T) { } func testLookup(url string) ([]string, error) { - disco, err := NewGlobal(url, tls.Certificate{}, nil, events.NoopLogger) + disco, err := NewGlobal(url, tls.Certificate{}, nil, events.NoopLogger, registry.New()) if err != nil { return nil, err } diff --git a/lib/discover/manager.go b/lib/discover/manager.go index 686d67310..9f3caf135 100644 --- a/lib/discover/manager.go +++ b/lib/discover/manager.go @@ -19,6 +19,7 @@ import ( "github.com/thejerf/suture/v4" "github.com/syncthing/syncthing/lib/config" + "github.com/syncthing/syncthing/lib/connections/registry" "github.com/syncthing/syncthing/lib/events" "github.com/syncthing/syncthing/lib/protocol" "github.com/syncthing/syncthing/lib/svcutil" @@ -44,12 +45,13 @@ type manager struct { cert tls.Certificate evLogger events.Logger addressLister AddressLister + registry *registry.Registry finders map[string]cachedFinder mut sync.RWMutex } -func NewManager(myID protocol.DeviceID, cfg config.Wrapper, cert tls.Certificate, evLogger events.Logger, lister AddressLister) Manager { +func NewManager(myID protocol.DeviceID, cfg config.Wrapper, cert tls.Certificate, evLogger events.Logger, lister AddressLister, registry *registry.Registry) Manager { m := &manager{ Supervisor: suture.New("discover.Manager", svcutil.SpecWithDebugLogger(l)), myID: myID, @@ -57,6 +59,7 @@ func NewManager(myID protocol.DeviceID, cfg config.Wrapper, cert tls.Certificate cert: cert, evLogger: evLogger, addressLister: lister, + registry: registry, finders: make(map[string]cachedFinder), mut: sync.NewRWMutex(), @@ -257,7 +260,7 @@ func (m *manager) CommitConfiguration(_, to config.Configuration) (handled bool) if _, ok := m.finders[identity]; ok { continue } - gd, err := NewGlobal(srv, m.cert, m.addressLister, m.evLogger) + gd, err := NewGlobal(srv, m.cert, m.addressLister, m.evLogger, m.registry) if err != nil { l.Warnln("Global discovery:", err) continue diff --git a/lib/syncthing/syncthing.go b/lib/syncthing/syncthing.go index 271acb4d1..b0fe9adbd 100644 --- a/lib/syncthing/syncthing.go +++ b/lib/syncthing/syncthing.go @@ -26,6 +26,7 @@ import ( "github.com/syncthing/syncthing/lib/build" "github.com/syncthing/syncthing/lib/config" "github.com/syncthing/syncthing/lib/connections" + "github.com/syncthing/syncthing/lib/connections/registry" "github.com/syncthing/syncthing/lib/db" "github.com/syncthing/syncthing/lib/db/backend" "github.com/syncthing/syncthing/lib/discover" @@ -276,8 +277,9 @@ func (a *App) startup() error { // Create a wrapper that is then wired after they are both setup. addrLister := &lateAddressLister{} - discoveryManager := discover.NewManager(a.myID, a.cfg, a.cert, a.evLogger, addrLister) - connectionsService := connections.NewService(a.cfg, a.myID, m, tlsCfg, discoveryManager, bepProtocolName, tlsDefaultCommonName, a.evLogger) + connRegistry := registry.New() + discoveryManager := discover.NewManager(a.myID, a.cfg, a.cert, a.evLogger, addrLister, connRegistry) + connectionsService := connections.NewService(a.cfg, a.myID, m, tlsCfg, discoveryManager, bepProtocolName, tlsDefaultCommonName, a.evLogger, connRegistry) addrLister.AddressLister = connectionsService