github.com/apernet/quic-go@v0.43.1-0.20240515053213-5e9e635fd9f0/internal/qtls/client_session_cache_test.go (about)

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