client.go | 28 ++++++++++++++-------------- torrent.go | 3 ++- diff --git a/client.go b/client.go index 79e9680b9628a51436d5c08913053a7245a947d4..dfa375dcc5cd27626131ddf305a4429f3077ed28 100644 --- a/client.go +++ b/client.go @@ -1668,17 +1668,19 @@ cl.mu.RUnlock() return } -func (cl *Client) announceTorrentSingleTracker(tr string, req *tracker.AnnounceRequest, t *Torrent) error { +func (cl *Client) announceTorrentSingleTracker(tr string, req *tracker.AnnounceRequest, t *Torrent) (interval time.Duration, err error) { blocked, err := cl.trackerBlockedUnlocked(tr) if err != nil { - return fmt.Errorf("error determining if tracker blocked: %s", err) + err = fmt.Errorf("error determining if tracker blocked: %s", err) + return } if blocked { - return fmt.Errorf("tracker blocked: %s", tr) + err = errors.New("tracker has blocked IP") + return } resp, err := tracker.Announce(tr, req) if err != nil { - return fmt.Errorf("error announcing: %s", err) + return } var peers []Peer for _, peer := range resp.Peers { @@ -1687,14 +1689,9 @@ IP: peer.IP, Port: peer.Port, }) } - cl.mu.Lock() - cl.addPeers(t, peers) - cl.mu.Unlock() - - // log.Printf("%s: %d new peers from %s", t, len(peers), tr) - - time.Sleep(time.Second * time.Duration(resp.Interval)) - return nil + t.AddPeers(peers) + interval = time.Second * time.Duration(resp.Interval) + return } func (cl *Client) announceTorrentTrackersFastStart(req *tracker.AnnounceRequest, trackers []trackerTier, t *Torrent) (atLeastOne bool) { @@ -1704,7 +1701,7 @@ for _, tier := range trackers { for _, tr := range tier { outstanding++ go func(tr string) { - err := cl.announceTorrentSingleTracker(tr, req, t) + _, err := cl.announceTorrentSingleTracker(tr, req, t) oks <- err == nil }(tr) } @@ -1748,8 +1745,9 @@ numTrackersTried := 0 for _, tier := range trackers { for trIndex, tr := range tier { numTrackersTried++ - err := cl.announceTorrentSingleTracker(tr, &req, t) + interval, err := cl.announceTorrentSingleTracker(tr, &req, t) if err != nil { + // Try the next tracker. continue } // Float the successful announce to the top of the tier. If @@ -1760,6 +1758,8 @@ tier[0], tier[trIndex] = tier[trIndex], tier[0] cl.mu.Unlock() req.Event = tracker.None + // Wait the interval before attempting another announce. + time.Sleep(interval) continue newAnnounce } } diff --git a/torrent.go b/torrent.go index f8dfea2c59d6e6ffe51d34dcd12ca5ff90be0c1f..68937544f9740a8d0233cf06c248a82933ab7853 100644 --- a/torrent.go +++ b/torrent.go @@ -2,6 +2,7 @@ package torrent import ( "container/heap" + "errors" "fmt" "io" "log" @@ -208,7 +209,7 @@ if err != nil { return fmt.Errorf("error unmarshalling info bytes: %s", err) } if ie.Hash() != t.infoHash { - return fmt.Errorf("info bytes have wrong hash") + return errors.New("info bytes have wrong hash") } err = validateInfo(&ie.Info) if err != nil {