postedCancels = expvar.NewInt("postedCancels")
)
-const extensionBytes = "\x00\x00\x00\x00\x00\x10\x00\x00"
+// Justification for set bits follows.
+//
+// Extension protocol: http://www.bittorrent.org/beps/bep_0010.html
+// DHT: http://www.bittorrent.org/beps/bep_0005.html
+const extensionBytes = "\x00\x00\x00\x00\x00\x10\x00\x01"
// Currently doesn't really queue, but should in the future.
func (cl *Client) queuePieceCheck(t *torrent, pieceIndex pp.Integer) {
Bitfield: torrent.bitfield(),
})
}
+ if conn.PeerExtensionBytes[7]&0x01 != 0 && me.dHT != nil {
+ addr, _ := me.dHT.LocalAddr().(*net.UDPAddr)
+ conn.Post(pp.Message{
+ Type: pp.Port,
+ Port: uint16(addr.Port),
+ })
+ }
err = me.connectionLoop(torrent, conn)
if err != nil {
err = fmt.Errorf("during Connection loop with peer %q: %s", conn.PeerID, err)
if err != nil {
log.Printf("peer extension map: %#v", c.PeerExtensionIDs)
}
+ case pp.Port:
+ if me.dHT == nil {
+ break
+ }
+ addr, _ := c.Socket.RemoteAddr().(*net.TCPAddr)
+ _, err = me.dHT.Ping(&net.UDPAddr{
+ IP: addr.IP,
+ Zone: addr.Zone,
+ Port: int(msg.Port),
+ })
default:
err = fmt.Errorf("received unknown message type: %#v", msg.Type)
}
Request // 6
Piece // 7
Cancel // 8
+ Port // 9
Extended = 20
HandshakeExtendedID = 0
Bitfield []bool
ExtendedID byte
ExtendedPayload []byte
+ Port uint16
}
func (msg Message) MarshalBinary() (data []byte, err error) {
return
}
_, err = buf.Write(msg.ExtendedPayload)
+ case Port:
+ err = binary.Write(buf, binary.BigEndian, msg.Port)
default:
err = fmt.Errorf("unknown message type: %v", msg.Type)
}
break
}
msg.ExtendedPayload, err = ioutil.ReadAll(r)
+ case Port:
+ err = binary.Read(r, binary.BigEndian, &msg.Port)
default:
err = fmt.Errorf("unknown message type %#v", c)
}
t.Fatalf("marshalled keepalive is %q, expected %q", bs, expected)
}
}
+
+func TestMarshalPortMsg(t *testing.T) {
+ b, err := (Message{
+ Type: Port,
+ Port: 0xaabb,
+ }).MarshalBinary()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if string(b) != "\x00\x00\x00\x03\x09\xaa\xbb" {
+ t.FailNow()
+ }
+}
+
+func TestUnmarshalPortMsg(t *testing.T) {
+ var m Message
+ d := Decoder{
+ R: bufio.NewReader(bytes.NewBufferString("\x00\x00\x00\x03\x09\xaa\xbb")),
+ MaxLength: 8,
+ }
+ err := d.Decode(&m)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if m.Type != Port {
+ t.FailNow()
+ }
+ if m.Port != 0xaabb {
+ t.FailNow()
+ }
+}