Back to

Package dht

Latest Go to latest

The latest major version is v2.

Published: Sep 29, 2020 | License: MPL-2.0 | Module:


Package dht implements a Distributed Hash Table (DHT) part of the BitTorrent protocol, as specified by BEP 5:

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.


func MakeDeterministicNodeID

func MakeDeterministicNodeID(public net.Addr) (id [20]byte)

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.

func RandomNodeID

func RandomNodeID() (id [20]byte)

func ReadNodesFromFile

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

func SecureNodeId

func SecureNodeId(id *[20]byte, ip net.IP)

Makes a node ID secure, in-place. The ID is 20 raw bytes.

func WriteNodesToFile

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

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) (addrs []Addr, err error)

func NewAddr

func NewAddr(raw net.Addr) Addr

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

func (a *Announce) NumContacted() int64

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

func (*Announce) String

func (a *Announce) String() string

type AnnounceOpt

type AnnounceOpt *struct{}

func Scrape

func Scrape() AnnounceOpt

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.

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

func (s *Server) Announce(infoHash [20]byte, port int, impliedPort bool, opts ...AnnounceOpt) (*Announce, 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() (ts 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) 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) Nodes

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

Exports the current node table.

func (*Server) NumNodes

func (s *Server) NumNodes() int

Returns how many nodes are in the node table.

func (*Server) Ping

func (s *Server) Ping(node *net.UDPAddr, callback func(krpc.Msg, error)) error

Sends a ping query to the address given.

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) 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 [20]byte
	Conn   net.PacketConn
	// Don't respond to queries from other nodes.
	Passive       bool
	StartingNodes StartingNodesGetter
	// Disable the DHT security extension:
	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

	ConnectionTracking *conntrack.Instance

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

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

func NewDefaultServerConfig

func NewDefaultServerConfig() *ServerConfig

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

type TraversalStats

type TraversalStats struct {
	NumAddrsTried int64
	NumResponses  int64

func (TraversalStats) String

func (me TraversalStats) String() string

Package Files

Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to identifier