1
2
3
4
5
6
7 package quic
8
9 import (
10 "context"
11 "crypto/tls"
12 "testing"
13 )
14
15 func TestStreamLimitNewStreamBlocked(t *testing.T) {
16
17
18
19 testStreamTypes(t, "", func(t *testing.T, styp streamType) {
20 ctx := canceledContext()
21 tc := newTestConn(t, clientSide,
22 permissiveTransportParameters,
23 func(p *transportParameters) {
24 p.initialMaxStreamsBidi = 0
25 p.initialMaxStreamsUni = 0
26 })
27 tc.handshake()
28 tc.ignoreFrame(frameTypeAck)
29 opening := runAsync(tc, func(ctx context.Context) (*Stream, error) {
30 return tc.conn.newLocalStream(ctx, styp)
31 })
32 if _, err := opening.result(); err != errNotDone {
33 t.Fatalf("new stream blocked by limit: %v, want errNotDone", err)
34 }
35 tc.writeFrames(packetType1RTT, debugFrameMaxStreams{
36 streamType: styp,
37 max: 1,
38 })
39 if _, err := opening.result(); err != nil {
40 t.Fatalf("new stream not created after limit raised: %v", err)
41 }
42 if _, err := tc.conn.newLocalStream(ctx, styp); err == nil {
43 t.Fatalf("new stream blocked by raised limit: %v, want error", err)
44 }
45 })
46 }
47
48 func TestStreamLimitMaxStreamsDecreases(t *testing.T) {
49
50
51 testStreamTypes(t, "", func(t *testing.T, styp streamType) {
52 ctx := canceledContext()
53 tc := newTestConn(t, clientSide,
54 permissiveTransportParameters,
55 func(p *transportParameters) {
56 p.initialMaxStreamsBidi = 0
57 p.initialMaxStreamsUni = 0
58 })
59 tc.handshake()
60 tc.ignoreFrame(frameTypeAck)
61 tc.writeFrames(packetType1RTT, debugFrameMaxStreams{
62 streamType: styp,
63 max: 2,
64 })
65 tc.writeFrames(packetType1RTT, debugFrameMaxStreams{
66 streamType: styp,
67 max: 1,
68 })
69 if _, err := tc.conn.newLocalStream(ctx, styp); err != nil {
70 t.Fatalf("open stream 1, limit 2, got error: %v", err)
71 }
72 if _, err := tc.conn.newLocalStream(ctx, styp); err != nil {
73 t.Fatalf("open stream 2, limit 2, got error: %v", err)
74 }
75 if _, err := tc.conn.newLocalStream(ctx, styp); err == nil {
76 t.Fatalf("open stream 3, limit 2, got error: %v", err)
77 }
78 })
79 }
80
81 func TestStreamLimitViolated(t *testing.T) {
82 testStreamTypes(t, "", func(t *testing.T, styp streamType) {
83 tc := newTestConn(t, serverSide,
84 func(c *Config) {
85 if styp == bidiStream {
86 c.MaxBidiRemoteStreams = 10
87 } else {
88 c.MaxUniRemoteStreams = 10
89 }
90 })
91 tc.handshake()
92 tc.ignoreFrame(frameTypeAck)
93 tc.writeFrames(packetType1RTT, debugFrameStream{
94 id: newStreamID(clientSide, styp, 9),
95 })
96 tc.wantIdle("stream number 9 is within the limit")
97 tc.writeFrames(packetType1RTT, debugFrameStream{
98 id: newStreamID(clientSide, styp, 10),
99 })
100 tc.wantFrame("stream number 10 is beyond the limit",
101 packetType1RTT, debugFrameConnectionCloseTransport{
102 code: errStreamLimit,
103 },
104 )
105 })
106 }
107
108 func TestStreamLimitImplicitStreams(t *testing.T) {
109 testStreamTypes(t, "", func(t *testing.T, styp streamType) {
110 tc := newTestConn(t, serverSide,
111 func(c *Config) {
112 c.MaxBidiRemoteStreams = 1 << 60
113 c.MaxUniRemoteStreams = 1 << 60
114 })
115 tc.handshake()
116 tc.ignoreFrame(frameTypeAck)
117 if got, want := tc.sentTransportParameters.initialMaxStreamsBidi, int64(implicitStreamLimit); got != want {
118 t.Errorf("sent initial_max_streams_bidi = %v, want %v", got, want)
119 }
120 if got, want := tc.sentTransportParameters.initialMaxStreamsUni, int64(implicitStreamLimit); got != want {
121 t.Errorf("sent initial_max_streams_uni = %v, want %v", got, want)
122 }
123
124
125 tc.writeFrames(packetType1RTT, debugFrameStream{
126 id: newStreamID(clientSide, styp, 0),
127 })
128 tc.wantIdle("max streams not increased enough to send a new frame")
129
130
131 tc.writeFrames(packetType1RTT, debugFrameStream{
132 id: newStreamID(clientSide, styp, implicitStreamLimit-1),
133 })
134 tc.wantFrame("max streams increases to implicit stream limit",
135 packetType1RTT, debugFrameMaxStreams{
136 streamType: styp,
137 max: 2 * implicitStreamLimit,
138 })
139
140
141 tc.writeFrames(packetType1RTT, debugFrameStream{
142 id: newStreamID(clientSide, styp, 2*implicitStreamLimit),
143 })
144 tc.wantFrame("stream is past the limit",
145 packetType1RTT, debugFrameConnectionCloseTransport{
146 code: errStreamLimit,
147 },
148 )
149 })
150 }
151
152 func TestStreamLimitMaxStreamsTransportParameterTooLarge(t *testing.T) {
153
154
155
156
157 testStreamTypes(t, "", func(t *testing.T, styp streamType) {
158 tc := newTestConn(t, serverSide,
159 func(p *transportParameters) {
160 if styp == bidiStream {
161 p.initialMaxStreamsBidi = 1<<60 + 1
162 } else {
163 p.initialMaxStreamsUni = 1<<60 + 1
164 }
165 })
166 tc.writeFrames(packetTypeInitial, debugFrameCrypto{
167 data: tc.cryptoDataIn[tls.QUICEncryptionLevelInitial],
168 })
169 tc.wantFrame("max streams transport parameter is too large",
170 packetTypeInitial, debugFrameConnectionCloseTransport{
171 code: errTransportParameter,
172 },
173 )
174 })
175 }
176
177 func TestStreamLimitMaxStreamsFrameTooLarge(t *testing.T) {
178
179
180
181
182 testStreamTypes(t, "", func(t *testing.T, styp streamType) {
183 tc := newTestConn(t, serverSide)
184 tc.handshake()
185 tc.writeFrames(packetTypeInitial,
186 debugFrameCrypto{
187 data: tc.cryptoDataIn[tls.QUICEncryptionLevelInitial],
188 })
189 tc.writeFrames(packetType1RTT, debugFrameMaxStreams{
190 streamType: styp,
191 max: 1<<60 + 1,
192 })
193 tc.wantFrame("MAX_STREAMS value is too large",
194 packetType1RTT, debugFrameConnectionCloseTransport{
195 code: errFrameEncoding,
196 },
197 )
198 })
199 }
200
201 func TestStreamLimitSendUpdatesMaxStreams(t *testing.T) {
202 testStreamTypes(t, "", func(t *testing.T, styp streamType) {
203 ctx := canceledContext()
204 tc := newTestConn(t, serverSide, func(c *Config) {
205 if styp == uniStream {
206 c.MaxUniRemoteStreams = 4
207 c.MaxBidiRemoteStreams = 0
208 } else {
209 c.MaxUniRemoteStreams = 0
210 c.MaxBidiRemoteStreams = 4
211 }
212 })
213 tc.handshake()
214 tc.ignoreFrame(frameTypeAck)
215 var streams []*Stream
216 for i := 0; i < 4; i++ {
217 tc.writeFrames(packetType1RTT, debugFrameStream{
218 id: newStreamID(clientSide, styp, int64(i)),
219 fin: true,
220 })
221 s, err := tc.conn.AcceptStream(ctx)
222 if err != nil {
223 t.Fatalf("AcceptStream = %v", err)
224 }
225 streams = append(streams, s)
226 }
227 streams[3].CloseContext(ctx)
228 if styp == bidiStream {
229 tc.wantFrame("stream is closed",
230 packetType1RTT, debugFrameStream{
231 id: streams[3].id,
232 fin: true,
233 data: []byte{},
234 })
235 tc.writeAckForAll()
236 }
237 tc.wantFrame("closing a stream when peer is at limit immediately extends the limit",
238 packetType1RTT, debugFrameMaxStreams{
239 streamType: styp,
240 max: 5,
241 })
242 })
243 }
244
245 func TestStreamLimitStopSendingDoesNotUpdateMaxStreams(t *testing.T) {
246 tc, s := newTestConnAndRemoteStream(t, serverSide, bidiStream, func(c *Config) {
247 c.MaxBidiRemoteStreams = 1
248 })
249 tc.writeFrames(packetType1RTT, debugFrameStream{
250 id: s.id,
251 fin: true,
252 })
253 s.CloseRead()
254 tc.writeFrames(packetType1RTT, debugFrameStopSending{
255 id: s.id,
256 })
257 tc.wantFrame("recieved STOP_SENDING, send RESET_STREAM",
258 packetType1RTT, debugFrameResetStream{
259 id: s.id,
260 })
261 tc.writeAckForAll()
262 tc.wantIdle("MAX_STREAMS is not extended until the user fully closes the stream")
263 s.CloseWrite()
264 tc.wantFrame("user closing the stream triggers MAX_STREAMS update",
265 packetType1RTT, debugFrameMaxStreams{
266 streamType: bidiStream,
267 max: 2,
268 })
269 }
270
View as plain text