github.com/anacrolix/torrent@v1.61.0/tracker/udp.go (about) 1 package tracker 2 3 import ( 4 "context" 5 "encoding/binary" 6 7 "github.com/anacrolix/generics" 8 9 trHttp "github.com/anacrolix/torrent/tracker/http" 10 "github.com/anacrolix/torrent/tracker/udp" 11 "github.com/anacrolix/torrent/types/infohash" 12 ) 13 14 type udpClient struct { 15 cl *udp.ConnClient 16 requestUri string 17 } 18 19 func (c *udpClient) Scrape(ctx context.Context, ihs []infohash.T) (out udp.ScrapeResponse, err error) { 20 return c.cl.Client.Scrape( 21 ctx, 22 generics.SliceMap(ihs, func(from infohash.T) udp.InfoHash { 23 return from 24 }), 25 ) 26 } 27 28 func (c *udpClient) Close() error { 29 return c.cl.Close() 30 } 31 32 func (c *udpClient) Announce( 33 ctx context.Context, 34 req AnnounceRequest, 35 opts trHttp.AnnounceOpt, 36 ) (res AnnounceResponse, err error) { 37 if req.IPAddress == 0 && opts.ClientIp4 != nil { 38 // I think we're taking bytes in big-endian order (all IPs), and writing it to a natively 39 // ordered uint32. This will be correctly ordered when written back out by the UDP client 40 // later. I'm ignoring the fact that IPv6 announces shouldn't have an IP address, we have a 41 // perfectly good IPv4 address. 42 req.IPAddress = binary.BigEndian.Uint32(opts.ClientIp4.To4()) 43 } 44 h, nas, err := c.cl.Announce(ctx, req, udp.Options{RequestUri: c.requestUri}) 45 if err != nil { 46 return 47 } 48 res.Interval = h.Interval 49 res.Leechers = h.Leechers 50 res.Seeders = h.Seeders 51 for _, cp := range nas.NodeAddrs() { 52 res.Peers = append(res.Peers, trHttp.Peer{}.FromNodeAddr(cp)) 53 } 54 return 55 }