comparison src/http/v3/ngx_http_v3_streams.c @ 8226:268f4389130d quic

Refactored HTTP/3 parser.
author Roman Arutyunyan <arut@nginx.com>
date Wed, 18 Mar 2020 13:46:35 +0300
parents 38c0898b6df7
children ac41c53e446d
comparison
equal deleted inserted replaced
8225:714a19dba6af 8226:268f4389130d
8 #include <ngx_config.h> 8 #include <ngx_config.h>
9 #include <ngx_core.h> 9 #include <ngx_core.h>
10 #include <ngx_http.h> 10 #include <ngx_http.h>
11 11
12 12
13 #define NGX_HTTP_V3_CONTROL_STREAM 0x00 13 typedef ngx_int_t (*ngx_http_v3_handler_pt)(ngx_connection_t *c, void *data,
14 #define NGX_HTTP_V3_PUSH_STREAM 0x01 14 u_char ch);
15 #define NGX_HTTP_V3_ENCODER_STREAM 0x02
16 #define NGX_HTTP_V3_DECODER_STREAM 0x03
17 15
18 16
19 typedef struct { 17 typedef struct {
20 uint32_t signature; /* QSTR */ 18 uint32_t signature; /* QSTR */
21 u_char buf[4]; 19
22 20 ngx_http_v3_handler_pt handler;
23 ngx_uint_t len; 21 void *data;
24 ngx_uint_t type; 22
25 ngx_uint_t state; 23 ngx_uint_t type;
26 ngx_uint_t index; 24 ngx_uint_t client; /* unsigned client:1; */
27 ngx_uint_t offset;
28
29 ngx_str_t name;
30 ngx_str_t value;
31
32 unsigned client:1;
33 unsigned dynamic:1;
34 unsigned huffman:1;
35 } ngx_http_v3_uni_stream_t; 25 } ngx_http_v3_uni_stream_t;
36 26
37 27
38 static void ngx_http_v3_close_uni_stream(ngx_connection_t *c); 28 static void ngx_http_v3_close_uni_stream(ngx_connection_t *c);
39 static void ngx_http_v3_uni_stream_cleanup(void *data); 29 static void ngx_http_v3_uni_stream_cleanup(void *data);
40 static void ngx_http_v3_read_uni_stream_type(ngx_event_t *rev); 30 static void ngx_http_v3_read_uni_stream_type(ngx_event_t *rev);
41 static void ngx_http_v3_dummy_stream_handler(ngx_event_t *rev); 31 static void ngx_http_v3_uni_read_handler(ngx_event_t *rev);
42 static void ngx_http_v3_client_encoder_handler(ngx_event_t *rev);
43 static void ngx_http_v3_client_decoder_handler(ngx_event_t *rev);
44
45 static ngx_connection_t *ngx_http_v3_create_uni_stream(ngx_connection_t *c, 32 static ngx_connection_t *ngx_http_v3_create_uni_stream(ngx_connection_t *c,
46 ngx_uint_t type); 33 ngx_uint_t type);
47 static ngx_connection_t *ngx_http_v3_get_server_encoder(ngx_connection_t *c); 34 static ngx_connection_t *ngx_http_v3_get_control(ngx_connection_t *c);
48 static ngx_connection_t *ngx_http_v3_get_server_decoder(ngx_connection_t *c); 35 static ngx_connection_t *ngx_http_v3_get_encoder(ngx_connection_t *c);
36 static ngx_connection_t *ngx_http_v3_get_decoder(ngx_connection_t *c);
49 37
50 38
51 void 39 void
52 ngx_http_v3_handle_client_uni_stream(ngx_connection_t *c) 40 ngx_http_v3_handle_client_uni_stream(ngx_connection_t *c)
53 { 41 {
54 ngx_pool_cleanup_t *cln; 42 ngx_pool_cleanup_t *cln;
55 ngx_http_v3_uni_stream_t *us; 43 ngx_http_v3_uni_stream_t *us;
56 44
57 c->log->connection = c->number; 45 c->log->connection = c->number;
58 46
47 /* XXX */
48 (void) ngx_http_v3_get_control(c);
49 (void) ngx_http_v3_get_encoder(c);
50 (void) ngx_http_v3_get_decoder(c);
51
59 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, 52 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
60 "http3 new uni stream id:0x%uXL", c->qs->id); 53 "http3 new uni stream id:0x%uxL", c->qs->id);
61 54
62 us = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_uni_stream_t)); 55 us = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_uni_stream_t));
63 if (us == NULL) { 56 if (us == NULL) {
64 ngx_http_v3_close_uni_stream(c); 57 ngx_http_v3_close_uni_stream(c);
65 return; 58 return;
79 72
80 cln->handler = ngx_http_v3_uni_stream_cleanup; 73 cln->handler = ngx_http_v3_uni_stream_cleanup;
81 cln->data = c; 74 cln->data = c;
82 75
83 c->read->handler = ngx_http_v3_read_uni_stream_type; 76 c->read->handler = ngx_http_v3_read_uni_stream_type;
84 c->read->handler(c->read); 77 ngx_http_v3_read_uni_stream_type(c->read);
85 } 78 }
86 79
87 80
88 static void 81 static void
89 ngx_http_v3_close_uni_stream(ngx_connection_t *c) 82 ngx_http_v3_close_uni_stream(ngx_connection_t *c)
113 106
114 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 close stream"); 107 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 close stream");
115 108
116 switch (us->type) { 109 switch (us->type) {
117 110
118 case NGX_HTTP_V3_ENCODER_STREAM: 111 case NGX_HTTP_V3_STREAM_ENCODER:
119 112
120 if (us->client) { 113 if (us->client) {
121 h3c->client_encoder = NULL; 114 h3c->client_encoder = NULL;
122 } else { 115 } else {
123 h3c->server_encoder = NULL; 116 h3c->server_encoder = NULL;
124 } 117 }
125 118
126 break; 119 break;
127 120
128 case NGX_HTTP_V3_DECODER_STREAM: 121 case NGX_HTTP_V3_STREAM_DECODER:
129 122
130 if (us->client) { 123 if (us->client) {
131 h3c->client_decoder = NULL; 124 h3c->client_decoder = NULL;
132 } else { 125 } else {
133 h3c->server_decoder = NULL; 126 h3c->server_decoder = NULL;
134 } 127 }
135 128
136 break; 129 break;
130
131 case NGX_HTTP_V3_STREAM_CONTROL:
132
133 if (us->client) {
134 h3c->client_control = NULL;
135 } else {
136 h3c->server_control = NULL;
137 }
138
139 break;
137 } 140 }
138 } 141 }
139 142
140 143
141 static void 144 static void
142 ngx_http_v3_read_uni_stream_type(ngx_event_t *rev) 145 ngx_http_v3_read_uni_stream_type(ngx_event_t *rev)
143 { 146 {
144 u_char *p; 147 u_char ch;
145 ssize_t n, len; 148 ssize_t n;
146 ngx_connection_t *c; 149 ngx_connection_t *c;
147 ngx_http_v3_connection_t *h3c; 150 ngx_http_v3_connection_t *h3c;
148 ngx_http_v3_uni_stream_t *us; 151 ngx_http_v3_uni_stream_t *st;
149 152
150 c = rev->data; 153 c = rev->data;
151 us = c->data; 154 st = c->data;
152 h3c = c->qs->parent->data; 155 h3c = c->qs->parent->data;
153 156
154 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read stream type"); 157 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read stream type");
155 158
156 while (rev->ready) { 159 while (rev->ready) {
157 160
158 p = &us->buf[us->len]; 161 n = c->recv(c, &ch, 1);
159
160 if (us->len == 0) {
161 len = 1;
162 } else {
163 len = (us->buf[0] >> 6) + 1 - us->len;
164 }
165
166 n = c->recv(c, p, len);
167 162
168 if (n == NGX_ERROR) { 163 if (n == NGX_ERROR) {
169 goto failed; 164 goto failed;
170 } 165 }
171 166
167 if (n == NGX_AGAIN || n != 1) {
168 break;
169 }
170
171 st->type = ch;
172
173 switch (st->type) {
174
175 case NGX_HTTP_V3_STREAM_ENCODER:
176
177 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
178 "http3 encoder stream");
179
180 if (h3c->client_encoder) {
181 goto failed;
182 }
183
184 h3c->client_encoder = c;
185 st->handler = ngx_http_v3_parse_encoder;
186 n = sizeof(ngx_http_v3_parse_encoder_t);
187
188 break;
189
190 case NGX_HTTP_V3_STREAM_DECODER:
191
192 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
193 "http3 decoder stream");
194
195 if (h3c->client_decoder) {
196 goto failed;
197 }
198
199 h3c->client_decoder = c;
200 st->handler = ngx_http_v3_parse_decoder;
201 n = sizeof(ngx_http_v3_parse_decoder_t);
202
203 break;
204
205 case NGX_HTTP_V3_STREAM_CONTROL:
206
207 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
208 "http3 control stream");
209
210 if (h3c->client_control) {
211 goto failed;
212 }
213
214 h3c->client_control = c;
215 st->handler = ngx_http_v3_parse_control;
216 n = sizeof(ngx_http_v3_parse_control_t);
217
218 break;
219
220 default:
221
222 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
223 "http3 stream 0x%02xi", st->type);
224 n = 0;
225 }
226
227 if (n) {
228 st->data = ngx_pcalloc(c->pool, n);
229 if (st->data == NULL) {
230 goto failed;
231 }
232 }
233
234 rev->handler = ngx_http_v3_uni_read_handler;
235 ngx_http_v3_uni_read_handler(rev);
236 return;
237 }
238
239 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
240 goto failed;
241 }
242
243 return;
244
245 failed:
246
247 ngx_http_v3_close_uni_stream(c);
248 }
249
250
251 static void
252 ngx_http_v3_uni_read_handler(ngx_event_t *rev)
253 {
254 u_char buf[128];
255 ssize_t n;
256 ngx_int_t rc, i;
257 ngx_connection_t *c;
258 ngx_http_v3_uni_stream_t *st;
259
260 c = rev->data;
261 st = c->data;
262
263 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read handler");
264
265 while (rev->ready) {
266
267 n = c->recv(c, buf, sizeof(buf));
268
269 if (n == NGX_ERROR || n == 0) {
270 goto failed;
271 }
272
172 if (n == NGX_AGAIN) { 273 if (n == NGX_AGAIN) {
173 break; 274 break;
174 } 275 }
175 276
176 us->len += n; 277 if (st->handler == NULL) {
177 278 continue;
178 if (n != len) { 279 }
179 break; 280
180 } 281 for (i = 0; i < n; i++) {
181 282
182 if ((us->buf[0] >> 6) + 1 == us->len) { 283 rc = st->handler(c, st->data, buf[i]);
183 us->type = ngx_http_v3_decode_varlen_int(us->buf); 284
184 285 if (rc == NGX_ERROR) {
185 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
186 "http3 stream type:%ui", us->type);
187
188 switch (us->type) {
189
190 case NGX_HTTP_V3_ENCODER_STREAM:
191 if (h3c->client_encoder) {
192 goto failed;
193 }
194
195 h3c->client_encoder = c;
196 rev->handler = ngx_http_v3_client_encoder_handler;
197 break;
198
199 case NGX_HTTP_V3_DECODER_STREAM:
200 if (h3c->client_decoder) {
201 goto failed;
202 }
203
204 h3c->client_decoder = c;
205 rev->handler = ngx_http_v3_client_decoder_handler;
206 break;
207
208 case NGX_HTTP_V3_CONTROL_STREAM:
209 case NGX_HTTP_V3_PUSH_STREAM:
210
211 /* ignore these */
212
213 default:
214 rev->handler = ngx_http_v3_dummy_stream_handler;
215 }
216
217 rev->handler(rev);
218 return;
219 }
220 }
221
222 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
223 goto failed;
224 }
225
226 return;
227
228 failed:
229
230 ngx_http_v3_close_uni_stream(c);
231 }
232
233
234 static void
235 ngx_http_v3_dummy_stream_handler(ngx_event_t *rev)
236 {
237 u_char buf[128];
238 ngx_connection_t *c;
239
240 /* read out and ignore */
241
242 c = rev->data;
243
244 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 dummy stream reader");
245
246 while (rev->ready) {
247 if (c->recv(c, buf, sizeof(buf)) == NGX_ERROR) {
248 goto failed;
249 }
250 }
251
252 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
253 goto failed;
254 }
255
256 return;
257
258 failed:
259
260 ngx_http_v3_close_uni_stream(c);
261 }
262
263
264 static void
265 ngx_http_v3_client_encoder_handler(ngx_event_t *rev)
266 {
267 u_char v;
268 ssize_t n;
269 ngx_str_t name, value;
270 ngx_uint_t dynamic, huffman, index, offset;
271 ngx_connection_t *c, *pc;
272 ngx_http_v3_uni_stream_t *st;
273 enum {
274 sw_start = 0,
275 sw_inr_name_index,
276 sw_inr_value_length,
277 sw_inr_read_value_length,
278 sw_inr_value,
279 sw_iwnr_name_length,
280 sw_iwnr_name,
281 sw_iwnr_value_length,
282 sw_iwnr_read_value_length,
283 sw_iwnr_value,
284 sw_capacity,
285 sw_duplicate
286 } state;
287
288 c = rev->data;
289 st = c->data;
290 pc = c->qs->parent;
291
292 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 client encoder");
293
294 state = st->state;
295 dynamic = st->dynamic;
296 huffman = st->huffman;
297 index = st->index;
298 offset = st->offset;
299 name = st->name;
300 value = st->value;
301
302 while (rev->ready) {
303
304 /* XXX limit checks */
305 /* XXX buffer input */
306
307 n = c->recv(c, &v, 1);
308
309 if (n == NGX_ERROR || n == 0) {
310 goto failed;
311 }
312
313 if (n != 1) {
314 break;
315 }
316
317 /* XXX v -> ch */
318
319 switch (state) {
320
321 case sw_start:
322
323 if (v & 0x80) {
324 /* Insert With Name Reference */
325
326 dynamic = (v & 0x40) ? 0 : 1;
327 index = v & 0x3f;
328
329 if (index != 0x3f) {
330 state = sw_inr_value_length;
331 break;
332 }
333
334 index = 0;
335 state = sw_inr_name_index;
336 break;
337 }
338
339 if (v & 0x40) {
340 /* Insert Without Name Reference */
341
342 huffman = (v & 0x20) ? 1 : 0;
343 name.len = v & 0x1f;
344
345 if (name.len != 0x1f) {
346 offset = 0;
347 state = sw_iwnr_name;
348 break;
349 }
350
351 name.len = 0;
352 state = sw_iwnr_name_length;
353 break;
354 }
355
356 if (v & 0x20) {
357 /* Set Dynamic Table Capacity */
358
359 index = v & 0x1f;
360
361 if (index != 0x1f) {
362 if (ngx_http_v3_set_capacity(c, index) != NGX_OK) {
363 goto failed;
364 }
365
366 break;
367 }
368
369 index = 0;
370 state = sw_capacity;
371 break;
372 }
373
374 /* Duplicate */
375
376 index = v & 0x1f;
377
378 if (index != 0x1f) {
379 if (ngx_http_v3_duplicate(c, index) != NGX_OK) {
380 goto failed;
381 }
382
383 break;
384 }
385
386 index = 0;
387 state = sw_duplicate;
388 break;
389
390 case sw_inr_name_index:
391
392 index = (index << 7) + (v & 0x7f);
393 if (v & 0x80) {
394 break;
395 }
396
397 index += 0x3f;
398 state = sw_inr_value_length;
399 break;
400
401 case sw_inr_value_length:
402
403 huffman = (v & 0x80) ? 1 : 0;
404 value.len = v & 0x7f;
405
406 if (value.len == 0) {
407 value.data = NULL;
408
409 if (ngx_http_v3_ref_insert(c, dynamic, index, &value) != NGX_OK)
410 {
411 goto failed;
412 }
413
414 state = sw_start;
415 break;
416 }
417
418 if (value.len != 0x7f) {
419 value.data = ngx_pnalloc(pc->pool, value.len);
420 if (value.data == NULL) {
421 goto failed;
422 }
423
424 state = sw_inr_value;
425 offset = 0;
426 break;
427 }
428
429 value.len = 0;
430 state = sw_inr_read_value_length;
431 break;
432
433 case sw_inr_read_value_length:
434
435 value.len = (value.len << 7) + (v & 0x7f);
436 if (v & 0x80) {
437 break;
438 }
439
440 value.len += 0x7f;
441
442 value.data = ngx_pnalloc(pc->pool, value.len);
443 if (value.data == NULL) {
444 goto failed; 286 goto failed;
445 } 287 }
446 288
447 state = sw_inr_value; 289 if (rc == NGX_DONE) {
448 offset = 0; 290 goto done;
449 break;
450
451 case sw_inr_value:
452
453 value.data[offset++] = v;
454 if (offset != value.len) {
455 break;
456 } 291 }
457 292
458 if (huffman) { 293 /* rc == NGX_AGAIN */
459 if (ngx_http_v3_decode_huffman(pc, &value) != NGX_OK) { 294 }
460 goto failed; 295 }
461 }
462 }
463
464 if (ngx_http_v3_ref_insert(c, dynamic, index, &value) != NGX_OK) {
465 goto failed;
466 }
467
468 state = sw_start;
469 break;
470
471 case sw_iwnr_name_length:
472
473 name.len = (name.len << 7) + (v & 0x7f);
474 if (v & 0x80) {
475 break;
476 }
477
478 name.len += 0x1f;
479
480 name.data = ngx_pnalloc(pc->pool, name.len);
481 if (name.data == NULL) {
482 goto failed;
483 }
484
485 offset = 0;
486 state = sw_iwnr_name;
487 break;
488
489 case sw_iwnr_name:
490
491 name.data[offset++] = v;
492 if (offset != name.len) {
493 break;
494 }
495
496 if (huffman) {
497 if (ngx_http_v3_decode_huffman(pc, &name) != NGX_OK) {
498 goto failed;
499 }
500 }
501
502 state = sw_iwnr_value_length;
503 break;
504
505 case sw_iwnr_value_length:
506
507 huffman = (v & 0x80) ? 1 : 0;
508 value.len = v & 0x7f;
509
510 if (value.len == 0) {
511 value.data = NULL;
512
513 if (ngx_http_v3_insert(c, &name, &value) != NGX_OK) {
514 goto failed;
515 }
516
517 state = sw_start;
518 break;
519 }
520
521 if (value.len != 0x7f) {
522 value.data = ngx_pnalloc(pc->pool, value.len);
523 if (value.data == NULL) {
524 goto failed;
525 }
526
527 offset = 0;
528 state = sw_iwnr_value;
529 break;
530 }
531
532 state = sw_iwnr_read_value_length;
533 break;
534
535 case sw_iwnr_read_value_length:
536
537 value.len = (value.len << 7) + (v & 0x7f);
538 if (v & 0x80) {
539 break;
540 }
541
542 value.data = ngx_pnalloc(pc->pool, value.len);
543 if (value.data == NULL) {
544 goto failed;
545 }
546
547 offset = 0;
548 state = sw_iwnr_value;
549 break;
550
551 case sw_iwnr_value:
552
553 value.data[offset++] = v;
554 if (offset != value.len) {
555 break;
556 }
557
558 if (huffman) {
559 if (ngx_http_v3_decode_huffman(pc, &value) != NGX_OK) {
560 goto failed;
561 }
562 }
563
564 if (ngx_http_v3_insert(c, &name, &value) != NGX_OK) {
565 goto failed;
566 }
567
568 state = sw_start;
569 break;
570
571
572 case sw_capacity:
573
574 index = (index << 7) + (v & 0x7f);
575 if (v & 0x80) {
576 break;
577 }
578
579 index += 0x1f;
580
581 if (ngx_http_v3_set_capacity(c, index) != NGX_OK) {
582 goto failed;
583 }
584
585 state = sw_start;
586 break;
587
588 case sw_duplicate:
589
590 index = (index << 7) + (v & 0x7f);
591 if (v & 0x80) {
592 break;
593 }
594
595 index += 0x1f;
596
597 if (ngx_http_v3_duplicate(c, index) != NGX_OK) {
598 goto failed;
599 }
600
601 state = sw_start;
602 break;
603 }
604 }
605
606 st->state = state;
607 st->dynamic = dynamic;
608 st->huffman = huffman;
609 st->index = index;
610 st->offset = offset;
611 st->name = name;
612 st->value = value;
613 296
614 if (ngx_handle_read_event(rev, 0) != NGX_OK) { 297 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
615 goto failed; 298 goto failed;
616 } 299 }
617 300
618 return; 301 return;
619 302
620 failed: 303 done:
621 304
622 ngx_http_v3_close_uni_stream(c); 305 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read done");
623 }
624
625
626 static void
627 ngx_http_v3_client_decoder_handler(ngx_event_t *rev)
628 {
629 u_char v;
630 ssize_t n;
631 ngx_uint_t index;
632 ngx_connection_t *c;
633 ngx_http_v3_uni_stream_t *st;
634 enum {
635 sw_start = 0,
636 sw_ack_header,
637 sw_cancel_stream,
638 sw_inc_insert_count
639 } state;
640
641 c = rev->data;
642 st = c->data;
643
644 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 client decoder");
645
646 state = st->state;
647 index = st->index;
648
649 while (rev->ready) {
650
651 /* XXX limit checks */
652 /* XXX buffer input */
653
654 n = c->recv(c, &v, 1);
655
656 if (n == NGX_ERROR || n == 0) {
657 goto failed;
658 }
659
660 if (n != 1) {
661 break;
662 }
663
664 switch (state) {
665
666 case sw_start:
667
668 if (v & 0x80) {
669 /* Header Acknowledgement */
670
671 index = v & 0x7f;
672
673 if (index != 0x7f) {
674 if (ngx_http_v3_ack_header(c, index) != NGX_OK) {
675 goto failed;
676 }
677
678 break;
679 }
680
681 index = 0;
682 state = sw_ack_header;
683 break;
684 }
685
686 if (v & 0x40) {
687 /* Stream Cancellation */
688
689 index = v & 0x3f;
690
691 if (index != 0x3f) {
692 if (ngx_http_v3_cancel_stream(c, index) != NGX_OK) {
693 goto failed;
694 }
695
696 break;
697 }
698
699 index = 0;
700 state = sw_cancel_stream;
701 break;
702 }
703
704 /* Insert Count Increment */
705
706 index = v & 0x3f;
707
708 if (index != 0x3f) {
709 if (ngx_http_v3_inc_insert_count(c, index) != NGX_OK) {
710 goto failed;
711 }
712
713 break;
714 }
715
716 index = 0;
717 state = sw_inc_insert_count;
718 break;
719
720 case sw_ack_header:
721
722 index = (index << 7) + (v & 0x7f);
723 if (v & 0x80) {
724 break;
725 }
726
727 index += 0x7f;
728
729 if (ngx_http_v3_ack_header(c, index) != NGX_OK) {
730 goto failed;
731 }
732
733 state = sw_start;
734 break;
735
736 case sw_cancel_stream:
737
738 index = (index << 7) + (v & 0x7f);
739 if (v & 0x80) {
740 break;
741 }
742
743 index += 0x3f;
744
745 if (ngx_http_v3_cancel_stream(c, index) != NGX_OK) {
746 goto failed;
747 }
748
749 state = sw_start;
750 break;
751
752 case sw_inc_insert_count:
753
754 index = (index << 7) + (v & 0x7f);
755 if (v & 0x80) {
756 break;
757 }
758
759 index += 0x3f;
760
761 if (ngx_http_v3_inc_insert_count(c, index) != NGX_OK) {
762 goto failed;
763 }
764
765 state = sw_start;
766 break;
767 }
768 }
769
770 st->state = state;
771 st->index = index;
772
773 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
774 goto failed;
775 }
776
777 return;
778 306
779 failed: 307 failed:
780 308
781 ngx_http_v3_close_uni_stream(c); 309 ngx_http_v3_close_uni_stream(c);
782 } 310 }
833 return NULL; 361 return NULL;
834 } 362 }
835 363
836 364
837 static ngx_connection_t * 365 static ngx_connection_t *
838 ngx_http_v3_get_server_encoder(ngx_connection_t *c) 366 ngx_http_v3_get_control(ngx_connection_t *c)
839 { 367 {
840 ngx_http_v3_connection_t *h3c; 368 ngx_http_v3_connection_t *h3c;
841 369
842 h3c = c->qs->parent->data; 370 h3c = c->qs->parent->data;
843 371
844 if (h3c->server_encoder == NULL) { 372 if (h3c->server_encoder == NULL) {
845 h3c->server_encoder = ngx_http_v3_create_uni_stream(c, 373 h3c->server_encoder = ngx_http_v3_create_uni_stream(c,
846 NGX_HTTP_V3_ENCODER_STREAM); 374 NGX_HTTP_V3_STREAM_CONTROL);
847 } 375 }
848 376
849 return h3c->server_encoder; 377 return h3c->server_encoder;
850 } 378 }
851 379
852 380
853 static ngx_connection_t * 381 static ngx_connection_t *
854 ngx_http_v3_get_server_decoder(ngx_connection_t *c) 382 ngx_http_v3_get_encoder(ngx_connection_t *c)
855 { 383 {
856 ngx_http_v3_connection_t *h3c; 384 ngx_http_v3_connection_t *h3c;
857 385
858 h3c = c->qs->parent->data; 386 h3c = c->qs->parent->data;
859 387
860 if (h3c->server_decoder == NULL) { 388 if (h3c->server_encoder == NULL) {
861 h3c->server_decoder = ngx_http_v3_create_uni_stream(c, 389 h3c->server_encoder = ngx_http_v3_create_uni_stream(c,
862 NGX_HTTP_V3_DECODER_STREAM); 390 NGX_HTTP_V3_STREAM_ENCODER);
863 } 391 }
864 392
865 return h3c->server_decoder; 393 return h3c->server_encoder;
394 }
395
396
397 static ngx_connection_t *
398 ngx_http_v3_get_decoder(ngx_connection_t *c)
399 {
400 ngx_http_v3_connection_t *h3c;
401
402 h3c = c->qs->parent->data;
403
404 if (h3c->server_encoder == NULL) {
405 h3c->server_encoder = ngx_http_v3_create_uni_stream(c,
406 NGX_HTTP_V3_STREAM_DECODER);
407 }
408
409 return h3c->server_encoder;
866 } 410 }
867 411
868 412
869 ngx_int_t 413 ngx_int_t
870 ngx_http_v3_client_ref_insert(ngx_connection_t *c, ngx_uint_t dynamic, 414 ngx_http_v3_client_ref_insert(ngx_connection_t *c, ngx_uint_t dynamic,
876 420
877 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, 421 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
878 "http3 client ref insert, %s[%ui] \"%V\"", 422 "http3 client ref insert, %s[%ui] \"%V\"",
879 dynamic ? "dynamic" : "static", index, value); 423 dynamic ? "dynamic" : "static", index, value);
880 424
881 ec = ngx_http_v3_get_server_encoder(c); 425 ec = ngx_http_v3_get_encoder(c);
882 if (ec == NULL) { 426 if (ec == NULL) {
883 return NGX_ERROR; 427 return NGX_ERROR;
884 } 428 }
885 429
886 p = buf; 430 p = buf;
921 ngx_connection_t *ec; 465 ngx_connection_t *ec;
922 466
923 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, 467 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
924 "http3 client insert \"%V\":\"%V\"", name, value); 468 "http3 client insert \"%V\":\"%V\"", name, value);
925 469
926 ec = ngx_http_v3_get_server_encoder(c); 470 ec = ngx_http_v3_get_encoder(c);
927 if (ec == NULL) { 471 if (ec == NULL) {
928 return NGX_ERROR; 472 return NGX_ERROR;
929 } 473 }
930 474
931 /* XXX option for huffman? */ 475 /* XXX option for huffman? */
970 ngx_connection_t *ec; 514 ngx_connection_t *ec;
971 515
972 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, 516 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
973 "http3 client set capacity %ui", capacity); 517 "http3 client set capacity %ui", capacity);
974 518
975 ec = ngx_http_v3_get_server_encoder(c); 519 ec = ngx_http_v3_get_encoder(c);
976 if (ec == NULL) { 520 if (ec == NULL) {
977 return NGX_ERROR; 521 return NGX_ERROR;
978 } 522 }
979 523
980 buf[0] = 0x20; 524 buf[0] = 0x20;
997 ngx_connection_t *ec; 541 ngx_connection_t *ec;
998 542
999 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, 543 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
1000 "http3 client duplicate %ui", index); 544 "http3 client duplicate %ui", index);
1001 545
1002 ec = ngx_http_v3_get_server_encoder(c); 546 ec = ngx_http_v3_get_encoder(c);
1003 if (ec == NULL) { 547 if (ec == NULL) {
1004 return NGX_ERROR; 548 return NGX_ERROR;
1005 } 549 }
1006 550
1007 buf[0] = 0; 551 buf[0] = 0;
1024 ngx_connection_t *dc; 568 ngx_connection_t *dc;
1025 569
1026 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, 570 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
1027 "http3 client ack header %ui", stream_id); 571 "http3 client ack header %ui", stream_id);
1028 572
1029 dc = ngx_http_v3_get_server_decoder(c); 573 dc = ngx_http_v3_get_decoder(c);
1030 if (dc == NULL) { 574 if (dc == NULL) {
1031 return NGX_ERROR; 575 return NGX_ERROR;
1032 } 576 }
1033 577
1034 buf[0] = 0x80; 578 buf[0] = 0x80;
1051 ngx_connection_t *dc; 595 ngx_connection_t *dc;
1052 596
1053 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, 597 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
1054 "http3 client cancel stream %ui", stream_id); 598 "http3 client cancel stream %ui", stream_id);
1055 599
1056 dc = ngx_http_v3_get_server_decoder(c); 600 dc = ngx_http_v3_get_decoder(c);
1057 if (dc == NULL) { 601 if (dc == NULL) {
1058 return NGX_ERROR; 602 return NGX_ERROR;
1059 } 603 }
1060 604
1061 buf[0] = 0x40; 605 buf[0] = 0x40;
1078 ngx_connection_t *dc; 622 ngx_connection_t *dc;
1079 623
1080 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, 624 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
1081 "http3 client increment insert count %ui", inc); 625 "http3 client increment insert count %ui", inc);
1082 626
1083 dc = ngx_http_v3_get_server_decoder(c); 627 dc = ngx_http_v3_get_decoder(c);
1084 if (dc == NULL) { 628 if (dc == NULL) {
1085 return NGX_ERROR; 629 return NGX_ERROR;
1086 } 630 }
1087 631
1088 buf[0] = 0; 632 buf[0] = 0;