]> Sergey Matveev's repositories - btrtrc.git/blob - tracker/udp/udp_tracker_test.go
488cd49a067da9f17382908807d981d2cb8ea523
[btrtrc.git] / tracker / udp / udp_tracker_test.go
1 package udp_tracker
2
3 import (
4         "bytes"
5         "crypto/rand"
6         "encoding/binary"
7         "io"
8         "io/ioutil"
9         "log"
10         "net"
11         "net/url"
12         "sync"
13         "syscall"
14         "testing"
15
16         "bitbucket.org/anacrolix/go.torrent/tracker"
17 )
18
19 // Ensure net.IPs are stored big-endian, to match the way they're read from
20 // the wire.
21 func TestNetIPv4Bytes(t *testing.T) {
22         ip := net.IP([]byte{127, 0, 0, 1})
23         if ip.String() != "127.0.0.1" {
24                 t.FailNow()
25         }
26         if string(ip) != "\x7f\x00\x00\x01" {
27                 t.Fatal([]byte(ip))
28         }
29 }
30
31 func TestMarshalAnnounceResponse(t *testing.T) {
32         w := bytes.NewBuffer(nil)
33         if err := binary.Write(w, binary.BigEndian, []Peer{{[4]byte{127, 0, 0, 1}, 2}, {[4]byte{255, 0, 0, 3}, 4}}); err != nil {
34                 t.Fatalf("error writing udp announce response addrs: %s", err)
35         }
36         if w.String() != "\x7f\x00\x00\x01\x00\x02\xff\x00\x00\x03\x00\x04" {
37                 t.FailNow()
38         }
39         if binary.Size(AnnounceResponseHeader{}) != 12 {
40                 t.FailNow()
41         }
42 }
43
44 // Failure to write an entire packet to UDP is expected to given an error.
45 func TestLongWriteUDP(t *testing.T) {
46         l, err := net.ListenUDP("udp", nil)
47         defer l.Close()
48         if err != nil {
49                 t.Fatal(err)
50         }
51         c, err := net.DialUDP("udp", nil, l.LocalAddr().(*net.UDPAddr))
52         if err != nil {
53                 t.Fatal(err)
54         }
55         defer c.Close()
56         for msgLen := 1; ; msgLen *= 2 {
57                 n, err := c.Write(make([]byte, msgLen))
58                 if err != nil {
59                         err := err.(*net.OpError).Err
60                         if err != syscall.EMSGSIZE {
61                                 t.Fatalf("write error isn't EMSGSIZE: %s", err)
62                         }
63                         return
64                 }
65                 if n < msgLen {
66                         t.FailNow()
67                 }
68         }
69 }
70
71 func TestShortBinaryRead(t *testing.T) {
72         var data ResponseHeader
73         err := binary.Read(bytes.NewBufferString("\x00\x00\x00\x01"), binary.BigEndian, &data)
74         if err != io.ErrUnexpectedEOF {
75                 t.FailNow()
76         }
77 }
78
79 func TestConvertInt16ToInt(t *testing.T) {
80         i := 50000
81         if int(uint16(int16(i))) != 50000 {
82                 t.FailNow()
83         }
84 }
85
86 func TestUDPTracker(t *testing.T) {
87         if testing.Short() {
88                 t.SkipNow()
89         }
90         tr, err := tracker.New("udp://tracker.openbittorrent.com:80/announce")
91         if err != nil {
92                 t.Skip(err)
93         }
94         if err := tr.Connect(); err != nil {
95                 t.Skip(err)
96         }
97         req := tracker.AnnounceRequest{
98                 NumWant: -1,
99                 Event:   tracker.Started,
100         }
101         rand.Read(req.PeerId[:])
102         copy(req.InfoHash[:], []uint8{0xa3, 0x56, 0x41, 0x43, 0x74, 0x23, 0xe6, 0x26, 0xd9, 0x38, 0x25, 0x4a, 0x6b, 0x80, 0x49, 0x10, 0xa6, 0x67, 0xa, 0xc1})
103         _, err = tr.Announce(&req)
104         if err != nil {
105                 t.Skip(err)
106         }
107 }
108
109 // TODO: Create a fake UDP tracker to make these requests to.
110 func TestAnnounceRandomInfoHash(t *testing.T) {
111         if testing.Short() {
112                 t.SkipNow()
113         }
114         req := tracker.AnnounceRequest{
115                 Event: tracker.Stopped,
116         }
117         rand.Read(req.PeerId[:])
118         rand.Read(req.InfoHash[:])
119         wg := sync.WaitGroup{}
120         for _, url := range []string{
121                 "udp://tracker.openbittorrent.com:80/announce",
122                 "udp://tracker.publicbt.com:80",
123                 "udp://tracker.istole.it:6969",
124                 "udp://tracker.ccc.de:80",
125                 "udp://tracker.open.demonii.com:1337",
126         } {
127                 go func(url string) {
128                         defer wg.Done()
129                         tr, err := tracker.New(url)
130                         if err != nil {
131                                 t.Fatal(err)
132                         }
133                         if err := tr.Connect(); err != nil {
134                                 t.Log(err)
135                                 return
136                         }
137                         resp, err := tr.Announce(&req)
138                         if err != nil {
139                                 t.Logf("error announcing to %s: %s", url, err)
140                                 return
141                         }
142                         if resp.Leechers != 0 || resp.Seeders != 0 || len(resp.Peers) != 0 {
143                                 t.Fatal(resp)
144                         }
145                 }(url)
146                 wg.Add(1)
147         }
148         wg.Wait()
149 }
150
151 // Check that URLPath option is done correctly.
152 func TestURLPathOption(t *testing.T) {
153         conn, err := net.ListenUDP("udp", nil)
154         if err != nil {
155                 panic(err)
156         }
157         defer conn.Close()
158         cl := newClient(&url.URL{
159                 Host: conn.LocalAddr().String(),
160                 Path: "/announce",
161         })
162         go func() {
163                 err = cl.Connect()
164                 if err != nil {
165                         t.Fatal(err)
166                 }
167                 log.Print("connected")
168                 _, err = cl.Announce(&tracker.AnnounceRequest{})
169                 if err != nil {
170                         t.Fatal(err)
171                 }
172         }()
173         var b [512]byte
174         _, addr, _ := conn.ReadFrom(b[:])
175         r := bytes.NewReader(b[:])
176         var h RequestHeader
177         read(r, &h)
178         w := &bytes.Buffer{}
179         write(w, ResponseHeader{
180                 TransactionId: h.TransactionId,
181         })
182         write(w, ConnectionResponse{42})
183         conn.WriteTo(w.Bytes(), addr)
184         n, _, _ := conn.ReadFrom(b[:])
185         r = bytes.NewReader(b[:n])
186         read(r, &h)
187         read(r, &tracker.AnnounceRequest{})
188         all, _ := ioutil.ReadAll(r)
189         if string(all) != "\x02\x09/announce" {
190                 t.FailNow()
191         }
192         w = &bytes.Buffer{}
193         write(w, ResponseHeader{
194                 TransactionId: h.TransactionId,
195         })
196         write(w, AnnounceResponseHeader{})
197         conn.WriteTo(w.Bytes(), addr)
198 }