dht

package module
v2.0.0-...-be9fe6b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 2, 2023 License: MPL-2.0 Imports: 42 Imported by: 0

README

dht

Go Reference

Installation

Get the library package with go get github.com/anacrolix/dht/v2, or the provided cmds with go install github.com/anacrolix/dht/v2/cmd/...@latest.

Commands

Here I'll describe what some of the provided commands in ./cmd do.

dht-ping

Pings DHT nodes with the given network addresses.

$ go run ./cmd/dht-ping router.bittorrent.com:6881 router.utorrent.com:6881
2015/04/01 17:21:23 main.go:33: dht server on [::]:60058
32f54e697351ff4aec29cdbaabf2fbe3467cc267 (router.bittorrent.com:6881): 648.218621ms
ebff36697351ff4aec29cdbaabf2fbe3467cc267 (router.utorrent.com:6881): 873.864706ms
2/2 responses (100.000000%)

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

Constants

This section is empty.

Variables

View Source
var DefaultGlobalBootstrapHostPorts = []string{
	"router.utorrent.com:6881",
	"router.bittorrent.com:6881",
	"dht.transmissionbt.com:6881",
	"dht.aelitis.com:6881",
	"router.silotis.us:6881",
	"dht.libtorrent.org:25401",
	"dht.anacrolix.link:42069",
	"router.bittorrent.cloud:42069",
}
View Source
var DefaultSendLimiter = rate.NewLimiter(25, 25)
View Source
var TransactionTimeout = errors.New("transaction timed out")

Functions

func HashTuple

func HashTuple(bs ...[]byte) (ret [20]byte)

func MakeDeterministicNodeID

func MakeDeterministicNodeID(public net.Addr) (id krpc.ID)

func NodeIdSecure

func NodeIdSecure(id [20]byte, ip net.IP) bool

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 RandomNodeID() (id krpc.ID)

Deprecated: Use function from krpc.

func ReadNodesFromFile

func ReadNodesFromFile(fileName string) (ns []krpc.NodeInfo, err error)

func SecureNodeId

func SecureNodeId(id *krpc.ID, ip net.IP)

Makes a node ID secure, in-place. The ID is 20 raw bytes. http://www.libtorrent.org/dht_sec.html

func WriteNodesToFile

func WriteNodesToFile(ns []krpc.NodeInfo, fileName string) (err error)

Types

type Addr

type Addr interface {
	Raw() net.Addr
	Port() int
	IP() net.IP
	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

func GlobalBootstrapAddrs(network string) ([]Addr, error)

Returns the resolved addresses of the default global bootstrap nodes. Network is unused but was historically passed by anacrolix/torrent.

func NewAddr

func NewAddr(raw net.Addr) Addr

func ResolveHostPorts

func ResolveHostPorts(hostPorts []string) (addrs []Addr, err error)

Resolves host:port strings to dht.Addrs, using the dht DNS resolver cache. Suitable for use with ServerConfig.BootstrapAddrs.

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) Close

func (a *Announce) Close()

Stop the announce.

func (*Announce) Finished

func (a *Announce) Finished() events.Done

Traversal and peer announcing steps are done.

func (*Announce) NumContacted

func (a *Announce) NumContacted() uint32

Returns the number of distinct remote addresses the announce has queried.

func (*Announce) StopTraversing

func (a *Announce) StopTraversing()

Halts traversal, but won't block peer announcing.

func (*Announce) String

func (a *Announce) String() string

func (*Announce) TraversalStats

func (a *Announce) TraversalStats() TraversalStats

type AnnounceOpt

type AnnounceOpt func(a *Announce)

Server.Announce option

func AnnouncePeer

func AnnouncePeer(opts AnnouncePeerOpts) AnnounceOpt

Finish an Announce get_peers traversal with an announce of a local peer.

func Scrape

func Scrape() AnnounceOpt

Scrape BEP 33 bloom filters in queries.

type AnnouncePeerOpts

type AnnouncePeerOpts struct {
	// The peer port that we're announcing.
	Port int
	// The peer port should be determined by the receiver to be the source port of the query packet.
	ImpliedPort bool
}

Arguments for announce_peer from a Server.Announce.

type Peer

type Peer = krpc.NodeAddr

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
}

The zero value for this uses reasonable/traditional defaults on Server methods.

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
	NoWaitFirst   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

type QueryResult struct {
	Reply  krpc.Msg
	Writes numWrites
	Err    error
}

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) AddNode

func (s *Server) AddNode(ni krpc.NodeInfo) error

Adds directly to the node table.

func (*Server) AddNodesFromFile

func (s *Server) AddNodesFromFile(fileName string) (added int, err error)

func (*Server) Addr

func (s *Server) Addr() net.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 deprecated

func (s *Server) Announce(infoHash [20]byte, port int, impliedPort bool, opts ...AnnounceOpt) (_ *Announce, err error)

Deprecated: Use Server.AnnounceTraversal. 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) AnnounceTraversal

func (s *Server) AnnounceTraversal(infoHash [20]byte, opts ...AnnounceOpt) (_ *Announce, err error)

Traverses the DHT graph toward nodes that store peers for the infohash, streaming them to the caller.

func (*Server) Bootstrap

func (s *Server) Bootstrap() (TraversalStats, error)

See BootstrapContext.

func (*Server) BootstrapContext

func (s *Server) BootstrapContext(ctx context.Context) (_ 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) Get

func (s *Server) Get(ctx context.Context, addr Addr, target bep44.Target, seq *int64, rl QueryRateLimiting) QueryResult

Get gets item information from a specific target ID. If seq is set to a specific value, only items with seq bigger than the one provided will return a V, K and Sig, if any. Get must be used to get a Put write token, when you want to write an item instead of read it.

func (*Server) GetPeers

func (s *Server) GetPeers(ctx context.Context, addr Addr, infoHash int160.T, scrape bool, rl QueryRateLimiting) (ret QueryResult)

func (*Server) ID

func (s *Server) ID() [20]byte

ID returns the 20-byte server ID. This is the ID used to communicate with the DHT network.

func (*Server) IPBlocklist

func (s *Server) IPBlocklist() iplist.Ranger

func (*Server) IsGood

func (s *Server) IsGood(n *node) bool

Per the spec in BEP 5.

func (*Server) IsQuestionable

func (s *Server) IsQuestionable(n *node) bool

func (*Server) NodeRespondedToPing

func (s *Server) NodeRespondedToPing(addr Addr, id int160.T)

func (*Server) Nodes

func (s *Server) Nodes() (nis []krpc.NodeInfo)

Returns non-bad nodes from the routing table.

func (*Server) NumNodes

func (s *Server) NumNodes() int

Returns how many nodes are in the node table.

func (*Server) PeerStore

func (s *Server) PeerStore() peer_store.Interface

func (*Server) Ping

func (s *Server) Ping(node *net.UDPAddr) QueryResult

Sends a ping query to the address given.

func (*Server) PingQueryInput

func (s *Server) PingQueryInput(node *net.UDPAddr, qi QueryInput) QueryResult

Sends a ping query to the address given.

func (*Server) Put

func (s *Server) Put(ctx context.Context, node Addr, i bep44.Put, token string, rl QueryRateLimiting) QueryResult

Put adds a new item to node. You need to call Get first for a write token.

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

func (s *Server) SetIPBlockList(list iplist.Ranger)

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) String

func (s *Server) String() string

Returns a description of 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

func (s *Server) TraversalNodeFilter(node addrMaybeId) bool

Whether we should consider a node for contact based on its address and possible ID.

func (*Server) TraversalStartingNodes

func (s *Server) TraversalStartingNodes() (nodes []addrMaybeId, err error)

func (*Server) WriteStatus

func (s *Server) WriteStatus(w io.Writer)

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   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

	// Called when there are no good nodes to use in the routing table. This might be called any
	// time when there are no nodes, including during bootstrap if one is performed. Typically it
	// returns the resolve addresses of bootstrap or "router" nodes that are designed to kick-start
	// a routing table.
	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 2s.
	// After the last send, a query is aborted after this time.
	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
}

ServerConfig allows setting up a configuration of the `Server` instance to be created with NewServer.

func NewDefaultServerConfig

func NewDefaultServerConfig() *ServerConfig

func (*ServerConfig) InitNodeId

func (c *ServerConfig) InitNodeId() (deterministic bool)

If the NodeId hasn't been specified, generate a suitable one. deterministic if c.Conn and c.PublicIP are non-nil.

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 StartingNodesGetter func() ([]Addr, error)

type TraversalStats

type TraversalStats = traversal.Stats

Directories

Path Synopsis
cmd
dht
Pings DHT nodes with the given network addresses.
Pings DHT nodes with the given network addresses.
exts
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL