This commit is contained in:
2018-11-04 15:58:15 +01:00
commit f956bcee28
1178 changed files with 584552 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
package krpc
type CompactIPv4NodeAddrs []NodeAddr
func (CompactIPv4NodeAddrs) ElemSize() int { return 6 }
func (me CompactIPv4NodeAddrs) MarshalBinary() ([]byte, error) {
return marshalBinarySlice(me)
}
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
}

View 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)
}

View File

@@ -0,0 +1,30 @@
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
}

View 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)
}

View File

@@ -0,0 +1,67 @@
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()
for len(b) != 0 {
if len(b) < bytesPerElem {
err = fmt.Errorf("%d trailing bytes < %d required for element", len(b), bytesPerElem)
break
}
elem := reflect.New(elemType)
err = elem.Interface().(encoding.BinaryUnmarshaler).UnmarshalBinary(b[:bytesPerElem])
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)
}

59
vendor/github.com/anacrolix/dht/krpc/error.go generated vendored Normal file
View File

@@ -0,0 +1,59 @@
package krpc
import (
"fmt"
"github.com/anacrolix/torrent/bencode"
)
var ErrorMethodUnknown = Error{
Code: 204,
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)
}

36
vendor/github.com/anacrolix/dht/krpc/id.go generated vendored Normal file
View File

@@ -0,0 +1,36 @@
package krpc
import (
"fmt"
"github.com/anacrolix/torrent/bencode"
)
type ID [20]byte
var _ interface {
bencode.Marshaler
bencode.Unmarshaler
} = (*ID)(nil)
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
}

85
vendor/github.com/anacrolix/dht/krpc/msg.go generated vendored Normal file
View File

@@ -0,0 +1,85 @@
package krpc
import (
"fmt"
)
// Msg represents messages that nodes in the network send to each other as specified by the protocol.
// They are also refered to as the KRPC messages.
// There are three types of messages: QUERY, RESPONSE, ERROR
// The message is a dictonary 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"`
}
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 string `bencode:"token,omitempty"` // Token received from an earlier get_peers query
Port int `bencode:"port,omitempty"` // Senders 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.
}
type Want string
const (
WantNodes Want = "n4"
WantNodes6 Want = "n6"
)
type Return struct {
ID ID `bencode:"id"` // ID of the querying node
Nodes CompactIPv4NodeInfo `bencode:"nodes,omitempty"` // K closest nodes to the requested target
Nodes6 CompactIPv6NodeInfo `bencode:"nodes6,omitempty"` // K closest nodes to the requested target
Token string `bencode:"token,omitempty"` // Token for future announce_peer
Values []NodeAddr `bencode:"values,omitempty"` // Torrent peers
}
var _ fmt.Stringer = Msg{}
func (m Msg) String() string {
return fmt.Sprintf("%#v", m)
}
// 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
}
func (m Msg) Error() *Error {
if m.Y != "e" {
return nil
}
return m.E
}

62
vendor/github.com/anacrolix/dht/krpc/nodeaddr.go generated vendored Normal file
View File

@@ -0,0 +1,62 @@
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
}

46
vendor/github.com/anacrolix/dht/krpc/nodeinfo.go generated vendored Normal file
View File

@@ -0,0 +1,46 @@
package krpc
import (
"bytes"
"encoding"
"encoding/binary"
"fmt"
"math"
"math/rand"
"net"
)
type NodeInfo struct {
ID [20]byte
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:])
}