diff --git a/torrent.go b/torrent.go index 4a519d34..5d54bad7 100644 --- a/torrent.go +++ b/torrent.go @@ -666,6 +666,11 @@ func (t *Torrent) numPiecesCompleted() (num int) { } func (t *Torrent) close() (err error) { + t.logger.Printf("Sending stopped event to trackers") + for _, ta := range t.trackerAnnouncers { + ta.Stop() + } + t.closed.Set() t.tickleReaders() if t.storage != nil { @@ -1298,11 +1303,11 @@ func (t *Torrent) startMissingTrackerScrapers() { // Returns an AnnounceRequest with fields filled out to defaults and current // values. -func (t *Torrent) announceRequest() tracker.AnnounceRequest { +func (t *Torrent) announceRequest(event tracker.AnnounceEvent) tracker.AnnounceRequest { // Note that IPAddress is not set. It's set for UDP inside the tracker // code, since it's dependent on the network in use. return tracker.AnnounceRequest{ - Event: tracker.None, + Event: event, NumWant: -1, Port: uint16(t.cl.incomingPeerPort()), PeerId: t.cl.peerID, diff --git a/tracker_scraper.go b/tracker_scraper.go index 5f31a019..8148c0f6 100644 --- a/tracker_scraper.go +++ b/tracker_scraper.go @@ -96,7 +96,7 @@ func (me *trackerScraper) trackerUrl(ip net.IP) string { // Return how long to wait before trying again. For most errors, we return 5 // minutes, a relatively quick turn around for DNS changes. -func (me *trackerScraper) announce() (ret trackerAnnounceResult) { +func (me *trackerScraper) announce(event tracker.AnnounceEvent) (ret trackerAnnounceResult) { defer func() { ret.Completed = time.Now() }() @@ -107,7 +107,7 @@ func (me *trackerScraper) announce() (ret trackerAnnounceResult) { return } me.t.cl.lock() - req := me.t.announceRequest() + req := me.t.announceRequest(event) me.t.cl.unlock() res, err := tracker.Announce{ HTTPProxy: me.t.cl.config.HTTPProxy, @@ -131,8 +131,12 @@ func (me *trackerScraper) announce() (ret trackerAnnounceResult) { } func (me *trackerScraper) Run() { + // make sure first announce is a "started" + e := tracker.Started for { - ar := me.announce() + ar := me.announce(e) + // after first announce, get back to regular "none" + e = tracker.None me.t.cl.lock() me.lastAnnounce = ar me.t.cl.unlock() @@ -163,3 +167,16 @@ func (me *trackerScraper) Run() { } } } + +func (me *trackerScraper) Stop() { + req := me.t.announceRequest(tracker.Stopped) + ip, _ := me.getIp() + tracker.Announce{ + HTTPProxy: me.t.cl.config.HTTPProxy, + UserAgent: me.t.cl.config.HTTPUserAgent, + TrackerUrl: me.trackerUrl(ip), + Request: req, + HostHeader: me.u.Host, + ServerName: me.u.Hostname(), + }.Do() +}