simplify the maximum stream limit

This commit is contained in:
Marten Seemann
2017-10-15 09:46:09 +08:00
parent daff6256b9
commit f5acb690d3
7 changed files with 25 additions and 29 deletions

View File

@@ -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),

View File

@@ -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) {

View File

@@ -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))

View File

@@ -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))

View File

@@ -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

View File

@@ -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())
} }

View File

@@ -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)),