2
0
mirror of synced 2025-02-24 14:48:27 +00:00
torrent/tracker/udp.go

61 lines
1.5 KiB
Go
Raw Normal View History

package tracker
import (
"encoding/binary"
"net/url"
trHttp "github.com/anacrolix/torrent/tracker/http"
2021-06-22 22:36:43 +10:00
"github.com/anacrolix/torrent/tracker/udp"
)
type udpAnnounce struct {
2021-06-22 22:36:43 +10:00
url url.URL
a *Announce
}
func (c *udpAnnounce) Do(req AnnounceRequest) (res AnnounceResponse, err error) {
2021-06-24 09:53:18 +10:00
cl, err := udp.NewConnClient(udp.NewConnClientOpts{
Network: c.dialNetwork(),
Host: c.url.Host,
Ipv6: nil,
})
if err != nil {
return
}
2021-06-24 09:53:18 +10:00
defer cl.Close()
if req.IPAddress == 0 && c.a.ClientIp4.IP != nil {
// I think we're taking bytes in big-endian order (all IPs), and writing it to a natively
// ordered uint32. This will be correctly ordered when written back out by the UDP client
// later. I'm ignoring the fact that IPv6 announces shouldn't have an IP address, we have a
// perfectly good IPv4 address.
req.IPAddress = binary.BigEndian.Uint32(c.a.ClientIp4.IP.To4())
}
2021-06-24 09:53:18 +10:00
h, nas, err := cl.Announce(c.a.Context, req, udp.Options{RequestUri: c.url.RequestURI()})
2015-08-17 19:52:47 +10:00
if err != nil {
return
}
2021-06-22 22:36:43 +10:00
res.Interval = h.Interval
res.Leechers = h.Leechers
res.Seeders = h.Seeders
2018-02-19 16:19:18 +11:00
for _, cp := range nas.NodeAddrs() {
res.Peers = append(res.Peers, trHttp.Peer{}.FromNodeAddr(cp))
}
2015-08-17 19:52:47 +10:00
return
}
2018-02-19 16:19:18 +11:00
func (c *udpAnnounce) dialNetwork() string {
if c.a.UdpNetwork != "" {
return c.a.UdpNetwork
}
return "udp"
}
2021-06-22 22:36:43 +10:00
// TODO: Split on IPv6, as BEP 15 says response peer decoding depends on network in use.
2018-02-19 16:19:18 +11:00
func announceUDP(opt Announce, _url *url.URL) (AnnounceResponse, error) {
ua := udpAnnounce{
url: *_url,
2018-02-19 16:19:18 +11:00
a: &opt,
}
return ua.Do(opt.Request)
}