client.go | 2 +- connection.go | 3 +-- pex.go | 21 +++++++++++++++++---- tracker/http.go | 6 +++--- tracker/server.go | 4 ++-- tracker/udp.go | 6 +++--- tracker/udp_test.go | 7 +++---- util/types.go | 105 ----------------------------------------------------- diff --git a/client.go b/client.go index 40dc88af5045630c5027e8af514d9234f155430b..60bd43b4460821c26958f8536bf081dde2ad9f71 100644 --- a/client.go +++ b/client.go @@ -1177,7 +1177,7 @@ log.Printf("won't add DHT node with bad IP: %q", hmp.Host) continue } ni := krpc.NodeInfo{ - Addr: &net.UDPAddr{ + Addr: krpc.NodeAddr{ IP: ip, Port: hmp.Port, }, diff --git a/connection.go b/connection.go index 09b09a64d4a69460b9ee590786515297e7d73c40..379b45f9668e84b74f176423294d01faf09de99b 100644 --- a/connection.go +++ b/connection.go @@ -1154,14 +1154,13 @@ cl.mu.Lock() 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 674074fec2a26db1a64741449ca2ee640fa436a5..b3e3e16660ea36d39c74c5e2e5aaf0ab0641cb60 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 6767a6725217f4ba72f5b3e47e18f1dde32dc8cd..d207f85268435ef30db2d370d688d61daa510f06 100644 --- a/tracker/http.go +++ b/tracker/http.go @@ -9,10 +9,10 @@ "net/http" "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 @@ 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 27879d400f7d6be8af8b3b7500ff00f1d6b2611e..fbb9840d8197996fd33c519e2ac680fc1853998d 100644 --- a/tracker/server.go +++ b/tracker/server.go @@ -7,13 +7,13 @@ "fmt" "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 07c7f0ae2d0d19a9c38442f8745483b499dcf625..0302a4e8a8be963b6e89673d7ec4086c91629a9e 100644 --- a/tracker/udp.go +++ b/tracker/udp.go @@ -11,10 +11,9 @@ "net" "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 @@ } 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 3330cba3807078549d5f3f2a012e8dfea36a4323..f080621f1675e6575c7248e533c78c28f3608898 100644 --- a/tracker/udp_test.go +++ b/tracker/udp_test.go @@ -12,11 +12,10 @@ "net/url" "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 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 @@ t: map[[20]byte]torrent{ {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 ad14f157c335e84908f6766e43aa617aac5d864f..0000000000000000000000000000000000000000 --- 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 -}