From 87e64b3088a7e45ba69fab18185780aa23af58a4 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Thu, 15 Dec 2022 23:21:08 +1100 Subject: [PATCH] Propagate announce interval, particularly for UDP --- tracker/http/server/server.go | 9 +++++---- tracker/server.go | 28 ++++++++++++++++++---------- tracker/udp/server/server.go | 14 ++++++++------ 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/tracker/http/server/server.go b/tracker/http/server/server.go index 8937ed5e..781c640b 100644 --- a/tracker/http/server/server.go +++ b/tracker/http/server/server.go @@ -74,22 +74,23 @@ func (me Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } portU64, err := strconv.ParseUint(vs.Get("port"), 0, 16) addrPort := netip.AddrPortFrom(addr, uint16(portU64)) - peers, err := me.Announce.Serve(r.Context(), tracker.AnnounceRequest{ + res := me.Announce.Serve(r.Context(), tracker.AnnounceRequest{ InfoHash: infoHash, PeerId: peerId, Event: event, Port: addrPort.Port(), NumWant: -1, - }, addrPort, tracker.GetPeersOpts{generics.Some[uint](200)}) + }, addrPort, tracker.GetPeersOpts{MaxCount: generics.Some[uint](200)}) + err = res.Err if err != nil { log.Printf("error serving announce: %v", err) http.Error(w, "error handling announce", http.StatusInternalServerError) return } var resp httpTracker.HttpResponse - resp.Interval = 5 * 60 + resp.Interval = res.Interval.UnwrapOr(5 * 60) resp.Peers.Compact = true - for _, peer := range peers { + for _, peer := range res.Peers { if peer.Addr().Is4() { resp.Peers.List = append(resp.Peers.List, tracker.Peer{ IP: peer.Addr().AsSlice(), diff --git a/tracker/server.go b/tracker/server.go index c74cbd24..67b46e0c 100644 --- a/tracker/server.go +++ b/tracker/server.go @@ -34,7 +34,15 @@ type AnnounceAddr = netip.AddrPort type AnnounceTracker interface { TrackAnnounce(ctx context.Context, req udp.AnnounceRequest, addr AnnounceAddr) error Scrape(ctx context.Context, infoHashes []InfoHash) ([]udp.ScrapeInfohashResult, error) - GetPeers(ctx context.Context, infoHash InfoHash, opts GetPeersOpts) ([]PeerInfo, error) + GetPeers(ctx context.Context, infoHash InfoHash, opts GetPeersOpts) ServerAnnounceResult +} + +type ServerAnnounceResult struct { + Err error + Peers []PeerInfo + Interval generics.Option[int32] + Leechers generics.Option[int32] + Seeders generics.Option[int32] } type AnnounceHandler struct { @@ -91,7 +99,7 @@ var tracer = otel.Tracer("torrent.tracker.udp") func (me *AnnounceHandler) Serve( ctx context.Context, req AnnounceRequest, addr AnnounceAddr, opts GetPeersOpts, -) (peers []PeerInfo, err error) { +) (ret ServerAnnounceResult) { ctx, span := tracer.Start( ctx, "AnnounceHandler.Serve", @@ -108,11 +116,11 @@ func (me *AnnounceHandler) Serve( ) defer span.End() defer func() { - span.SetAttributes(attribute.Int("announce.get_peers.len", len(peers))) + span.SetAttributes(attribute.Int("announce.get_peers.len", len(ret.Peers))) }() - err = me.AnnounceTracker.TrackAnnounce(ctx, req, addr) - if err != nil { + ret.Err = me.AnnounceTracker.TrackAnnounce(ctx, req, addr) + if ret.Err != nil { return } infoHash := req.InfoHash @@ -133,15 +141,15 @@ func (me *AnnounceHandler) Serve( opts.MaxCount = generics.Some(newCount) } } - peers, err = me.AnnounceTracker.GetPeers(ctx, infoHash, opts) - if err != nil { + ret = me.AnnounceTracker.GetPeers(ctx, infoHash, opts) + if ret.Err != nil { return } // Take whatever peers it has ready. If it's finished, it doesn't matter if we do this inside // the mutex or not. if op.Ok { curPeers, done := op.Value.getCurPeersAndDone() - addMissing(peers, curPeers) + addMissing(ret.Peers, curPeers) if done { // It doesn't get any better with this operation. Forget it. op.Ok = false @@ -152,7 +160,7 @@ func (me *AnnounceHandler) Serve( // assuming the announcing peer might be that one. Really we should record a value to prevent // duplicate announces. Also don't announce upstream if we got no peers because the caller asked // for none. - if !op.Ok && len(peers) <= 1 && opts.MaxCount.UnwrapOr(1) > 0 { + if !op.Ok && len(ret.Peers) <= 1 && opts.MaxCount.UnwrapOr(1) > 0 { op.Value, op.Ok = me.ongoingUpstreamAugmentations[infoHash] if !op.Ok { op.Set(me.augmentPeersFromUpstream(req.InfoHash)) @@ -170,7 +178,7 @@ func (me *AnnounceHandler) Serve( case <-op.Value.doneAnnouncing: } cancel() - addMissing(peers, op.Value.getCurPeers()) + addMissing(ret.Peers, op.Value.getCurPeers()) } return } diff --git a/tracker/udp/server/server.go b/tracker/udp/server/server.go index 716c3916..c8c9bec3 100644 --- a/tracker/udp/server/server.go +++ b/tracker/udp/server/server.go @@ -104,12 +104,12 @@ func (me *Server) handleAnnounce( if addrFamily == udp.AddrFamilyIpv4 { opts.MaxCount = generics.Some[uint](150) } - peers, err := me.Announce.Serve(ctx, req, announceAddr, opts) - if err != nil { - return err + res := me.Announce.Serve(ctx, req, announceAddr, opts) + if res.Err != nil { + return res.Err } - nodeAddrs := make([]krpc.NodeAddr, 0, len(peers)) - for _, p := range peers { + nodeAddrs := make([]krpc.NodeAddr, 0, len(res.Peers)) + for _, p := range res.Peers { var ip net.IP switch addrFamily { default: @@ -137,7 +137,9 @@ func (me *Server) handleAnnounce( if err != nil { return err } - err = udp.Write(&buf, udp.AnnounceResponseHeader{}) + err = udp.Write(&buf, udp.AnnounceResponseHeader{ + Interval: res.Interval.UnwrapOr(5 * 60), + }) if err != nil { return err } -- 2.48.1