mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-03 20:27:35 +03:00
use separate streamsMaps for gQUIC and IETF QUIC
This is a lot of duplicate code for now, but it will make moving towards the new stream ID mapping in IETF QUIC (and unidirectional streams) much easier.
This commit is contained in:
parent
69437a0e78
commit
a20e94ee16
5 changed files with 873 additions and 89 deletions
|
@ -3,6 +3,7 @@ package quic
|
|||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/lucas-clemente/quic-go/internal/handshake"
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/wire"
|
||||
|
@ -12,7 +13,7 @@ import (
|
|||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Streams Map", func() {
|
||||
var _ = Describe("Streams Map (for IETF QUIC)", func() {
|
||||
var m *streamsMap
|
||||
|
||||
newStream := func(id protocol.StreamID) streamI {
|
||||
|
@ -21,8 +22,8 @@ var _ = Describe("Streams Map", func() {
|
|||
return str
|
||||
}
|
||||
|
||||
setNewStreamsMap := func(p protocol.Perspective, v protocol.VersionNumber) {
|
||||
m = newStreamsMap(newStream, p, v)
|
||||
setNewStreamsMap := func(p protocol.Perspective) {
|
||||
m = newStreamsMap(newStream, p).(*streamsMap)
|
||||
}
|
||||
|
||||
deleteStream := func(id protocol.StreamID) {
|
||||
|
@ -32,15 +33,15 @@ var _ = Describe("Streams Map", func() {
|
|||
Context("getting and creating streams", func() {
|
||||
Context("as a server", func() {
|
||||
BeforeEach(func() {
|
||||
setNewStreamsMap(protocol.PerspectiveServer, versionGQUICFrames)
|
||||
setNewStreamsMap(protocol.PerspectiveServer)
|
||||
})
|
||||
|
||||
Context("client-side streams", func() {
|
||||
It("gets new streams", func() {
|
||||
s, err := m.GetOrOpenStream(3)
|
||||
s, err := m.GetOrOpenStream(1)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(s).ToNot(BeNil())
|
||||
Expect(s.StreamID()).To(Equal(protocol.StreamID(3)))
|
||||
Expect(s.StreamID()).To(Equal(protocol.StreamID(1)))
|
||||
Expect(m.streams).To(HaveLen(1))
|
||||
Expect(m.numIncomingStreams).To(BeEquivalentTo(1))
|
||||
Expect(m.numOutgoingStreams).To(BeZero())
|
||||
|
@ -264,8 +265,7 @@ var _ = Describe("Streams Map", func() {
|
|||
Consistently(func() bool { return accepted }).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("starts with stream 1, if the crypto stream is stream 0", func() {
|
||||
setNewStreamsMap(protocol.PerspectiveServer, versionIETFFrames)
|
||||
It("starts with stream 1", func() {
|
||||
var str Stream
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
|
@ -281,7 +281,7 @@ var _ = Describe("Streams Map", func() {
|
|||
Expect(str.StreamID()).To(Equal(protocol.StreamID(1)))
|
||||
})
|
||||
|
||||
It("starts with stream 3, if the crypto stream is stream 1", func() {
|
||||
It("returns an implicitly opened stream, if a stream number is skipped", func() {
|
||||
var str Stream
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
|
@ -294,23 +294,7 @@ var _ = Describe("Streams Map", func() {
|
|||
_, err := m.GetOrOpenStream(3)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Eventually(done).Should(BeClosed())
|
||||
Expect(str.StreamID()).To(Equal(protocol.StreamID(3)))
|
||||
})
|
||||
|
||||
It("returns an implicitly opened stream, if a stream number is skipped", func() {
|
||||
var str Stream
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
var err error
|
||||
str, err = m.AcceptStream()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
close(done)
|
||||
}()
|
||||
_, err := m.GetOrOpenStream(5)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Eventually(done).Should(BeClosed())
|
||||
Expect(str.StreamID()).To(Equal(protocol.StreamID(3)))
|
||||
Expect(str.StreamID()).To(Equal(protocol.StreamID(1)))
|
||||
})
|
||||
|
||||
It("returns to multiple accepts", func() {
|
||||
|
@ -331,12 +315,12 @@ var _ = Describe("Streams Map", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
close(done2)
|
||||
}()
|
||||
_, err := m.GetOrOpenStream(5) // opens stream 3 and 5
|
||||
_, err := m.GetOrOpenStream(3) // opens stream 1 and 3
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Eventually(done1).Should(BeClosed())
|
||||
Eventually(done2).Should(BeClosed())
|
||||
Expect(str1.StreamID()).ToNot(Equal(str2.StreamID()))
|
||||
Expect(str1.StreamID() + str2.StreamID()).To(BeEquivalentTo(3 + 5))
|
||||
Expect(str1.StreamID() + str2.StreamID()).To(BeEquivalentTo(1 + 3))
|
||||
})
|
||||
|
||||
It("waits until a new stream is available", func() {
|
||||
|
@ -350,10 +334,10 @@ var _ = Describe("Streams Map", func() {
|
|||
close(done)
|
||||
}()
|
||||
Consistently(done).ShouldNot(BeClosed())
|
||||
_, err := m.GetOrOpenStream(3)
|
||||
_, err := m.GetOrOpenStream(1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Eventually(done).Should(BeClosed())
|
||||
Expect(str.StreamID()).To(Equal(protocol.StreamID(3)))
|
||||
Expect(str.StreamID()).To(Equal(protocol.StreamID(1)))
|
||||
})
|
||||
|
||||
It("returns multiple streams on subsequent Accept calls, if available", func() {
|
||||
|
@ -366,39 +350,46 @@ var _ = Describe("Streams Map", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
close(done)
|
||||
}()
|
||||
_, err := m.GetOrOpenStream(5)
|
||||
_, err := m.GetOrOpenStream(3)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Eventually(done).Should(BeClosed())
|
||||
Expect(str.StreamID()).To(Equal(protocol.StreamID(3)))
|
||||
Expect(str.StreamID()).To(Equal(protocol.StreamID(1)))
|
||||
str, err = m.AcceptStream()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str.StreamID()).To(Equal(protocol.StreamID(5)))
|
||||
Expect(str.StreamID()).To(Equal(protocol.StreamID(3)))
|
||||
})
|
||||
|
||||
It("blocks after accepting a stream", func() {
|
||||
var accepted bool
|
||||
_, err := m.GetOrOpenStream(3)
|
||||
_, err := m.GetOrOpenStream(1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
str, err := m.AcceptStream()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str.StreamID()).To(Equal(protocol.StreamID(3)))
|
||||
Expect(str.StreamID()).To(Equal(protocol.StreamID(1)))
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
_, _ = m.AcceptStream()
|
||||
accepted = true
|
||||
close(done)
|
||||
}()
|
||||
Consistently(func() bool { return accepted }).Should(BeFalse())
|
||||
Consistently(done).ShouldNot(BeClosed())
|
||||
// make the go routine return
|
||||
str.(*MockStreamI).EXPECT().closeForShutdown(gomock.Any())
|
||||
m.CloseWithError(errors.New("shut down"))
|
||||
Eventually(done).Should(BeClosed())
|
||||
})
|
||||
|
||||
It("stops waiting when an error is registered", func() {
|
||||
testErr := errors.New("testErr")
|
||||
var acceptErr error
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
_, acceptErr = m.AcceptStream()
|
||||
defer GinkgoRecover()
|
||||
_, err := m.AcceptStream()
|
||||
Expect(err).To(MatchError(testErr))
|
||||
close(done)
|
||||
}()
|
||||
Consistently(func() error { return acceptErr }).ShouldNot(HaveOccurred())
|
||||
Consistently(done).ShouldNot(BeClosed())
|
||||
m.CloseWithError(testErr)
|
||||
Eventually(func() error { return acceptErr }).Should(MatchError(testErr))
|
||||
Eventually(done).Should(BeClosed())
|
||||
})
|
||||
|
||||
It("immediately returns when Accept is called after an error was registered", func() {
|
||||
|
@ -412,7 +403,7 @@ var _ = Describe("Streams Map", func() {
|
|||
|
||||
Context("as a client", func() {
|
||||
BeforeEach(func() {
|
||||
setNewStreamsMap(protocol.PerspectiveClient, versionGQUICFrames)
|
||||
setNewStreamsMap(protocol.PerspectiveClient)
|
||||
m.UpdateLimits(&handshake.TransportParameters{MaxStreams: 10000})
|
||||
})
|
||||
|
||||
|
@ -451,18 +442,18 @@ var _ = Describe("Streams Map", func() {
|
|||
It("doesn't reopen an already closed stream", func() {
|
||||
str, err := m.OpenStream()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str.StreamID()).To(Equal(protocol.StreamID(3)))
|
||||
deleteStream(3)
|
||||
Expect(str.StreamID()).To(Equal(protocol.StreamID(1)))
|
||||
deleteStream(1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
str, err = m.GetOrOpenStream(3)
|
||||
str, err = m.GetOrOpenStream(1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(str).To(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
Context("client-side streams", func() {
|
||||
It("starts with stream 1, if the crypto stream is stream 0", func() {
|
||||
setNewStreamsMap(protocol.PerspectiveClient, versionIETFFrames)
|
||||
It("starts with stream 1", func() {
|
||||
setNewStreamsMap(protocol.PerspectiveClient)
|
||||
m.UpdateLimits(&handshake.TransportParameters{MaxStreams: 10000})
|
||||
s, err := m.OpenStream()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -472,15 +463,6 @@ var _ = Describe("Streams Map", func() {
|
|||
Expect(m.numIncomingStreams).To(BeZero())
|
||||
})
|
||||
|
||||
It("starts with stream 3, if the crypto stream is stream 1", func() {
|
||||
s, err := m.OpenStream()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(s).ToNot(BeNil())
|
||||
Expect(s.StreamID()).To(BeEquivalentTo(3))
|
||||
Expect(m.numOutgoingStreams).To(BeEquivalentTo(1))
|
||||
Expect(m.numIncomingStreams).To(BeZero())
|
||||
})
|
||||
|
||||
It("opens multiple streams", func() {
|
||||
s1, err := m.OpenStream()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -522,17 +504,17 @@ var _ = Describe("Streams Map", func() {
|
|||
|
||||
Context("deleting streams", func() {
|
||||
BeforeEach(func() {
|
||||
setNewStreamsMap(protocol.PerspectiveServer, versionGQUICFrames)
|
||||
setNewStreamsMap(protocol.PerspectiveServer)
|
||||
})
|
||||
|
||||
It("deletes an incoming stream", func() {
|
||||
_, err := m.GetOrOpenStream(5) // open stream 3 and 5
|
||||
_, err := m.GetOrOpenStream(3) // open stream 1 and 3
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(m.numIncomingStreams).To(BeEquivalentTo(2))
|
||||
err = m.DeleteStream(3)
|
||||
err = m.DeleteStream(1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(m.streams).To(HaveLen(1))
|
||||
Expect(m.streams).To(HaveKey(protocol.StreamID(5)))
|
||||
Expect(m.streams).To(HaveKey(protocol.StreamID(3)))
|
||||
Expect(m.numIncomingStreams).To(BeEquivalentTo(1))
|
||||
})
|
||||
|
||||
|
@ -555,15 +537,15 @@ var _ = Describe("Streams Map", func() {
|
|||
})
|
||||
|
||||
It("sets the flow control limit", func() {
|
||||
setNewStreamsMap(protocol.PerspectiveServer, versionGQUICFrames)
|
||||
_, err := m.GetOrOpenStream(5)
|
||||
setNewStreamsMap(protocol.PerspectiveServer)
|
||||
_, err := m.GetOrOpenStream(3)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
m.streams[3].(*MockStreamI).EXPECT().handleMaxStreamDataFrame(&wire.MaxStreamDataFrame{
|
||||
StreamID: 3,
|
||||
m.streams[1].(*MockStreamI).EXPECT().handleMaxStreamDataFrame(&wire.MaxStreamDataFrame{
|
||||
StreamID: 1,
|
||||
ByteOffset: 321,
|
||||
})
|
||||
m.streams[5].(*MockStreamI).EXPECT().handleMaxStreamDataFrame(&wire.MaxStreamDataFrame{
|
||||
StreamID: 5,
|
||||
m.streams[3].(*MockStreamI).EXPECT().handleMaxStreamDataFrame(&wire.MaxStreamDataFrame{
|
||||
StreamID: 3,
|
||||
ByteOffset: 321,
|
||||
})
|
||||
m.UpdateLimits(&handshake.TransportParameters{StreamFlowControlWindow: 321})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue