19 func (i *Integer) Read(r io.Reader) error {
20 return binary.Read(r, binary.BigEndian, i)
23 // It's perfectly fine to cast these to an int.
24 func (i Integer) Int() int {
29 Protocol = "\x13BitTorrent protocol"
33 Choke MessageType = iota
49 AllowedFast = 0x11 // 17
53 HandshakeExtendedID = 0
55 RequestMetadataExtensionMsgType = 0
56 DataMetadataExtensionMsgType = 1
57 RejectMetadataExtensionMsgType = 2
63 Index, Begin, Length Integer
67 ExtendedPayload []byte
71 func (msg Message) MustMarshalBinary() []byte {
72 b, err := msg.MarshalBinary()
79 func (msg Message) MarshalBinary() (data []byte, err error) {
80 buf := &bytes.Buffer{}
82 err = buf.WriteByte(byte(msg.Type))
87 case Choke, Unchoke, Interested, NotInterested, HaveAll, HaveNone:
89 err = binary.Write(buf, binary.BigEndian, msg.Index)
90 case Request, Cancel, Reject:
91 for _, i := range []Integer{msg.Index, msg.Begin, msg.Length} {
92 err = binary.Write(buf, binary.BigEndian, i)
98 _, err = buf.Write(marshalBitfield(msg.Bitfield))
100 for _, i := range []Integer{msg.Index, msg.Begin} {
101 err = binary.Write(buf, binary.BigEndian, i)
106 n, err := buf.Write(msg.Piece)
110 if n != len(msg.Piece) {
114 err = buf.WriteByte(msg.ExtendedID)
118 _, err = buf.Write(msg.ExtendedPayload)
120 err = binary.Write(buf, binary.BigEndian, msg.Port)
122 err = fmt.Errorf("unknown message type: %v", msg.Type)
125 data = make([]byte, 4+buf.Len())
126 binary.BigEndian.PutUint32(data, uint32(buf.Len()))
127 if buf.Len() != copy(data[4:], buf.Bytes()) {
133 type Decoder struct {
136 MaxLength Integer // TODO: Should this include the length header or not?
139 func readByte(r io.Reader) (b byte, err error) {
141 n, err := r.Read(arr[:])
153 // io.EOF is returned if the source terminates cleanly on a message boundary.
154 func (d *Decoder) Decode(msg *Message) (err error) {
156 err = binary.Read(d.R, binary.BigEndian, &length)
159 err = fmt.Errorf("error reading message length: %s", err)
163 if length > d.MaxLength {
164 return errors.New("message too long")
170 msg.Keepalive = false
171 r := &io.LimitedReader{d.R, int64(length)}
172 // Check that all of r was utilized.
178 err = fmt.Errorf("%d bytes unused in message type %d", r.N, msg.Type)
181 msg.Keepalive = false
182 c, err := readByte(r)
186 msg.Type = MessageType(c)
188 case Choke, Unchoke, Interested, NotInterested, HaveAll, HaveNone:
191 err = msg.Index.Read(r)
192 case Request, Cancel, Reject:
193 for _, data := range []*Integer{&msg.Index, &msg.Begin, &msg.Length} {
200 b := make([]byte, length-1)
201 _, err = io.ReadFull(r, b)
202 msg.Bitfield = unmarshalBitfield(b)
204 for _, pi := range []*Integer{&msg.Index, &msg.Begin} {
213 //msg.Piece, err = ioutil.ReadAll(r)
214 b := *d.Pool.Get().(*[]byte)
215 n, err := io.ReadFull(r, b)
217 if err != io.ErrUnexpectedEOF || n != int(length-9) {
224 msg.ExtendedID, err = readByte(r)
228 msg.ExtendedPayload, err = ioutil.ReadAll(r)
230 err = binary.Read(r, binary.BigEndian, &msg.Port)
232 err = fmt.Errorf("unknown message type %#v", c)
239 func (b Bytes) MarshalBinary() ([]byte, error) {
243 func unmarshalBitfield(b []byte) (bf []bool) {
244 for _, c := range b {
245 for i := 7; i >= 0; i-- {
246 bf = append(bf, (c>>uint(i))&1 == 1)
252 func marshalBitfield(bf []bool) (b []byte) {
253 b = make([]byte, (len(bf)+7)/8)
254 for i, have := range bf {
259 c |= 1 << uint(7-i%8)
265 func MakeCancelMessage(piece, offset, length Integer) Message {