github.com/MerlinKodo/quic-go@v0.39.2/internal/qtls/client_session_cache_test.go (about)

     1  //go:build go1.21
     2  
     3  package qtls
     4  
     5  import (
     6  	"crypto/tls"
     7  	"fmt"
     8  	"net"
     9  
    10  	"github.com/MerlinKodo/quic-go/internal/testdata"
    11  
    12  	. "github.com/onsi/ginkgo/v2"
    13  	. "github.com/onsi/gomega"
    14  )
    15  
    16  var _ = Describe("Client Session Cache", func() {
    17  	It("adds data to and restores data from a session ticket", func() {
    18  		ln, err := tls.Listen("tcp4", "localhost:0", testdata.GetTLSConfig())
    19  		Expect(err).ToNot(HaveOccurred())
    20  
    21  		done := make(chan struct{})
    22  		go func() {
    23  			defer GinkgoRecover()
    24  			defer close(done)
    25  
    26  			for {
    27  				conn, err := ln.Accept()
    28  				if err != nil {
    29  					return
    30  				}
    31  				_, err = conn.Read(make([]byte, 10))
    32  				Expect(err).ToNot(HaveOccurred())
    33  				_, err = conn.Write([]byte("foobar"))
    34  				Expect(err).ToNot(HaveOccurred())
    35  			}
    36  		}()
    37  
    38  		restored := make(chan []byte, 1)
    39  		clientConf := &tls.Config{
    40  			RootCAs: testdata.GetRootCA(),
    41  			ClientSessionCache: &clientSessionCache{
    42  				wrapped: tls.NewLRUClientSessionCache(10),
    43  				getData: func() []byte { return []byte("session") },
    44  				setData: func(data []byte) { restored <- data },
    45  			},
    46  		}
    47  		conn, err := tls.Dial(
    48  			"tcp4",
    49  			fmt.Sprintf("localhost:%d", ln.Addr().(*net.TCPAddr).Port),
    50  			clientConf,
    51  		)
    52  		Expect(err).ToNot(HaveOccurred())
    53  		_, err = conn.Write([]byte("foobar"))
    54  		Expect(err).ToNot(HaveOccurred())
    55  		Expect(conn.ConnectionState().DidResume).To(BeFalse())
    56  		Expect(restored).To(HaveLen(0))
    57  		_, err = conn.Read(make([]byte, 10))
    58  		Expect(err).ToNot(HaveOccurred())
    59  		Expect(conn.Close()).To(Succeed())
    60  
    61  		// make sure the cache can deal with nonsensical inputs
    62  		clientConf.ClientSessionCache.Put("foo", nil)
    63  		clientConf.ClientSessionCache.Put("bar", &tls.ClientSessionState{})
    64  
    65  		conn, err = tls.Dial(
    66  			"tcp4",
    67  			fmt.Sprintf("localhost:%d", ln.Addr().(*net.TCPAddr).Port),
    68  			clientConf,
    69  		)
    70  		Expect(err).ToNot(HaveOccurred())
    71  		_, err = conn.Write([]byte("foobar"))
    72  		Expect(err).ToNot(HaveOccurred())
    73  		Expect(conn.ConnectionState().DidResume).To(BeTrue())
    74  		var restoredData []byte
    75  		Expect(restored).To(Receive(&restoredData))
    76  		Expect(restoredData).To(Equal([]byte("session")))
    77  		Expect(conn.Close()).To(Succeed())
    78  
    79  		Expect(ln.Close()).To(Succeed())
    80  		Eventually(done).Should(BeClosed())
    81  	})
    82  })