blob: 2205ff2f793f8841c1c15f8f59fc06895f70c7ca [file] [log] [blame]
// 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.
//go:build go1.21
package quic
import (
"testing"
"time"
)
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++ {
tc.advance(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) {
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 {
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)
}
}
}