36
vendor/github.com/anacrolix/dht/v2/krpc/CompactIPv4NodeAddrs.go
generated
vendored
Normal file
36
vendor/github.com/anacrolix/dht/v2/krpc/CompactIPv4NodeAddrs.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
package krpc
|
||||
|
||||
import "github.com/anacrolix/missinggo/slices"
|
||||
|
||||
type CompactIPv4NodeAddrs []NodeAddr
|
||||
|
||||
func (CompactIPv4NodeAddrs) ElemSize() int { return 6 }
|
||||
|
||||
func (me CompactIPv4NodeAddrs) MarshalBinary() ([]byte, error) {
|
||||
return marshalBinarySlice(slices.Map(func(addr NodeAddr) NodeAddr {
|
||||
if a := addr.IP.To4(); a != nil {
|
||||
addr.IP = a
|
||||
}
|
||||
return addr
|
||||
}, me).(CompactIPv4NodeAddrs))
|
||||
}
|
||||
|
||||
func (me CompactIPv4NodeAddrs) MarshalBencode() ([]byte, error) {
|
||||
return bencodeBytesResult(me.MarshalBinary())
|
||||
}
|
||||
|
||||
func (me *CompactIPv4NodeAddrs) UnmarshalBinary(b []byte) error {
|
||||
return unmarshalBinarySlice(me, b)
|
||||
}
|
||||
|
||||
func (me *CompactIPv4NodeAddrs) UnmarshalBencode(b []byte) error {
|
||||
return unmarshalBencodedBinary(me, b)
|
||||
}
|
||||
|
||||
func (me CompactIPv4NodeAddrs) NodeAddrs() []NodeAddr {
|
||||
return me
|
||||
}
|
||||
|
||||
func (me CompactIPv4NodeAddrs) Index(x NodeAddr) int {
|
||||
return addrIndex(me, x)
|
||||
}
|
||||
37
vendor/github.com/anacrolix/dht/v2/krpc/CompactIPv4NodeInfo.go
generated
vendored
Normal file
37
vendor/github.com/anacrolix/dht/v2/krpc/CompactIPv4NodeInfo.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
package krpc
|
||||
|
||||
import "github.com/anacrolix/missinggo/slices"
|
||||
|
||||
type (
|
||||
CompactIPv4NodeInfo []NodeInfo
|
||||
)
|
||||
|
||||
func (CompactIPv4NodeInfo) ElemSize() int {
|
||||
return 26
|
||||
}
|
||||
|
||||
// func (me *CompactIPv4NodeInfo) Scrub() {
|
||||
// slices.FilterInPlace(me, func(ni *NodeInfo) bool {
|
||||
// ni.Addr.IP = ni.Addr.IP.To4()
|
||||
// return ni.Addr.IP != nil
|
||||
// })
|
||||
// }
|
||||
|
||||
func (me CompactIPv4NodeInfo) MarshalBinary() ([]byte, error) {
|
||||
return marshalBinarySlice(slices.Map(func(ni NodeInfo) NodeInfo {
|
||||
ni.Addr.IP = ni.Addr.IP.To4()
|
||||
return ni
|
||||
}, me).(CompactIPv4NodeInfo))
|
||||
}
|
||||
|
||||
func (me CompactIPv4NodeInfo) MarshalBencode() ([]byte, error) {
|
||||
return bencodeBytesResult(me.MarshalBinary())
|
||||
}
|
||||
|
||||
func (me *CompactIPv4NodeInfo) UnmarshalBinary(b []byte) error {
|
||||
return unmarshalBinarySlice(me, b)
|
||||
}
|
||||
|
||||
func (me *CompactIPv4NodeInfo) UnmarshalBencode(b []byte) error {
|
||||
return unmarshalBencodedBinary(me, b)
|
||||
}
|
||||
34
vendor/github.com/anacrolix/dht/v2/krpc/CompactIPv6NodeAddrs.go
generated
vendored
Normal file
34
vendor/github.com/anacrolix/dht/v2/krpc/CompactIPv6NodeAddrs.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
package krpc
|
||||
|
||||
import "github.com/anacrolix/missinggo/slices"
|
||||
|
||||
type CompactIPv6NodeAddrs []NodeAddr
|
||||
|
||||
func (CompactIPv6NodeAddrs) ElemSize() int { return 18 }
|
||||
|
||||
func (me CompactIPv6NodeAddrs) MarshalBinary() ([]byte, error) {
|
||||
return marshalBinarySlice(slices.Map(func(na NodeAddr) NodeAddr {
|
||||
na.IP = na.IP.To16()
|
||||
return na
|
||||
}, me).(CompactIPv6NodeAddrs))
|
||||
}
|
||||
|
||||
func (me CompactIPv6NodeAddrs) MarshalBencode() ([]byte, error) {
|
||||
return bencodeBytesResult(me.MarshalBinary())
|
||||
}
|
||||
|
||||
func (me *CompactIPv6NodeAddrs) UnmarshalBinary(b []byte) error {
|
||||
return unmarshalBinarySlice(me, b)
|
||||
}
|
||||
|
||||
func (me *CompactIPv6NodeAddrs) UnmarshalBencode(b []byte) error {
|
||||
return unmarshalBencodedBinary(me, b)
|
||||
}
|
||||
|
||||
func (me CompactIPv6NodeAddrs) NodeAddrs() []NodeAddr {
|
||||
return me
|
||||
}
|
||||
|
||||
func (me CompactIPv6NodeAddrs) Index(x NodeAddr) int {
|
||||
return addrIndex(me, x)
|
||||
}
|
||||
32
vendor/github.com/anacrolix/dht/v2/krpc/CompactIPv6NodeInfo.go
generated
vendored
Normal file
32
vendor/github.com/anacrolix/dht/v2/krpc/CompactIPv6NodeInfo.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
package krpc
|
||||
|
||||
import (
|
||||
"github.com/anacrolix/missinggo/slices"
|
||||
)
|
||||
|
||||
type (
|
||||
CompactIPv6NodeInfo []NodeInfo
|
||||
)
|
||||
|
||||
func (CompactIPv6NodeInfo) ElemSize() int {
|
||||
return 38
|
||||
}
|
||||
|
||||
func (me CompactIPv6NodeInfo) MarshalBinary() ([]byte, error) {
|
||||
return marshalBinarySlice(slices.Map(func(ni NodeInfo) NodeInfo {
|
||||
ni.Addr.IP = ni.Addr.IP.To16()
|
||||
return ni
|
||||
}, me).(CompactIPv6NodeInfo))
|
||||
}
|
||||
|
||||
func (me CompactIPv6NodeInfo) MarshalBencode() ([]byte, error) {
|
||||
return bencodeBytesResult(me.MarshalBinary())
|
||||
}
|
||||
|
||||
func (me *CompactIPv6NodeInfo) UnmarshalBinary(b []byte) error {
|
||||
return unmarshalBinarySlice(me, b)
|
||||
}
|
||||
|
||||
func (me *CompactIPv6NodeInfo) UnmarshalBencode(b []byte) error {
|
||||
return unmarshalBencodedBinary(me, b)
|
||||
}
|
||||
49
vendor/github.com/anacrolix/dht/v2/krpc/bep33.go
generated
vendored
Normal file
49
vendor/github.com/anacrolix/dht/v2/krpc/bep33.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
package krpc
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"math"
|
||||
"math/bits"
|
||||
"net"
|
||||
)
|
||||
|
||||
const (
|
||||
m = 256 * 8
|
||||
k = 2
|
||||
)
|
||||
|
||||
type ScrapeBloomFilter [256]byte
|
||||
|
||||
// Note that if you intend for an IP to be in the IPv4 space, you might want to trim it to 4 bytes
|
||||
// with IP.To4.
|
||||
func (me *ScrapeBloomFilter) AddIp(ip net.IP) {
|
||||
h := sha1.New()
|
||||
h.Write(ip)
|
||||
var sum [20]byte
|
||||
h.Sum(sum[:0])
|
||||
me.addK(int(sum[0]) | int(sum[1])<<8)
|
||||
me.addK(int(sum[2]) | int(sum[3])<<8)
|
||||
}
|
||||
|
||||
func (me *ScrapeBloomFilter) addK(index int) {
|
||||
index %= m
|
||||
me[index/8] |= 1 << (index % 8)
|
||||
}
|
||||
|
||||
func (me ScrapeBloomFilter) countZeroes() (ret int) {
|
||||
for _, i := range me {
|
||||
ret += 8 - bits.OnesCount8(i)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (me *ScrapeBloomFilter) EstimateCount() float64 {
|
||||
if me == nil {
|
||||
return 0
|
||||
}
|
||||
c := float64(me.countZeroes())
|
||||
if c > m-1 {
|
||||
c = m - 1
|
||||
}
|
||||
return math.Log(c/m) / (k * math.Log(1.-1./m))
|
||||
}
|
||||
9
vendor/github.com/anacrolix/dht/v2/krpc/bep46.go
generated
vendored
Normal file
9
vendor/github.com/anacrolix/dht/v2/krpc/bep46.go
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
package krpc
|
||||
|
||||
import (
|
||||
"github.com/anacrolix/torrent/metainfo"
|
||||
)
|
||||
|
||||
type Bep46Payload struct {
|
||||
Ih metainfo.Hash `bencode:"ih"`
|
||||
}
|
||||
23
vendor/github.com/anacrolix/dht/v2/krpc/compact-infohashes.go
generated
vendored
Normal file
23
vendor/github.com/anacrolix/dht/v2/krpc/compact-infohashes.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
package krpc
|
||||
|
||||
type Infohash [20]byte
|
||||
|
||||
type CompactInfohashes [][20]byte
|
||||
|
||||
func (CompactInfohashes) ElemSize() int { return 20 }
|
||||
|
||||
func (me CompactInfohashes) MarshalBinary() ([]byte, error) {
|
||||
return marshalBinarySlice(me)
|
||||
}
|
||||
|
||||
func (me CompactInfohashes) MarshalBencode() ([]byte, error) {
|
||||
return bencodeBytesResult(me.MarshalBinary())
|
||||
}
|
||||
|
||||
func (me *CompactInfohashes) UnmarshalBinary(b []byte) error {
|
||||
return unmarshalBinarySlice(me, b)
|
||||
}
|
||||
|
||||
func (me *CompactInfohashes) UnmarshalBencode(b []byte) error {
|
||||
return unmarshalBencodedBinary(me, b)
|
||||
}
|
||||
84
vendor/github.com/anacrolix/dht/v2/krpc/compact_helpers.go
generated
vendored
Normal file
84
vendor/github.com/anacrolix/dht/v2/krpc/compact_helpers.go
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
package krpc
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/anacrolix/missinggo/slices"
|
||||
|
||||
"github.com/anacrolix/torrent/bencode"
|
||||
)
|
||||
|
||||
func unmarshalBencodedBinary(u encoding.BinaryUnmarshaler, b []byte) (err error) {
|
||||
var ub string
|
||||
err = bencode.Unmarshal(b, &ub)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return u.UnmarshalBinary([]byte(ub))
|
||||
}
|
||||
|
||||
type elemSizer interface {
|
||||
ElemSize() int
|
||||
}
|
||||
|
||||
func unmarshalBinarySlice(slice elemSizer, b []byte) (err error) {
|
||||
sliceValue := reflect.ValueOf(slice).Elem()
|
||||
elemType := sliceValue.Type().Elem()
|
||||
bytesPerElem := slice.ElemSize()
|
||||
elem := reflect.New(elemType)
|
||||
for len(b) != 0 {
|
||||
if len(b) < bytesPerElem {
|
||||
err = fmt.Errorf("%d trailing bytes < %d required for element", len(b), bytesPerElem)
|
||||
break
|
||||
}
|
||||
if bu, ok := elem.Interface().(encoding.BinaryUnmarshaler); ok {
|
||||
err = bu.UnmarshalBinary(b[:bytesPerElem])
|
||||
} else if elem.Elem().Len() == bytesPerElem {
|
||||
reflect.Copy(elem.Elem(), reflect.ValueOf(b[:bytesPerElem]))
|
||||
} else {
|
||||
err = fmt.Errorf("can't unmarshal %v bytes into %v", bytesPerElem, elem.Type())
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sliceValue.Set(reflect.Append(sliceValue, elem.Elem()))
|
||||
b = b[bytesPerElem:]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func marshalBinarySlice(slice elemSizer) (ret []byte, err error) {
|
||||
var elems []encoding.BinaryMarshaler
|
||||
slices.MakeInto(&elems, slice)
|
||||
for _, e := range elems {
|
||||
var b []byte
|
||||
b, err = e.MarshalBinary()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(b) != slice.ElemSize() {
|
||||
panic(fmt.Sprintf("marshalled %d bytes, but expected %d", len(b), slice.ElemSize()))
|
||||
}
|
||||
ret = append(ret, b...)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func bencodeBytesResult(b []byte, err error) ([]byte, error) {
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
return bencode.Marshal(b)
|
||||
}
|
||||
|
||||
// returns position of x in v, or -1 if not found
|
||||
func addrIndex(v []NodeAddr, x NodeAddr) int {
|
||||
for i := 0; i < len(v); i += 1 {
|
||||
if v[i].Equal(x) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
73
vendor/github.com/anacrolix/dht/v2/krpc/error.go
generated
vendored
Normal file
73
vendor/github.com/anacrolix/dht/v2/krpc/error.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
package krpc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/anacrolix/torrent/bencode"
|
||||
)
|
||||
|
||||
const (
|
||||
// These are documented in BEP 5.
|
||||
ErrorCodeGenericError = 201
|
||||
ErrorCodeServerError = 202
|
||||
ErrorCodeProtocolError = 203
|
||||
ErrorCodeMethodUnknown = 204
|
||||
// BEP 44
|
||||
ErrorCodeMessageValueFieldTooBig = 205
|
||||
ErrorCodeInvalidSignature = 206
|
||||
ErrorCodeSaltFieldTooBig = 207
|
||||
ErrorCodeCasHashMismatched = 301
|
||||
ErrorCodeSequenceNumberLessThanCurrent = 302
|
||||
)
|
||||
|
||||
var ErrorMethodUnknown = Error{
|
||||
Code: ErrorCodeMethodUnknown,
|
||||
Msg: "Method Unknown",
|
||||
}
|
||||
|
||||
// Represented as a string or list in bencode.
|
||||
type Error struct {
|
||||
Code int
|
||||
Msg string
|
||||
}
|
||||
|
||||
var (
|
||||
_ bencode.Unmarshaler = (*Error)(nil)
|
||||
_ bencode.Marshaler = (*Error)(nil)
|
||||
_ error = Error{}
|
||||
)
|
||||
|
||||
func (e *Error) UnmarshalBencode(_b []byte) (err error) {
|
||||
var _v interface{}
|
||||
err = bencode.Unmarshal(_b, &_v)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch v := _v.(type) {
|
||||
case []interface{}:
|
||||
func() {
|
||||
defer func() {
|
||||
r := recover()
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
err = fmt.Errorf("unpacking %#v: %s", v, r)
|
||||
}()
|
||||
e.Code = int(v[0].(int64))
|
||||
e.Msg = v[1].(string)
|
||||
}()
|
||||
case string:
|
||||
e.Msg = v
|
||||
default:
|
||||
err = fmt.Errorf(`KRPC error bencode value has unexpected type: %T`, _v)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (e Error) MarshalBencode() (ret []byte, err error) {
|
||||
return bencode.Marshal([]interface{}{e.Code, e.Msg})
|
||||
}
|
||||
|
||||
func (e Error) Error() string {
|
||||
return fmt.Sprintf("KRPC error %d: %s", e.Code, e.Msg)
|
||||
}
|
||||
74
vendor/github.com/anacrolix/dht/v2/krpc/id.go
generated
vendored
Normal file
74
vendor/github.com/anacrolix/dht/v2/krpc/id.go
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
package krpc
|
||||
|
||||
import (
|
||||
crand "crypto/rand"
|
||||
"encoding"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/anacrolix/torrent/bencode"
|
||||
|
||||
"github.com/anacrolix/dht/v2/int160"
|
||||
)
|
||||
|
||||
func RandomNodeID() (id ID) {
|
||||
crand.Read(id[:])
|
||||
return
|
||||
}
|
||||
|
||||
type ID [20]byte
|
||||
|
||||
var (
|
||||
_ interface {
|
||||
bencode.Unmarshaler
|
||||
encoding.TextUnmarshaler
|
||||
} = (*ID)(nil)
|
||||
_ bencode.Marshaler = ID{}
|
||||
_ fmt.Formatter = ID{}
|
||||
)
|
||||
|
||||
func (h ID) Format(f fmt.State, c rune) {
|
||||
// See metainfo.Hash.
|
||||
f.Write([]byte(h.String()))
|
||||
}
|
||||
|
||||
func IdFromString(s string) (id ID) {
|
||||
if n := copy(id[:], s); n != 20 {
|
||||
panic(n)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (id ID) MarshalBencode() ([]byte, error) {
|
||||
return []byte("20:" + string(id[:])), nil
|
||||
}
|
||||
|
||||
func (id *ID) UnmarshalBencode(b []byte) error {
|
||||
var s string
|
||||
if err := bencode.Unmarshal(b, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
if n := copy(id[:], s); n != 20 {
|
||||
return fmt.Errorf("string has wrong length: %d", n)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (id *ID) UnmarshalText(b []byte) (err error) {
|
||||
n, err := hex.Decode(id[:], b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if n != len(*id) {
|
||||
err = fmt.Errorf("expected %v bytes, only got %v", len(*id), n)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (id ID) String() string {
|
||||
return hex.EncodeToString(id[:])
|
||||
}
|
||||
|
||||
func (id ID) Int160() int160.T {
|
||||
return int160.FromByteArray(id)
|
||||
}
|
||||
131
vendor/github.com/anacrolix/dht/v2/krpc/msg.go
generated
vendored
Normal file
131
vendor/github.com/anacrolix/dht/v2/krpc/msg.go
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
package krpc
|
||||
|
||||
// Msg represents messages that nodes in the network send to each other as specified by the protocol.
|
||||
// They are also referred to as the KRPC messages.
|
||||
// There are three types of messages: QUERY, RESPONSE, ERROR
|
||||
// The message is a dictionary that is then
|
||||
// "bencoded" (serialization & compression format adopted by the BitTorrent)
|
||||
// and sent via the UDP connection to peers.
|
||||
//
|
||||
// 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.
|
||||
// 3 message types: QUERY, RESPONSE, ERROR
|
||||
type Msg struct {
|
||||
Q string `bencode:"q,omitempty"` // Query method (one of 4: "ping", "find_node", "get_peers", "announce_peer")
|
||||
A *MsgArgs `bencode:"a,omitempty"` // named arguments sent with a query
|
||||
T string `bencode:"t"` // required: transaction ID
|
||||
Y string `bencode:"y"` // required: type of the message: q for QUERY, r for RESPONSE, e for ERROR
|
||||
R *Return `bencode:"r,omitempty"` // RESPONSE type only
|
||||
E *Error `bencode:"e,omitempty"` // ERROR type only
|
||||
IP NodeAddr `bencode:"ip,omitempty"`
|
||||
ReadOnly bool `bencode:"ro,omitempty"` // BEP 43. Sender does not respond to queries.
|
||||
}
|
||||
|
||||
type MsgArgs struct {
|
||||
ID ID `bencode:"id"` // ID of the querying Node
|
||||
InfoHash ID `bencode:"info_hash,omitempty"` // InfoHash of the torrent
|
||||
Target ID `bencode:"target,omitempty"` // ID of the node sought
|
||||
// Token received from an earlier get_peers query. Also used in a BEP 44 put.
|
||||
Token string `bencode:"token,omitempty"`
|
||||
Port *int `bencode:"port,omitempty"` // Sender's torrent port
|
||||
ImpliedPort bool `bencode:"implied_port,omitempty"` // Use senders apparent DHT port
|
||||
Want []Want `bencode:"want,omitempty"` // Contains strings like "n4" and "n6" from BEP 32.
|
||||
NoSeed int `bencode:"noseed,omitempty"` // BEP 33
|
||||
Scrape int `bencode:"scrape,omitempty"` // BEP 33
|
||||
|
||||
// BEP 44
|
||||
|
||||
// I don't know if we should use bencode.Bytes for this. If we unmarshalled bytes that didn't
|
||||
// marshal back the same, our hashes will not match. But this might also serve to prevent abuse.
|
||||
V interface{} `bencode:"v,omitempty"`
|
||||
Seq *int64 `bencode:"seq,omitempty"`
|
||||
Cas int64 `bencode:"cas,omitempty"`
|
||||
K [32]byte `bencode:"k,omitempty"`
|
||||
Salt []byte `bencode:"salt,omitempty"`
|
||||
Sig [64]byte `bencode:"sig,omitempty"`
|
||||
}
|
||||
|
||||
type Want string
|
||||
|
||||
const (
|
||||
WantNodes Want = "n4"
|
||||
WantNodes6 Want = "n6"
|
||||
)
|
||||
|
||||
// BEP 51 (DHT Infohash Indexing)
|
||||
type Bep51Return struct {
|
||||
Interval *int64 `bencode:"interval,omitempty"`
|
||||
Num *int64 `bencode:"num,omitempty"`
|
||||
// Nodes supporting this extension should always include the samples field in the response, even
|
||||
// when it is zero-length. This lets indexing nodes to distinguish nodes supporting this
|
||||
// extension from those that respond to unknown query types which contain a target field [2].
|
||||
Samples *CompactInfohashes `bencode:"samples,omitempty"`
|
||||
}
|
||||
|
||||
type Bep44Return struct {
|
||||
V interface{} `bencode:"v,omitempty"`
|
||||
K [32]byte `bencode:"k,omitempty"`
|
||||
Sig [64]byte `bencode:"sig,omitempty"`
|
||||
Seq *int64 `bencode:"seq,omitempty"`
|
||||
}
|
||||
|
||||
type Return struct {
|
||||
// All returns are supposed to contain an ID, but what if they don't?
|
||||
ID ID `bencode:"id"` // ID of the queried (and responding) node
|
||||
|
||||
// K closest nodes to the requested target. Included in responses to queries that imply
|
||||
// traversal, for example get_peers, find_nodes, get, sample_infohashes.
|
||||
Nodes CompactIPv4NodeInfo `bencode:"nodes,omitempty"`
|
||||
Nodes6 CompactIPv6NodeInfo `bencode:"nodes6,omitempty"`
|
||||
|
||||
Token *string `bencode:"token,omitempty"` // Token for future announce_peer or put (BEP 44)
|
||||
Values []NodeAddr `bencode:"values,omitempty"` // Torrent peers
|
||||
|
||||
// BEP 33 (scrapes)
|
||||
BFsd *ScrapeBloomFilter `bencode:"BFsd,omitempty"`
|
||||
BFpe *ScrapeBloomFilter `bencode:"BFpe,omitempty"`
|
||||
|
||||
Bep51Return
|
||||
|
||||
// BEP 44
|
||||
Bep44Return
|
||||
}
|
||||
|
||||
func (r Return) ForAllNodes(f func(NodeInfo)) {
|
||||
for _, n := range r.Nodes {
|
||||
f(n)
|
||||
}
|
||||
for _, n := range r.Nodes6 {
|
||||
f(n)
|
||||
}
|
||||
}
|
||||
|
||||
// The node ID of the source of this Msg. Returns nil if it isn't present.
|
||||
// TODO: Can we verify Msgs more aggressively so this is guaranteed to return
|
||||
// a valid ID for a checked Msg?
|
||||
func (m Msg) SenderID() *ID {
|
||||
switch m.Y {
|
||||
case "q":
|
||||
if m.A == nil {
|
||||
return nil
|
||||
}
|
||||
return &m.A.ID
|
||||
case "r":
|
||||
if m.R == nil {
|
||||
return nil
|
||||
}
|
||||
return &m.R.ID
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// This does not return an error, but (*Error)(nil) is still a non-nil error. You have been warned!
|
||||
// This language is evil.
|
||||
func (m Msg) Error() *Error {
|
||||
if m.Y != "e" {
|
||||
return nil
|
||||
}
|
||||
return m.E
|
||||
}
|
||||
66
vendor/github.com/anacrolix/dht/v2/krpc/nodeaddr.go
generated
vendored
Normal file
66
vendor/github.com/anacrolix/dht/v2/krpc/nodeaddr.go
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
package krpc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"github.com/anacrolix/torrent/bencode"
|
||||
)
|
||||
|
||||
type NodeAddr struct {
|
||||
IP net.IP
|
||||
Port int
|
||||
}
|
||||
|
||||
// A zero Port is taken to mean no port provided, per BEP 7.
|
||||
func (me NodeAddr) String() string {
|
||||
if me.Port == 0 {
|
||||
return me.IP.String()
|
||||
}
|
||||
return net.JoinHostPort(me.IP.String(), strconv.FormatInt(int64(me.Port), 10))
|
||||
}
|
||||
|
||||
func (me *NodeAddr) UnmarshalBinary(b []byte) error {
|
||||
me.IP = make(net.IP, len(b)-2)
|
||||
copy(me.IP, b[:len(b)-2])
|
||||
me.Port = int(binary.BigEndian.Uint16(b[len(b)-2:]))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (me *NodeAddr) UnmarshalBencode(b []byte) (err error) {
|
||||
var _b []byte
|
||||
err = bencode.Unmarshal(b, &_b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return me.UnmarshalBinary(_b)
|
||||
}
|
||||
|
||||
func (me NodeAddr) MarshalBinary() ([]byte, error) {
|
||||
var b bytes.Buffer
|
||||
b.Write(me.IP)
|
||||
binary.Write(&b, binary.BigEndian, uint16(me.Port))
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func (me NodeAddr) MarshalBencode() ([]byte, error) {
|
||||
return bencodeBytesResult(me.MarshalBinary())
|
||||
}
|
||||
|
||||
func (me NodeAddr) UDP() *net.UDPAddr {
|
||||
return &net.UDPAddr{
|
||||
IP: me.IP,
|
||||
Port: me.Port,
|
||||
}
|
||||
}
|
||||
|
||||
func (me *NodeAddr) FromUDPAddr(ua *net.UDPAddr) {
|
||||
me.IP = ua.IP
|
||||
me.Port = ua.Port
|
||||
}
|
||||
|
||||
func (me NodeAddr) Equal(x NodeAddr) bool {
|
||||
return me.IP.Equal(x.IP) && me.Port == x.Port
|
||||
}
|
||||
46
vendor/github.com/anacrolix/dht/v2/krpc/nodeinfo.go
generated
vendored
Normal file
46
vendor/github.com/anacrolix/dht/v2/krpc/nodeinfo.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
package krpc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
"net"
|
||||
)
|
||||
|
||||
type NodeInfo struct {
|
||||
ID ID
|
||||
Addr NodeAddr
|
||||
}
|
||||
|
||||
func (me NodeInfo) String() string {
|
||||
return fmt.Sprintf("{%x at %s}", me.ID, me.Addr)
|
||||
}
|
||||
|
||||
func RandomNodeInfo(ipLen int) (ni NodeInfo) {
|
||||
rand.Read(ni.ID[:])
|
||||
ni.Addr.IP = make(net.IP, ipLen)
|
||||
rand.Read(ni.Addr.IP)
|
||||
ni.Addr.Port = rand.Intn(math.MaxUint16 + 1)
|
||||
return
|
||||
}
|
||||
|
||||
var _ interface {
|
||||
encoding.BinaryMarshaler
|
||||
encoding.BinaryUnmarshaler
|
||||
} = (*NodeInfo)(nil)
|
||||
|
||||
func (ni NodeInfo) MarshalBinary() ([]byte, error) {
|
||||
var w bytes.Buffer
|
||||
w.Write(ni.ID[:])
|
||||
w.Write(ni.Addr.IP)
|
||||
binary.Write(&w, binary.BigEndian, uint16(ni.Addr.Port))
|
||||
return w.Bytes(), nil
|
||||
}
|
||||
|
||||
func (ni *NodeInfo) UnmarshalBinary(b []byte) error {
|
||||
copy(ni.ID[:], b)
|
||||
return ni.Addr.UnmarshalBinary(b[20:])
|
||||
}
|
||||
Reference in New Issue
Block a user