Add support for extended handshake "v", "reqq", and "p" fields

This commit is contained in:
Matt Joiner 2014-06-29 18:57:49 +10:00
parent 5e7fe0383b
commit aec5074f3d
2 changed files with 30 additions and 0 deletions

View File

@ -291,6 +291,22 @@ func (me *Client) initiateConn(peer Peer, torrent *torrent) {
}() }()
} }
func (cl *Client) incomingPeerPort() int {
if cl.Listener == nil {
return 0
}
_, p, err := net.SplitHostPort(cl.Listener.Addr().String())
if err != nil {
panic(err)
}
var i int
_, err = fmt.Sscanf(p, "%d", &i)
if err != nil {
panic(err)
}
return i
}
func (me *Client) runConnection(sock net.Conn, torrent *torrent) (err error) { func (me *Client) runConnection(sock net.Conn, torrent *torrent) (err error) {
conn := &connection{ conn := &connection{
Socket: sock, Socket: sock,
@ -364,10 +380,14 @@ func (me *Client) runConnection(sock net.Conn, torrent *torrent) (err error) {
"m": map[string]int{ "m": map[string]int{
"ut_metadata": 1, "ut_metadata": 1,
}, },
"v": "go.torrent dev",
} }
if torrent.metadataSizeKnown() { if torrent.metadataSizeKnown() {
d["metadata_size"] = torrent.metadataSize() d["metadata_size"] = torrent.metadataSize()
} }
if p := me.incomingPeerPort(); p != 0 {
d["p"] = p
}
b, err := bencode.Marshal(d) b, err := bencode.Marshal(d)
if err != nil { if err != nil {
panic(err) panic(err)
@ -599,12 +619,21 @@ func (me *Client) connectionLoop(t *torrent, c *connection) error {
case pp.Extended: case pp.Extended:
switch msg.ExtendedID { switch msg.ExtendedID {
case pp.HandshakeExtendedID: case pp.HandshakeExtendedID:
// TODO: Create a bencode struct for this.
var d map[string]interface{} var d map[string]interface{}
err = bencode.Unmarshal(msg.ExtendedPayload, &d) err = bencode.Unmarshal(msg.ExtendedPayload, &d)
if err != nil { if err != nil {
err = fmt.Errorf("error decoding extended message payload: %s", err) err = fmt.Errorf("error decoding extended message payload: %s", err)
break break
} }
if reqq, ok := d["reqq"]; ok {
if i, ok := reqq.(int64); ok {
c.PeerMaxRequests = int(i)
}
}
if v, ok := d["v"]; ok {
c.PeerClientName = v.(string)
}
m, ok := d["m"] m, ok := d["m"]
if !ok { if !ok {
err = errors.New("handshake missing m item") err = errors.New("handshake missing m item")

View File

@ -35,6 +35,7 @@ type connection struct {
PeerPieces []bool PeerPieces []bool
PeerMaxRequests int // Maximum pending requests the peer allows. PeerMaxRequests int // Maximum pending requests the peer allows.
PeerExtensionIDs map[string]int64 PeerExtensionIDs map[string]int64
PeerClientName string
} }
func (cn *connection) completedString() string { func (cn *connection) completedString() string {