github.com/sagernet/quic-go@v0.43.1-beta.1/internal/qtls_ech/client_session_cache.go (about) 1 //go:build go1.21 2 3 package qtls 4 5 import ( 6 "sync" 7 8 "github.com/sagernet/cloudflare-tls" 9 ) 10 11 type clientSessionCache struct { 12 mx sync.Mutex 13 getData func(earlyData bool) []byte 14 setData func(data []byte, earlyData bool) (allowEarlyData bool) 15 wrapped tls.ClientSessionCache 16 } 17 18 var _ tls.ClientSessionCache = &clientSessionCache{} 19 20 func (c *clientSessionCache) Put(key string, cs *tls.ClientSessionState) { 21 c.mx.Lock() 22 defer c.mx.Unlock() 23 24 if cs == nil { 25 c.wrapped.Put(key, nil) 26 return 27 } 28 ticket, state, err := cs.ResumptionState() 29 if err != nil || state == nil { 30 c.wrapped.Put(key, cs) 31 return 32 } 33 state.Extra = append(state.Extra, addExtraPrefix(c.getData(state.EarlyData))) 34 newCS, err := tls.NewResumptionState(ticket, state) 35 if err != nil { 36 // It's not clear why this would error. Just save the original state. 37 c.wrapped.Put(key, cs) 38 return 39 } 40 c.wrapped.Put(key, newCS) 41 } 42 43 func (c *clientSessionCache) Get(key string) (*tls.ClientSessionState, bool) { 44 c.mx.Lock() 45 defer c.mx.Unlock() 46 47 cs, ok := c.wrapped.Get(key) 48 if !ok || cs == nil { 49 return cs, ok 50 } 51 ticket, state, err := cs.ResumptionState() 52 if err != nil { 53 // It's not clear why this would error. 54 // Remove the ticket from the session cache, so we don't run into this error over and over again 55 c.wrapped.Put(key, nil) 56 return nil, false 57 } 58 // restore QUIC transport parameters and RTT stored in state.Extra 59 if extra := findExtraData(state.Extra); extra != nil { 60 earlyData := c.setData(extra, state.EarlyData) 61 if state.EarlyData { 62 state.EarlyData = earlyData 63 } 64 } 65 session, err := tls.NewResumptionState(ticket, state) 66 if err != nil { 67 // It's not clear why this would error. 68 // Remove the ticket from the session cache, so we don't run into this error over and over again 69 c.wrapped.Put(key, nil) 70 return nil, false 71 } 72 return session, true 73 }