main.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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 https://mozilla.org/MPL/2.0/.
  6. package main
  7. import (
  8. "context"
  9. "crypto/tls"
  10. "errors"
  11. "flag"
  12. "fmt"
  13. "net/url"
  14. "os"
  15. "time"
  16. "github.com/syncthing/syncthing/lib/config"
  17. "github.com/syncthing/syncthing/lib/discover"
  18. "github.com/syncthing/syncthing/lib/events"
  19. "github.com/syncthing/syncthing/lib/protocol"
  20. )
  21. var timeout = 5 * time.Second
  22. func main() {
  23. var server string
  24. flag.StringVar(&server, "server", "", "Announce server (blank for default set)")
  25. flag.DurationVar(&timeout, "timeout", timeout, "Query timeout")
  26. flag.Usage = usage
  27. flag.Parse()
  28. if flag.NArg() != 1 {
  29. flag.Usage()
  30. os.Exit(64)
  31. }
  32. id, err := protocol.DeviceIDFromString(flag.Args()[0])
  33. if err != nil {
  34. fmt.Println(err)
  35. os.Exit(1)
  36. }
  37. if server != "" {
  38. checkServers(id, server)
  39. } else {
  40. checkServers(id, config.DefaultDiscoveryServers...)
  41. }
  42. }
  43. type checkResult struct {
  44. server string
  45. addresses []string
  46. error
  47. }
  48. func checkServers(deviceID protocol.DeviceID, servers ...string) {
  49. t0 := time.Now()
  50. resc := make(chan checkResult)
  51. for _, srv := range servers {
  52. srv := srv
  53. go func() {
  54. res := checkServer(deviceID, srv)
  55. res.server = srv
  56. resc <- res
  57. }()
  58. }
  59. for range servers {
  60. res := <-resc
  61. u, _ := url.Parse(res.server)
  62. fmt.Printf("%s (%v):\n", u.Host, time.Since(t0))
  63. if res.error != nil {
  64. fmt.Println(" " + res.error.Error())
  65. }
  66. for _, addr := range res.addresses {
  67. fmt.Println(" address:", addr)
  68. }
  69. }
  70. }
  71. func checkServer(deviceID protocol.DeviceID, server string) checkResult {
  72. disco, err := discover.NewGlobal(server, tls.Certificate{}, nil, events.NoopLogger)
  73. if err != nil {
  74. return checkResult{error: err}
  75. }
  76. res := make(chan checkResult, 1)
  77. time.AfterFunc(timeout, func() {
  78. res <- checkResult{error: errors.New("timeout")}
  79. })
  80. go func() {
  81. addresses, err := disco.Lookup(context.Background(), deviceID)
  82. res <- checkResult{addresses: addresses, error: err}
  83. }()
  84. return <-res
  85. }
  86. func usage() {
  87. fmt.Printf("Usage:\n\t%s [options] <device ID>\n\nOptions:\n", os.Args[0])
  88. flag.PrintDefaults()
  89. }