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 if isErrMessageTooLong(err) {
63 t.Fatalf("expected message too long error: %v", err)
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 {
79 func TestConvertInt16ToInt(t *testing.T) {
81 if int(uint16(int16(i))) != 50000 {
86 func TestConnClientLogDispatchUnknownTransactionId(t *testing.T) {
88 cc, err := NewConnClient(NewConnClientOpts{
92 c.Assert(err, qt.IsNil)
94 pc, err := net.ListenPacket(network, ":0")
95 c.Assert(err, qt.IsNil)
97 ccAddr := *cc.LocalAddr().(*net.UDPAddr)
98 ccAddr.IP = net.IPv6loopback
99 _, err = pc.WriteTo(make([]byte, 30), &ccAddr)
100 c.Assert(err, qt.IsNil)
103 func TestConnectionIdMismatch(t *testing.T) {
104 t.Skip("Server host returns consistent connection ID in limited tests and so isn't effective.")
105 cl, err := NewConnClient(NewConnClientOpts{
106 // This host seems to return `Connection ID missmatch.\x00` every 2 minutes or so under
108 Host: "tracker.torrent.eu.org:451",
109 //Host: "tracker.opentrackr.org:1337",
113 c.Assert(err, qt.IsNil)
115 ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
117 // Force every request to use a different connection ID. It's racey, but we want to get a
118 // different ID issued before a request can be sent with an old ID.
119 cl.Client.shouldReconnectOverride = func() bool { return true }
120 started := time.Now()
121 var wg sync.WaitGroup
122 for range iter.N(2) {
123 ar := AnnounceRequest{
127 rand.Read(ar.InfoHash[:])
128 rand.Read(ar.PeerId[:])
133 _, _, err := cl.Announce(ctx, ar, Options{})
134 // I'm looking for `error response: "Connection ID missmatch.\x00"`.
135 t.Logf("announce error after %v: %v", time.Since(started), err)