]> Sergey Matveev's repositories - btrtrc.git/blobdiff - torrent.go
Rename tracker/http package
[btrtrc.git] / torrent.go
index c8606ad82ccbf2f47aade00c8e3198bff4d71deb..1b2fc978f45c0bc50168fdb3a96775504cb98b14 100644 (file)
@@ -30,8 +30,6 @@ import (
        "github.com/anacrolix/missinggo/v2/pubsub"
        "github.com/anacrolix/multiless"
        "github.com/anacrolix/sync"
-       request_strategy "github.com/anacrolix/torrent/request-strategy"
-       typedRoaring "github.com/anacrolix/torrent/typed-roaring"
        "github.com/davecgh/go-spew/spew"
        "github.com/pion/datachannel"
 
@@ -39,9 +37,11 @@ import (
        "github.com/anacrolix/torrent/common"
        "github.com/anacrolix/torrent/metainfo"
        pp "github.com/anacrolix/torrent/peer_protocol"
+       request_strategy "github.com/anacrolix/torrent/request-strategy"
        "github.com/anacrolix/torrent/segments"
        "github.com/anacrolix/torrent/storage"
        "github.com/anacrolix/torrent/tracker"
+       typedRoaring "github.com/anacrolix/torrent/typed-roaring"
        "github.com/anacrolix/torrent/webseed"
        "github.com/anacrolix/torrent/webtorrent"
 )
@@ -61,6 +61,7 @@ type Torrent struct {
        userOnWriteChunkErr    func(error)
 
        closed   chansync.SetOnce
+       onClose  []func()
        infoHash metainfo.Hash
        pieces   []Piece
 
@@ -168,7 +169,7 @@ type Torrent struct {
 }
 
 func (t *Torrent) length() int64 {
-       return t._length.Value()
+       return t._length.Value
 }
 
 func (t *Torrent) selectivePieceAvailabilityFromPeers(i pieceIndex) (count int) {
@@ -534,7 +535,7 @@ func (t *Torrent) setMetadataSize(size int) (err error) {
                return
        }
        if uint32(size) > maxMetadataSize {
-               return errors.New("bad size")
+               return log.WithLevel(log.Warning, errors.New("bad size"))
        }
        if len(t.metadataBytes) == size {
                return
@@ -865,6 +866,9 @@ func (t *Torrent) close(wg *sync.WaitGroup) (err error) {
                err = errors.New("already closed")
                return
        }
+       for _, f := range t.onClose {
+               f()
+       }
        if t.storage != nil {
                wg.Add(1)
                go func() {
@@ -1571,18 +1575,23 @@ func (t *Torrent) onWebRtcConn(
                DataChannelContext: dcc,
        }
        peerRemoteAddr := netConn.RemoteAddr()
+       //t.logger.Levelf(log.Critical, "onWebRtcConn remote addr: %v", peerRemoteAddr)
        if t.cl.badPeerAddr(peerRemoteAddr) {
                return
        }
+       localAddrIpPort := missinggo.IpPortFromNetAddr(netConn.LocalAddr())
        pc, err := t.cl.initiateProtocolHandshakes(
                context.Background(),
                netConn,
                t,
-               dcc.LocalOffered,
                false,
-               netConn.RemoteAddr(),
-               webrtcNetwork,
-               fmt.Sprintf("webrtc offer_id %x: %v", dcc.OfferId, regularNetConnPeerConnConnString(netConn)),
+               newConnectionOpts{
+                       outgoing:        dcc.LocalOffered,
+                       remoteAddr:      peerRemoteAddr,
+                       localPublicAddr: localAddrIpPort,
+                       network:         webrtcNetwork,
+                       connString:      fmt.Sprintf("webrtc offer_id %x: %v", dcc.OfferId, regularNetConnPeerConnConnString(netConn)),
+               },
        )
        if err != nil {
                t.logger.WithDefaultLevel(log.Error).Printf("error in handshaking webrtc connection: %v", err)
@@ -1605,7 +1614,7 @@ func (t *Torrent) onWebRtcConn(
 func (t *Torrent) logRunHandshookConn(pc *PeerConn, logAll bool, level log.Level) {
        err := t.cl.runHandshookConn(pc, t)
        if err != nil || logAll {
-               t.logger.WithDefaultLevel(level).Printf("error running handshook conn: %v", err)
+               t.logger.WithDefaultLevel(level).Levelf(log.ErrorLevel(err), "error running handshook conn: %v", err)
        }
 }
 
@@ -1614,11 +1623,10 @@ func (t *Torrent) runHandshookConnLoggingErr(pc *PeerConn) {
 }
 
 func (t *Torrent) startWebsocketAnnouncer(u url.URL) torrentTrackerAnnouncer {
-       wtc, release := t.cl.websocketTrackers.Get(u.String())
-       go func() {
-               <-t.closed.Done()
-               release()
-       }()
+       wtc, release := t.cl.websocketTrackers.Get(u.String(), t.infoHash)
+       // This needs to run before the Torrent is dropped from the Client, to prevent a new webtorrent.TrackerClient for
+       // the same info hash before the old one is cleaned up.
+       t.onClose = append(t.onClose, release)
        wst := websocketTrackerStatus{u, wtc}
        go func() {
                err := wtc.Announce(tracker.Started, t.infoHash)
@@ -1711,7 +1719,7 @@ func (t *Torrent) announceRequest(event tracker.AnnounceEvent) tracker.AnnounceR
                Event: event,
                NumWant: func() int32 {
                        if t.wantPeers() && len(t.cl.dialers) > 0 {
-                               return -1
+                               return 200 // Win has UDP packet limit. See: https://github.com/anacrolix/torrent/issues/764
                        } else {
                                return 0
                        }
@@ -2007,7 +2015,11 @@ func (t *Torrent) pieceHashed(piece pieceIndex, passed bool, hashIoErr error) {
                        c._stats.incrementPiecesDirtiedGood()
                }
                t.clearPieceTouchers(piece)
+               hasDirty := p.hasDirtyChunks()
                t.cl.unlock()
+               if hasDirty {
+                       p.Flush() // You can be synchronous here!
+               }
                err := p.Storage().MarkComplete()
                if err != nil {
                        t.logger.Printf("%T: error marking piece complete %d: %s", t.storage, piece, err)
@@ -2157,7 +2169,7 @@ func (t *Torrent) dropBannedPeers() {
        t.iterPeers(func(p *Peer) {
                remoteIp := p.remoteIp()
                if remoteIp == nil {
-                       if p.bannableAddr.Ok() {
+                       if p.bannableAddr.Ok {
                                t.logger.WithDefaultLevel(log.Debug).Printf("can't get remote ip for peer %v", p)
                        }
                        return