main.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Copyright (C) 2014 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at http://mozilla.org/MPL/2.0/.
  6. package main
  7. import (
  8. "crypto/tls"
  9. "errors"
  10. "flag"
  11. "fmt"
  12. "net/url"
  13. "os"
  14. "time"
  15. "github.com/syncthing/syncthing/lib/config"
  16. "github.com/syncthing/syncthing/lib/discover"
  17. "github.com/syncthing/syncthing/lib/protocol"
  18. )
  19. var timeout = 5 * time.Second
  20. func main() {
  21. var server string
  22. flag.StringVar(&server, "server", "", "Announce server (blank for default set)")
  23. flag.DurationVar(&timeout, "timeout", timeout, "Query timeout")
  24. flag.Usage = usage
  25. flag.Parse()
  26. if flag.NArg() != 1 {
  27. flag.Usage()
  28. os.Exit(64)
  29. }
  30. id, err := protocol.DeviceIDFromString(flag.Args()[0])
  31. if err != nil {
  32. fmt.Println(err)
  33. os.Exit(1)
  34. }
  35. if server != "" {
  36. checkServers(id, server)
  37. } else {
  38. checkServers(id, config.DefaultDiscoveryServers...)
  39. }
  40. }
  41. type checkResult struct {
  42. server string
  43. direct []string
  44. relays []discover.Relay
  45. error
  46. }
  47. func checkServers(deviceID protocol.DeviceID, servers ...string) {
  48. t0 := time.Now()
  49. resc := make(chan checkResult)
  50. for _, srv := range servers {
  51. srv := srv
  52. go func() {
  53. res := checkServer(deviceID, srv)
  54. res.server = srv
  55. resc <- res
  56. }()
  57. }
  58. for _ = range servers {
  59. res := <-resc
  60. u, _ := url.Parse(res.server)
  61. fmt.Printf("%s (%v):\n", u.Host, time.Since(t0))
  62. if res.error != nil {
  63. fmt.Println(" " + res.error.Error())
  64. }
  65. for _, addr := range res.direct {
  66. fmt.Println(" address:", addr)
  67. }
  68. for _, rel := range res.relays {
  69. fmt.Printf(" relay: %s (%d ms)\n", rel.URL, rel.Latency)
  70. }
  71. }
  72. }
  73. func checkServer(deviceID protocol.DeviceID, server string) checkResult {
  74. disco, err := discover.NewGlobal(server, tls.Certificate{}, nil, nil)
  75. if err != nil {
  76. return checkResult{error: err}
  77. }
  78. res := make(chan checkResult, 1)
  79. time.AfterFunc(timeout, func() {
  80. res <- checkResult{error: errors.New("timeout")}
  81. })
  82. go func() {
  83. direct, relays, err := disco.Lookup(deviceID)
  84. res <- checkResult{direct: direct, relays: relays, error: err}
  85. }()
  86. return <-res
  87. }
  88. func usage() {
  89. fmt.Printf("Usage:\n\t%s [options] <device ID>\n\nOptions:\n", os.Args[0])
  90. flag.PrintDefaults()
  91. }