]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Propagate announce interval, particularly for UDP
authorMatt Joiner <anacrolix@gmail.com>
Thu, 15 Dec 2022 12:21:08 +0000 (23:21 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Thu, 15 Dec 2022 12:21:08 +0000 (23:21 +1100)
tracker/http/server/server.go
tracker/server.go
tracker/udp/server/server.go

index 8937ed5ec1f15bc314a2fd63fcbdc88423b72cfc..781c640ba4ae84cd6d9671fab2225dfba51e93be 100644 (file)
@@ -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(),
index c74cbd245f3c7617b404fd8ae5c197def27168bd..67b46e0c1cc6b15924ffef814e715667aaaa3734 100644 (file)
@@ -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
 }
index 716c3916a106e8b44575705fcb86640c7bdb5142..c8c9bec364c65a180caa30c6459e21f58d9a27f0 100644 (file)
@@ -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
        }