]> Sergey Matveev's repositories - btrtrc.git/blob - tracker/tracker.go
c3eefb98d929957f569fda9280275ac6aee576e7
[btrtrc.git] / tracker / tracker.go
1 package tracker
2
3 import (
4         "context"
5         "errors"
6         "net/http"
7         "net/url"
8
9         "github.com/anacrolix/dht/krpc"
10 )
11
12 // Marshalled as binary by the UDP client, so be careful making changes.
13 type AnnounceRequest struct {
14         InfoHash   [20]byte
15         PeerId     [20]byte
16         Downloaded int64
17         Left       int64 // If less than 0, math.MaxInt64 will be used for HTTP trackers instead.
18         Uploaded   int64
19         // Apparently this is optional. None can be used for announces done at
20         // regular intervals.
21         Event     AnnounceEvent
22         IPAddress uint32
23         Key       int32
24         NumWant   int32 // How many peer addresses are desired. -1 for default.
25         Port      uint16
26 } // 82 bytes
27
28 type AnnounceResponse struct {
29         Interval int32 // Minimum seconds the local peer should wait before next announce.
30         Leechers int32
31         Seeders  int32
32         Peers    []Peer
33 }
34
35 type AnnounceEvent int32
36
37 func (e AnnounceEvent) String() string {
38         // See BEP 3, "event".
39         return []string{"empty", "completed", "started", "stopped"}[e]
40 }
41
42 const (
43         None      AnnounceEvent = iota
44         Completed               // The local peer just completed the torrent.
45         Started                 // The local peer has just resumed this torrent.
46         Stopped                 // The local peer is leaving the swarm.
47 )
48
49 var (
50         ErrBadScheme = errors.New("unknown scheme")
51 )
52
53 type Announce struct {
54         TrackerUrl string
55         Request    AnnounceRequest
56         HostHeader string
57         HTTPProxy  func(*http.Request) (*url.URL, error)
58         ServerName string
59         UserAgent  string
60         UdpNetwork string
61         // If the port is zero, it's assumed to be the same as the Request.Port.
62         ClientIp4 krpc.NodeAddr
63         // If the port is zero, it's assumed to be the same as the Request.Port.
64         ClientIp6 krpc.NodeAddr
65         Context   context.Context
66 }
67
68 func (me Announce) Do() (res AnnounceResponse, err error) {
69         _url, err := url.Parse(me.TrackerUrl)
70         if err != nil {
71                 return
72         }
73         switch _url.Scheme {
74         case "http", "https":
75                 return announceHTTP(me, _url)
76         case "udp", "udp4", "udp6":
77                 return announceUDP(me, _url)
78         default:
79                 err = ErrBadScheme
80                 return
81         }
82 }