github.com/anacrolix/torrent@v1.61.0/tracker/tracker.go (about) 1 package tracker 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "net" 8 "net/http" 9 "net/url" 10 "time" 11 12 "github.com/anacrolix/dht/v2/krpc" 13 "github.com/anacrolix/log" 14 15 trHttp "github.com/anacrolix/torrent/tracker/http" 16 "github.com/anacrolix/torrent/tracker/shared" 17 "github.com/anacrolix/torrent/tracker/udp" 18 ) 19 20 const ( 21 None = shared.None 22 Started = shared.Started 23 Stopped = shared.Stopped 24 Completed = shared.Completed 25 ) 26 27 type AnnounceRequest = udp.AnnounceRequest 28 29 type AnnounceResponse = trHttp.AnnounceResponse 30 31 type Peer = trHttp.Peer 32 33 type AnnounceEvent = shared.AnnounceEvent 34 35 var ErrBadScheme = errors.New("unknown scheme") 36 37 // Deprecated. Use tracker.NewClient and friends instead. 38 type Announce struct { 39 TrackerUrl string 40 Request AnnounceRequest 41 HostHeader string 42 HttpProxy func(*http.Request) (*url.URL, error) 43 HttpRequestDirector func(*http.Request) error 44 DialContext func(ctx context.Context, network, addr string) (net.Conn, error) 45 ListenPacket func(network, addr string) (net.PacketConn, error) 46 ServerName string 47 UserAgent string 48 UdpNetwork string 49 // If the port is zero, it's assumed to be the same as the Request.Port. 50 ClientIp4 krpc.NodeAddr 51 // If the port is zero, it's assumed to be the same as the Request.Port. 52 ClientIp6 krpc.NodeAddr 53 Context context.Context 54 Logger log.Logger 55 } 56 57 // The code *is* the documentation. 58 const DefaultTrackerAnnounceTimeout = 15 * time.Second 59 60 func (me Announce) Do() (res AnnounceResponse, err error) { 61 cl, err := NewClient(me.TrackerUrl, NewClientOpts{ 62 Http: trHttp.NewClientOpts{ 63 Proxy: me.HttpProxy, 64 DialContext: me.DialContext, 65 ServerName: me.ServerName, 66 }, 67 UdpNetwork: me.UdpNetwork, 68 Logger: me.Logger.WithContextValue(fmt.Sprintf("tracker client for %q", me.TrackerUrl)), 69 ListenPacket: me.ListenPacket, 70 }) 71 if err != nil { 72 return 73 } 74 defer cl.Close() 75 if me.Context == nil { 76 // This is just to maintain the old behaviour that should be a timeout of 15s. Users can 77 // override it by providing their own Context. See comments elsewhere about longer timeouts 78 // acting as rate limiting overloaded trackers. 79 ctx, cancel := context.WithTimeout(context.Background(), DefaultTrackerAnnounceTimeout) 80 defer cancel() 81 me.Context = ctx 82 } 83 return cl.Announce(me.Context, me.Request, trHttp.AnnounceOpt{ 84 UserAgent: me.UserAgent, 85 HostHeader: me.HostHeader, 86 ClientIp4: me.ClientIp4.IP, 87 ClientIp6: me.ClientIp6.IP, 88 HttpRequestDirector: me.HttpRequestDirector, 89 }) 90 }