Mercurial > hg > nginx-quic
annotate src/http/v3/ngx_http_v3_tables.c @ 7870:e169cce912c7 quic
Avoid retransmitting of packets with discarded keys.
Sections 4.10.1 and 4.10.2 of quic transport describe discarding of initial
and handshake keys. Since the keys are discarded, we no longer need
to retransmit packets and corresponding queues should be emptied.
This patch removes previously added workaround that did not require
acknowledgement for initial packets, resulting in avoiding retransmission,
which is wrong because a packet could be lost and we have to retransmit it.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Mon, 18 May 2020 13:54:53 +0300 |
parents | f11b7981a03d |
children | 26cb2f3259b1 |
rev | line source |
---|---|
7681 | 1 |
2 /* | |
3 * Copyright (C) Roman Arutyunyan | |
4 * Copyright (C) Nginx, Inc. | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
13 static ngx_array_t *ngx_http_v3_get_dynamic_table(ngx_connection_t *c); | |
14 static ngx_int_t ngx_http_v3_new_header(ngx_connection_t *c); | |
15 | |
16 | |
17 static ngx_http_v3_header_t ngx_http_v3_static_table[] = { | |
18 | |
19 { ngx_string(":authority"), ngx_string("") }, | |
7762
f11b7981a03d
HTTP/3: static table cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7692
diff
changeset
|
20 { ngx_string(":path"), ngx_string("/") }, |
7681 | 21 { ngx_string("age"), ngx_string("0") }, |
22 { ngx_string("content-disposition"), ngx_string("") }, | |
23 { ngx_string("content-length"), ngx_string("0") }, | |
24 { ngx_string("cookie"), ngx_string("") }, | |
25 { ngx_string("date"), ngx_string("") }, | |
26 { ngx_string("etag"), ngx_string("") }, | |
27 { ngx_string("if-modified-since"), ngx_string("") }, | |
28 { ngx_string("if-none-match"), ngx_string("") }, | |
29 { ngx_string("last-modified"), ngx_string("") }, | |
30 { ngx_string("link"), ngx_string("") }, | |
31 { ngx_string("location"), ngx_string("") }, | |
32 { ngx_string("referer"), ngx_string("") }, | |
33 { ngx_string("set-cookie"), ngx_string("") }, | |
34 { ngx_string(":method"), ngx_string("CONNECT") }, | |
35 { ngx_string(":method"), ngx_string("DELETE") }, | |
36 { ngx_string(":method"), ngx_string("GET") }, | |
37 { ngx_string(":method"), ngx_string("HEAD") }, | |
38 { ngx_string(":method"), ngx_string("OPTIONS") }, | |
39 { ngx_string(":method"), ngx_string("POST") }, | |
40 { ngx_string(":method"), ngx_string("PUT") }, | |
41 { ngx_string(":scheme"), ngx_string("http") }, | |
42 { ngx_string(":scheme"), ngx_string("https") }, | |
43 { ngx_string(":status"), ngx_string("103") }, | |
44 { ngx_string(":status"), ngx_string("200") }, | |
45 { ngx_string(":status"), ngx_string("304") }, | |
46 { ngx_string(":status"), ngx_string("404") }, | |
47 { ngx_string(":status"), ngx_string("503") }, | |
48 { ngx_string("accept"), ngx_string("*/*") }, | |
49 { ngx_string("accept"), | |
7762
f11b7981a03d
HTTP/3: static table cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7692
diff
changeset
|
50 ngx_string("application/dns-message") }, |
f11b7981a03d
HTTP/3: static table cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7692
diff
changeset
|
51 { ngx_string("accept-encoding"), ngx_string("gzip, deflate, br") }, |
7681 | 52 { ngx_string("accept-ranges"), ngx_string("bytes") }, |
53 { ngx_string("access-control-allow-headers"), | |
54 ngx_string("cache-control") }, | |
55 { ngx_string("access-control-allow-headers"), | |
56 ngx_string("content-type") }, | |
57 { ngx_string("access-control-allow-origin"), | |
58 ngx_string("*") }, | |
59 { ngx_string("cache-control"), ngx_string("max-age=0") }, | |
60 { ngx_string("cache-control"), ngx_string("max-age=2592000") }, | |
61 { ngx_string("cache-control"), ngx_string("max-age=604800") }, | |
62 { ngx_string("cache-control"), ngx_string("no-cache") }, | |
63 { ngx_string("cache-control"), ngx_string("no-store") }, | |
64 { ngx_string("cache-control"), | |
7762
f11b7981a03d
HTTP/3: static table cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7692
diff
changeset
|
65 ngx_string("public, max-age=31536000") }, |
7681 | 66 { ngx_string("content-encoding"), ngx_string("br") }, |
67 { ngx_string("content-encoding"), ngx_string("gzip") }, | |
68 { ngx_string("content-type"), | |
69 ngx_string("application/dns-message") }, | |
70 { ngx_string("content-type"), | |
71 ngx_string("application/javascript") }, | |
72 { ngx_string("content-type"), ngx_string("application/json") }, | |
73 { ngx_string("content-type"), | |
74 ngx_string("application/x-www-form-urlencoded") }, | |
75 { ngx_string("content-type"), ngx_string("image/gif") }, | |
76 { ngx_string("content-type"), ngx_string("image/jpeg") }, | |
77 { ngx_string("content-type"), ngx_string("image/png") }, | |
78 { ngx_string("content-type"), ngx_string("text/css") }, | |
79 { ngx_string("content-type"), | |
80 ngx_string("text/html;charset=utf-8") }, | |
81 { ngx_string("content-type"), ngx_string("text/plain") }, | |
82 { ngx_string("content-type"), | |
83 ngx_string("text/plain;charset=utf-8") }, | |
84 { ngx_string("range"), ngx_string("bytes=0-") }, | |
85 { ngx_string("strict-transport-security"), | |
86 ngx_string("max-age=31536000") }, | |
87 { ngx_string("strict-transport-security"), | |
88 ngx_string("max-age=31536000;includesubdomains") }, | |
89 { ngx_string("strict-transport-security"), | |
90 ngx_string("max-age=31536000;includesubdomains;preload") }, | |
91 { ngx_string("vary"), ngx_string("accept-encoding") }, | |
92 { ngx_string("vary"), ngx_string("origin") }, | |
7762
f11b7981a03d
HTTP/3: static table cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7692
diff
changeset
|
93 { ngx_string("x-content-type-options"), |
f11b7981a03d
HTTP/3: static table cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7692
diff
changeset
|
94 ngx_string("nosniff") }, |
7681 | 95 { ngx_string("x-xss-protection"), ngx_string("1;mode=block") }, |
96 { ngx_string(":status"), ngx_string("100") }, | |
97 { ngx_string(":status"), ngx_string("204") }, | |
98 { ngx_string(":status"), ngx_string("206") }, | |
99 { ngx_string(":status"), ngx_string("302") }, | |
100 { ngx_string(":status"), ngx_string("400") }, | |
101 { ngx_string(":status"), ngx_string("403") }, | |
102 { ngx_string(":status"), ngx_string("421") }, | |
103 { ngx_string(":status"), ngx_string("425") }, | |
104 { ngx_string(":status"), ngx_string("500") }, | |
105 { ngx_string("accept-language"), ngx_string("") }, | |
106 { ngx_string("access-control-allow-credentials"), | |
107 ngx_string("FALSE") }, | |
108 { ngx_string("access-control-allow-credentials"), | |
109 ngx_string("TRUE") }, | |
110 { ngx_string("access-control-allow-headers"), | |
111 ngx_string("*") }, | |
112 { ngx_string("access-control-allow-methods"), | |
113 ngx_string("get") }, | |
114 { ngx_string("access-control-allow-methods"), | |
115 ngx_string("get, post, options") }, | |
116 { ngx_string("access-control-allow-methods"), | |
117 ngx_string("options") }, | |
118 { ngx_string("access-control-expose-headers"), | |
119 ngx_string("content-length") }, | |
120 { ngx_string("access-control-request-headers"), | |
121 ngx_string("content-type") }, | |
122 { ngx_string("access-control-request-method"), | |
123 ngx_string("get") }, | |
124 { ngx_string("access-control-request-method"), | |
125 ngx_string("post") }, | |
126 { ngx_string("alt-svc"), ngx_string("clear") }, | |
7762
f11b7981a03d
HTTP/3: static table cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7692
diff
changeset
|
127 { ngx_string("authorization"), ngx_string("") }, |
7681 | 128 { ngx_string("content-security-policy"), |
7762
f11b7981a03d
HTTP/3: static table cleanup.
Sergey Kandaurov <pluknet@nginx.com>
parents:
7692
diff
changeset
|
129 ngx_string("script-src 'none';object-src 'none';base-uri 'none'") }, |
7681 | 130 { ngx_string("early-data"), ngx_string("1") }, |
131 { ngx_string("expect-ct"), ngx_string("") }, | |
132 { ngx_string("forwarded"), ngx_string("") }, | |
133 { ngx_string("if-range"), ngx_string("") }, | |
134 { ngx_string("origin"), ngx_string("") }, | |
135 { ngx_string("purpose"), ngx_string("prefetch") }, | |
136 { ngx_string("server"), ngx_string("") }, | |
137 { ngx_string("timing-allow-origin"), ngx_string("*") }, | |
138 { ngx_string("upgrade-insecure-requests"), | |
139 ngx_string("1") }, | |
140 { ngx_string("user-agent"), ngx_string("") }, | |
141 { ngx_string("x-forwarded-for"), ngx_string("") }, | |
142 { ngx_string("x-frame-options"), ngx_string("deny") }, | |
143 { ngx_string("x-frame-options"), ngx_string("sameorigin") } | |
144 }; | |
145 | |
146 | |
147 ngx_int_t | |
148 ngx_http_v3_ref_insert(ngx_connection_t *c, ngx_uint_t dynamic, | |
149 ngx_uint_t index, ngx_str_t *value) | |
150 { | |
151 ngx_array_t *dt; | |
152 ngx_http_v3_header_t *ref, *h; | |
153 | |
154 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
155 "http3 ref insert %s[$ui] \"%V\"", | |
156 dynamic ? "dynamic" : "static", index, value); | |
157 | |
158 ref = ngx_http_v3_lookup_table(c, dynamic, index); | |
159 if (ref == NULL) { | |
160 return NGX_ERROR; | |
161 } | |
162 | |
163 dt = ngx_http_v3_get_dynamic_table(c); | |
164 if (dt == NULL) { | |
165 return NGX_ERROR; | |
166 } | |
167 | |
168 h = ngx_array_push(dt); | |
169 if (h == NULL) { | |
170 return NGX_ERROR; | |
171 } | |
172 | |
173 h->name = ref->name; | |
174 h->value = *value; | |
175 | |
176 if (ngx_http_v3_new_header(c) != NGX_OK) { | |
177 return NGX_ERROR; | |
178 } | |
179 | |
180 return NGX_OK; | |
181 } | |
182 | |
183 | |
184 ngx_int_t | |
185 ngx_http_v3_insert(ngx_connection_t *c, ngx_str_t *name, | |
186 ngx_str_t *value) | |
187 { | |
188 ngx_array_t *dt; | |
189 ngx_http_v3_header_t *h; | |
190 | |
191 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
192 "http3 insert \"%V\":\"%V\"", name, value); | |
193 | |
194 dt = ngx_http_v3_get_dynamic_table(c); | |
195 if (dt == NULL) { | |
196 return NGX_ERROR; | |
197 } | |
198 | |
199 h = ngx_array_push(dt); | |
200 if (h == NULL) { | |
201 return NGX_ERROR; | |
202 } | |
203 | |
204 h->name = *name; | |
205 h->value = *value; | |
206 | |
207 if (ngx_http_v3_new_header(c) != NGX_OK) { | |
208 return NGX_ERROR; | |
209 } | |
210 | |
211 return NGX_OK; | |
212 } | |
213 | |
214 | |
215 ngx_int_t | |
216 ngx_http_v3_set_capacity(ngx_connection_t *c, ngx_uint_t capacity) | |
217 { | |
218 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
219 "http3 set capacity %ui", capacity); | |
220 | |
221 /* XXX ignore capacity */ | |
222 | |
223 return NGX_OK; | |
224 } | |
225 | |
226 | |
227 ngx_int_t | |
228 ngx_http_v3_duplicate(ngx_connection_t *c, ngx_uint_t index) | |
229 { | |
230 ngx_array_t *dt; | |
231 ngx_http_v3_header_t *ref, *h; | |
232 | |
233 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 duplicate %ui", index); | |
234 | |
235 ref = ngx_http_v3_lookup_table(c, 1, index); | |
236 if (ref == NULL) { | |
237 return NGX_ERROR; | |
238 } | |
239 | |
240 dt = ngx_http_v3_get_dynamic_table(c); | |
241 if (dt == NULL) { | |
242 return NGX_ERROR; | |
243 } | |
244 | |
245 h = ngx_array_push(dt); | |
246 if (h == NULL) { | |
247 return NGX_ERROR; | |
248 } | |
249 | |
250 *h = *ref; | |
251 | |
252 if (ngx_http_v3_new_header(c) != NGX_OK) { | |
253 return NGX_ERROR; | |
254 } | |
255 | |
256 return NGX_OK; | |
257 } | |
258 | |
259 | |
260 ngx_int_t | |
261 ngx_http_v3_ack_header(ngx_connection_t *c, ngx_uint_t stream_id) | |
262 { | |
263 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
264 "http3 ack header %ui", stream_id); | |
265 | |
266 /* XXX */ | |
267 | |
268 return NGX_OK; | |
269 } | |
270 | |
271 | |
272 ngx_int_t | |
273 ngx_http_v3_cancel_stream(ngx_connection_t *c, ngx_uint_t stream_id) | |
274 { | |
275 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
276 "http3 cancel stream %ui", stream_id); | |
277 | |
278 /* XXX */ | |
279 | |
280 return NGX_OK; | |
281 } | |
282 | |
283 | |
284 ngx_int_t | |
285 ngx_http_v3_inc_insert_count(ngx_connection_t *c, ngx_uint_t inc) | |
286 { | |
287 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
288 "http3 increment insert count %ui", inc); | |
289 | |
290 /* XXX */ | |
291 | |
292 return NGX_OK; | |
293 } | |
294 | |
295 | |
296 static ngx_array_t * | |
297 ngx_http_v3_get_dynamic_table(ngx_connection_t *c) | |
298 { | |
299 ngx_connection_t *pc; | |
300 ngx_http_v3_connection_t *h3c; | |
301 | |
302 pc = c->qs->parent; | |
303 h3c = pc->data; | |
304 | |
305 if (h3c->dynamic) { | |
306 return h3c->dynamic; | |
307 } | |
308 | |
309 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 create dynamic table"); | |
310 | |
311 h3c->dynamic = ngx_array_create(pc->pool, 1, sizeof(ngx_http_v3_header_t)); | |
312 | |
313 return h3c->dynamic; | |
314 } | |
315 | |
316 | |
317 ngx_http_v3_header_t * | |
318 ngx_http_v3_lookup_table(ngx_connection_t *c, ngx_uint_t dynamic, | |
319 ngx_uint_t index) | |
320 { | |
321 ngx_uint_t nelts; | |
322 ngx_array_t *dt; | |
323 ngx_http_v3_header_t *table; | |
324 | |
325 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 lookup %s[%ui]", | |
326 dynamic ? "dynamic" : "static", index); | |
327 | |
328 if (dynamic) { | |
329 dt = ngx_http_v3_get_dynamic_table(c); | |
330 if (dt == NULL) { | |
331 return NULL; | |
332 } | |
333 | |
334 table = dt->elts; | |
335 nelts = dt->nelts; | |
336 | |
337 } else { | |
338 table = ngx_http_v3_static_table; | |
339 nelts = sizeof(ngx_http_v3_static_table) | |
340 / sizeof(ngx_http_v3_static_table[0]); | |
341 } | |
342 | |
343 if (index >= nelts) { | |
344 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
345 "http3 lookup out of bounds: %ui", nelts); | |
346 return NULL; | |
347 } | |
348 | |
349 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 lookup \"%V\":\"%V\"", | |
350 &table[index].name, &table[index].value); | |
351 | |
352 return &table[index]; | |
353 } | |
354 | |
355 | |
356 ngx_int_t | |
357 ngx_http_v3_check_insert_count(ngx_connection_t *c, ngx_uint_t insert_count) | |
358 { | |
359 size_t n; | |
360 ngx_http_v3_connection_t *h3c; | |
361 | |
362 h3c = c->qs->parent->data; | |
363 n = h3c->dynamic ? h3c->dynamic->nelts : 0; | |
364 | |
365 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
366 "http3 check insert count %ui/%ui", insert_count, n); | |
367 | |
368 if (n < insert_count) { | |
369 /* XXX how to get notified? */ | |
370 /* XXX wake all streams on any arrival to the encoder stream? */ | |
371 return NGX_AGAIN; | |
372 } | |
373 | |
374 return NGX_OK; | |
375 } | |
376 | |
377 | |
378 static ngx_int_t | |
379 ngx_http_v3_new_header(ngx_connection_t *c) | |
380 { | |
381 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 new dynamic header"); | |
382 | |
383 /* XXX report all waiting streams of a new header */ | |
384 | |
385 return NGX_OK; | |
386 } | |
7692
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
387 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
388 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
389 ngx_int_t |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
390 ngx_http_v3_set_param(ngx_connection_t *c, uint64_t id, uint64_t value) |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
391 { |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
392 switch (id) { |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
393 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
394 case NGX_HTTP_V3_PARAM_MAX_TABLE_CAPACITY: |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
395 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
396 "http3 param QPACK_MAX_TABLE_CAPACITY:%uL", value); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
397 break; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
398 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
399 case NGX_HTTP_V3_PARAM_MAX_HEADER_LIST_SIZE: |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
400 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
401 "http3 param SETTINGS_MAX_HEADER_LIST_SIZE:%uL", value); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
402 break; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
403 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
404 case NGX_HTTP_V3_PARAM_BLOCKED_STREAMS: |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
405 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
406 "http3 param QPACK_BLOCKED_STREAMS:%uL", value); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
407 break; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
408 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
409 default: |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
410 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
411 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
412 "http3 param #%uL:%uL", id, value); |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
413 } |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
414 |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
415 return NGX_OK; |
268f4389130d
Refactored HTTP/3 parser.
Roman Arutyunyan <arut@nginx.com>
parents:
7681
diff
changeset
|
416 } |