forked from quic-go/quic-go
allow 0-RTT when the server's connection receive limit is increased
This commit is contained in:
@@ -19,6 +19,7 @@ import (
|
|||||||
"github.com/lucas-clemente/quic-go/logging"
|
"github.com/lucas-clemente/quic-go/logging"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/ginkgo/extensions/table"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -550,77 +551,84 @@ var _ = Describe("0-RTT", func() {
|
|||||||
Expect(get0RTTPackets(tracer.getRcvdPackets())).To(BeEmpty())
|
Expect(get0RTTPackets(tracer.getRcvdPackets())).To(BeEmpty())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("doesn't reject 0-RTT when the server's transport stream flow control limit increased", func() {
|
DescribeTable("flow control limits",
|
||||||
tlsConf, clientConf := dialAndReceiveSessionTicket(getQuicConfig(&quic.Config{
|
func(addFlowControlLimit func(*quic.Config, uint64)) {
|
||||||
InitialStreamReceiveWindow: 3,
|
tracer := newRcvdPacketTracer()
|
||||||
AcceptToken: func(_ net.Addr, _ *quic.Token) bool { return true },
|
firstConf := getQuicConfig(&quic.Config{
|
||||||
}))
|
AcceptToken: func(_ net.Addr, _ *quic.Token) bool { return true },
|
||||||
|
Versions: []protocol.VersionNumber{version},
|
||||||
|
})
|
||||||
|
addFlowControlLimit(firstConf, 3)
|
||||||
|
tlsConf, clientConf := dialAndReceiveSessionTicket(firstConf)
|
||||||
|
|
||||||
tracer := newRcvdPacketTracer()
|
secondConf := getQuicConfig(&quic.Config{
|
||||||
ln, err := quic.ListenAddrEarly(
|
Versions: []protocol.VersionNumber{version},
|
||||||
"localhost:0",
|
AcceptToken: func(_ net.Addr, _ *quic.Token) bool { return true },
|
||||||
tlsConf,
|
Tracer: newTracer(func() logging.ConnectionTracer { return tracer }),
|
||||||
getQuicConfig(&quic.Config{
|
})
|
||||||
Versions: []protocol.VersionNumber{version},
|
addFlowControlLimit(secondConf, 100)
|
||||||
AcceptToken: func(_ net.Addr, _ *quic.Token) bool { return true },
|
ln, err := quic.ListenAddrEarly(
|
||||||
InitialStreamReceiveWindow: 100,
|
"localhost:0",
|
||||||
Tracer: newTracer(func() logging.ConnectionTracer { return tracer }),
|
tlsConf,
|
||||||
}),
|
secondConf,
|
||||||
)
|
)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
defer ln.Close()
|
|
||||||
proxy, _ := runCountingProxy(ln.Addr().(*net.UDPAddr).Port)
|
|
||||||
defer proxy.Close()
|
|
||||||
|
|
||||||
sess, err := quic.DialAddrEarly(
|
|
||||||
fmt.Sprintf("localhost:%d", proxy.LocalPort()),
|
|
||||||
clientConf,
|
|
||||||
getQuicConfig(&quic.Config{Versions: []protocol.VersionNumber{version}}),
|
|
||||||
)
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
str, err := sess.OpenUniStream()
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
written := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
defer GinkgoRecover()
|
|
||||||
defer close(written)
|
|
||||||
_, err := str.Write([]byte("foobar"))
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(str.Close()).To(Succeed())
|
defer ln.Close()
|
||||||
}()
|
proxy, _ := runCountingProxy(ln.Addr().(*net.UDPAddr).Port)
|
||||||
|
defer proxy.Close()
|
||||||
|
|
||||||
Eventually(written).Should(BeClosed())
|
sess, err := quic.DialAddrEarly(
|
||||||
|
fmt.Sprintf("localhost:%d", proxy.LocalPort()),
|
||||||
|
clientConf,
|
||||||
|
getQuicConfig(&quic.Config{Versions: []protocol.VersionNumber{version}}),
|
||||||
|
)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
str, err := sess.OpenUniStream()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
written := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
defer GinkgoRecover()
|
||||||
|
defer close(written)
|
||||||
|
_, err := str.Write([]byte("foobar"))
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(str.Close()).To(Succeed())
|
||||||
|
}()
|
||||||
|
|
||||||
serverSess, err := ln.Accept(context.Background())
|
Eventually(written).Should(BeClosed())
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
rstr, err := serverSess.AcceptUniStream(context.Background())
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
data, err := ioutil.ReadAll(rstr)
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
Expect(data).To(Equal([]byte("foobar")))
|
|
||||||
Expect(serverSess.ConnectionState().TLS.Used0RTT).To(BeTrue())
|
|
||||||
Expect(serverSess.CloseWithError(0, "")).To(Succeed())
|
|
||||||
Eventually(sess.Context().Done()).Should(BeClosed())
|
|
||||||
|
|
||||||
var processedFirst bool
|
serverSess, err := ln.Accept(context.Background())
|
||||||
for _, p := range tracer.getRcvdPackets() {
|
Expect(err).ToNot(HaveOccurred())
|
||||||
for _, f := range p.frames {
|
rstr, err := serverSess.AcceptUniStream(context.Background())
|
||||||
if sf, ok := f.(*logging.StreamFrame); ok {
|
Expect(err).ToNot(HaveOccurred())
|
||||||
if !processedFirst {
|
data, err := ioutil.ReadAll(rstr)
|
||||||
// The first STREAM should have been sent in a 0-RTT packet.
|
Expect(err).ToNot(HaveOccurred())
|
||||||
// Due to the flow control limit, the STREAM frame was limit to the first 3 bytes.
|
Expect(data).To(Equal([]byte("foobar")))
|
||||||
Expect(p.hdr.Type).To(Equal(protocol.PacketType0RTT))
|
Expect(serverSess.ConnectionState().TLS.Used0RTT).To(BeTrue())
|
||||||
Expect(sf.Length).To(BeEquivalentTo(3))
|
Expect(serverSess.CloseWithError(0, "")).To(Succeed())
|
||||||
processedFirst = true
|
Eventually(sess.Context().Done()).Should(BeClosed())
|
||||||
} else {
|
|
||||||
// All other STREAM frames can only be sent after handshake completion.
|
var processedFirst bool
|
||||||
Expect(p.hdr.IsLongHeader).To(BeFalse())
|
for _, p := range tracer.getRcvdPackets() {
|
||||||
Expect(sf.Offset).ToNot(BeZero())
|
for _, f := range p.frames {
|
||||||
|
if sf, ok := f.(*logging.StreamFrame); ok {
|
||||||
|
if !processedFirst {
|
||||||
|
// The first STREAM should have been sent in a 0-RTT packet.
|
||||||
|
// Due to the flow control limit, the STREAM frame was limit to the first 3 bytes.
|
||||||
|
Expect(p.hdr.Type).To(Equal(protocol.PacketType0RTT))
|
||||||
|
Expect(sf.Length).To(BeEquivalentTo(3))
|
||||||
|
processedFirst = true
|
||||||
|
} else {
|
||||||
|
// All other STREAM frames can only be sent after handshake completion.
|
||||||
|
Expect(p.hdr.IsLongHeader).To(BeFalse())
|
||||||
|
Expect(sf.Offset).ToNot(BeZero())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
})
|
Entry("doesn't reject 0-RTT when the server's transport stream flow control limit increased", func(c *quic.Config, limit uint64) { c.InitialStreamReceiveWindow = limit }),
|
||||||
|
Entry("doesn't reject 0-RTT when the server's transport connection flow control limit increased", func(c *quic.Config, limit uint64) { c.InitialConnectionReceiveWindow = limit }),
|
||||||
|
)
|
||||||
|
|
||||||
It("correctly deals with 0-RTT rejections", func() {
|
It("correctly deals with 0-RTT rejections", func() {
|
||||||
tlsConf, clientConf := dialAndReceiveSessionTicket(nil)
|
tlsConf, clientConf := dialAndReceiveSessionTicket(nil)
|
||||||
|
|||||||
@@ -776,7 +776,7 @@ var _ = Describe("Crypto Setup TLS", func() {
|
|||||||
Expect(client.ConnectionState().Used0RTT).To(BeTrue())
|
Expect(client.ConnectionState().Used0RTT).To(BeTrue())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("rejects 0-RTT, whent the transport parameters changed", func() {
|
It("rejects 0-RTT, when the transport parameters changed", func() {
|
||||||
csc := mocktls.NewMockClientSessionCache(mockCtrl)
|
csc := mocktls.NewMockClientSessionCache(mockCtrl)
|
||||||
var state *tls.ClientSessionState
|
var state *tls.ClientSessionState
|
||||||
receivedSessionTicket := make(chan struct{})
|
receivedSessionTicket := make(chan struct{})
|
||||||
@@ -810,7 +810,7 @@ var _ = Describe("Crypto Setup TLS", func() {
|
|||||||
clientHelloWrittenChan, client, clientErr, server, serverErr = handshakeWithTLSConf(
|
clientHelloWrittenChan, client, clientErr, server, serverErr = handshakeWithTLSConf(
|
||||||
clientConf, serverConf,
|
clientConf, serverConf,
|
||||||
clientRTTStats, &utils.RTTStats{},
|
clientRTTStats, &utils.RTTStats{},
|
||||||
&wire.TransportParameters{}, &wire.TransportParameters{InitialMaxData: initialMaxData + 1},
|
&wire.TransportParameters{}, &wire.TransportParameters{InitialMaxData: initialMaxData - 1},
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
Expect(clientErr).ToNot(HaveOccurred())
|
Expect(clientErr).ToNot(HaveOccurred())
|
||||||
|
|||||||
@@ -528,11 +528,16 @@ var _ = Describe("Transport Parameters", func() {
|
|||||||
Expect(p.ValidFor0RTT(saved)).To(BeTrue())
|
Expect(p.ValidFor0RTT(saved)).To(BeTrue())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("rejects the parameters if the InitialMaxData changed", func() {
|
It("rejects the parameters if the InitialMaxData was reduced", func() {
|
||||||
p.InitialMaxData = 0
|
p.InitialMaxData = saved.InitialMaxData - 1
|
||||||
Expect(p.ValidFor0RTT(saved)).To(BeFalse())
|
Expect(p.ValidFor0RTT(saved)).To(BeFalse())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("doesn't reject the parameters if the InitialMaxData was increased", func() {
|
||||||
|
p.InitialMaxData = saved.InitialMaxData + 1
|
||||||
|
Expect(p.ValidFor0RTT(saved)).To(BeTrue())
|
||||||
|
})
|
||||||
|
|
||||||
It("rejects the parameters if the MaxBidiStreamNum was reduced", func() {
|
It("rejects the parameters if the MaxBidiStreamNum was reduced", func() {
|
||||||
p.MaxBidiStreamNum = saved.MaxBidiStreamNum - 1
|
p.MaxBidiStreamNum = saved.MaxBidiStreamNum - 1
|
||||||
Expect(p.ValidFor0RTT(saved)).To(BeFalse())
|
Expect(p.ValidFor0RTT(saved)).To(BeFalse())
|
||||||
|
|||||||
@@ -444,7 +444,7 @@ func (p *TransportParameters) ValidFor0RTT(saved *TransportParameters) bool {
|
|||||||
return p.InitialMaxStreamDataBidiLocal >= saved.InitialMaxStreamDataBidiLocal &&
|
return p.InitialMaxStreamDataBidiLocal >= saved.InitialMaxStreamDataBidiLocal &&
|
||||||
p.InitialMaxStreamDataBidiRemote >= saved.InitialMaxStreamDataBidiRemote &&
|
p.InitialMaxStreamDataBidiRemote >= saved.InitialMaxStreamDataBidiRemote &&
|
||||||
p.InitialMaxStreamDataUni >= saved.InitialMaxStreamDataUni &&
|
p.InitialMaxStreamDataUni >= saved.InitialMaxStreamDataUni &&
|
||||||
p.InitialMaxData == saved.InitialMaxData &&
|
p.InitialMaxData >= saved.InitialMaxData &&
|
||||||
p.MaxBidiStreamNum >= saved.MaxBidiStreamNum &&
|
p.MaxBidiStreamNum >= saved.MaxBidiStreamNum &&
|
||||||
p.MaxUniStreamNum >= saved.MaxUniStreamNum &&
|
p.MaxUniStreamNum >= saved.MaxUniStreamNum &&
|
||||||
p.ActiveConnectionIDLimit == saved.ActiveConnectionIDLimit
|
p.ActiveConnectionIDLimit == saved.ActiveConnectionIDLimit
|
||||||
|
|||||||
Reference in New Issue
Block a user