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
}
}
}
-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
}
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)
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)
}
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)
"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 {
// 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.
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")
// 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
}