Browse Source

Add timeouts to relay methods

Audrius Butkevicius 10 years ago
parent
commit
431d51f5c4

+ 1 - 1
lib/connections/connections.go

@@ -377,7 +377,7 @@ func (s *connectionSvc) connectViaRelay(deviceID protocol.DeviceID, addr discove
 		return nil
 	}
 
-	inv, err := client.GetInvitationFromRelay(uri, deviceID, s.tlsCfg.Certificates)
+	inv, err := client.GetInvitationFromRelay(uri, deviceID, s.tlsCfg.Certificates, 10*time.Second)
 	if err != nil {
 		l.Debugf("Failed to get invitation for %s from %s: %v", deviceID, uri, err)
 		return nil

+ 3 - 3
lib/relay/client/client.go

@@ -11,7 +11,7 @@ import (
 	"github.com/syncthing/syncthing/lib/relay/protocol"
 )
 
-type relayClientFactory func(uri *url.URL, certs []tls.Certificate, invitations chan protocol.SessionInvitation) RelayClient
+type relayClientFactory func(uri *url.URL, certs []tls.Certificate, invitations chan protocol.SessionInvitation, timeout time.Duration) RelayClient
 
 var (
 	supportedSchemes = map[string]relayClientFactory{
@@ -31,11 +31,11 @@ type RelayClient interface {
 	URI() *url.URL
 }
 
-func NewClient(uri *url.URL, certs []tls.Certificate, invitations chan protocol.SessionInvitation) (RelayClient, error) {
+func NewClient(uri *url.URL, certs []tls.Certificate, invitations chan protocol.SessionInvitation, timeout time.Duration) (RelayClient, error) {
 	factory, ok := supportedSchemes[uri.Scheme]
 	if !ok {
 		return nil, fmt.Errorf("Unsupported scheme: %s", uri.Scheme)
 	}
 
-	return factory(uri, certs, invitations), nil
+	return factory(uri, certs, invitations, timeout), nil
 }

+ 4 - 2
lib/relay/client/dynamic.go

@@ -22,13 +22,14 @@ type dynamicClient struct {
 	certs                    []tls.Certificate
 	invitations              chan protocol.SessionInvitation
 	closeInvitationsOnFinish bool
+	timeout                  time.Duration
 
 	mut    sync.RWMutex
 	client RelayClient
 	stop   chan struct{}
 }
 
-func newDynamicClient(uri *url.URL, certs []tls.Certificate, invitations chan protocol.SessionInvitation) RelayClient {
+func newDynamicClient(uri *url.URL, certs []tls.Certificate, invitations chan protocol.SessionInvitation, timeout time.Duration) RelayClient {
 	closeInvitationsOnFinish := false
 	if invitations == nil {
 		closeInvitationsOnFinish = true
@@ -39,6 +40,7 @@ func newDynamicClient(uri *url.URL, certs []tls.Certificate, invitations chan pr
 		certs:                    certs,
 		invitations:              invitations,
 		closeInvitationsOnFinish: closeInvitationsOnFinish,
+		timeout:                  timeout,
 
 		mut: sync.NewRWMutex(),
 	}
@@ -94,7 +96,7 @@ func (c *dynamicClient) Serve() {
 				l.Debugln(c, "skipping relay", addr, err)
 				continue
 			}
-			client, err := NewClient(ruri, c.certs, c.invitations)
+			client, err := NewClient(ruri, c.certs, c.invitations, c.timeout)
 			if err != nil {
 				continue
 			}

+ 5 - 5
lib/relay/client/methods.go

@@ -16,7 +16,7 @@ import (
 	"github.com/syncthing/syncthing/lib/relay/protocol"
 )
 
-func GetInvitationFromRelay(uri *url.URL, id syncthingprotocol.DeviceID, certs []tls.Certificate) (protocol.SessionInvitation, error) {
+func GetInvitationFromRelay(uri *url.URL, id syncthingprotocol.DeviceID, certs []tls.Certificate, timeout time.Duration) (protocol.SessionInvitation, error) {
 	if uri.Scheme != "relay" {
 		return protocol.SessionInvitation{}, fmt.Errorf("Unsupported relay scheme: %v", uri.Scheme)
 	}
@@ -27,7 +27,7 @@ func GetInvitationFromRelay(uri *url.URL, id syncthingprotocol.DeviceID, certs [
 	}
 
 	conn := tls.Client(rconn, configForCerts(certs))
-	conn.SetDeadline(time.Now().Add(10 * time.Second))
+	conn.SetDeadline(time.Now().Add(timeout))
 
 	if err := performHandshakeAndValidation(conn, uri); err != nil {
 		return protocol.SessionInvitation{}, err
@@ -99,10 +99,10 @@ func JoinSession(invitation protocol.SessionInvitation) (net.Conn, error) {
 	}
 }
 
-func TestRelay(uri *url.URL, certs []tls.Certificate, sleep time.Duration, times int) bool {
+func TestRelay(uri *url.URL, certs []tls.Certificate, sleep, timeout time.Duration, times int) bool {
 	id := syncthingprotocol.NewDeviceID(certs[0].Certificate[0])
 	invs := make(chan protocol.SessionInvitation, 1)
-	c, err := NewClient(uri, certs, invs)
+	c, err := NewClient(uri, certs, invs, timeout)
 	if err != nil {
 		close(invs)
 		return false
@@ -114,7 +114,7 @@ func TestRelay(uri *url.URL, certs []tls.Certificate, sleep time.Duration, times
 	}()
 
 	for i := 0; i < times; i++ {
-		_, err := GetInvitationFromRelay(uri, id, certs)
+		_, err := GetInvitationFromRelay(uri, id, certs, timeout)
 		if err == nil {
 			return true
 		}

+ 8 - 6
lib/relay/client/static.go

@@ -22,7 +22,8 @@ type staticClient struct {
 
 	config *tls.Config
 
-	timeout time.Duration
+	messageTimeout time.Duration
+	connectTimeout time.Duration
 
 	stop    chan struct{}
 	stopped chan struct{}
@@ -34,7 +35,7 @@ type staticClient struct {
 	latency   time.Duration
 }
 
-func newStaticClient(uri *url.URL, certs []tls.Certificate, invitations chan protocol.SessionInvitation) RelayClient {
+func newStaticClient(uri *url.URL, certs []tls.Certificate, invitations chan protocol.SessionInvitation, timeout time.Duration) RelayClient {
 	closeInvitationsOnFinish := false
 	if invitations == nil {
 		closeInvitationsOnFinish = true
@@ -49,7 +50,8 @@ func newStaticClient(uri *url.URL, certs []tls.Certificate, invitations chan pro
 
 		config: configForCerts(certs),
 
-		timeout: time.Minute * 2,
+		messageTimeout: time.Minute * 2,
+		connectTimeout: timeout,
 
 		stop:    make(chan struct{}),
 		stopped: make(chan struct{}),
@@ -95,12 +97,12 @@ func (c *staticClient) Serve() {
 
 	go messageReader(c.conn, messages, errors)
 
-	timeout := time.NewTimer(c.timeout)
+	timeout := time.NewTimer(c.messageTimeout)
 
 	for {
 		select {
 		case message := <-messages:
-			timeout.Reset(c.timeout)
+			timeout.Reset(c.messageTimeout)
 			l.Debugf("%s received message %T", c, message)
 
 			switch msg := message.(type) {
@@ -201,7 +203,7 @@ func (c *staticClient) connect() error {
 		return err
 	}
 
-	if err := conn.SetDeadline(time.Now().Add(10 * time.Second)); err != nil {
+	if err := conn.SetDeadline(time.Now().Add(c.connectTimeout)); err != nil {
 		conn.Close()
 		return err
 	}

+ 1 - 1
lib/relay/relay.go

@@ -110,7 +110,7 @@ func (s *Svc) CommitConfiguration(from, to config.Configuration) bool {
 		_, ok := s.tokens[key]
 		if !ok {
 			l.Debugln("Connecting to relay", uri)
-			c, err := client.NewClient(uri, s.tlsCfg.Certificates, s.invitations)
+			c, err := client.NewClient(uri, s.tlsCfg.Certificates, s.invitations, 10*time.Second)
 			if err != nil {
 				l.Debugln("Failed to connect to relay", uri, err)
 				continue