diff --git a/client/methods.go b/client/methods.go index ef6145e9c..cfc810f5e 100644 --- a/client/methods.go +++ b/client/methods.go @@ -8,6 +8,7 @@ import ( "net" "net/url" "strconv" + "strings" "time" syncthingprotocol "github.com/syncthing/protocol" @@ -20,10 +21,10 @@ func GetInvitationFromRelay(uri *url.URL, id syncthingprotocol.DeviceID, certs [ } conn, err := tls.Dial("tcp", uri.Host, configForCerts(certs)) - conn.SetDeadline(time.Now().Add(10 * time.Second)) if err != nil { return protocol.SessionInvitation{}, err } + conn.SetDeadline(time.Now().Add(10 * time.Second)) if err := performHandshakeAndValidation(conn, uri); err != nil { return protocol.SessionInvitation{}, err @@ -97,6 +98,25 @@ func JoinSession(invitation protocol.SessionInvitation) (net.Conn, error) { } } +func TestRelay(uri *url.URL, certs []tls.Certificate) bool { + id := syncthingprotocol.NewDeviceID(certs[0].Certificate[0]) + c := NewProtocolClient(uri, certs, nil) + go c.Serve() + defer c.Stop() + + for i := 0; i < 5; i++ { + _, err := GetInvitationFromRelay(uri, id, certs) + if err == nil { + return true + } + if !strings.Contains(err.Error(), "Incorrect response code") { + return false + } + time.Sleep(time.Second) + } + return false +} + func configForCerts(certs []tls.Certificate) *tls.Config { return &tls.Config{ Certificates: certs, diff --git a/testutil/main.go b/testutil/main.go index 69dbb00a1..ffeb9942d 100644 --- a/testutil/main.go +++ b/testutil/main.go @@ -23,10 +23,11 @@ func main() { log.SetFlags(log.LstdFlags | log.Lshortfile) var connect, relay, dir string - var join bool + var join, test bool flag.StringVar(&connect, "connect", "", "Device ID to which to connect to") flag.BoolVar(&join, "join", false, "Join relay") + flag.BoolVar(&test, "test", false, "Generic relay test") flag.StringVar(&relay, "relay", "relay://127.0.0.1:22067", "Relay address") flag.StringVar(&dir, "keys", ".", "Directory where cert.pem and key.pem is stored") @@ -99,6 +100,12 @@ func main() { log.Println("Joined", conn.RemoteAddr(), conn.LocalAddr()) connectToStdio(stdin, conn) log.Println("Finished", conn.RemoteAddr(), conn.LocalAddr()) + } else if test { + if client.TestRelay(uri, []tls.Certificate{cert}) { + log.Println("OK") + } else { + log.Println("FAIL") + } } else { log.Fatal("Requires either join or connect") }