10 "github.com/bradfitz/iter"
12 "github.com/anacrolix/torrent/bencode"
15 // Concatenated 6-byte peer addresses.
16 type CompactIPv4Peers []CompactPeer
19 // This allows bencode.Unmarshal to do better than a string or []byte.
20 _ bencode.Unmarshaler = &CompactIPv4Peers{}
21 _ encoding.BinaryMarshaler = CompactIPv4Peers{}
24 // This allows bencode.Unmarshal to do better than a string or []byte.
25 func (me *CompactIPv4Peers) UnmarshalBencode(b []byte) (err error) {
27 err = bencode.Unmarshal(b, &bb)
31 *me, err = UnmarshalIPv4CompactPeers(bb)
35 func (me CompactIPv4Peers) MarshalBinary() (ret []byte, err error) {
36 ret = make([]byte, len(me)*6)
37 for i, cp := range me {
38 copy(ret[6*i:], cp.IP.To4())
39 binary.BigEndian.PutUint16(ret[6*i+4:], uint16(cp.Port))
44 // Represents peer address in either IPv6 or IPv4 form.
45 type CompactPeer struct {
51 _ bencode.Marshaler = &CompactPeer{}
52 _ bencode.Unmarshaler = &CompactPeer{}
55 func (me CompactPeer) MarshalBencode() (ret []byte, err error) {
57 if ip4 := ip.To4(); ip4 != nil {
60 ret = make([]byte, len(ip)+2)
62 binary.BigEndian.PutUint16(ret[len(ip):], uint16(me.Port))
63 return bencode.Marshal(ret)
66 func (me *CompactPeer) UnmarshalBinary(b []byte) error {
69 me.IP = make([]byte, 16)
71 me.IP = make([]byte, 4)
73 return fmt.Errorf("bad compact peer string: %q", b)
77 me.Port = int(binary.BigEndian.Uint16(b))
81 func (me *CompactPeer) UnmarshalBencode(b []byte) (err error) {
83 err = bencode.Unmarshal(b, &_b)
87 return me.UnmarshalBinary(_b)
90 func UnmarshalIPv4CompactPeers(b []byte) (ret []CompactPeer, err error) {
92 err = errors.New("bad length")
96 ret = make([]CompactPeer, num)
97 for i := range iter.N(num) {
99 err = ret[i].UnmarshalBinary(b[off : off+6])