mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-02 19:57:35 +03:00
uTLS is not yet bumped to the new version, so this commit breaks the dependencies relationship by getting rid of the local replace.
120 lines
3.5 KiB
Go
120 lines
3.5 KiB
Go
package self_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net"
|
|
"time"
|
|
|
|
quic "github.com/refraction-networking/uquic"
|
|
quicproxy "github.com/refraction-networking/uquic/integrationtests/tools/proxy"
|
|
"github.com/refraction-networking/uquic/logging"
|
|
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
var _ = Describe("Packetization", func() {
|
|
// In this test, the client sends 100 small messages. The server echoes these messages.
|
|
// This means that every endpoint will send 100 ack-eliciting packets in short succession.
|
|
// This test then tests that no more than 110 packets are sent in every direction, making sure that ACK are bundled.
|
|
It("bundles ACKs", func() {
|
|
const numMsg = 100
|
|
|
|
serverTracer := newPacketTracer()
|
|
server, err := quic.ListenAddr(
|
|
"localhost:0",
|
|
getTLSConfig(),
|
|
getQuicConfig(&quic.Config{
|
|
DisablePathMTUDiscovery: true,
|
|
Tracer: newTracer(serverTracer),
|
|
}),
|
|
)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
defer server.Close()
|
|
serverAddr := fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port)
|
|
|
|
proxy, err := quicproxy.NewQuicProxy("localhost:0", &quicproxy.Opts{
|
|
RemoteAddr: serverAddr,
|
|
DelayPacket: func(dir quicproxy.Direction, _ []byte) time.Duration {
|
|
return 5 * time.Millisecond
|
|
},
|
|
})
|
|
Expect(err).ToNot(HaveOccurred())
|
|
defer proxy.Close()
|
|
|
|
clientTracer := newPacketTracer()
|
|
conn, err := quic.DialAddr(
|
|
context.Background(),
|
|
fmt.Sprintf("localhost:%d", proxy.LocalPort()),
|
|
getTLSClientConfig(),
|
|
getQuicConfig(&quic.Config{
|
|
DisablePathMTUDiscovery: true,
|
|
Tracer: newTracer(clientTracer),
|
|
}),
|
|
)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
defer conn.CloseWithError(0, "")
|
|
|
|
go func() {
|
|
defer GinkgoRecover()
|
|
conn, err := server.Accept(context.Background())
|
|
Expect(err).ToNot(HaveOccurred())
|
|
str, err := conn.AcceptStream(context.Background())
|
|
Expect(err).ToNot(HaveOccurred())
|
|
b := make([]byte, 1)
|
|
// Echo every byte received from the client.
|
|
for {
|
|
if _, err := str.Read(b); err != nil {
|
|
break
|
|
}
|
|
_, err = str.Write(b)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
}
|
|
}()
|
|
|
|
str, err := conn.OpenStreamSync(context.Background())
|
|
Expect(err).ToNot(HaveOccurred())
|
|
b := make([]byte, 1)
|
|
// Send numMsg 1-byte messages.
|
|
for i := 0; i < numMsg; i++ {
|
|
_, err = str.Write([]byte{uint8(i)})
|
|
Expect(err).ToNot(HaveOccurred())
|
|
_, err = str.Read(b)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(b[0]).To(Equal(uint8(i)))
|
|
}
|
|
Expect(conn.CloseWithError(0, "")).To(Succeed())
|
|
|
|
countBundledPackets := func(packets []shortHeaderPacket) (numBundled int) {
|
|
for _, p := range packets {
|
|
var hasAck, hasStreamFrame bool
|
|
for _, f := range p.frames {
|
|
switch f.(type) {
|
|
case *logging.AckFrame:
|
|
hasAck = true
|
|
case *logging.StreamFrame:
|
|
hasStreamFrame = true
|
|
}
|
|
}
|
|
if hasAck && hasStreamFrame {
|
|
numBundled++
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
numBundledIncoming := countBundledPackets(clientTracer.getRcvdShortHeaderPackets())
|
|
numBundledOutgoing := countBundledPackets(serverTracer.getRcvdShortHeaderPackets())
|
|
fmt.Fprintf(GinkgoWriter, "bundled incoming packets: %d / %d\n", numBundledIncoming, numMsg)
|
|
fmt.Fprintf(GinkgoWriter, "bundled outgoing packets: %d / %d\n", numBundledOutgoing, numMsg)
|
|
Expect(numBundledIncoming).To(And(
|
|
BeNumerically("<=", numMsg),
|
|
BeNumerically(">", numMsg*9/10),
|
|
))
|
|
Expect(numBundledOutgoing).To(And(
|
|
BeNumerically("<=", numMsg),
|
|
BeNumerically(">", numMsg*9/10),
|
|
))
|
|
})
|
|
})
|