Support IPv6 peers over PEX

This commit is contained in:
Matt Joiner 2018-02-13 00:50:32 +11:00
parent 39bde7237e
commit 70010ce691
4 changed files with 45 additions and 15 deletions

17
Peers.go Normal file
View File

@ -0,0 +1,17 @@
package torrent
import "github.com/anacrolix/dht/krpc"
type Peers []Peer
func (me *Peers) FromPex(nas []krpc.NodeAddr, fs []pexPeerFlags) {
for i, na := range nas {
var p Peer
var f pexPeerFlags
if i < len(fs) {
f = fs[i]
}
p.FromPex(na, f)
*me = append(*me, p)
}
}

View File

@ -1142,6 +1142,8 @@ func (c *connection) onReadExtendedMsg(id byte, payload []byte) (err error) {
return nil
case pexExtendedId:
if cl.config.DisablePEX {
// TODO: Maybe close the connection. Check that we're not
// advertising that we support PEX if it's disabled.
return nil
}
var pexMsg peerExchangeMessage
@ -1150,21 +1152,9 @@ func (c *connection) onReadExtendedMsg(id byte, payload []byte) (err error) {
return fmt.Errorf("error unmarshalling PEX message: %s", err)
}
go func() {
ps := pexMsg.AddedPeers()
cl.mu.Lock()
t.addPeers(func() (ret []Peer) {
for i, cp := range pexMsg.Added {
p := Peer{
IP: append(make(net.IP, 0, 4), cp.IP...),
Port: cp.Port,
Source: peerSourcePEX,
}
if i < len(pexMsg.AddedFlags) && pexMsg.AddedFlags[i]&0x01 != 0 {
p.SupportsEncryption = true
}
ret = append(ret, p)
}
return
}())
t.addPeers(ps)
cl.mu.Unlock()
}()
return nil

12
pex.go
View File

@ -6,13 +6,17 @@ type peerExchangeMessage struct {
Added krpc.CompactIPv4NodeAddrs `bencode:"added"`
AddedFlags []pexPeerFlags `bencode:"added.f"`
Added6 krpc.CompactIPv6NodeAddrs `bencode:"added6"`
AddedFlags6 []pexPeerFlags `bencode:"added6.f"`
Added6Flags []pexPeerFlags `bencode:"added6.f"`
Dropped krpc.CompactIPv4NodeAddrs `bencode:"dropped"`
Dropped6 krpc.CompactIPv6NodeAddrs `bencode:"dropped6"`
}
type pexPeerFlags byte
func (me pexPeerFlags) Get(f pexPeerFlags) bool {
return me&f == f
}
const (
pexPrefersEncryption = 0x01
pexSeedUploadOnly = 0x02
@ -20,3 +24,9 @@ const (
pexHolepunchSupport = 0x08
pexOutgoingConn = 0x10
)
func (me *peerExchangeMessage) AddedPeers() (ret Peers) {
ret.FromPex(me.Added, me.AddedFlags)
ret.FromPex(me.Added6, me.Added6Flags)
return
}

View File

@ -16,6 +16,7 @@ import (
"time"
"github.com/anacrolix/dht"
"github.com/anacrolix/dht/krpc"
"github.com/anacrolix/log"
"github.com/anacrolix/missinggo"
"github.com/anacrolix/missinggo/bitmap"
@ -738,6 +739,18 @@ type Peer struct {
Source peerSource
// Peer is known to support encryption.
SupportsEncryption bool
pexPeerFlags
}
func (me *Peer) FromPex(na krpc.NodeAddr, fs pexPeerFlags) {
me.IP = append([]byte(nil), na.IP...)
me.Port = na.Port
me.Source = peerSourcePEX
// If they prefer encryption, they must support it.
if fs.Get(pexPrefersEncryption) {
me.SupportsEncryption = true
}
me.pexPeerFlags = fs
}
func (t *Torrent) pieceLength(piece int) pp.Integer {