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