From e9b68a224c5096f10616871cfd19904e70566833 Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Wed, 9 Dec 2020 19:23:50 +0100 Subject: [PATCH] lib/connections: Handle QUIC not being available (#7186) This does two things: - Exclude QUIC from go1.16 builds, automatically, for now, since it doesn't work and just panics. - Provide some fake listeners and dialers when QUIC is disabled. These fake listeners and dialers indicate that they are disabled and unsupported, which silences "Dialing $address: unknown address scheme: quic" type of stuff which is not super helpful to the user. --- lib/connections/deprecated.go | 38 ++++++++++++++++++----------- lib/connections/quic_dial.go | 2 +- lib/connections/quic_listen.go | 2 +- lib/connections/quic_misc.go | 2 +- lib/connections/quic_unsupported.go | 16 ++++++++++++ lib/connections/service.go | 37 ++++++++++++---------------- 6 files changed, 58 insertions(+), 39 deletions(-) create mode 100644 lib/connections/quic_unsupported.go diff --git a/lib/connections/deprecated.go b/lib/connections/deprecated.go index 2438008b3..976aa1485 100644 --- a/lib/connections/deprecated.go +++ b/lib/connections/deprecated.go @@ -8,29 +8,39 @@ package connections import "github.com/syncthing/syncthing/lib/config" -// deprecatedListener is never valid -type deprecatedListener struct { +// invalidListener is never valid +type invalidListener struct { listenerFactory + err error } -func (deprecatedListener) Valid(_ config.Configuration) error { - return errDeprecated +func (i invalidListener) Valid(_ config.Configuration) error { + if i.err == nil { + // fallback so we don't accidentally return nil + return errUnsupported + } + return i.err } -// deprecatedDialer is never valid -type deprecatedDialer struct { +// invalidDialer is never valid +type invalidDialer struct { dialerFactory + err error } -func (deprecatedDialer) Valid(_ config.Configuration) error { - return errDeprecated +func (i invalidDialer) Valid(_ config.Configuration) error { + if i.err == nil { + // fallback so we don't accidentally return nil + return errUnsupported + } + return i.err } func init() { - listeners["kcp"] = deprecatedListener{} - listeners["kcp4"] = deprecatedListener{} - listeners["kcp6"] = deprecatedListener{} - dialers["kcp"] = deprecatedDialer{} - dialers["kcp4"] = deprecatedDialer{} - dialers["kcp6"] = deprecatedDialer{} + listeners["kcp"] = invalidListener{err: errDeprecated} + listeners["kcp4"] = invalidListener{err: errDeprecated} + listeners["kcp6"] = invalidListener{err: errDeprecated} + dialers["kcp"] = invalidDialer{err: errDeprecated} + dialers["kcp4"] = invalidDialer{err: errDeprecated} + dialers["kcp6"] = invalidDialer{err: errDeprecated} } diff --git a/lib/connections/quic_dial.go b/lib/connections/quic_dial.go index 92afe3626..df988fc48 100644 --- a/lib/connections/quic_dial.go +++ b/lib/connections/quic_dial.go @@ -4,7 +4,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at https://mozilla.org/MPL/2.0/. -// +build go1.12,!noquic +// +build go1.14,!noquic,!go1.16 package connections diff --git a/lib/connections/quic_listen.go b/lib/connections/quic_listen.go index 8a320de8f..8a8db5e98 100644 --- a/lib/connections/quic_listen.go +++ b/lib/connections/quic_listen.go @@ -4,7 +4,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at http://mozilla.org/MPL/2.0/. -// +build go1.12,!noquic +// +build go1.14,!noquic,!go1.16 package connections diff --git a/lib/connections/quic_misc.go b/lib/connections/quic_misc.go index cebc8e5eb..b4bb640d7 100644 --- a/lib/connections/quic_misc.go +++ b/lib/connections/quic_misc.go @@ -4,7 +4,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at http://mozilla.org/MPL/2.0/. -// +build go1.12,!noquic +// +build go1.14,!noquic,!go1.16 package connections diff --git a/lib/connections/quic_unsupported.go b/lib/connections/quic_unsupported.go new file mode 100644 index 000000000..4a000480f --- /dev/null +++ b/lib/connections/quic_unsupported.go @@ -0,0 +1,16 @@ +// Copyright (C) 2020 The Syncthing Authors. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at http://mozilla.org/MPL/2.0/. + +// +build noquic !go1.14 go1.16 + +package connections + +func init() { + for _, scheme := range []string{"quic", "quic4", "quic6"} { + listeners[scheme] = invalidListener{err: errNotInBuild} + dialers[scheme] = invalidDialer{err: errNotInBuild} + } +} diff --git a/lib/connections/service.go b/lib/connections/service.go index 4a347be57..7723a12a9 100644 --- a/lib/connections/service.go +++ b/lib/connections/service.go @@ -41,8 +41,15 @@ var ( ) var ( - errDisabled = errors.New("disabled by configuration") - errDeprecated = errors.New("deprecated protocol") + // Dialers and listeners return errUnsupported (or a wrapped variant) + // when they are intentionally out of service due to configuration, + // build, etc. This is not logged loudly. + errUnsupported = errors.New("unsupported protocol") + + // These are specific explanations for errUnsupported. + errDisabled = fmt.Errorf("%w: disabled by configuration", errUnsupported) + errDeprecated = fmt.Errorf("%w: deprecated", errUnsupported) + errNotInBuild = fmt.Errorf("%w: disabled at build time", errUnsupported) ) const ( @@ -336,7 +343,6 @@ func (s *service) handle(ctx context.Context) error { s.model.AddConnection(modelConn, hello) continue } - return nil } func (s *service) connect(ctx context.Context) error { @@ -441,16 +447,10 @@ func (s *service) connect(ctx context.Context) error { if err != nil { s.setConnectionStatus(addr, err) } - switch err { - case nil: - // all good - case errDisabled: - l.Debugln("Dialer for", uri, "is disabled") + if errors.Is(err, errUnsupported) { + l.Debugf("Dialer for %v: %v", uri, err) continue - case errDeprecated: - l.Debugln("Dialer for", uri, "is deprecated") - continue - default: + } else if err != nil { l.Infof("Dialer for %v: %v", uri, err) continue } @@ -505,7 +505,6 @@ func (s *service) connect(ctx context.Context) error { return ctx.Err() } } - return nil } func (s *service) isLANHost(host string) bool { @@ -634,16 +633,10 @@ func (s *service) CommitConfiguration(from, to config.Configuration) bool { } factory, err := getListenerFactory(to, uri) - switch err { - case nil: - // all good - case errDisabled: - l.Debugln("Listener for", uri, "is disabled") + if errors.Is(err, errUnsupported) { + l.Debugf("Listener for %v: %v", uri, err) continue - case errDeprecated: - l.Debugln("Listener for", uri, "is deprecated") - continue - default: + } else if err != nil { l.Infof("Listener for %v: %v", uri, err) continue }