save the RTT along the session ticket and use it on resumed connections

This commit is contained in:
Marten Seemann
2020-02-01 16:58:09 +07:00
parent 8ad95ce2d3
commit 69ab66ba82
7 changed files with 177 additions and 35 deletions

View File

@@ -1,38 +1,122 @@
package handshake
import (
"bytes"
"crypto/tls"
"time"
"unsafe"
"github.com/lucas-clemente/quic-go/internal/utils"
"github.com/marten-seemann/qtls"
"github.com/lucas-clemente/quic-go/internal/congestion"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("ClientSessionCache", func() {
var (
csc *clientSessionCache
get, set chan []byte
)
encodeIntoSessionTicket := func(data []byte) *tls.ClientSessionState {
var session clientSessionState
sessBytes := (*[unsafe.Sizeof(session)]byte)(unsafe.Pointer(&session))[:]
session.nonce = data
var tlsSession tls.ClientSessionState
tlsSessBytes := (*[unsafe.Sizeof(tlsSession)]byte)(unsafe.Pointer(&tlsSession))[:]
copy(tlsSessBytes, sessBytes)
return &tlsSession
}
BeforeEach(func() {
get = make(chan []byte, 100)
set = make(chan []byte, 100)
csc = newClientSessionCache(
It("puts and gets", func() {
get := make(chan []byte, 100)
set := make(chan []byte, 100)
csc := newClientSessionCache(
tls.NewLRUClientSessionCache(100),
congestion.NewRTTStats(),
func() []byte { return <-get },
func(b []byte) { set <- b },
)
})
It("puts and gets", func() {
get <- []byte("foobar")
csc.Put("localhost", &qtls.ClientSessionState{})
Expect(set).To(BeEmpty())
state, ok := csc.Get("localhost")
Expect(ok).To(BeTrue())
Expect(state).ToNot(BeNil())
Expect(set).To(Receive(Equal([]byte("foobar"))))
})
It("saves the RTT", func() {
rttStatsOrig := congestion.NewRTTStats()
rttStatsOrig.UpdateRTT(10*time.Second, 0, time.Now())
Expect(rttStatsOrig.SmoothedRTT()).To(Equal(10 * time.Second))
cache := tls.NewLRUClientSessionCache(100)
csc1 := newClientSessionCache(
cache,
rttStatsOrig,
func() []byte { return nil },
func([]byte) {},
)
csc1.Put("localhost", &qtls.ClientSessionState{})
rttStats := congestion.NewRTTStats()
csc2 := newClientSessionCache(
cache,
rttStats,
func() []byte { return nil },
func([]byte) {},
)
Expect(rttStats.SmoothedRTT()).ToNot(Equal(10 * time.Second))
_, ok := csc2.Get("localhost")
Expect(ok).To(BeTrue())
Expect(rttStats.SmoothedRTT()).To(Equal(10 * time.Second))
})
It("refuses a session state that is too short for the revision", func() {
cache := tls.NewLRUClientSessionCache(1)
cache.Put("localhost", encodeIntoSessionTicket([]byte{}))
csc := newClientSessionCache(
cache,
congestion.NewRTTStats(),
func() []byte { return nil },
func([]byte) {},
)
_, ok := csc.Get("localhost")
Expect(ok).To(BeFalse())
})
It("refuses a session state with the wrong revision", func() {
cache := tls.NewLRUClientSessionCache(1)
b := &bytes.Buffer{}
utils.WriteVarInt(b, clientSessionStateRevision+1)
cache.Put("localhost", encodeIntoSessionTicket(b.Bytes()))
csc := newClientSessionCache(
cache,
congestion.NewRTTStats(),
func() []byte { return nil },
func([]byte) {},
)
_, ok := csc.Get("localhost")
Expect(ok).To(BeFalse())
})
It("refuses a session state when unmarshalling fails", func() {
cache := tls.NewLRUClientSessionCache(1)
b := &bytes.Buffer{}
utils.WriteVarInt(b, clientSessionStateRevision)
b.Write([]byte("foobar"))
cache.Put("localhost", encodeIntoSessionTicket(b.Bytes()))
csc := newClientSessionCache(
cache,
congestion.NewRTTStats(),
func() []byte { return nil },
func([]byte) {},
)
_, ok := csc.Get("localhost")
Expect(ok).To(BeFalse())
})
})