-
-
Notifications
You must be signed in to change notification settings - Fork 629
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package torrent | ||
|
||
import ( | ||
"fmt" | ||
"net" | ||
"net/netip" | ||
|
||
"github.com/anacrolix/dht/v2/krpc" | ||
) | ||
|
||
func ipv4AddrPortFromKrpcNodeAddr(na krpc.NodeAddr) (_ netip.AddrPort, err error) { | ||
ip4 := na.IP.To4() | ||
if ip4 == nil { | ||
err = fmt.Errorf("not an ipv4 address: %v", na.IP) | ||
return | ||
} | ||
addr := netip.AddrFrom4([4]byte(ip4)) | ||
addrPort := netip.AddrPortFrom(addr, uint16(na.Port)) | ||
return addrPort, nil | ||
} | ||
|
||
func ipv6AddrPortFromKrpcNodeAddr(na krpc.NodeAddr) (_ netip.AddrPort, err error) { | ||
ip6 := na.IP.To16() | ||
if ip6 == nil { | ||
err = fmt.Errorf("not an ipv4 address: %v", na.IP) | ||
return | ||
} | ||
addr := netip.AddrFrom16([16]byte(ip6)) | ||
addrPort := netip.AddrPortFrom(addr, uint16(na.Port)) | ||
return addrPort, nil | ||
} | ||
|
||
func addrPortFromPeerRemoteAddr(pra PeerRemoteAddr) (netip.AddrPort, error) { | ||
switch v := pra.(type) { | ||
case *net.TCPAddr: | ||
return v.AddrPort(), nil | ||
case *net.UDPAddr: | ||
return v.AddrPort(), nil | ||
case netip.AddrPort: | ||
return v, nil | ||
default: | ||
return netip.ParseAddrPort(pra.String()) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,11 @@ package torrent | |
|
||
import ( | ||
"fmt" | ||
"net/netip" | ||
"time" | ||
|
||
g "github.com/anacrolix/generics" | ||
|
||
"github.com/anacrolix/log" | ||
|
||
pp "github.com/anacrolix/torrent/peer_protocol" | ||
|
@@ -26,6 +29,8 @@ type pexConnState struct { | |
Listed bool | ||
info log.Logger | ||
dbg log.Logger | ||
// Running record of live connections the remote end of the connection purports to have. | ||
remoteLiveConns map[netip.AddrPort]g.Option[pp.PexPeerFlags] | ||
} | ||
|
||
func (s *pexConnState) IsEnabled() bool { | ||
|
@@ -67,6 +72,13 @@ func (s *pexConnState) genmsg() *pp.PexMsg { | |
return &tx | ||
} | ||
|
||
func (s *pexConnState) numPending() int { | ||
if s.torrent == nil { | ||
return 0 | ||
} | ||
return s.torrent.pex.numPending(s.last) | ||
} | ||
|
||
// Share is called from the writer goroutine if when it is woken up with the write buffers empty | ||
// Returns whether there's more room on the send buffer to write to. | ||
func (s *pexConnState) Share(postfn messageWriter) bool { | ||
|
@@ -86,25 +98,51 @@ func (s *pexConnState) Share(postfn messageWriter) bool { | |
return true | ||
} | ||
|
||
func (s *pexConnState) updateRemoteLiveConns(rx pp.PexMsg) (errs []error) { | ||
for _, dropped := range rx.Dropped { | ||
addrPort, _ := ipv4AddrPortFromKrpcNodeAddr(dropped) | ||
delete(s.remoteLiveConns, addrPort) | ||
} | ||
for _, dropped := range rx.Dropped6 { | ||
addrPort, _ := ipv6AddrPortFromKrpcNodeAddr(dropped) | ||
delete(s.remoteLiveConns, addrPort) | ||
} | ||
for i, added := range rx.Added { | ||
addr := netip.AddrFrom4([4]byte(added.IP.To4())) | ||
addrPort := netip.AddrPortFrom(addr, uint16(added.Port)) | ||
flags := g.SliceGet(rx.AddedFlags, i) | ||
g.MakeMapIfNilAndSet(&s.remoteLiveConns, addrPort, flags) | ||
} | ||
for i, added := range rx.Added6 { | ||
addr := netip.AddrFrom16([16]byte(added.IP.To16())) | ||
addrPort := netip.AddrPortFrom(addr, uint16(added.Port)) | ||
flags := g.SliceGet(rx.Added6Flags, i) | ||
g.MakeMapIfNilAndSet(&s.remoteLiveConns, addrPort, flags) | ||
} | ||
return | ||
} | ||
|
||
// Recv is called from the reader goroutine | ||
func (s *pexConnState) Recv(payload []byte) error { | ||
rx, err := pp.LoadPexMsg(payload) | ||
if err != nil { | ||
return fmt.Errorf("unmarshalling pex message: %w", err) | ||
} | ||
s.dbg.Printf("received pex message: %v", rx) | ||
torrent.Add("pex added peers received", int64(len(rx.Added))) | ||
torrent.Add("pex added6 peers received", int64(len(rx.Added6))) | ||
s.updateRemoteLiveConns(rx) | ||
|
||
if !s.torrent.wantPeers() { | ||
s.dbg.Printf("peer reserve ok, incoming PEX discarded") | ||
return nil | ||
} | ||
// TODO: This should be per conn, not for the whole Torrent. | ||
if time.Now().Before(s.torrent.pex.rest) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
anacrolix
Author
Owner
|
||
s.dbg.Printf("in cooldown period, incoming PEX discarded") | ||
return nil | ||
} | ||
|
||
rx, err := pp.LoadPexMsg(payload) | ||
if err != nil { | ||
return fmt.Errorf("error unmarshalling PEX message: %s", err) | ||
} | ||
s.dbg.Print("incoming PEX message: ", rx) | ||
torrent.Add("pex added peers received", int64(len(rx.Added))) | ||
torrent.Add("pex added6 peers received", int64(len(rx.Added6))) | ||
|
||
var peers peerInfos | ||
peers.AppendFromPex(rx.Added6, rx.Added6Flags) | ||
peers.AppendFromPex(rx.Added, rx.AddedFlags) | ||
|
this "if" is useless after this change, as the throttled code is now executed before the gating check, @anacrolix