torrent.go | 13 ++++++++----- webtorrent/tracker-client.go | 11 +++++++++++ wstracker.go | 3 ++- diff --git a/torrent.go b/torrent.go index e53b6bef23f0c032aa6da9e08d212e27a8df7855..f18fc25231ac476c2c5e40124b8782e9c060c812 100644 --- a/torrent.go +++ b/torrent.go @@ -61,6 +61,7 @@ dataUploadDisallowed bool userOnWriteChunkErr func(error) closed chansync.SetOnce + onClose []func() infoHash metainfo.Hash pieces []Piece @@ -865,6 +866,9 @@ if !t.closed.Set() { err = errors.New("already closed") return } + for _, f := range t.onClose { + f() + } if t.storage != nil { wg.Add(1) go func() { @@ -1614,11 +1618,10 @@ t.logRunHandshookConn(pc, false, log.Debug) } 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) diff --git a/webtorrent/tracker-client.go b/webtorrent/tracker-client.go index 1ec4b9d9c6f917200c2795665283a2ad8e286df9..3b8c6a6bbcdfb2a4cbe08a9a78fce75eace7cc7d 100644 --- a/webtorrent/tracker-client.go +++ b/webtorrent/tracker-client.go @@ -187,6 +187,17 @@ } tc.outboundOffers = nil } +func (tc *TrackerClient) CloseOffersForInfohash(infoHash [20]byte) { + tc.mu.Lock() + defer tc.mu.Unlock() + for key, offer := range tc.outboundOffers { + if offer.infoHash == infoHash { + offer.peerConnection.Close() + delete(tc.outboundOffers, key) + } + } +} + func (tc *TrackerClient) Announce(event tracker.AnnounceEvent, infoHash [20]byte) error { metrics.Add("outbound announces", 1) var randOfferId [20]byte diff --git a/wstracker.go b/wstracker.go index 5338ceb913da7644b2d0db1623b8355799a0d38b..e8bde8c348c8a7ba36106ed1ae11e8f1f77d9702 100644 --- a/wstracker.go +++ b/wstracker.go @@ -42,7 +42,7 @@ clients map[string]*refCountedWebtorrentTrackerClient Proxy http.ProxyFunc } -func (me *websocketTrackers) Get(url string) (*webtorrent.TrackerClient, func()) { +func (me *websocketTrackers) Get(url string, infoHash [20]byte) (*webtorrent.TrackerClient, func()) { me.mu.Lock() defer me.mu.Unlock() value, ok := me.clients[url] @@ -74,6 +74,7 @@ value.refCount++ return &value.TrackerClient, func() { me.mu.Lock() defer me.mu.Unlock() + value.TrackerClient.CloseOffersForInfohash(infoHash) value.refCount-- if value.refCount == 0 { value.TrackerClient.Close()