dht.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. package dht
  2. import (
  3. "context"
  4. "crypto"
  5. _ "crypto/sha1"
  6. "errors"
  7. "math/rand"
  8. "net"
  9. "time"
  10. "github.com/anacrolix/log"
  11. "github.com/anacrolix/missinggo/v2"
  12. "github.com/anacrolix/torrent/iplist"
  13. "github.com/anacrolix/torrent/metainfo"
  14. "golang.org/x/time/rate"
  15. "github.com/anacrolix/dht/v2/bep44"
  16. "github.com/anacrolix/dht/v2/krpc"
  17. peer_store "github.com/anacrolix/dht/v2/peer-store"
  18. )
  19. func defaultQueryResendDelay() time.Duration {
  20. // This should be the highest reasonable UDP latency an end-user might have.
  21. return 2 * time.Second
  22. }
  23. // Uniquely identifies a transaction to us.
  24. type transactionKey struct {
  25. RemoteAddr string // host:port
  26. T string // The KRPC transaction ID.
  27. }
  28. type StartingNodesGetter func() ([]Addr, error)
  29. // ServerConfig allows setting up a configuration of the `Server` instance to be created with
  30. // NewServer.
  31. type ServerConfig struct {
  32. // Set NodeId Manually. Caller must ensure that if NodeId does not conform
  33. // to DHT Security Extensions, that NoSecurity is also set.
  34. NodeId krpc.ID
  35. Conn net.PacketConn
  36. // Don't respond to queries from other nodes.
  37. Passive bool
  38. // Whether to wait for rate limiting to allow us to reply.
  39. WaitToReply bool
  40. StartingNodes StartingNodesGetter
  41. // Disable the DHT security extension: http://www.libtorrent.org/dht_sec.html.
  42. NoSecurity bool
  43. // Initial IP blocklist to use. Applied before serving and bootstrapping
  44. // begins.
  45. IPBlocklist iplist.Ranger
  46. // Used to secure the server's ID. Defaults to the Conn's LocalAddr(). Set to the IP that remote
  47. // nodes will see, as that IP is what they'll use to validate our ID.
  48. PublicIP net.IP
  49. // Hook received queries. Return false if you don't want to propagate to the default handlers.
  50. OnQuery func(query *krpc.Msg, source net.Addr) (propagate bool)
  51. // Called when a peer successfully announces to us.
  52. OnAnnouncePeer func(infoHash metainfo.Hash, ip net.IP, port int, portOk bool)
  53. // How long to wait before resending queries that haven't received a response. Defaults to a
  54. // random value between 4.5 and 5.5s.
  55. QueryResendDelay func() time.Duration
  56. // TODO: Expose Peers, to return NodeInfo for received get_peers queries.
  57. PeerStore peer_store.Interface
  58. // BEP-44: Storing arbitrary data in the DHT. If not store provided, a default in-memory
  59. // implementation will be used.
  60. Store bep44.Store
  61. // BEP-44: expiration time with non-announced items. Two hours by default
  62. Exp time.Duration
  63. // If no Logger is provided, log.Default is used and log.Debug messages are filtered out. Note
  64. // that all messages without a log.Level, have log.Debug added to them before being passed to
  65. // this Logger.
  66. Logger log.Logger
  67. DefaultWant []krpc.Want
  68. SendLimiter *rate.Limiter
  69. }
  70. // ServerStats instance is returned by Server.Stats() and stores Server metrics
  71. type ServerStats struct {
  72. // Count of nodes in the node table that responded to our last query or
  73. // haven't yet been queried.
  74. GoodNodes int
  75. // Count of nodes in the node table.
  76. Nodes int
  77. // Transactions awaiting a response.
  78. OutstandingTransactions int
  79. // Individual announce_peer requests that got a success response.
  80. SuccessfulOutboundAnnouncePeerQueries int64
  81. // Nodes that have been blocked.
  82. BadNodes uint
  83. OutboundQueriesAttempted int64
  84. }
  85. func jitterDuration(average time.Duration, plusMinus time.Duration) time.Duration {
  86. return average - plusMinus/2 + time.Duration(rand.Int63n(int64(plusMinus)))
  87. }
  88. type Peer = krpc.NodeAddr
  89. var DefaultGlobalBootstrapHostPorts = []string{
  90. "router.utorrent.com:6881",
  91. "router.bittorrent.com:6881",
  92. "dht.transmissionbt.com:6881",
  93. "dht.aelitis.com:6881", // Vuze
  94. "router.silotis.us:6881", // IPv6
  95. "dht.libtorrent.org:25401", // @arvidn's
  96. "dht.anacrolix.link:42069",
  97. "router.bittorrent.cloud:42069",
  98. }
  99. func GlobalBootstrapAddrs(network string) (addrs []Addr, err error) {
  100. initDnsResolver()
  101. for _, s := range DefaultGlobalBootstrapHostPorts {
  102. host, port, err := net.SplitHostPort(s)
  103. if err != nil {
  104. panic(err)
  105. }
  106. hostAddrs, err := dnsResolver.LookupHost(context.Background(), host)
  107. if err != nil {
  108. // log.Default.WithDefaultLevel(log.Debug).Printf("error looking up %q: %v", s, err)
  109. continue
  110. }
  111. for _, a := range hostAddrs {
  112. ua, err := net.ResolveUDPAddr("udp", net.JoinHostPort(a, port))
  113. if err != nil {
  114. log.Printf("error resolving %q: %v", a, err)
  115. continue
  116. }
  117. addrs = append(addrs, NewAddr(ua))
  118. }
  119. }
  120. if len(addrs) == 0 {
  121. err = errors.New("nothing resolved")
  122. }
  123. return
  124. }
  125. // Deprecated: Use function from krpc.
  126. func RandomNodeID() (id krpc.ID) {
  127. return krpc.RandomNodeID()
  128. }
  129. func MakeDeterministicNodeID(public net.Addr) (id krpc.ID) {
  130. h := crypto.SHA1.New()
  131. h.Write([]byte(public.String()))
  132. h.Sum(id[:0:20])
  133. SecureNodeId(&id, missinggo.AddrIP(public))
  134. return
  135. }