"io"
"net"
"strings"
- "sync/atomic"
"time"
"github.com/RoaringBitmap/roaring"
peerTouchedPieces map[pieceIndex]struct{}
peerAllowedFast typedRoaring.Bitmap[pieceIndex]
- PeerMaxRequests maxRequests // Maximum pending requests the peer allows.
- PeerExtensionIDs map[pp.ExtensionName]pp.ExtensionNumber
- PeerClientName atomic.Value
+ PeerMaxRequests maxRequests // Maximum pending requests the peer allows.
logger log.Logger
}
return cn.t.cl.locker()
}
-func (cn *Peer) supportsExtension(ext pp.ExtensionName) bool {
+func (cn *PeerConn) supportsExtension(ext pp.ExtensionName) bool {
_, ok := cn.PeerExtensionIDs[ext]
return ok
}
}
}
-func (cn *Peer) peerPiecesChanged() {
- cn.t.maybeDropMutuallyCompletePeer(cn)
-}
-
// After handshake, we know what Torrent and Client stats to include for a
// connection.
func (cn *Peer) postHandshakeStats(f func(*ConnStats)) {
cn.allStats(add(n, func(cs *ConnStats) *Count { return &cs.BytesRead }))
}
-// Returns whether the connection could be useful to us. We're seeding and
-// they want data, we don't have metainfo and they can provide it, etc.
-func (c *Peer) useful() bool {
- t := c.t
- if c.closed.IsSet() {
- return false
- }
- if !t.haveInfo() {
- return c.supportsExtension("ut_metadata")
- }
- if t.seeding() && c.peerInterested {
- return true
- }
- if c.peerHasWantedPieces() {
- return true
- }
- return false
-}
-
func (c *Peer) lastHelpful() (ret time.Time) {
ret = c.lastUsefulChunkReceived
if c.t.seeding() && c.lastChunkSent.After(ret) {
"net/netip"
"strconv"
"strings"
+ "sync/atomic"
"time"
"github.com/RoaringBitmap/roaring"
messageWriter peerConnMsgWriter
- uploadTimer *time.Timer
- pex pexConnState
+ PeerExtensionIDs map[pp.ExtensionName]pp.ExtensionNumber
+ PeerClientName atomic.Value
+ uploadTimer *time.Timer
+ pex pexConnState
// The pieces the peer has claimed to have.
_peerPieces roaring.Bitmap
func (pc *PeerConn) bitExtensionEnabled(bit pp.ExtensionBit) bool {
return pc.t.cl.config.Extensions.GetBit(bit) && pc.PeerExtensionBytes.GetBit(bit)
}
+
+func (cn *PeerConn) peerPiecesChanged() {
+ cn.t.maybeDropMutuallyCompletePeer(cn)
+}
+
+// Returns whether the connection could be useful to us. We're seeding and
+// they want data, we don't have metainfo and they can provide it, etc.
+func (c *PeerConn) useful() bool {
+ t := c.t
+ if c.closed.IsSet() {
+ return false
+ }
+ if !t.haveInfo() {
+ return c.supportsExtension("ut_metadata")
+ }
+ if t.seeding() && c.peerInterested {
+ return true
+ }
+ if c.peerHasWantedPieces() {
+ return true
+ }
+ return false
+}
func (t *Torrent) maybeDropMutuallyCompletePeer(
// I'm not sure about taking peer here, not all peer implementations actually drop. Maybe that's
// okay?
- p *Peer,
+ p *PeerConn,
) {
if !t.cl.config.DropMutuallyCompletePeers {
return
t.piece(piece).readerCond.Broadcast()
for conn := range t.conns {
conn.have(piece)
- t.maybeDropMutuallyCompletePeer(&conn.Peer)
+ t.maybeDropMutuallyCompletePeer(conn)
}
}
incomingIsBad, outgoingIsBad bool
}
-func worseConnInputFromPeer(p *Peer, opts worseConnLensOpts) worseConnInput {
+func worseConnInputFromPeer(p *PeerConn, opts worseConnLensOpts) worseConnInput {
ret := worseConnInput{
Useful: p.useful(),
LastHelpful: p.lastHelpful(),
return ret
}
-func worseConn(_l, _r *Peer) bool {
- // TODO: Use generics for ptr to
- l := worseConnInputFromPeer(_l, worseConnLensOpts{})
- r := worseConnInputFromPeer(_r, worseConnLensOpts{})
- return l.Less(&r)
-}
-
func (l *worseConnInput) Less(r *worseConnInput) bool {
less, ok := multiless.New().Bool(
r.BadDirection, l.BadDirection).Bool(
func (me *worseConnSlice) initKeys(opts worseConnLensOpts) {
me.keys = make([]worseConnInput, len(me.conns))
for i, c := range me.conns {
- me.keys[i] = worseConnInputFromPeer(&c.Peer, opts)
+ me.keys[i] = worseConnInputFromPeer(c, opts)
}
}