Browse Source

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.
Jakob Borg 4 years ago
parent
commit
e9b68a224c

+ 24 - 14
lib/connections/deprecated.go

@@ -8,29 +8,39 @@ package connections
 
 
 import "github.com/syncthing/syncthing/lib/config"
 import "github.com/syncthing/syncthing/lib/config"
 
 
-// deprecatedListener is never valid
-type deprecatedListener struct {
+// invalidListener is never valid
+type invalidListener struct {
 	listenerFactory
 	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
 	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() {
 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}
 }
 }

+ 1 - 1
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,
 // 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
 
 

+ 1 - 1
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,
 // 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
 
 

+ 1 - 1
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,
 // 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
 
 

+ 16 - 0
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}
+	}
+}

+ 15 - 22
lib/connections/service.go

@@ -41,8 +41,15 @@ var (
 )
 )
 
 
 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 (
 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 {
-				case nil:
-					// all good
-				case errDisabled:
-					l.Debugln("Dialer for", uri, "is disabled")
-					continue
-				case errDeprecated:
-					l.Debugln("Dialer for", uri, "is deprecated")
+				if errors.Is(err, errUnsupported) {
+					l.Debugf("Dialer for %v: %v", uri, err)
 					continue
 					continue
-				default:
+				} else if err != nil {
 					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 {
-		case nil:
-			// all good
-		case errDisabled:
-			l.Debugln("Listener for", uri, "is disabled")
-			continue
-		case errDeprecated:
-			l.Debugln("Listener for", uri, "is deprecated")
+		if errors.Is(err, errUnsupported) {
+			l.Debugf("Listener for %v: %v", uri, err)
 			continue
 			continue
-		default:
+		} else if err != nil {
 			l.Infof("Listener for %v: %v", uri, err)
 			l.Infof("Listener for %v: %v", uri, err)
 			continue
 			continue
 		}
 		}