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) {
conn := &connection{
Socket: sock,
@ -364,10 +380,14 @@ func (me *Client) runConnection(sock net.Conn, torrent *torrent) (err error) {
"m": map[string]int{
"ut_metadata": 1,
},
"v": "go.torrent dev",
}
if torrent.metadataSizeKnown() {
d["metadata_size"] = torrent.metadataSize()
}
if p := me.incomingPeerPort(); p != 0 {
d["p"] = p
}
b, err := bencode.Marshal(d)
if err != nil {
panic(err)
@ -599,12 +619,21 @@ func (me *Client) connectionLoop(t *torrent, c *connection) error {
case pp.Extended:
switch msg.ExtendedID {
case pp.HandshakeExtendedID:
// TODO: Create a bencode struct for this.
var d map[string]interface{}
err = bencode.Unmarshal(msg.ExtendedPayload, &d)
if err != nil {
err = fmt.Errorf("error decoding extended message payload: %s", err)
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"]
if !ok {
err = errors.New("handshake missing m item")

View File

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