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