Support IPv6 peers over PEX
This commit is contained in:
parent
39bde7237e
commit
70010ce691
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1142,6 +1142,8 @@ func (c *connection) onReadExtendedMsg(id byte, payload []byte) (err error) {
|
||||||
return nil
|
return nil
|
||||||
case pexExtendedId:
|
case pexExtendedId:
|
||||||
if cl.config.DisablePEX {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
var pexMsg peerExchangeMessage
|
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)
|
return fmt.Errorf("error unmarshalling PEX message: %s", err)
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
|
ps := pexMsg.AddedPeers()
|
||||||
cl.mu.Lock()
|
cl.mu.Lock()
|
||||||
t.addPeers(func() (ret []Peer) {
|
t.addPeers(ps)
|
||||||
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
|
|
||||||
}())
|
|
||||||
cl.mu.Unlock()
|
cl.mu.Unlock()
|
||||||
}()
|
}()
|
||||||
return nil
|
return nil
|
||||||
|
|
12
pex.go
12
pex.go
|
@ -6,13 +6,17 @@ type peerExchangeMessage struct {
|
||||||
Added krpc.CompactIPv4NodeAddrs `bencode:"added"`
|
Added krpc.CompactIPv4NodeAddrs `bencode:"added"`
|
||||||
AddedFlags []pexPeerFlags `bencode:"added.f"`
|
AddedFlags []pexPeerFlags `bencode:"added.f"`
|
||||||
Added6 krpc.CompactIPv6NodeAddrs `bencode:"added6"`
|
Added6 krpc.CompactIPv6NodeAddrs `bencode:"added6"`
|
||||||
AddedFlags6 []pexPeerFlags `bencode:"added6.f"`
|
Added6Flags []pexPeerFlags `bencode:"added6.f"`
|
||||||
Dropped krpc.CompactIPv4NodeAddrs `bencode:"dropped"`
|
Dropped krpc.CompactIPv4NodeAddrs `bencode:"dropped"`
|
||||||
Dropped6 krpc.CompactIPv6NodeAddrs `bencode:"dropped6"`
|
Dropped6 krpc.CompactIPv6NodeAddrs `bencode:"dropped6"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type pexPeerFlags byte
|
type pexPeerFlags byte
|
||||||
|
|
||||||
|
func (me pexPeerFlags) Get(f pexPeerFlags) bool {
|
||||||
|
return me&f == f
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
pexPrefersEncryption = 0x01
|
pexPrefersEncryption = 0x01
|
||||||
pexSeedUploadOnly = 0x02
|
pexSeedUploadOnly = 0x02
|
||||||
|
@ -20,3 +24,9 @@ const (
|
||||||
pexHolepunchSupport = 0x08
|
pexHolepunchSupport = 0x08
|
||||||
pexOutgoingConn = 0x10
|
pexOutgoingConn = 0x10
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (me *peerExchangeMessage) AddedPeers() (ret Peers) {
|
||||||
|
ret.FromPex(me.Added, me.AddedFlags)
|
||||||
|
ret.FromPex(me.Added6, me.Added6Flags)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
13
torrent.go
13
torrent.go
|
@ -16,6 +16,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/anacrolix/dht"
|
"github.com/anacrolix/dht"
|
||||||
|
"github.com/anacrolix/dht/krpc"
|
||||||
"github.com/anacrolix/log"
|
"github.com/anacrolix/log"
|
||||||
"github.com/anacrolix/missinggo"
|
"github.com/anacrolix/missinggo"
|
||||||
"github.com/anacrolix/missinggo/bitmap"
|
"github.com/anacrolix/missinggo/bitmap"
|
||||||
|
@ -738,6 +739,18 @@ type Peer struct {
|
||||||
Source peerSource
|
Source peerSource
|
||||||
// Peer is known to support encryption.
|
// Peer is known to support encryption.
|
||||||
SupportsEncryption bool
|
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 {
|
func (t *Torrent) pieceLength(piece int) pp.Integer {
|
||||||
|
|
Loading…
Reference in New Issue