lib/connections, lib/model: Connection service should expose a single interface
Makes testing easier, which we'll need GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3771
This commit is contained in:
@@ -28,21 +28,21 @@ type relayDialer struct {
|
||||
tlsCfg *tls.Config
|
||||
}
|
||||
|
||||
func (d *relayDialer) Dial(id protocol.DeviceID, uri *url.URL) (IntermediateConnection, error) {
|
||||
func (d *relayDialer) Dial(id protocol.DeviceID, uri *url.URL) (internalConn, error) {
|
||||
inv, err := client.GetInvitationFromRelay(uri, id, d.tlsCfg.Certificates, 10*time.Second)
|
||||
if err != nil {
|
||||
return IntermediateConnection{}, err
|
||||
return internalConn{}, err
|
||||
}
|
||||
|
||||
conn, err := client.JoinSession(inv)
|
||||
if err != nil {
|
||||
return IntermediateConnection{}, err
|
||||
return internalConn{}, err
|
||||
}
|
||||
|
||||
err = dialer.SetTCPOptions(conn)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
return IntermediateConnection{}, err
|
||||
return internalConn{}, err
|
||||
}
|
||||
|
||||
var tc *tls.Conn
|
||||
@@ -55,10 +55,10 @@ func (d *relayDialer) Dial(id protocol.DeviceID, uri *url.URL) (IntermediateConn
|
||||
err = tlsTimedHandshake(tc)
|
||||
if err != nil {
|
||||
tc.Close()
|
||||
return IntermediateConnection{}, err
|
||||
return internalConn{}, err
|
||||
}
|
||||
|
||||
return IntermediateConnection{tc, "Relay (Client)", relayPriority}, nil
|
||||
return internalConn{tc, connTypeRelayClient, relayPriority}, nil
|
||||
}
|
||||
|
||||
func (relayDialer) Priority() int {
|
||||
|
||||
@@ -30,7 +30,7 @@ type relayListener struct {
|
||||
|
||||
uri *url.URL
|
||||
tlsCfg *tls.Config
|
||||
conns chan IntermediateConnection
|
||||
conns chan internalConn
|
||||
factory listenerFactory
|
||||
|
||||
err error
|
||||
@@ -93,7 +93,7 @@ func (t *relayListener) Serve() {
|
||||
continue
|
||||
}
|
||||
|
||||
t.conns <- IntermediateConnection{tc, "Relay (Server)", relayPriority}
|
||||
t.conns <- internalConn{tc, connTypeRelayServer, relayPriority}
|
||||
|
||||
// Poor mans notifier that informs the connection service that the
|
||||
// relay URI has changed. This can only happen when we connect to a
|
||||
@@ -167,7 +167,7 @@ func (t *relayListener) String() string {
|
||||
|
||||
type relayListenerFactory struct{}
|
||||
|
||||
func (f *relayListenerFactory) New(uri *url.URL, cfg *config.Wrapper, tlsCfg *tls.Config, conns chan IntermediateConnection, natService *nat.Service) genericListener {
|
||||
func (f *relayListenerFactory) New(uri *url.URL, cfg *config.Wrapper, tlsCfg *tls.Config, conns chan internalConn, natService *nat.Service) genericListener {
|
||||
return &relayListener{
|
||||
uri: uri,
|
||||
tlsCfg: tlsCfg,
|
||||
|
||||
@@ -50,7 +50,7 @@ type Service struct {
|
||||
model Model
|
||||
tlsCfg *tls.Config
|
||||
discoverer discover.Finder
|
||||
conns chan IntermediateConnection
|
||||
conns chan internalConn
|
||||
bepProtocolName string
|
||||
tlsDefaultCommonName string
|
||||
lans []*net.IPNet
|
||||
@@ -65,7 +65,7 @@ type Service struct {
|
||||
listenerSupervisor *suture.Supervisor
|
||||
|
||||
curConMut sync.Mutex
|
||||
currentConnection map[protocol.DeviceID]Connection
|
||||
currentConnection map[protocol.DeviceID]completeConn
|
||||
}
|
||||
|
||||
func NewService(cfg *config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg *tls.Config, discoverer discover.Finder,
|
||||
@@ -82,7 +82,7 @@ func NewService(cfg *config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg *
|
||||
model: mdl,
|
||||
tlsCfg: tlsCfg,
|
||||
discoverer: discoverer,
|
||||
conns: make(chan IntermediateConnection),
|
||||
conns: make(chan internalConn),
|
||||
bepProtocolName: bepProtocolName,
|
||||
tlsDefaultCommonName: tlsDefaultCommonName,
|
||||
lans: lans,
|
||||
@@ -105,7 +105,7 @@ func NewService(cfg *config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg *
|
||||
}),
|
||||
|
||||
curConMut: sync.NewMutex(),
|
||||
currentConnection: make(map[protocol.DeviceID]Connection),
|
||||
currentConnection: make(map[protocol.DeviceID]completeConn),
|
||||
}
|
||||
cfg.Subscribe(service)
|
||||
|
||||
@@ -218,7 +218,7 @@ next:
|
||||
priorityKnown := ok && connected
|
||||
|
||||
// Lower priority is better, just like nice etc.
|
||||
if priorityKnown && ct.Priority > c.Priority {
|
||||
if priorityKnown && ct.internalConn.priority > c.priority {
|
||||
l.Debugln("Switching connections", remoteID)
|
||||
} else if connected {
|
||||
// We should not already be connected to the other party. TODO: This
|
||||
@@ -268,9 +268,9 @@ next:
|
||||
rd = NewReadLimiter(c, s.readRateLimit)
|
||||
}
|
||||
|
||||
name := fmt.Sprintf("%s-%s (%s)", c.LocalAddr(), c.RemoteAddr(), c.Type)
|
||||
name := fmt.Sprintf("%s-%s (%s)", c.LocalAddr(), c.RemoteAddr(), c.Type())
|
||||
protoConn := protocol.NewConnection(remoteID, rd, wr, s.model, name, deviceCfg.Compression)
|
||||
modelConn := Connection{c, protoConn}
|
||||
modelConn := completeConn{c, protoConn}
|
||||
|
||||
l.Infof("Established secure connection to %s at %s", remoteID, name)
|
||||
l.Debugf("cipher suite: %04X in lan: %t", c.ConnectionState().CipherSuite, !limit)
|
||||
@@ -329,7 +329,7 @@ func (s *Service) connect() {
|
||||
s.curConMut.Unlock()
|
||||
priorityKnown := ok && connected
|
||||
|
||||
if priorityKnown && ct.Priority == bestDialerPrio {
|
||||
if priorityKnown && ct.internalConn.priority == bestDialerPrio {
|
||||
// Things are already as good as they can get.
|
||||
continue
|
||||
}
|
||||
@@ -377,8 +377,8 @@ func (s *Service) connect() {
|
||||
continue
|
||||
}
|
||||
|
||||
if priorityKnown && dialerFactory.Priority() >= ct.Priority {
|
||||
l.Debugf("Not dialing using %s as priority is less than current connection (%d >= %d)", dialerFactory, dialerFactory.Priority(), ct.Priority)
|
||||
if priorityKnown && dialerFactory.Priority() >= ct.internalConn.priority {
|
||||
l.Debugf("Not dialing using %s as priority is less than current connection (%d >= %d)", dialerFactory, dialerFactory.Priority(), ct.internalConn.priority)
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ package connections
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/url"
|
||||
"time"
|
||||
@@ -18,19 +19,61 @@ import (
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
)
|
||||
|
||||
type IntermediateConnection struct {
|
||||
*tls.Conn
|
||||
Type string
|
||||
Priority int
|
||||
// Connection is what we expose to the outside. It is a protocol.Connection
|
||||
// that can be closed and has some metadata.
|
||||
type Connection interface {
|
||||
protocol.Connection
|
||||
io.Closer
|
||||
Type() string
|
||||
RemoteAddr() net.Addr
|
||||
}
|
||||
|
||||
type Connection struct {
|
||||
IntermediateConnection
|
||||
// completeConn is the aggregation of an internalConn and the
|
||||
// protocol.Connection running on top of it. It implements the Connection
|
||||
// interface.
|
||||
type completeConn struct {
|
||||
internalConn
|
||||
protocol.Connection
|
||||
}
|
||||
|
||||
func (c Connection) String() string {
|
||||
return fmt.Sprintf("%s-%s/%s", c.LocalAddr(), c.RemoteAddr(), c.Type)
|
||||
// internalConn is the raw TLS connection plus some metadata on where it
|
||||
// came from (type, priority).
|
||||
type internalConn struct {
|
||||
*tls.Conn
|
||||
connType connType
|
||||
priority int
|
||||
}
|
||||
|
||||
type connType int
|
||||
|
||||
const (
|
||||
connTypeRelayClient connType = iota
|
||||
connTypeRelayServer
|
||||
connTypeTCPClient
|
||||
connTypeTCPServer
|
||||
)
|
||||
|
||||
func (t connType) String() string {
|
||||
switch t {
|
||||
case connTypeRelayClient:
|
||||
return "relay-client"
|
||||
case connTypeRelayServer:
|
||||
return "relay-server"
|
||||
case connTypeTCPClient:
|
||||
return "tcp-client"
|
||||
case connTypeTCPServer:
|
||||
return "tcp-server"
|
||||
default:
|
||||
return "unknown-type"
|
||||
}
|
||||
}
|
||||
|
||||
func (c internalConn) Type() string {
|
||||
return c.connType.String()
|
||||
}
|
||||
|
||||
func (c internalConn) String() string {
|
||||
return fmt.Sprintf("%s-%s/%s", c.LocalAddr(), c.RemoteAddr(), c.connType.String())
|
||||
}
|
||||
|
||||
type dialerFactory interface {
|
||||
@@ -41,12 +84,12 @@ type dialerFactory interface {
|
||||
}
|
||||
|
||||
type genericDialer interface {
|
||||
Dial(protocol.DeviceID, *url.URL) (IntermediateConnection, error)
|
||||
Dial(protocol.DeviceID, *url.URL) (internalConn, error)
|
||||
RedialFrequency() time.Duration
|
||||
}
|
||||
|
||||
type listenerFactory interface {
|
||||
New(*url.URL, *config.Wrapper, *tls.Config, chan IntermediateConnection, *nat.Service) genericListener
|
||||
New(*url.URL, *config.Wrapper, *tls.Config, chan internalConn, *nat.Service) genericListener
|
||||
Enabled(config.Configuration) bool
|
||||
}
|
||||
|
||||
|
||||
@@ -30,23 +30,23 @@ type tcpDialer struct {
|
||||
tlsCfg *tls.Config
|
||||
}
|
||||
|
||||
func (d *tcpDialer) Dial(id protocol.DeviceID, uri *url.URL) (IntermediateConnection, error) {
|
||||
func (d *tcpDialer) Dial(id protocol.DeviceID, uri *url.URL) (internalConn, error) {
|
||||
uri = fixupPort(uri)
|
||||
|
||||
conn, err := dialer.DialTimeout(uri.Scheme, uri.Host, 10*time.Second)
|
||||
if err != nil {
|
||||
l.Debugln(err)
|
||||
return IntermediateConnection{}, err
|
||||
return internalConn{}, err
|
||||
}
|
||||
|
||||
tc := tls.Client(conn, d.tlsCfg)
|
||||
err = tlsTimedHandshake(tc)
|
||||
if err != nil {
|
||||
tc.Close()
|
||||
return IntermediateConnection{}, err
|
||||
return internalConn{}, err
|
||||
}
|
||||
|
||||
return IntermediateConnection{tc, "TCP (Client)", tcpPriority}, nil
|
||||
return internalConn{tc, connTypeTCPClient, tcpPriority}, nil
|
||||
}
|
||||
|
||||
func (d *tcpDialer) RedialFrequency() time.Duration {
|
||||
|
||||
@@ -32,7 +32,7 @@ type tcpListener struct {
|
||||
uri *url.URL
|
||||
tlsCfg *tls.Config
|
||||
stop chan struct{}
|
||||
conns chan IntermediateConnection
|
||||
conns chan internalConn
|
||||
factory listenerFactory
|
||||
|
||||
natService *nat.Service
|
||||
@@ -115,7 +115,7 @@ func (t *tcpListener) Serve() {
|
||||
continue
|
||||
}
|
||||
|
||||
t.conns <- IntermediateConnection{tc, "TCP (Server)", tcpPriority}
|
||||
t.conns <- internalConn{tc, connTypeTCPServer, tcpPriority}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ func (t *tcpListener) Factory() listenerFactory {
|
||||
|
||||
type tcpListenerFactory struct{}
|
||||
|
||||
func (f *tcpListenerFactory) New(uri *url.URL, cfg *config.Wrapper, tlsCfg *tls.Config, conns chan IntermediateConnection, natService *nat.Service) genericListener {
|
||||
func (f *tcpListenerFactory) New(uri *url.URL, cfg *config.Wrapper, tlsCfg *tls.Config, conns chan internalConn, natService *nat.Service) genericListener {
|
||||
return &tcpListener{
|
||||
uri: fixupPort(uri),
|
||||
tlsCfg: tlsCfg,
|
||||
|
||||
Reference in New Issue
Block a user