github.com/danielpfeifer02/quic-go-prio-packs@v0.41.0-28/integrationtests/self/close_test.go (about)

     1  package self_test
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net"
     7  	"sync/atomic"
     8  	"time"
     9  
    10  	"github.com/danielpfeifer02/quic-go-prio-packs"
    11  	quicproxy "github.com/danielpfeifer02/quic-go-prio-packs/integrationtests/tools/proxy"
    12  
    13  	. "github.com/onsi/ginkgo/v2"
    14  	. "github.com/onsi/gomega"
    15  )
    16  
    17  var _ = Describe("Connection ID lengths tests", func() {
    18  	It("retransmits the CONNECTION_CLOSE packet", func() {
    19  		server, err := quic.ListenAddr(
    20  			"localhost:0",
    21  			getTLSConfig(),
    22  			getQuicConfig(&quic.Config{
    23  				DisablePathMTUDiscovery: true,
    24  			}),
    25  		)
    26  		Expect(err).ToNot(HaveOccurred())
    27  		defer server.Close()
    28  
    29  		var drop atomic.Bool
    30  		dropped := make(chan []byte, 100)
    31  		proxy, err := quicproxy.NewQuicProxy("localhost:0", &quicproxy.Opts{
    32  			RemoteAddr: fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
    33  			DelayPacket: func(dir quicproxy.Direction, _ []byte) time.Duration {
    34  				return 5 * time.Millisecond // 10ms RTT
    35  			},
    36  			DropPacket: func(dir quicproxy.Direction, b []byte) bool {
    37  				if drop := drop.Load(); drop && dir == quicproxy.DirectionOutgoing {
    38  					dropped <- b
    39  					return true
    40  				}
    41  				return false
    42  			},
    43  		})
    44  		Expect(err).ToNot(HaveOccurred())
    45  		defer proxy.Close()
    46  
    47  		conn, err := quic.DialAddr(
    48  			context.Background(),
    49  			fmt.Sprintf("localhost:%d", proxy.LocalPort()),
    50  			getTLSClientConfig(),
    51  			getQuicConfig(nil),
    52  		)
    53  		Expect(err).ToNot(HaveOccurred())
    54  		defer conn.CloseWithError(0, "")
    55  
    56  		sconn, err := server.Accept(context.Background())
    57  		Expect(err).ToNot(HaveOccurred())
    58  		time.Sleep(100 * time.Millisecond)
    59  		drop.Store(true)
    60  		sconn.CloseWithError(1337, "closing")
    61  
    62  		// send 100 packets
    63  		for i := 0; i < 100; i++ {
    64  			str, err := conn.OpenStream()
    65  			Expect(err).ToNot(HaveOccurred())
    66  			_, err = str.Write([]byte("foobar"))
    67  			Expect(err).ToNot(HaveOccurred())
    68  			time.Sleep(time.Millisecond)
    69  		}
    70  		// Expect retransmissions of the CONNECTION_CLOSE for the
    71  		// 1st, 2nd, 4th, 8th, 16th, 32th, 64th packet: 7 in total (+1 for the original packet)
    72  		Eventually(dropped).Should(HaveLen(8))
    73  		first := <-dropped
    74  		for len(dropped) > 0 {
    75  			Expect(<-dropped).To(Equal(first)) // these packets are all identical
    76  		}
    77  	})
    78  })