lib/config, lib/connections: Configurable protocol priority (ref #8626) (#8868)

This makes the various protocol priorities configurable among the other
options. With this, it's possible to prefer QUIC over TCP for WAN
connections, for example. Both sides need to be similarly configured for
this to work properly.

The default priority order remains the same as previously (TCP, QUIC,
Relay, with LAN better than WAN).

To make this happen I made each dialer & listener more priority aware,
and moved the check for whether a connection is LAN or not into the
dialer / listener -- this is the new "lanChecker" type that's passed
around.
This commit is contained in:
Jakob Borg
2023-04-16 14:54:28 +02:00
committed by GitHub
parent c867a5f5b3
commit 9b660c1959
16 changed files with 622 additions and 361 deletions
+20 -5
View File
@@ -87,10 +87,11 @@ func (t connType) Transport() string {
}
}
func newInternalConn(tc tlsConn, connType connType, priority int) internalConn {
func newInternalConn(tc tlsConn, connType connType, isLocal bool, priority int) internalConn {
return internalConn{
tlsConn: tc,
connType: connType,
isLocal: isLocal,
priority: priority,
establishedAt: time.Now().Truncate(time.Second),
}
@@ -138,12 +139,15 @@ func (c internalConn) EstablishedAt() time.Time {
}
func (c internalConn) String() string {
return fmt.Sprintf("%s-%s/%s/%s", c.LocalAddr(), c.RemoteAddr(), c.Type(), c.Crypto())
t := "WAN"
if c.isLocal {
t = "LAN"
}
return fmt.Sprintf("%s-%s/%s/%s/%s-P%d", c.LocalAddr(), c.RemoteAddr(), c.Type(), c.Crypto(), t, c.Priority())
}
type dialerFactory interface {
New(config.OptionsConfiguration, *tls.Config, *registry.Registry) genericDialer
Priority() int
New(config.OptionsConfiguration, *tls.Config, *registry.Registry, *lanChecker) genericDialer
AlwaysWAN() bool
Valid(config.Configuration) error
String() string
@@ -153,19 +157,30 @@ type commonDialer struct {
trafficClass int
reconnectInterval time.Duration
tlsCfg *tls.Config
lanChecker *lanChecker
lanPriority int
wanPriority int
}
func (d *commonDialer) RedialFrequency() time.Duration {
return d.reconnectInterval
}
func (d *commonDialer) Priority(host string) int {
if d.lanChecker.isLANHost(host) {
return d.lanPriority
}
return d.wanPriority
}
type genericDialer interface {
Dial(context.Context, protocol.DeviceID, *url.URL) (internalConn, error)
RedialFrequency() time.Duration
Priority(host string) int
}
type listenerFactory interface {
New(*url.URL, config.Wrapper, *tls.Config, chan internalConn, *nat.Service, *registry.Registry) genericListener
New(*url.URL, config.Wrapper, *tls.Config, chan internalConn, *nat.Service, *registry.Registry, *lanChecker) genericListener
Valid(config.Configuration) error
}