github.com/anacrolix/torrent@v1.61.0/tracker/udp/udp_test.go (about) 1 package udp 2 3 import ( 4 "bytes" 5 "context" 6 "crypto/rand" 7 "encoding/binary" 8 "io" 9 "net" 10 "sync" 11 "testing" 12 "time" 13 14 "github.com/anacrolix/dht/v2/krpc" 15 _ "github.com/anacrolix/envpprof" 16 "github.com/anacrolix/missinggo/v2/iter" 17 qt "github.com/go-quicktest/qt" 18 "github.com/stretchr/testify/require" 19 ) 20 21 // Ensure net.IPs are stored big-endian, to match the way they're read from 22 // the wire. 23 func TestNetIPv4Bytes(t *testing.T) { 24 ip := net.IP([]byte{127, 0, 0, 1}) 25 if ip.String() != "127.0.0.1" { 26 t.FailNow() 27 } 28 if string(ip) != "\x7f\x00\x00\x01" { 29 t.Fatal([]byte(ip)) 30 } 31 } 32 33 func TestMarshalAnnounceResponse(t *testing.T) { 34 peers := krpc.CompactIPv4NodeAddrs{ 35 {[]byte{127, 0, 0, 1}, 2}, 36 {[]byte{255, 0, 0, 3}, 4}, 37 } 38 b, err := peers.MarshalBinary() 39 require.NoError(t, err) 40 require.EqualValues(t, 41 "\x7f\x00\x00\x01\x00\x02\xff\x00\x00\x03\x00\x04", 42 b) 43 require.EqualValues(t, 12, binary.Size(AnnounceResponseHeader{})) 44 } 45 46 // Failure to write an entire packet to UDP is expected to given an error. 47 func TestLongWriteUDP(t *testing.T) { 48 t.Parallel() 49 l, err := net.ListenUDP("udp4", nil) 50 require.NoError(t, err) 51 defer l.Close() 52 c, err := net.DialUDP("udp", nil, l.LocalAddr().(*net.UDPAddr)) 53 if err != nil { 54 t.Fatal(err) 55 } 56 defer c.Close() 57 for msgLen := 1; ; msgLen *= 2 { 58 n, err := c.Write(make([]byte, msgLen)) 59 if err != nil { 60 if isErrMessageTooLong(err) { 61 return 62 } 63 t.Fatalf("expected message too long error: %v", err) 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 TestConnClientLogDispatchUnknownTransactionId(t *testing.T) { 87 const network = "udp" 88 cc, err := NewConnClient(NewConnClientOpts{ 89 Network: network, 90 }) 91 qt.Assert(t, qt.IsNil(err)) 92 defer cc.Close() 93 pc, err := net.ListenPacket(network, ":0") 94 qt.Assert(t, qt.IsNil(err)) 95 defer pc.Close() 96 ccAddr := *cc.LocalAddr().(*net.UDPAddr) 97 ipAddrs, err := net.DefaultResolver.LookupIPAddr(context.Background(), "localhost") 98 qt.Assert(t, qt.IsNil(err)) 99 ccAddr.IP = ipAddrs[0].IP 100 ccAddr.Zone = ipAddrs[0].Zone 101 _, err = pc.WriteTo(make([]byte, 30), &ccAddr) 102 qt.Assert(t, qt.IsNil(err)) 103 } 104 105 func TestConnectionIdMismatch(t *testing.T) { 106 t.Skip("Server host returns consistent connection ID in limited tests and so isn't effective.") 107 cl, err := NewConnClient(NewConnClientOpts{ 108 // This host seems to return `Connection ID missmatch.\x00` every 2 minutes or so under 109 // heavy use. 110 Host: "tracker.torrent.eu.org:451", 111 //Host: "tracker.opentrackr.org:1337", 112 Network: "udp", 113 }) 114 qt.Assert(t, qt.IsNil(err)) 115 defer cl.Close() 116 ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) 117 defer cancel() 118 // Force every request to use a different connection ID. It's racey, but we want to get a 119 // different ID issued before a request can be sent with an old ID. 120 cl.Client.shouldReconnectOverride = func() bool { return true } 121 started := time.Now() 122 var wg sync.WaitGroup 123 for range iter.N(2) { 124 ar := AnnounceRequest{ 125 NumWant: -1, 126 Event: 2, 127 } 128 rand.Read(ar.InfoHash[:]) 129 rand.Read(ar.PeerId[:]) 130 //spew.Dump(ar) 131 wg.Add(1) 132 go func() { 133 defer wg.Done() 134 _, _, err := cl.Announce(ctx, ar, Options{}) 135 // I'm looking for `error response: "Connection ID missmatch.\x00"`. 136 t.Logf("announce error after %v: %v", time.Since(started), err) 137 }() 138 } 139 wg.Wait() 140 }