14 "github.com/anacrolix/dht/v2/krpc"
15 _ "github.com/anacrolix/envpprof"
16 "github.com/anacrolix/missinggo/v2/iter"
17 qt "github.com/frankban/quicktest"
18 "github.com/stretchr/testify/require"
21 // Ensure net.IPs are stored big-endian, to match the way they're read from
23 func TestNetIPv4Bytes(t *testing.T) {
24 ip := net.IP([]byte{127, 0, 0, 1})
25 if ip.String() != "127.0.0.1" {
28 if string(ip) != "\x7f\x00\x00\x01" {
33 func TestMarshalAnnounceResponse(t *testing.T) {
34 peers := krpc.CompactIPv4NodeAddrs{
35 {[]byte{127, 0, 0, 1}, 2},
36 {[]byte{255, 0, 0, 3}, 4},
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",
43 require.EqualValues(t, 12, binary.Size(AnnounceResponseHeader{}))
46 // Failure to write an entire packet to UDP is expected to given an error.
47 func TestLongWriteUDP(t *testing.T) {
49 l, err := net.ListenUDP("udp4", nil)
50 require.NoError(t, err)
52 c, err := net.DialUDP("udp", nil, l.LocalAddr().(*net.UDPAddr))
57 for msgLen := 1; ; msgLen *= 2 {
58 n, err := c.Write(make([]byte, msgLen))
60 require.Contains(t, err.Error(), "message too long")
69 func TestShortBinaryRead(t *testing.T) {
70 var data ResponseHeader
71 err := binary.Read(bytes.NewBufferString("\x00\x00\x00\x01"), binary.BigEndian, &data)
72 if err != io.ErrUnexpectedEOF {
77 func TestConvertInt16ToInt(t *testing.T) {
79 if int(uint16(int16(i))) != 50000 {
84 func TestConnClientLogDispatchUnknownTransactionId(t *testing.T) {
86 cc, err := NewConnClient(NewConnClientOpts{
90 c.Assert(err, qt.IsNil)
92 pc, err := net.ListenPacket(network, ":0")
93 c.Assert(err, qt.IsNil)
95 ccAddr := *cc.LocalAddr().(*net.UDPAddr)
96 ccAddr.IP = net.IPv6loopback
97 _, err = pc.WriteTo(make([]byte, 30), &ccAddr)
98 c.Assert(err, qt.IsNil)
101 func TestConnectionIdMismatch(t *testing.T) {
102 t.Skip("Server host returns consistent connection ID in limited tests and so isn't effective.")
103 cl, err := NewConnClient(NewConnClientOpts{
104 // This host seems to return `Connection ID missmatch.\x00` every 2 minutes or so under
106 Host: "tracker.torrent.eu.org:451",
107 //Host: "tracker.opentrackr.org:1337",
111 c.Assert(err, qt.IsNil)
113 ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
115 // Force every request to use a different connection ID. It's racey, but we want to get a
116 // different ID issued before a request can be sent with an old ID.
117 cl.Client.shouldReconnectOverride = func() bool { return true }
118 started := time.Now()
119 var wg sync.WaitGroup
120 for range iter.N(2) {
121 ar := AnnounceRequest{
125 rand.Read(ar.InfoHash[:])
126 rand.Read(ar.PeerId[:])
131 _, _, err := cl.Announce(ctx, ar, Options{})
132 // I'm looking for `error response: "Connection ID missmatch.\x00"`.
133 t.Logf("announce error after %v: %v", time.Since(started), err)