webtorrent/tracker_client.go | 31 +++++++++++++++++++++++++++++-- diff --git a/webtorrent/tracker_client.go b/webtorrent/tracker_client.go index 5af6c7c0df74a522614f47b949d629a749c707c3..47267e0ebe3b3bf3ccc6d53eaeaa049ea6784ab8 100644 --- a/webtorrent/tracker_client.go +++ b/webtorrent/tracker_client.go @@ -72,14 +72,14 @@ if err != nil { return fmt.Errorf("dialing tracker: %w", err) } defer c.Close() - tc.Logger.WithDefaultLevel(log.Debug).Printf("dialed tracker %q", tc.Url) + tc.Logger.WithDefaultLevel(log.Info).Printf("connected") tc.mu.Lock() tc.wsConn = c tc.cond.Broadcast() tc.mu.Unlock() + tc.announceOffers() err = tc.trackerReadLoop(tc.wsConn) tc.mu.Lock() - tc.closeUnusedOffers() c.Close() tc.mu.Unlock() return err @@ -111,11 +111,36 @@ tc.closed = true if tc.wsConn != nil { tc.wsConn.Close() } + tc.closeUnusedOffers() tc.mu.Unlock() tc.cond.Broadcast() return nil } +func (tc *TrackerClient) announceOffers() { + + // tc.Announce grabs a lock on tc.outboundOffers. It also handles the case where outboundOffers + // is nil. Take ownership of outboundOffers here. + tc.mu.Lock() + offers := tc.outboundOffers + tc.outboundOffers = nil + tc.mu.Unlock() + + if offers == nil { + return + } + + // Iterate over our locally-owned offers, close any existing "invalid" ones from before the + // socket reconnected, reannounce the infohash, adding it back into the tc.outboundOffers. + tc.Logger.WithDefaultLevel(log.Info).Printf("reannouncing %d infohashes after restart", len(offers)) + for _, offer := range offers { + // TODO: Capture the errors? Are we even in a position to do anything with them? + offer.peerConnection.Close() + // Use goroutine here to allow read loop to start and ensure the buffer drains. + go tc.Announce(tracker.Started, offer.infoHash) + } +} + func (tc *TrackerClient) closeUnusedOffers() { for _, offer := range tc.outboundOffers { offer.peerConnection.Close() @@ -139,6 +164,7 @@ } request, err := tc.GetAnnounceRequest(event, infoHash) if err != nil { + pc.Close() return fmt.Errorf("getting announce parameters: %w", err) } @@ -159,6 +185,7 @@ } data, err := json.Marshal(req) if err != nil { + pc.Close() return fmt.Errorf("marshalling request: %w", err) }