TODO | 2 ++ client.go | 36 +++++++++++++++--------------------- client_test.go | 4 ++-- cmd/tracker-announce/main.go | 14 ++------------ torrent.go | 13 +++---------- diff --git a/TODO b/TODO index 93749332aacae6c8a2f1a154c802bc8c69f0eb3e..05f032a20a30cf5c2572e9e06f48b0edb955bf2f 100644 --- a/TODO +++ b/TODO @@ -11,3 +11,5 @@ * Clean-up DHT transaction code, it's just nasty. * Handle wanted pieces more efficiently, it's slow in in fillRequests, since the prioritization system was changed. * Determine if we should accept connections, even if we just close them. http://stackoverflow.com/questions/35108571/can-i-leave-sockets-in-syn-recv-until-im-interested-in-accepting * Implement BEP 40. + * Rewrite tracker package to be announce-centric, rather than client. Currently the clients are private and adapted onto by the Announce() func. + * Move tracker management code in the torrent package to its own file. diff --git a/client.go b/client.go index 7d115467dc8104df2eec504d1fcbaf96b0a3b20c..162767055fee7a6dc52ed1d14ea3058804cd6c8b 100644 --- a/client.go +++ b/client.go @@ -1860,37 +1860,34 @@ // For shuffling the tracker tiers. mathRand.Seed(time.Now().Unix()) } +type trackerTier []string + // The trackers within each tier must be shuffled before use. // http://stackoverflow.com/a/12267471/149482 // http://www.bittorrent.org/beps/bep_0012.html#order-of-processing -func shuffleTier(tier []tracker.Client) { +func shuffleTier(tier trackerTier) { for i := range tier { j := mathRand.Intn(i + 1) tier[i], tier[j] = tier[j], tier[i] } } -func copyTrackers(base [][]tracker.Client) (copy [][]tracker.Client) { +func copyTrackers(base []trackerTier) (copy []trackerTier) { for _, tier := range base { - copy = append(copy, append([]tracker.Client{}, tier...)) + copy = append(copy, append(trackerTier(nil), tier...)) } return } -func mergeTier(tier []tracker.Client, newURLs []string) []tracker.Client { +func mergeTier(tier trackerTier, newURLs []string) trackerTier { nextURL: for _, url := range newURLs { - for _, tr := range tier { - if tr.URL() == url { + for _, trURL := range tier { + if trURL == url { continue nextURL } } - tr, err := tracker.New(url) - if err != nil { - // log.Printf("error creating tracker client for %q: %s", url, err) - continue - } - tier = append(tier, tr) + tier = append(tier, url) } return tier } @@ -2206,8 +2203,8 @@ // log.Printf("finished DHT peer scrape for %s: %d peers", t, len(allAddrs)) } } -func (cl *Client) trackerBlockedUnlocked(tr tracker.Client) (blocked bool, err error) { - url_, err := url.Parse(tr.URL()) +func (cl *Client) trackerBlockedUnlocked(trRawURL string) (blocked bool, err error) { + url_, err := url.Parse(trRawURL) if err != nil { return } @@ -2225,7 +2222,7 @@ cl.mu.RUnlock() return } -func (cl *Client) announceTorrentSingleTracker(tr tracker.Client, req *tracker.AnnounceRequest, t *torrent) error { +func (cl *Client) announceTorrentSingleTracker(tr string, req *tracker.AnnounceRequest, t *torrent) error { blocked, err := cl.trackerBlockedUnlocked(tr) if err != nil { return fmt.Errorf("error determining if tracker blocked: %s", err) @@ -2233,10 +2230,7 @@ } if blocked { return fmt.Errorf("tracker blocked: %s", tr) } - if err := tr.Connect(); err != nil { - return fmt.Errorf("error connecting: %s", err) - } - resp, err := tr.Announce(req) + resp, err := tracker.Announce(tr, req) if err != nil { return fmt.Errorf("error announcing: %s", err) } @@ -2257,13 +2251,13 @@ time.Sleep(time.Second * time.Duration(resp.Interval)) return nil } -func (cl *Client) announceTorrentTrackersFastStart(req *tracker.AnnounceRequest, trackers [][]tracker.Client, t *torrent) (atLeastOne bool) { +func (cl *Client) announceTorrentTrackersFastStart(req *tracker.AnnounceRequest, trackers []trackerTier, t *torrent) (atLeastOne bool) { oks := make(chan bool) outstanding := 0 for _, tier := range trackers { for _, tr := range tier { outstanding++ - go func(tr tracker.Client) { + go func(tr string) { err := cl.announceTorrentSingleTracker(tr, req, t) oks <- err == nil }(tr) diff --git a/client_test.go b/client_test.go index 734dfea318a4c2326c1ba1f4913830735948168b..b21de8bcbfa6f85cda1d1c0b5ccaf9c496259030 100644 --- a/client_test.go +++ b/client_test.go @@ -421,8 +421,8 @@ _, new, _ = cl.AddTorrentSpec(&spec) if new { t.FailNow() } - assert.EqualValues(t, T.torrent.Trackers[0][0].URL(), "http://a") - assert.EqualValues(t, T.torrent.Trackers[1][0].URL(), "udp://b") + assert.EqualValues(t, T.torrent.Trackers[0][0], "http://a") + assert.EqualValues(t, T.torrent.Trackers[1][0], "udp://b") } type badData struct{} diff --git a/cmd/tracker-announce/main.go b/cmd/tracker-announce/main.go index 776fae380a6ff8da2b91c58bcf07bb0f63e818e5..21d31a6949eb5b2082fae4b0a346e6ecfd4ebaf9 100644 --- a/cmd/tracker-announce/main.go +++ b/cmd/tracker-announce/main.go @@ -37,22 +37,12 @@ } ar.InfoHash = ts.InfoHash for _, tier := range ts.Trackers { for _, tURI := range tier { - tCl, err := tracker.New(tURI) - if err != nil { - log.Print(err) - continue - } - err = tCl.Connect() - if err != nil { - log.Print(err) - continue - } - resp, err := tCl.Announce(&ar) + resp, err := tracker.Announce(tURI, &ar) if err != nil { log.Print(err) continue } - log.Printf("%s: %#v", tCl, resp) + log.Printf("%q: %#v", tURI, resp) } } } diff --git a/torrent.go b/torrent.go index 82d34fd39599e18b5a08e4d6a57cc163db0fe7e3..eb6bcf0707f1c9094221e7d9d79c0bce6675e05f 100644 --- a/torrent.go +++ b/torrent.go @@ -21,7 +21,6 @@ "github.com/anacrolix/torrent/bencode" "github.com/anacrolix/torrent/metainfo" pp "github.com/anacrolix/torrent/peer_protocol" - "github.com/anacrolix/torrent/tracker" ) func (t *torrent) chunkIndexSpec(chunkIndex, piece int) chunkSpec { @@ -90,7 +89,7 @@ wantPeers sync.Cond // BEP 12 Multitracker Metadata Extension. The tracker.Client instances // mirror their respective URLs from the announce-list metainfo key. - Trackers [][]tracker.Client + Trackers []trackerTier // Name used if the info name isn't available. displayName string // The bencoded bytes of the info dict. @@ -439,7 +438,7 @@ fmt.Fprintln(w) fmt.Fprintf(w, "Trackers: ") for _, tier := range t.Trackers { for _, tr := range tier { - fmt.Fprintf(w, "%q ", tr.String()) + fmt.Fprintf(w, "%q ", tr) } } fmt.Fprintf(w, "\n") @@ -471,13 +470,7 @@ } // TODO: Include URIs that weren't converted to tracker clients. func (t *torrent) announceList() (al [][]string) { - for _, tier := range t.Trackers { - var l []string - for _, tr := range tier { - l = append(l, tr.URL()) - } - al = append(al, l) - } + missinggo.CastSlice(&al, t.Trackers) return }