18 func (i *Integer) Read(r io.Reader) error {
19 return binary.Read(r, binary.BigEndian, i)
22 // It's perfectly fine to cast these to an int.
23 func (i Integer) Int() int {
28 Protocol = "\x13BitTorrent protocol"
32 Choke MessageType = iota
48 AllowedFast = 0x11 // 17
52 HandshakeExtendedID = 0
54 RequestMetadataExtensionMsgType = 0
55 DataMetadataExtensionMsgType = 1
56 RejectMetadataExtensionMsgType = 2
62 Index, Begin, Length Integer
66 ExtendedPayload []byte
70 func (msg Message) MarshalBinary() (data []byte, err error) {
71 buf := &bytes.Buffer{}
73 err = buf.WriteByte(byte(msg.Type))
78 case Choke, Unchoke, Interested, NotInterested, HaveAll, HaveNone:
80 err = binary.Write(buf, binary.BigEndian, msg.Index)
81 case Request, Cancel, Reject:
82 for _, i := range []Integer{msg.Index, msg.Begin, msg.Length} {
83 err = binary.Write(buf, binary.BigEndian, i)
89 _, err = buf.Write(marshalBitfield(msg.Bitfield))
91 for _, i := range []Integer{msg.Index, msg.Begin} {
92 err = binary.Write(buf, binary.BigEndian, i)
97 n, err := buf.Write(msg.Piece)
101 if n != len(msg.Piece) {
105 err = buf.WriteByte(msg.ExtendedID)
109 _, err = buf.Write(msg.ExtendedPayload)
111 err = binary.Write(buf, binary.BigEndian, msg.Port)
113 err = fmt.Errorf("unknown message type: %v", msg.Type)
116 data = make([]byte, 4+buf.Len())
117 binary.BigEndian.PutUint32(data, uint32(buf.Len()))
118 if buf.Len() != copy(data[4:], buf.Bytes()) {
124 type Decoder struct {
126 MaxLength Integer // TODO: Should this include the length header or not?
129 // io.EOF is returned if the source terminates cleanly on a message boundary.
130 func (d *Decoder) Decode(msg *Message) (err error) {
132 err = binary.Read(d.R, binary.BigEndian, &length)
135 err = fmt.Errorf("error reading message length: %s", err)
139 if length > d.MaxLength {
140 return errors.New("message too long")
146 msg.Keepalive = false
147 b := make([]byte, length)
148 _, err = io.ReadFull(d.R, b)
151 err = io.ErrUnexpectedEOF
153 if err != io.ErrUnexpectedEOF {
154 err = fmt.Errorf("error reading message: %s", err)
158 r := bytes.NewReader(b)
159 // Check that all of r was utilized.
165 err = fmt.Errorf("%d bytes unused in message type %d", r.Len(), msg.Type)
168 msg.Keepalive = false
169 c, err := r.ReadByte()
173 msg.Type = MessageType(c)
175 case Choke, Unchoke, Interested, NotInterested, HaveAll, HaveNone:
178 err = msg.Index.Read(r)
179 case Request, Cancel, Reject:
180 for _, data := range []*Integer{&msg.Index, &msg.Begin, &msg.Length} {
187 b := make([]byte, length-1)
188 _, err = io.ReadFull(r, b)
189 msg.Bitfield = unmarshalBitfield(b)
191 for _, pi := range []*Integer{&msg.Index, &msg.Begin} {
200 msg.Piece, err = ioutil.ReadAll(r)
202 msg.ExtendedID, err = r.ReadByte()
206 msg.ExtendedPayload, err = ioutil.ReadAll(r)
208 err = binary.Read(r, binary.BigEndian, &msg.Port)
210 err = fmt.Errorf("unknown message type %#v", c)
217 func (b Bytes) MarshalBinary() ([]byte, error) {
221 func unmarshalBitfield(b []byte) (bf []bool) {
222 for _, c := range b {
223 for i := 7; i >= 0; i-- {
224 bf = append(bf, (c>>uint(i))&1 == 1)
230 func marshalBitfield(bf []bool) (b []byte) {
231 b = make([]byte, (len(bf)+7)/8)
232 for i, have := range bf {
237 c |= 1 << uint(7-i%8)