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

98 lines
2.0 KiB
Go
Raw Normal View History

package tracker
import (
2018-02-19 16:19:18 +11:00
"encoding"
"encoding/binary"
"net"
"net/url"
2019-08-10 18:46:07 +10:00
"github.com/anacrolix/dht/v2/krpc"
2015-08-17 19:52:47 +10:00
"github.com/anacrolix/missinggo"
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) Close() error {
return nil
}
2021-06-22 22:36:43 +10:00
func (c *udpAnnounce) ipv6(conn net.Conn) bool {
2018-02-19 16:19:18 +11:00
if c.a.UdpNetwork == "udp6" {
return true
}
2021-06-22 22:36:43 +10:00
rip := missinggo.AddrIP(conn.RemoteAddr())
2018-02-19 16:19:18 +11:00
return rip.To16() != nil && rip.To4() == nil
}
func (c *udpAnnounce) Do(req AnnounceRequest) (res AnnounceResponse, err error) {
2021-06-22 22:36:43 +10:00
conn, err := net.Dial(c.dialNetwork(), c.url.Host)
if err != nil {
return
}
2021-06-22 22:36:43 +10:00
defer conn.Close()
if c.ipv6(conn) {
// BEP 15
req.IPAddress = 0
} else if req.IPAddress == 0 && c.a.ClientIp4.IP != nil {
req.IPAddress = binary.BigEndian.Uint32(c.a.ClientIp4.IP.To4())
}
2021-06-22 22:36:43 +10:00
d := udp.Dispatcher{}
go func() {
for {
b := make([]byte, 0x800)
n, err := conn.Read(b)
if err != nil {
break
}
d.Dispatch(b[:n])
2015-03-12 20:07:10 +11:00
}
2021-06-22 22:36:43 +10:00
}()
cl := udp.Client{
Dispatcher: &d,
Writer: conn,
}
2018-02-19 16:19:18 +11:00
nas := func() interface {
encoding.BinaryUnmarshaler
NodeAddrs() []krpc.NodeAddr
} {
2021-06-22 22:36:43 +10:00
if c.ipv6(conn) {
2018-02-19 16:19:18 +11:00
return &krpc.CompactIPv6NodeAddrs{}
} else {
return &krpc.CompactIPv4NodeAddrs{}
}
}()
2021-06-22 22:36:43 +10:00
h, err := cl.Announce(c.a.Context, req, nas, 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,
}
defer ua.Close()
return ua.Do(opt.Request)
}