github.com/quic-go/quic-go@v0.44.0/internal/qtls/client_session_cache.go (about)

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