Files
golang.net/quic/conn_send_test.go
Dmitri Shuralyov 29181b8c03 all: remove go1.25 and older build constraints
Now that the x/net module requires Go 1.25.0,
the go1.25 build constraint is always satisfied.
Simplify the code accordingly.

Change-Id: I3d6fe4a132a26918455489b998730b494f5273c4
Reviewed-on: https://go-review.googlesource.com/c/net/+/744800
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Nicholas Husin <nsh@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2026-02-12 07:53:52 -08:00

93 lines
2.6 KiB
Go

// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package quic
import (
"testing"
"testing/synctest"
"time"
)
func TestAckElicitingAck(t *testing.T) {
synctest.Test(t, testAckElicitingAck)
}
func testAckElicitingAck(t *testing.T) {
// "A receiver that sends only non-ack-eliciting packets [...] might not receive
// an acknowledgment for a long period of time.
// [...] a receiver could send a [...] ack-eliciting frame occasionally [...]
// to elicit an ACK from the peer."
// https://www.rfc-editor.org/rfc/rfc9000#section-13.2.4-2
//
// Send a bunch of ack-eliciting packets, verify that the conn doesn't just
// send ACKs in response.
tc := newTestConn(t, clientSide, permissiveTransportParameters)
tc.handshake()
const count = 100
for i := 0; i < count; i++ {
time.Sleep(1 * time.Millisecond)
tc.writeFrames(packetType1RTT,
debugFramePing{},
)
got, _ := tc.readFrame()
switch got.(type) {
case debugFrameAck:
continue
case debugFramePing:
return
}
}
t.Errorf("after sending %v PINGs, got no ack-eliciting response", count)
}
func TestSendPacketNumberSize(t *testing.T) {
synctest.Test(t, testSendPacketNumberSize)
}
func testSendPacketNumberSize(t *testing.T) {
tc := newTestConn(t, clientSide, permissiveTransportParameters)
tc.handshake()
recvPing := func() *testPacket {
t.Helper()
tc.conn.ping(appDataSpace)
p := tc.readPacket()
if p == nil {
t.Fatalf("want packet containing PING, got none")
}
return p
}
// Desynchronize the packet numbers the conn is sending and the ones it is receiving,
// by having the conn send a number of unacked packets.
for i := 0; i < 16; i++ {
recvPing()
}
// Establish the maximum packet number the conn has received an ACK for.
maxAcked := recvPing().num
tc.writeAckForAll()
// Make the conn send a sequence of packets.
// Check that the packet number is encoded with two bytes once the difference between the
// current packet and the max acked one is sufficiently large.
for want := maxAcked + 1; want < maxAcked+0x100; want++ {
p := recvPing()
if p.num == want+1 {
// The conn skipped a packet number
// (defense against optimistic ACK attacks).
want++
} else if p.num != want {
t.Fatalf("received packet number %v, want %v", p.num, want)
}
gotPnumLen := int(p.header&0x03) + 1
wantPnumLen := 1
if p.num-maxAcked >= 0x80 {
wantPnumLen = 2
}
if gotPnumLen != wantPnumLen {
t.Fatalf("packet number 0x%x encoded with %v bytes, want %v (max acked = %v)", p.num, gotPnumLen, wantPnumLen, maxAcked)
}
}
}