forked from quic-go/quic-go
simplify the maximum stream limit
This commit is contained in:
@@ -54,7 +54,7 @@ var _ = Describe("Chrome tests", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("uploads many small files", func() {
|
It("uploads many small files", func() {
|
||||||
num := protocol.MaxStreamsPerConnection + 20
|
num := protocol.MaxIncomingStreams + 20
|
||||||
chromeTest(
|
chromeTest(
|
||||||
version,
|
version,
|
||||||
fmt.Sprintf("https://quic.clemente.io/uploadtest?num=%d&len=%d", num, dataLen),
|
fmt.Sprintf("https://quic.clemente.io/uploadtest?num=%d&len=%d", num, dataLen),
|
||||||
|
|||||||
@@ -39,13 +39,13 @@ type paramsNegotiatorBase struct {
|
|||||||
omitConnectionID bool
|
omitConnectionID bool
|
||||||
requestConnectionIDOmission bool
|
requestConnectionIDOmission bool
|
||||||
|
|
||||||
maxIncomingDynamicStreamsPerConnection uint32
|
maxOutgoingStreams uint32
|
||||||
idleTimeout time.Duration
|
idleTimeout time.Duration
|
||||||
remoteIdleTimeout time.Duration
|
remoteIdleTimeout time.Duration
|
||||||
sendStreamFlowControlWindow protocol.ByteCount
|
sendStreamFlowControlWindow protocol.ByteCount
|
||||||
sendConnectionFlowControlWindow protocol.ByteCount
|
sendConnectionFlowControlWindow protocol.ByteCount
|
||||||
receiveStreamFlowControlWindow protocol.ByteCount
|
receiveStreamFlowControlWindow protocol.ByteCount
|
||||||
receiveConnectionFlowControlWindow protocol.ByteCount
|
receiveConnectionFlowControlWindow protocol.ByteCount
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *paramsNegotiatorBase) init(params *TransportParameters) {
|
func (h *paramsNegotiatorBase) init(params *TransportParameters) {
|
||||||
@@ -56,15 +56,8 @@ func (h *paramsNegotiatorBase) init(params *TransportParameters) {
|
|||||||
h.requestConnectionIDOmission = params.RequestConnectionIDOmission
|
h.requestConnectionIDOmission = params.RequestConnectionIDOmission
|
||||||
|
|
||||||
h.idleTimeout = params.IdleTimeout
|
h.idleTimeout = params.IdleTimeout
|
||||||
if h.perspective == protocol.PerspectiveServer {
|
// use this as a default value. As soon as the client sends its value, this gets updated
|
||||||
h.maxIncomingDynamicStreamsPerConnection = protocol.MaxStreamsPerConnection // "incoming" seen from the client's perspective
|
h.maxOutgoingStreams = protocol.MaxOutgoingStreams
|
||||||
} else {
|
|
||||||
h.maxIncomingDynamicStreamsPerConnection = protocol.MaxStreamsPerConnection // "incoming" seen from the server's perspective
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *paramsNegotiatorBase) negotiateMaxIncomingDynamicStreamsPerConnection(clientValue uint32) uint32 {
|
|
||||||
return utils.MinUint32(clientValue, protocol.MaxIncomingDynamicStreamsPerConnection)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSendStreamFlowControlWindow gets the size of the stream-level flow control window for sending data
|
// GetSendStreamFlowControlWindow gets the size of the stream-level flow control window for sending data
|
||||||
@@ -97,8 +90,11 @@ func (h *paramsNegotiatorBase) GetReceiveConnectionFlowControlWindow() protocol.
|
|||||||
func (h *paramsNegotiatorBase) GetMaxOutgoingStreams() uint32 {
|
func (h *paramsNegotiatorBase) GetMaxOutgoingStreams() uint32 {
|
||||||
h.mutex.RLock()
|
h.mutex.RLock()
|
||||||
defer h.mutex.RUnlock()
|
defer h.mutex.RUnlock()
|
||||||
|
return h.maxOutgoingStreams
|
||||||
|
}
|
||||||
|
|
||||||
return h.maxIncomingDynamicStreamsPerConnection
|
func (h *paramsNegotiatorBase) setMaxOutgoingStreams(clientValue uint32) {
|
||||||
|
h.maxOutgoingStreams = utils.MinUint32(clientValue, protocol.MaxOutgoingStreams)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *paramsNegotiatorBase) setRemoteIdleTimeout(t time.Duration) {
|
func (h *paramsNegotiatorBase) setRemoteIdleTimeout(t time.Duration) {
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ func (h *paramsNegotiatorGQUIC) SetFromMap(params map[Tag][]byte) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errMalformedTag
|
return errMalformedTag
|
||||||
}
|
}
|
||||||
h.maxIncomingDynamicStreamsPerConnection = h.negotiateMaxIncomingDynamicStreamsPerConnection(clientValue)
|
h.setMaxOutgoingStreams(clientValue)
|
||||||
}
|
}
|
||||||
if value, ok := params[TagICSL]; ok {
|
if value, ok := params[TagICSL]; ok {
|
||||||
clientValue, err := utils.LittleEndian.ReadUint32(bytes.NewBuffer(value))
|
clientValue, err := utils.LittleEndian.ReadUint32(bytes.NewBuffer(value))
|
||||||
@@ -93,7 +93,7 @@ func (h *paramsNegotiatorGQUIC) GetHelloMap() (map[Tag][]byte, error) {
|
|||||||
cfcw := bytes.NewBuffer([]byte{})
|
cfcw := bytes.NewBuffer([]byte{})
|
||||||
utils.LittleEndian.WriteUint32(cfcw, uint32(h.GetReceiveConnectionFlowControlWindow()))
|
utils.LittleEndian.WriteUint32(cfcw, uint32(h.GetReceiveConnectionFlowControlWindow()))
|
||||||
mids := bytes.NewBuffer([]byte{})
|
mids := bytes.NewBuffer([]byte{})
|
||||||
utils.LittleEndian.WriteUint32(mids, protocol.MaxIncomingDynamicStreamsPerConnection)
|
utils.LittleEndian.WriteUint32(mids, protocol.MaxIncomingStreams)
|
||||||
icsl := bytes.NewBuffer([]byte{})
|
icsl := bytes.NewBuffer([]byte{})
|
||||||
utils.LittleEndian.WriteUint32(icsl, uint32(h.idleTimeout/time.Second))
|
utils.LittleEndian.WriteUint32(icsl, uint32(h.idleTimeout/time.Second))
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ var _ = Describe("Params Negotiator (for gQUIC)", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
entryMap, err := pn.GetHelloMap()
|
entryMap, err := pn.GetHelloMap()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(entryMap[TagMIDS]).To(Equal([]byte{byte(protocol.MaxIncomingDynamicStreamsPerConnection), 0, 0, 0}))
|
Expect(entryMap[TagMIDS]).To(Equal([]byte{byte(protocol.MaxIncomingStreams), 0, 0, 0}))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ var _ = Describe("Params Negotiator (for gQUIC)", func() {
|
|||||||
Expect(entryMap).To(HaveKey(TagICSL))
|
Expect(entryMap).To(HaveKey(TagICSL))
|
||||||
Expect(binary.LittleEndian.Uint32(entryMap[TagICSL])).To(BeEquivalentTo(idleTimeout / time.Second))
|
Expect(binary.LittleEndian.Uint32(entryMap[TagICSL])).To(BeEquivalentTo(idleTimeout / time.Second))
|
||||||
Expect(entryMap).To(HaveKey(TagMIDS))
|
Expect(entryMap).To(HaveKey(TagMIDS))
|
||||||
Expect(binary.LittleEndian.Uint32(entryMap[TagMIDS])).To(BeEquivalentTo(protocol.MaxIncomingDynamicStreamsPerConnection))
|
Expect(binary.LittleEndian.Uint32(entryMap[TagMIDS])).To(BeEquivalentTo(protocol.MaxIncomingStreams))
|
||||||
Expect(entryMap).To(HaveKey(TagSFCW))
|
Expect(entryMap).To(HaveKey(TagSFCW))
|
||||||
Expect(binary.LittleEndian.Uint32(entryMap[TagSFCW])).To(BeEquivalentTo(protocol.ReceiveStreamFlowControlWindow))
|
Expect(binary.LittleEndian.Uint32(entryMap[TagSFCW])).To(BeEquivalentTo(protocol.ReceiveStreamFlowControlWindow))
|
||||||
Expect(entryMap).To(HaveKey(TagCFCW))
|
Expect(entryMap).To(HaveKey(TagCFCW))
|
||||||
|
|||||||
@@ -56,11 +56,11 @@ const DefaultMaxReceiveConnectionFlowControlWindowClient = 15 * (1 << 20) // 15
|
|||||||
// This is the value that Chromium is using
|
// This is the value that Chromium is using
|
||||||
const ConnectionFlowControlMultiplier = 1.5
|
const ConnectionFlowControlMultiplier = 1.5
|
||||||
|
|
||||||
// MaxStreamsPerConnection is the maximum value accepted for the number of streams per connection
|
// MaxOutgoingStreams is the maximum number of streams that we will open to a peer
|
||||||
const MaxStreamsPerConnection = 100
|
const MaxOutgoingStreams = 100
|
||||||
|
|
||||||
// MaxIncomingDynamicStreamsPerConnection is the maximum value accepted for the incoming number of dynamic streams per connection
|
// MaxIncomingStreams is the maximum number of streams that a peer may open
|
||||||
const MaxIncomingDynamicStreamsPerConnection = 100
|
const MaxIncomingStreams = 100
|
||||||
|
|
||||||
// MaxStreamsMultiplier is the slack the client is allowed for the maximum number of streams per connection, needed e.g. when packets are out of order or dropped. The minimum of this procentual increase and the absolute increment specified by MaxStreamsMinimumIncrement is used.
|
// MaxStreamsMultiplier is the slack the client is allowed for the maximum number of streams per connection, needed e.g. when packets are out of order or dropped. The minimum of this procentual increase and the absolute increment specified by MaxStreamsMinimumIncrement is used.
|
||||||
const MaxStreamsMultiplier = 1.1
|
const MaxStreamsMultiplier = 1.1
|
||||||
@@ -70,7 +70,7 @@ const MaxStreamsMinimumIncrement = 10
|
|||||||
|
|
||||||
// MaxNewStreamIDDelta is the maximum difference between and a newly opened Stream and the highest StreamID that a client has ever opened
|
// MaxNewStreamIDDelta is the maximum difference between and a newly opened Stream and the highest StreamID that a client has ever opened
|
||||||
// note that the number of streams is half this value, since the client can only open streams with open StreamID
|
// note that the number of streams is half this value, since the client can only open streams with open StreamID
|
||||||
const MaxNewStreamIDDelta = 4 * MaxStreamsPerConnection
|
const MaxNewStreamIDDelta = 4 * MaxOutgoingStreams
|
||||||
|
|
||||||
// MaxSessionUnprocessedPackets is the max number of packets stored in each session that are not yet processed.
|
// MaxSessionUnprocessedPackets is the max number of packets stored in each session that are not yet processed.
|
||||||
const MaxSessionUnprocessedPackets = DefaultMaxCongestionWindow
|
const MaxSessionUnprocessedPackets = DefaultMaxCongestionWindow
|
||||||
|
|||||||
@@ -1563,7 +1563,7 @@ var _ = Describe("Session", func() {
|
|||||||
|
|
||||||
Context("counting streams", func() {
|
Context("counting streams", func() {
|
||||||
It("errors when too many streams are opened", func() {
|
It("errors when too many streams are opened", func() {
|
||||||
for i := 0; i < protocol.MaxStreamsPerConnection; i++ {
|
for i := 0; i < protocol.MaxIncomingStreams; i++ {
|
||||||
_, err := sess.GetOrOpenStream(protocol.StreamID(i*2 + 1))
|
_, err := sess.GetOrOpenStream(protocol.StreamID(i*2 + 1))
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ var errMapAccess = errors.New("streamsMap: Error accessing the streams map")
|
|||||||
|
|
||||||
func newStreamsMap(newStream newStreamLambda, removeStreamCallback removeStreamCallback, pers protocol.Perspective, connParams handshake.ParamsNegotiator) *streamsMap {
|
func newStreamsMap(newStream newStreamLambda, removeStreamCallback removeStreamCallback, pers protocol.Perspective, connParams handshake.ParamsNegotiator) *streamsMap {
|
||||||
// add some tolerance to the maximum incoming streams value
|
// add some tolerance to the maximum incoming streams value
|
||||||
maxStreams := uint32(protocol.MaxIncomingDynamicStreamsPerConnection)
|
maxStreams := uint32(protocol.MaxIncomingStreams)
|
||||||
maxIncomingStreams := utils.MaxUint32(
|
maxIncomingStreams := utils.MaxUint32(
|
||||||
maxStreams+protocol.MaxStreamsMinimumIncrement,
|
maxStreams+protocol.MaxStreamsMinimumIncrement,
|
||||||
uint32(float64(maxStreams)*float64(protocol.MaxStreamsMultiplier)),
|
uint32(float64(maxStreams)*float64(protocol.MaxStreamsMultiplier)),
|
||||||
|
|||||||
Reference in New Issue
Block a user