Documentation
¶
Overview ¶
Package dht implements a Distributed Hash Table (DHT) part of the BitTorrent protocol, as specified by BEP 5: http://www.bittorrent.org/beps/bep_0005.html
BitTorrent uses a "distributed hash table" (DHT) for storing peer contact information for "trackerless" torrents. In effect, each peer becomes a tracker. The protocol is based on Kademila DHT protocol and is implemented over UDP.
Please note the terminology used to avoid confusion. A "peer" is a client/server listening on a TCP port that implements the BitTorrent protocol. A "node" is a client/server listening on a UDP port implementing the distributed hash table protocol. The DHT is composed of nodes and stores the location of peers. BitTorrent clients include a DHT node, which is used to contact other nodes in the DHT to get the location of peers to download from using the BitTorrent protocol.
Standard use involves creating a Server, and calling Announce on it with the details of your local torrent client and infohash of interest.
Index ¶
- Variables
- func MakeDeterministicNodeID(public net.Addr) (id krpc.ID)
- func NodeIdSecure(id [20]byte, ip net.IP) bool
- func RandomNodeID() (id krpc.ID)deprecated
- func ReadNodesFromFile(fileName string) (ns []krpc.NodeInfo, err error)
- func SecureNodeId(id *krpc.ID, ip net.IP)
- func WriteNodesToFile(ns []krpc.NodeInfo, fileName string) (err error)
- type Addr
- type Announce
- type AnnounceOpt
- type Peer
- type PeersValues
- type QueryInput
- type QueryRateLimiting
- type QueryResult
- type Server
- func (s *Server) AddNode(ni krpc.NodeInfo) error
- func (s *Server) AddNodesFromFile(fileName string) (added int, err error)
- func (s *Server) Addr() net.Addr
- func (s *Server) Announce(infoHash [20]byte, port int, impliedPort bool, opts ...AnnounceOpt) (_ *Announce, err error)
- func (s *Server) Bootstrap() (_ TraversalStats, err error)
- func (s *Server) Close()
- func (s *Server) FindNode(addr Addr, targetID int160.T, rl QueryRateLimiting) (ret QueryResult)
- func (s *Server) GetPeers(ctx context.Context, addr Addr, infoHash int160.T, scrape bool, ...) (ret QueryResult)
- func (s *Server) ID() [20]byte
- func (s *Server) IPBlocklist() iplist.Ranger
- func (s *Server) IsGood(n *node) bool
- func (s *Server) IsQuestionable(n *node) bool
- func (s *Server) NodeRespondedToPing(addr Addr, id int160.T)
- func (s *Server) Nodes() (nis []krpc.NodeInfo)
- func (s *Server) NumNodes() int
- func (s *Server) PeerStore() peer_store.Interface
- func (s *Server) Ping(node *snet.UDPAddr) QueryResult
- func (s *Server) Query(ctx context.Context, addr Addr, q string, input QueryInput) (ret QueryResult)
- func (s *Server) SetIPBlockList(list iplist.Ranger)
- func (s *Server) Stats() ServerStats
- func (s *Server) String() string
- func (s *Server) TableMaintainer()
- func (s *Server) TraversalNodeFilter(node addrMaybeId) bool
- func (s *Server) TraversalStartingNodes() (nodes []addrMaybeId, err error)
- func (s *Server) WriteStatus(w io.Writer)
- type ServerConfig
- type ServerStats
- type StartingNodesGetter
- type Transaction
- type TraversalStats
Constants ¶
This section is empty.
Variables ¶
var TransactionTimeout = errors.New("transaction timed out")
Functions ¶
func NodeIdSecure ¶
Returns whether the node ID is considered secure. The id is the 20 raw bytes. http://www.libtorrent.org/dht_sec.html
func RandomNodeID
deprecated
func SecureNodeId ¶
Makes a node ID secure, in-place. The ID is 20 raw bytes. http://www.libtorrent.org/dht_sec.html
Types ¶
type Addr ¶
type Addr interface { Raw() snet.UDPAddr Port() int IP() net.IP IA() addr.IA String() string KRPC() krpc.NodeAddr }
Used internally to refer to node network addresses. String() is called a lot, and so can be optimized. Network() is not exposed, so that the interface does not satisfy net.Addr, as the underlying type must be passed to any OS-level function that take net.Addr.
func GlobalBootstrapAddrs ¶
type Announce ¶
type Announce struct { Peers chan PeersValues // contains filtered or unexported fields }
Maintains state for an ongoing Announce operation. An Announce is started by calling Server.Announce.
func (*Announce) NumContacted ¶
Returns the number of distinct remote addresses the announce has queried.
type PeersValues ¶
type PeersValues struct { Peers []Peer // Peers given in get_peers response. krpc.NodeInfo // The node that gave the response. krpc.Return }
Corresponds to the "values" key in a get_peers KRPC response. A list of peers that a node has reported as being in the swarm for a queried info hash.
type QueryInput ¶
type QueryInput struct { MsgArgs krpc.MsgArgs RateLimiting QueryRateLimiting NumTries int }
type QueryRateLimiting ¶
type QueryRateLimiting struct { // Don't rate-limit the first send for a query. NotFirst bool // Don't rate-limit any sends for a query. Note that there's still built-in waits before retries. NotAny bool WaitOnRetries bool }
Rate-limiting to be applied to writes for a given query. Queries occur inside transactions that will attempt to send several times. If the STM rate-limiting helpers are used, the first send is often already accounted for in the rate-limiting machinery before the query method that does the IO is invoked.
type QueryResult ¶
func (QueryResult) ToError ¶
func (qr QueryResult) ToError() error
func (QueryResult) TraversalQueryResult ¶
func (me QueryResult) TraversalQueryResult(addr krpc.NodeAddr) (ret traversal.QueryResult)
Converts a Server QueryResult to a traversal.QueryResult.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
A Server defines parameters for a DHT node server that is able to send queries, and respond to the ones from the network. Each node has a globally unique identifier known as the "node ID." Node IDs are chosen at random from the same 160-bit space as BitTorrent infohashes and define the behaviour of the node. Zero valued Server does not have a valid ID and thus is unable to function properly. Use `NewServer(nil)` to initialize a default node.
func NewServer ¶
func NewServer(c *ServerConfig) (s *Server, err error)
NewServer initializes a new DHT node server.
func (*Server) AddNodesFromFile ¶
func (*Server) Addr ¶
Addr returns the listen address for the server. Packets arriving to this address are processed by the server (unless aliens are involved).
func (*Server) Announce ¶
func (s *Server) Announce(infoHash [20]byte, port int, impliedPort bool, opts ...AnnounceOpt) (_ *Announce, err error)
Traverses the DHT graph toward nodes that store peers for the infohash, streaming them to the caller, and announcing the local node to each responding node if port is non-zero or impliedPort is true.
func (*Server) Bootstrap ¶
func (s *Server) Bootstrap() (_ TraversalStats, err error)
Populates the node table.
func (*Server) Close ¶
func (s *Server) Close()
Stops the server network activity. This is all that's required to clean-up a Server.
func (*Server) FindNode ¶
func (s *Server) FindNode(addr Addr, targetID int160.T, rl QueryRateLimiting) (ret QueryResult)
Sends a find_node query to addr. targetID is the node we're looking for. The Server makes use of some of the response fields.
func (*Server) GetPeers ¶
func (s *Server) GetPeers(ctx context.Context, addr Addr, infoHash int160.T, scrape bool, rl QueryRateLimiting) (ret QueryResult)
func (*Server) ID ¶
ID returns the 20-byte server ID. This is the ID used to communicate with the DHT network.
func (*Server) IPBlocklist ¶
func (*Server) IsQuestionable ¶
func (*Server) PeerStore ¶
func (s *Server) PeerStore() peer_store.Interface
func (*Server) Ping ¶
func (s *Server) Ping(node *snet.UDPAddr) QueryResult
Sends a ping query to the address given.
func (*Server) Query ¶
func (s *Server) Query(ctx context.Context, addr Addr, q string, input QueryInput) (ret QueryResult)
Performs an arbitrary query. `q` is the query value, defined by the DHT BEP. `a` should contain the appropriate argument values, if any. `a.ID` is clobbered by the Server. Responses to queries made this way are not interpreted by the Server. More specific methods like FindNode and GetPeers may make use of the response internally before passing it back to the caller.
func (*Server) SetIPBlockList ¶
Packets to and from any address matching a range in the list are dropped.
func (*Server) Stats ¶
func (s *Server) Stats() ServerStats
Stats returns statistics for the server.
func (*Server) TableMaintainer ¶
func (s *Server) TableMaintainer()
A routine that maintains the Server's routing table, by pinging questionable nodes, and refreshing buckets. This should be invoked on a running Server when the caller is satisfied with having set it up. It is not necessary to explicitly Bootstrap the Server once this routine has started.
func (*Server) TraversalNodeFilter ¶
Whether we should consider a node for contact based on its address and possible ID.
func (*Server) TraversalStartingNodes ¶
func (*Server) WriteStatus ¶
type ServerConfig ¶
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 *snet.Conn // Don't respond to queries from other nodes. Passive 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 snet.UDPAddr) (propagate bool) // Called when a peer successfully announces to us. OnAnnouncePeer func(infoHash metainfo.Hash, ip snet.UDPAddr, 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 // 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 }
ServerConfig allows to set up a configuration of the `Server` instance to be created with NewServer
func NewDefaultServerConfig ¶
func NewDefaultServerConfig() *ServerConfig
func (*ServerConfig) InitNodeId ¶
func (c *ServerConfig) InitNodeId()
If the NodeId hasn't been specified, generate one and secure it against the PublicIP if NoSecurity is not set.
type ServerStats ¶
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 }
ServerStats instance is returned by Server.Stats() and stores Server metrics
type StartingNodesGetter ¶
type Transaction ¶
type Transaction struct {
// contains filtered or unexported fields
}
Transaction keeps track of a message exchange between nodes, such as a query message and a response message.