tracker/http/server/server.go | 9 +++++---- tracker/server.go | 28 ++++++++++++++++++---------- tracker/udp/server/server.go | 14 ++++++++------ diff --git a/tracker/http/server/server.go b/tracker/http/server/server.go index 8937ed5ec1f15bc314a2fd63fcbdc88423b72cfc..781c640ba4ae84cd6d9671fab2225dfba51e93be 100644 --- a/tracker/http/server/server.go +++ b/tracker/http/server/server.go @@ -74,22 +74,23 @@ return } 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 c74cbd245f3c7617b404fd8ae5c197def27168bd..67b46e0c1cc6b15924ffef814e715667aaaa3734 100644 --- a/tracker/server.go +++ b/tracker/server.go @@ -34,7 +34,15 @@ 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 @@ ), ) 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 @@ } else { 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 @@ // If we didn't have an operation, and don't have enough peers, start one. Allowing 1 is // 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 @@ case <-ctx.Done(): 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 716c3916a106e8b44575705fcb86640c7bdb5142..c8c9bec364c65a180caa30c6459e21f58d9a27f0 100644 --- a/tracker/udp/server/server.go +++ b/tracker/udp/server/server.go @@ -104,12 +104,12 @@ opts := tracker.GetPeersOpts{MaxCount: generics.Some[uint](50)} 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 @@ }) 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 }