krpc

package
v0.0.0-...-403fe73 Latest Latest
Warning

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

Go to latest
Published: Jun 4, 2024 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package dht implements the bittorrent dht protocol. For more information see http://www.bittorrent.org/beps/bep_0005.html.

Index

Constants

View Source
const (
	// StandardMode follows the standard protocol
	StandardMode = iota
	// CrawlMode for crawling the dht network.
	CrawlMode
)
View Source
const (
	// BEP 5
	ErrorCodeGeneric       = 201
	ErrorCodeServer        = 202
	ErrorCodeProtocol      = 203
	ErrorCodeMethodUnknown = 204

	// BEP 44
	ErrorCodeMessageValueFieldTooBig       = 205
	ErrorCodeInvalidSignature              = 206
	ErrorCodeSaltFieldTooBig               = 207
	ErrorCodeCasHashMismatched             = 301
	ErrorCodeSequenceNumberLessThanCurrent = 302
)

Predefine some error code.

View Source
const HashSize = 20

HashSize is the size of the InfoHash.

Variables

View Source
var (
	// ErrNotReady is the error when DHT is not initialized.
	ErrNotReady = errors.New("dht is not ready")
	// ErrOnGetPeersResponseNotSet is the error that config
	// OnGetPeersResponseNotSet is not set when call dht.GetPeers.
	ErrOnGetPeersResponseNotSet = errors.New("OnGetPeersResponse is not set")
)

Functions

func ParseKey

func ParseKey(data map[string]interface{}, key string, t string) error

ParseKey parses the key in dict data. `t` is type of the keyed value. It's one of "int", "string", "map", "list".

func ParseKeys

func ParseKeys(data map[string]interface{}, pairs [][]string) error

ParseKeys parses keys. It just wraps ParseKey.

Types

type Addr

type Addr struct {
	IP   net.IP // For IPv4, its length must be 4.
	Port uint16

	// The original network address, which is only used by the DHT server.
	Orig net.Addr
}

Addr represents an address based on ip and port, which implements "Compact IP-address/port info".

See http://bittorrent.org/beps/bep_0005.html.

func NewAddr

func NewAddr(ip net.IP, port uint16) Addr

NewAddr returns a new Addr with ip and port.

func NewAddrFromUDPAddr

func NewAddrFromUDPAddr(ua *net.UDPAddr) Addr

NewAddrFromUDPAddr converts *net.UDPAddr to a new Addr.

func ParseAddrs

func ParseAddrs(s string) (addrs []Addr, err error)

ParseAddrs parses the address from the string s with the format "IP:PORT".

func (Addr) Equal

func (a Addr) Equal(o Addr) bool

Equal reports whether a is equal to o.

func (Addr) MarshalBencode

func (a Addr) MarshalBencode() (b []byte, err error)

MarshalBencode implements the interface bencode.Marshaler.

func (Addr) MarshalBinary

func (a Addr) MarshalBinary() (data []byte, err error)

MarshalBinary implements the interface encoding.BinaryMarshaler,

func (Addr) Network

func (a Addr) Network() string

Network implements the interface net.Addr#Network.

func (Addr) String

func (a Addr) String() string

func (Addr) UDPAddr

func (a Addr) UDPAddr() *net.UDPAddr

UDPAddr converts itself to *net.UDPAddr.

func (*Addr) UnmarshalBencode

func (a *Addr) UnmarshalBencode(b []byte) (err error)

UnmarshalBencode implements the interface bencode.Unmarshaler.

func (*Addr) UnmarshalBinary

func (a *Addr) UnmarshalBinary(data []byte) error

UnmarshalBinary implements the interface encoding.BinaryUnmarshaler.

func (Addr) Valid

func (a Addr) Valid() bool

Valid reports whether the addr is valid.

func (Addr) WriteBinary

func (a Addr) WriteBinary(w io.Writer) (n int, err error)

WriteBinary is the same as MarshalBinary, but writes the result into w instead of returning.

type CompactIPv4Addrs

type CompactIPv4Addrs []Addr

CompactIPv4Addrs is a set of IPv4 Addrs.

func (CompactIPv4Addrs) MarshalBencode

func (cas CompactIPv4Addrs) MarshalBencode() (b []byte, err error)

MarshalBencode implements the interface bencode.Marshaler.

func (CompactIPv4Addrs) MarshalBinary

func (cas CompactIPv4Addrs) MarshalBinary() ([]byte, error)

MarshalBinary implements the interface encoding.BinaryMarshaler.

func (*CompactIPv4Addrs) UnmarshalBencode

func (cas *CompactIPv4Addrs) UnmarshalBencode(b []byte) (err error)

UnmarshalBencode implements the interface bencode.Unmarshaler.

func (*CompactIPv4Addrs) UnmarshalBinary

func (cas *CompactIPv4Addrs) UnmarshalBinary(b []byte) (err error)

UnmarshalBinary implements the interface encoding.BinaryUnmarshaler.

type CompactIPv4Nodes

type CompactIPv4Nodes []Node

CompactIPv4Nodes is a set of IPv4 Nodes.

func (CompactIPv4Nodes) MarshalBencode

func (cns CompactIPv4Nodes) MarshalBencode() (b []byte, err error)

MarshalBencode implements the interface bencode.Marshaler.

func (CompactIPv4Nodes) MarshalBinary

func (cns CompactIPv4Nodes) MarshalBinary() ([]byte, error)

MarshalBinary implements the interface encoding.BinaryMarshaler.

func (*CompactIPv4Nodes) UnmarshalBencode

func (cns *CompactIPv4Nodes) UnmarshalBencode(b []byte) (err error)

UnmarshalBencode implements the interface bencode.Unmarshaler.

func (*CompactIPv4Nodes) UnmarshalBinary

func (cns *CompactIPv4Nodes) UnmarshalBinary(b []byte) (err error)

UnmarshalBinary implements the interface encoding.BinaryUnmarshaler.

type CompactIPv6Addrs

type CompactIPv6Addrs []Addr

CompactIPv6Addrs is a set of IPv6 Addrs.

func (CompactIPv6Addrs) MarshalBencode

func (cas CompactIPv6Addrs) MarshalBencode() (b []byte, err error)

MarshalBencode implements the interface bencode.Marshaler.

func (CompactIPv6Addrs) MarshalBinary

func (cas CompactIPv6Addrs) MarshalBinary() ([]byte, error)

MarshalBinary implements the interface encoding.BinaryMarshaler.

func (*CompactIPv6Addrs) UnmarshalBencode

func (cas *CompactIPv6Addrs) UnmarshalBencode(b []byte) (err error)

UnmarshalBencode implements the interface bencode.Unmarshaler.

func (*CompactIPv6Addrs) UnmarshalBinary

func (cas *CompactIPv6Addrs) UnmarshalBinary(b []byte) (err error)

UnmarshalBinary implements the interface encoding.BinaryUnmarshaler.

type CompactIPv6Nodes

type CompactIPv6Nodes []Node

CompactIPv6Nodes is a set of IPv6 Nodes.

func (CompactIPv6Nodes) MarshalBencode

func (cns CompactIPv6Nodes) MarshalBencode() (b []byte, err error)

MarshalBencode implements the interface bencode.Marshaler.

func (CompactIPv6Nodes) MarshalBinary

func (cns CompactIPv6Nodes) MarshalBinary() ([]byte, error)

MarshalBinary implements the interface encoding.BinaryMarshaler.

func (*CompactIPv6Nodes) UnmarshalBencode

func (cns *CompactIPv6Nodes) UnmarshalBencode(b []byte) (err error)

UnmarshalBencode implements the interface bencode.Unmarshaler.

func (*CompactIPv6Nodes) UnmarshalBinary

func (cns *CompactIPv6Nodes) UnmarshalBinary(b []byte) (err error)

UnmarshalBinary implements the interface encoding.BinaryUnmarshaler.

type Config

type Config struct {
	// in mainline dht, k = 8
	K int
	// for crawling mode, we put all nodes in one bucket, so KBucketSize may
	// not be K
	KBucketSize int
	// candidates are udp, udp4, udp6
	Network string
	// format is `ip:port`
	Address string
	// the prime nodes through which we can join in dht network
	PrimeNodes []string
	// the kbucket expired duration
	KBucketExpiredAfter time.Duration
	// the node expired duration
	NodeExpriedAfter time.Duration
	// how long it checks whether the bucket is expired
	CheckKBucketPeriod time.Duration
	// peer token expired duration
	TokenExpiredAfter time.Duration
	// the max transaction id
	MaxTransactionCursor uint64
	// how many nodes routing table can hold
	MaxNodes int
	// callback when got get_peers request
	OnGetPeers func(string, string, int)
	// callback when receive get_peers response
	OnGetPeersResponse func(string, *Peer)
	// callback when got announce_peer request
	OnAnnouncePeer func(string, string, int)
	// blcoked ips
	BlockedIPs []string
	// blacklist size
	BlackListMaxSize int
	// StandardMode or CrawlMode
	Mode int
	// the times it tries when send fails
	Try int
	// the size of packet need to be dealt with
	PacketJobLimit int
	// the size of packet handler
	PacketWorkerLimit int
	// the nodes num to be fresh in a kbucket
	RefreshNodeNum int
}

Config represents the configure of dht.

func NewCrawlConfig

func NewCrawlConfig() *Config

NewCrawlConfig returns a config in crawling mode.

func NewStandardConfig

func NewStandardConfig() *Config

NewStandardConfig returns a Config pointer with default values.

type DHT

type DHT struct {
	*Config

	Ready bool
	// contains filtered or unexported fields
}

DHT represents a DHT node.

func New

func New(config *Config) *DHT

New returns a DHT pointer. If config is nil, then config will be set to the default config.

func (*DHT) GetPeers

func (dht *DHT) GetPeers(infoHash string) error

GetPeers returns peers who have announced having infoHash.

func (*DHT) IsCrawlMode

func (dht *DHT) IsCrawlMode() bool

IsCrawlMode returns whether mode is CrawlMode.

func (*DHT) IsStandardMode

func (dht *DHT) IsStandardMode() bool

IsStandardMode returns whether mode is StandardMode.

func (*DHT) Run

func (dht *DHT) Run()

Run starts the dht.

type Error

type Error struct {
	Code   int    // BEP 5
	Reason string // BEP 5
}

Error represents a response error.

func NewError

func NewError(code int, reason string) Error

NewError returns a new Error.

func (Error) Error

func (e Error) Error() string

func (Error) MarshalBencode

func (e Error) MarshalBencode() (ret []byte, err error)

MarshalBencode implements the interface bencode.Marshaler.

func (*Error) UnmarshalBencode

func (e *Error) UnmarshalBencode(b []byte) (err error)

UnmarshalBencode implements the interface bencode.Unmarshaler.

type Hash

type Hash [HashSize]byte

Hash is the 20-byte SHA1 hash used for info and pieces.

func NewHash

func NewHash(b []byte) (h Hash)

NewHash converts the 20-bytes to Hash.

func NewHashFromBytes

func NewHashFromBytes(b []byte) (ret Hash)

NewHashFromBytes returns a new Hash from a byte slice.

func NewHashFromHexString

func NewHashFromHexString(s string) (h Hash)

NewHashFromHexString returns a new Hash from a hex string.

func NewHashFromString

func NewHashFromString(s string) (h Hash)

NewHashFromString returns a new Hash from a string.

func NewRandomHash

func NewRandomHash() (h Hash)

NewRandomHash returns a random hash.

func (Hash) Bytes

func (h Hash) Bytes() []byte

Bytes returns the byte slice type.

func (Hash) BytesString

func (h Hash) BytesString() string

BytesString returns the bytes string, that's, string(h[:]).

func (Hash) Compare

func (h Hash) Compare(o Hash) int

Compare returns 0 if h == o, -1 if h < o, or +1 if h > o.

func (*Hash) FromHexString

func (h *Hash) FromHexString(s string) (err error)

FromHexString resets the info hash from the hex string.

func (*Hash) FromString

func (h *Hash) FromString(s string) (err error)

FromString resets the info hash from the string.

func (Hash) HexString

func (h Hash) HexString() string

HexString returns the hex string format.

func (Hash) IsZero

func (h Hash) IsZero() bool

IsZero reports whether the whole hash is zero.

func (Hash) MarshalBencode

func (h Hash) MarshalBencode() (b []byte, err error)

MarshalBencode implements the interface bencode.Marshaler.

func (Hash) MarshalBinary

func (h Hash) MarshalBinary() (data []byte, err error)

MarshalBinary implements the interface binary.BinaryMarshaler.

func (Hash) String

func (h Hash) String() string

String is equal to HexString.

func (*Hash) UnmarshalBencode

func (h *Hash) UnmarshalBencode(b []byte) (err error)

UnmarshalBencode implements the interface bencode.Unmarshaler.

func (*Hash) UnmarshalBinary

func (h *Hash) UnmarshalBinary(b []byte) (err error)

UnmarshalBinary implements the interface binary.BinaryUnmarshaler.

func (Hash) WriteBinary

func (h Hash) WriteBinary(w io.Writer) (m int, err error)

WriteBinary is the same as MarshalBinary, but writes the result into w instead of returning.

func (Hash) Xor

func (h Hash) Xor(o Hash) (ret Hash)

Xor returns the hash of h XOR o.

type Hashes

type Hashes []Hash

Hashes is a set of Hashes.

func (Hashes) Contains

func (hs Hashes) Contains(h Hash) bool

Contains reports whether hs contains h.

func (Hashes) MarshalBencode

func (hs Hashes) MarshalBencode() ([]byte, error)

MarshalBencode implements the interface bencode.Marshaler.

func (*Hashes) UnmarshalBencode

func (hs *Hashes) UnmarshalBencode(b []byte) (err error)

UnmarshalBencode implements the interface bencode.Unmarshaler.

type Message

type Message struct {
	// Transaction ID
	//
	// Required
	T string `bencode:"t"` // BEP 5

	// Message Type: "q" for QUERY, "r" for RESPONSE, "e" for ERROR
	//
	// Required
	Y string `bencode:"y"` // BEP 5

	// Query Method: one of "ping", "find_node", "get_peers", "announce_peer"
	//
	// Required only if "y" is equal to "q".
	Q string `bencode:"q,omitempty"` // BEP 5

	A QueryArg       `bencode:"a,omitempty"` // BEP 5: Only for the QUERY message
	R ResponseResult `bencode:"r,omitempty"` // BEP 5: Only for the RESPONSE message
	E Error          `bencode:"e,omitempty"` // BEP 5: Only for the ERROR message

	RO bool `bencode:"ro,omitempty"` // BEP 43: ReadOnly
}

Message represents messages that nodes in the network send to each other as specified by the KRPC protocol, which are also referred to as the KRPC messages.

The message is a dictonary that is "bencoded" (serialization & compression format adopted by the BitTorrent) and sent via the UDP connection to peers.

There are three types of messages: QUERY, RESPONSE, ERROR.

A KRPC message is a single dictionary with two keys common to every message and additional keys depending on the type of message. Every message has a key "t" with a string value representing a transaction ID. This transaction ID is generated by the querying node and is echoed in the response, so responses may be correlated with multiple queries to the same node. The transaction ID should be encoded as a short string of binary numbers, typically 2 characters are enough as they cover 2^16 outstanding queries. The other key contained in every KRPC message is "y" with a single character value describing the type of message. The value of the "y" key is one of "q" for query, "r" for response, or "e" for error.

func NewErrorMsg

func NewErrorMsg(tid string, code int, reason string) Message

NewErrorMsg return a ERROR message.

func NewQueryMsg

func NewQueryMsg(tid, method string, arg QueryArg) Message

NewQueryMsg return a QUERY message.

func NewResponseMsg

func NewResponseMsg(tid string, data ResponseResult) Message

NewResponseMsg return a RESPONSE message.

func (Message) ID

func (m Message) ID() Hash

ID returns the QID or RID.

Notice: it will panic if the the message is not a query or response.

func (Message) IsError

func (m Message) IsError() bool

IsError reports whether the message is an ERROR message.

func (Message) IsQuery

func (m Message) IsQuery() bool

IsQuery reports whether the message is a QUERY message.

func (Message) IsResponse

func (m Message) IsResponse() bool

IsResponse reports whether the message is a RESPONSE message.

func (Message) QID

func (m Message) QID() Hash

QID returns the value named "id" in "a", that's, the query arguments.

Return the ZERO value instead if no "id".

func (Message) RID

func (m Message) RID() Hash

RID returns the value named "id" in "r".

Return the ZERO value instead if no "id".

type Node

type Node struct {
	ID   Hash
	Addr Addr
}

Node represents a node information.

func NewNode

func NewNode(id Hash, addr Addr) Node

NewNode returns a new Node.

func (Node) Equal

func (n Node) Equal(o Node) bool

Equal reports whether n is equal to o.

func (Node) MarshalBinary

func (n Node) MarshalBinary() (data []byte, err error)

MarshalBinary implements the interface encoding.BinaryMarshaler, which implements "Compact node info".

See http://bittorrent.org/beps/bep_0005.html.

func (Node) String

func (n Node) String() string

func (*Node) UnmarshalBinary

func (n *Node) UnmarshalBinary(b []byte) error

UnmarshalBinary implements the interface encoding.BinaryUnmarshaler, which implements "Compact node info".

See http://bittorrent.org/beps/bep_0005.html.

func (Node) WriteBinary

func (n Node) WriteBinary(w io.Writer) (m int, err error)

WriteBinary is the same as MarshalBinary, but writes the result into w instead of returning.

type Peer

type Peer struct {
	IP   net.IP
	Port int
	// contains filtered or unexported fields
}

Peer represents a peer contact.

func (*Peer) CompactIPPortInfo

func (p *Peer) CompactIPPortInfo() string

CompactIPPortInfo returns "Compact node info". See http://www.bittorrent.org/beps/bep_0005.html.

type QueryArg

type QueryArg struct {
	// ID is used to identify a querying node.
	ID Hash `bencode:"id"` // BEP 5

	// Target is used to identify the node sought by the queryer.
	//
	// find_node
	Target Hash `bencode:"target,omitempty"` // BEP 5

	// InfoHash is the infohash of the torrent file.
	//
	// get_peers, announce_peer
	InfoHash Hash `bencode:"info_hash,omitempty"` // BEP 5

	// Port is the port on where sender is listening to allow others
	// to download the torrent.
	//
	// announce_peer
	Port uint16 `bencode:"port,omitempty"` // BEP 5

	// Token is the received one from an earlier "get_peers" query.
	//
	// announce_peer
	Token string `bencode:"token,omitempty"` // BEP 5

	// ImpliedPort is used by the senders to apparent DHT port
	// to improve NAT support.
	//
	// announce_peer
	ImpliedPort bool `bencode:"implied_port,omitempty"` // BEP 5

	// Wants is only used to represent to expect "nodes" for "n4"
	// or "nodes6" for "n6".
	//
	// Notice: It only governs the presence of the "nodes" and "nodes6"
	// parameters, not the interpretation of "values".
	//
	// find_node, get_peers
	Wants []Want `bencode:"want,omitempty"` // BEP 32
}

QueryArg represents the arguments used by the QUERY message.

func (QueryArg) ContainsWant

func (a QueryArg) ContainsWant(w Want) bool

ContainsWant reports whether the request contains the given Want.

func (QueryArg) GetPort

func (a QueryArg) GetPort(port int) uint16

GetPort returns the real port of the peer.

type ResponseResult

type ResponseResult struct {
	// ID is used to indentify the queried node, that's, the response node.
	ID Hash `bencode:"id"` // BEP 5

	// Nodes is a string containing the compact node information for the list
	// of the ipv4 target node, or the K(8) closest good nodes in routing table
	// of the requested ipv4 target.
	//
	// find_node
	Nodes CompactIPv4Nodes `bencode:"nodes,omitempty"` // BEP 5

	// Nodes6 is a string containing the compact node information for the list
	// of the ipv6 target node, or the K(8) closest good nodes in routing table
	// of the requested ipv6 target.
	//
	// find_node
	Nodes6 CompactIPv6Nodes `bencode:"nodes6,omitempty"` // BEP 32

	// Token is used for future "announce_peer".
	//
	// get_peers
	Token string `bencode:"token,omitempty"` // BEP 5

	// Values is a list of the torrent peers.
	//
	// For each element, in general, it is a compact IP-address/port info and
	// may be decoded to Addr, for example,
	//
	//   addrs := make([]Addr, len(values))
	//   for i, v := range values {
	//       addrs[i].UnmarshalBinary([]byte(v))
	//   }
	//
	// get_peers
	Values []string `bencode:"values,omitempty"` // BEP 5
}

ResponseResult represents the results used by the RESPONSE message.

type Want

type Want string

Want represents the type of nodes that the request wants.

BEP 32

const (
	WantNodes  Want = "n4"
	WantNodes6 Want = "n6"
)

Predefine some wants.

BEP 32

Jump to

Keyboard shortcuts

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