From: Matt Joiner Date: Sun, 11 Feb 2018 04:13:00 +0000 (+1100) Subject: Standardize on krpc types, and extend PEX message type for IPv6 X-Git-Tag: v1.0.0~187 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=57216bd2997737813ab32adfd34575c7b29275c0;p=btrtrc.git Standardize on krpc types, and extend PEX message type for IPv6 --- diff --git a/client.go b/client.go index 40dc88af..60bd43b4 100644 --- a/client.go +++ b/client.go @@ -1177,7 +1177,7 @@ func (cl *Client) AddDHTNodes(nodes []string) { continue } ni := krpc.NodeInfo{ - Addr: &net.UDPAddr{ + Addr: krpc.NodeAddr{ IP: ip, Port: hmp.Port, }, diff --git a/connection.go b/connection.go index 09b09a64..379b45f9 100644 --- a/connection.go +++ b/connection.go @@ -1154,14 +1154,13 @@ func (c *connection) onReadExtendedMsg(id byte, payload []byte) (err error) { t.addPeers(func() (ret []Peer) { for i, cp := range pexMsg.Added { p := Peer{ - IP: make([]byte, 4), + IP: append(make(net.IP, 0, 4), cp.IP...), Port: cp.Port, Source: peerSourcePEX, } if i < len(pexMsg.AddedFlags) && pexMsg.AddedFlags[i]&0x01 != 0 { p.SupportsEncryption = true } - missinggo.CopyExact(p.IP, cp.IP[:]) ret = append(ret, p) } return diff --git a/pex.go b/pex.go index 674074fe..b3e3e166 100644 --- a/pex.go +++ b/pex.go @@ -1,9 +1,22 @@ package torrent -import "github.com/anacrolix/torrent/util" +import "github.com/anacrolix/dht/krpc" type peerExchangeMessage struct { - Added util.CompactIPv4Peers `bencode:"added"` - AddedFlags []byte `bencode:"added.f"` - Dropped util.CompactIPv4Peers `bencode:"dropped"` + Added krpc.CompactIPv4NodeAddrs `bencode:"added"` + AddedFlags []pexPeerFlags `bencode:"added.f"` + Added6 krpc.CompactIPv6NodeAddrs `bencode:"added6"` + AddedFlags6 []pexPeerFlags `bencode:"added6.f"` + Dropped krpc.CompactIPv4NodeAddrs `bencode:"dropped"` + Dropped6 krpc.CompactIPv6NodeAddrs `bencode:"dropped6"` } + +type pexPeerFlags byte + +const ( + pexPrefersEncryption = 0x01 + pexSeedUploadOnly = 0x02 + pexSupportsUtp = 0x04 + pexHolepunchSupport = 0x08 + pexOutgoingConn = 0x10 +) diff --git a/tracker/http.go b/tracker/http.go index 6767a672..d207f852 100644 --- a/tracker/http.go +++ b/tracker/http.go @@ -9,10 +9,10 @@ import ( "net/url" "strconv" + "github.com/anacrolix/dht/krpc" "github.com/anacrolix/missinggo/httptoo" "github.com/anacrolix/torrent/bencode" - "github.com/anacrolix/torrent/util" ) type httpResponse struct { @@ -27,8 +27,8 @@ type httpResponse struct { func (r *httpResponse) UnmarshalPeers() (ret []Peer, err error) { switch v := r.Peers.(type) { case string: - var cps []util.CompactPeer - cps, err = util.UnmarshalIPv4CompactPeers([]byte(v)) + var cps krpc.CompactIPv4NodeAddrs + err = cps.UnmarshalBinary([]byte(v)) if err != nil { return } diff --git a/tracker/server.go b/tracker/server.go index 27879d40..fbb9840d 100644 --- a/tracker/server.go +++ b/tracker/server.go @@ -7,13 +7,13 @@ import ( "math/rand" "net" - "github.com/anacrolix/torrent/util" + "github.com/anacrolix/dht/krpc" ) type torrent struct { Leechers int32 Seeders int32 - Peers util.CompactIPv4Peers + Peers krpc.CompactIPv4NodeAddrs } type server struct { diff --git a/tracker/udp.go b/tracker/udp.go index 07c7f0ae..0302a4e8 100644 --- a/tracker/udp.go +++ b/tracker/udp.go @@ -11,10 +11,9 @@ import ( "net/url" "time" + "github.com/anacrolix/dht/krpc" "github.com/anacrolix/missinggo" "github.com/anacrolix/missinggo/pproffd" - - "github.com/anacrolix/torrent/util" ) type Action int32 @@ -115,7 +114,8 @@ func (c *udpAnnounce) Do(req *AnnounceRequest) (res AnnounceResponse, err error) res.Interval = h.Interval res.Leechers = h.Leechers res.Seeders = h.Seeders - cps, err := util.UnmarshalIPv4CompactPeers(b.Bytes()) + var cps krpc.CompactIPv4NodeAddrs + err = cps.UnmarshalBinary(b.Bytes()) if err != nil { return } diff --git a/tracker/udp_test.go b/tracker/udp_test.go index 3330cba3..f080621f 100644 --- a/tracker/udp_test.go +++ b/tracker/udp_test.go @@ -12,11 +12,10 @@ import ( "sync" "testing" + "github.com/anacrolix/dht/krpc" _ "github.com/anacrolix/envpprof" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - - "github.com/anacrolix/torrent/util" ) // Ensure net.IPs are stored big-endian, to match the way they're read from @@ -32,7 +31,7 @@ func TestNetIPv4Bytes(t *testing.T) { } func TestMarshalAnnounceResponse(t *testing.T) { - peers := util.CompactIPv4Peers{ + peers := krpc.CompactIPv4NodeAddrs{ {[]byte{127, 0, 0, 1}, 2}, {[]byte{255, 0, 0, 3}, 4}, } @@ -89,7 +88,7 @@ func TestAnnounceLocalhost(t *testing.T) { {0xa3, 0x56, 0x41, 0x43, 0x74, 0x23, 0xe6, 0x26, 0xd9, 0x38, 0x25, 0x4a, 0x6b, 0x80, 0x49, 0x10, 0xa6, 0x67, 0xa, 0xc1}: { Seeders: 1, Leechers: 2, - Peers: []util.CompactPeer{ + Peers: krpc.CompactIPv4NodeAddrs{ {[]byte{1, 2, 3, 4}, 5}, {[]byte{6, 7, 8, 9}, 10}, }, diff --git a/util/types.go b/util/types.go deleted file mode 100644 index ad14f157..00000000 --- a/util/types.go +++ /dev/null @@ -1,105 +0,0 @@ -package util - -import ( - "encoding" - "encoding/binary" - "errors" - "fmt" - "net" - - "github.com/bradfitz/iter" - - "github.com/anacrolix/torrent/bencode" -) - -// Concatenated 6-byte peer addresses. -type CompactIPv4Peers []CompactPeer - -var ( - // This allows bencode.Unmarshal to do better than a string or []byte. - _ bencode.Unmarshaler = &CompactIPv4Peers{} - _ encoding.BinaryMarshaler = CompactIPv4Peers{} -) - -// This allows bencode.Unmarshal to do better than a string or []byte. -func (cps *CompactIPv4Peers) UnmarshalBencode(b []byte) (err error) { - var bb []byte - err = bencode.Unmarshal(b, &bb) - if err != nil { - return - } - *cps, err = UnmarshalIPv4CompactPeers(bb) - return -} - -func (cps CompactIPv4Peers) MarshalBinary() (ret []byte, err error) { - ret = make([]byte, len(cps)*6) - for i, cp := range cps { - copy(ret[6*i:], cp.IP.To4()) - binary.BigEndian.PutUint16(ret[6*i+4:], uint16(cp.Port)) - } - return -} - -// Represents peer address in either IPv6 or IPv4 form. -type CompactPeer struct { - IP net.IP - Port int -} - -var ( - _ bencode.Marshaler = &CompactPeer{} - _ bencode.Unmarshaler = &CompactPeer{} -) - -func (cp CompactPeer) MarshalBencode() (ret []byte, err error) { - ip := cp.IP - if ip4 := ip.To4(); ip4 != nil { - ip = ip4 - } - ret = make([]byte, len(ip)+2) - copy(ret, ip) - binary.BigEndian.PutUint16(ret[len(ip):], uint16(cp.Port)) - return bencode.Marshal(ret) -} - -func (cp *CompactPeer) UnmarshalBinary(b []byte) error { - switch len(b) { - case 18: - cp.IP = make([]byte, 16) - case 6: - cp.IP = make([]byte, 4) - default: - return fmt.Errorf("bad compact peer string: %q", b) - } - copy(cp.IP, b) - b = b[len(cp.IP):] - cp.Port = int(binary.BigEndian.Uint16(b)) - return nil -} - -func (cp *CompactPeer) UnmarshalBencode(b []byte) (err error) { - var _b []byte - err = bencode.Unmarshal(b, &_b) - if err != nil { - return - } - return cp.UnmarshalBinary(_b) -} - -func UnmarshalIPv4CompactPeers(b []byte) (ret []CompactPeer, err error) { - if len(b)%6 != 0 { - err = errors.New("bad length") - return - } - num := len(b) / 6 - ret = make([]CompactPeer, num) - for i := range iter.N(num) { - off := i * 6 - err = ret[i].UnmarshalBinary(b[off : off+6]) - if err != nil { - return - } - } - return -}