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.
This commit is contained in:
Jakob Borg 2020-12-09 19:23:50 +01:00 committed by GitHub
parent 8fd6b1d428
commit e9b68a224c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 39 deletions

View File

@ -8,29 +8,39 @@ package connections
import "github.com/syncthing/syncthing/lib/config" import "github.com/syncthing/syncthing/lib/config"
// deprecatedListener is never valid // invalidListener is never valid
type deprecatedListener struct { type invalidListener struct {
listenerFactory listenerFactory
err error
} }
func (deprecatedListener) Valid(_ config.Configuration) error { func (i invalidListener) Valid(_ config.Configuration) error {
return errDeprecated if i.err == nil {
// fallback so we don't accidentally return nil
return errUnsupported
}
return i.err
} }
// deprecatedDialer is never valid // invalidDialer is never valid
type deprecatedDialer struct { type invalidDialer struct {
dialerFactory dialerFactory
err error
} }
func (deprecatedDialer) Valid(_ config.Configuration) error { func (i invalidDialer) Valid(_ config.Configuration) error {
return errDeprecated if i.err == nil {
// fallback so we don't accidentally return nil
return errUnsupported
}
return i.err
} }
func init() { func init() {
listeners["kcp"] = deprecatedListener{} listeners["kcp"] = invalidListener{err: errDeprecated}
listeners["kcp4"] = deprecatedListener{} listeners["kcp4"] = invalidListener{err: errDeprecated}
listeners["kcp6"] = deprecatedListener{} listeners["kcp6"] = invalidListener{err: errDeprecated}
dialers["kcp"] = deprecatedDialer{} dialers["kcp"] = invalidDialer{err: errDeprecated}
dialers["kcp4"] = deprecatedDialer{} dialers["kcp4"] = invalidDialer{err: errDeprecated}
dialers["kcp6"] = deprecatedDialer{} dialers["kcp6"] = invalidDialer{err: errDeprecated}
} }

View File

@ -4,7 +4,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file, // 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/. // You can obtain one at https://mozilla.org/MPL/2.0/.
// +build go1.12,!noquic // +build go1.14,!noquic,!go1.16
package connections package connections

View File

@ -4,7 +4,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file, // 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/. // You can obtain one at http://mozilla.org/MPL/2.0/.
// +build go1.12,!noquic // +build go1.14,!noquic,!go1.16
package connections package connections

View File

@ -4,7 +4,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file, // 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/. // You can obtain one at http://mozilla.org/MPL/2.0/.
// +build go1.12,!noquic // +build go1.14,!noquic,!go1.16
package connections package connections

View File

@ -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}
}
}

View File

@ -41,8 +41,15 @@ var (
) )
var ( var (
errDisabled = errors.New("disabled by configuration") // Dialers and listeners return errUnsupported (or a wrapped variant)
errDeprecated = errors.New("deprecated protocol") // 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 ( const (
@ -336,7 +343,6 @@ func (s *service) handle(ctx context.Context) error {
s.model.AddConnection(modelConn, hello) s.model.AddConnection(modelConn, hello)
continue continue
} }
return nil
} }
func (s *service) connect(ctx context.Context) error { func (s *service) connect(ctx context.Context) error {
@ -441,16 +447,10 @@ func (s *service) connect(ctx context.Context) error {
if err != nil { if err != nil {
s.setConnectionStatus(addr, err) s.setConnectionStatus(addr, err)
} }
switch err { if errors.Is(err, errUnsupported) {
case nil: l.Debugf("Dialer for %v: %v", uri, err)
// all good
case errDisabled:
l.Debugln("Dialer for", uri, "is disabled")
continue continue
case errDeprecated: } else if err != nil {
l.Debugln("Dialer for", uri, "is deprecated")
continue
default:
l.Infof("Dialer for %v: %v", uri, err) l.Infof("Dialer for %v: %v", uri, err)
continue continue
} }
@ -505,7 +505,6 @@ func (s *service) connect(ctx context.Context) error {
return ctx.Err() return ctx.Err()
} }
} }
return nil
} }
func (s *service) isLANHost(host string) bool { 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) factory, err := getListenerFactory(to, uri)
switch err { if errors.Is(err, errUnsupported) {
case nil: l.Debugf("Listener for %v: %v", uri, err)
// all good
case errDisabled:
l.Debugln("Listener for", uri, "is disabled")
continue continue
case errDeprecated: } else if err != nil {
l.Debugln("Listener for", uri, "is deprecated")
continue
default:
l.Infof("Listener for %v: %v", uri, err) l.Infof("Listener for %v: %v", uri, err)
continue continue
} }