2015-03-27 15:12:15 +11:00
|
|
|
package tracker
|
2013-11-07 01:55:29 +11:00
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
|
|
|
"net/url"
|
2015-03-30 23:05:39 +11:00
|
|
|
|
2021-06-22 23:28:26 +10:00
|
|
|
trHttp "github.com/anacrolix/torrent/tracker/http"
|
2021-06-22 22:36:43 +10:00
|
|
|
"github.com/anacrolix/torrent/tracker/udp"
|
2013-11-07 01:55:29 +11:00
|
|
|
)
|
|
|
|
|
2016-05-20 00:48:46 +10:00
|
|
|
type udpAnnounce struct {
|
2021-06-22 22:36:43 +10:00
|
|
|
url url.URL
|
|
|
|
a *Announce
|
2013-11-07 01:55:29 +11:00
|
|
|
}
|
|
|
|
|
2018-02-21 13:33:12 +11:00
|
|
|
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,
|
|
|
|
})
|
2016-05-09 12:20:35 +10:00
|
|
|
if err != nil {
|
2013-11-07 01:55:29 +11:00
|
|
|
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.
|
2018-02-21 13:33:12 +11:00
|
|
|
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() {
|
2021-06-22 23:28:26 +10:00
|
|
|
res.Peers = append(res.Peers, trHttp.Peer{}.FromNodeAddr(cp))
|
2013-11-07 01:55:29 +11:00
|
|
|
}
|
2015-08-17 19:52:47 +10:00
|
|
|
return
|
2013-11-07 01:55:29 +11:00
|
|
|
}
|
|
|
|
|
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) {
|
2016-05-20 00:48:46 +10:00
|
|
|
ua := udpAnnounce{
|
|
|
|
url: *_url,
|
2018-02-19 16:19:18 +11:00
|
|
|
a: &opt,
|
2016-05-20 00:48:46 +10:00
|
|
|
}
|
2018-02-21 13:33:12 +11:00
|
|
|
return ua.Do(opt.Request)
|
2016-05-20 00:48:46 +10:00
|
|
|
}
|