Mercurial > hg > nginx
comparison src/http/v3/ngx_http_v3_streams.c @ 8902:925572184d4a quic
HTTP/3: adjusted QUIC connection finalization.
When an HTTP/3 function returns an error in context of a QUIC stream, it's
this function's responsibility now to finalize the entire QUIC connection
with the right code, if required. Previously, QUIC connection finalization
could be done both outside and inside such functions. The new rule follows
a similar rule for logging, leads to cleaner code, and allows to provide more
details about the error.
While here, a few error cases are no longer treated as fatal and QUIC connection
is no longer finalized in these cases. A few other cases now lead to
stream reset instead of connection finalization.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Mon, 18 Oct 2021 15:22:33 +0300 |
parents | 72b304f6207c |
children | 0d3bf08eaac0 |
comparison
equal
deleted
inserted
replaced
8901:a951e0809044 | 8902:925572184d4a |
---|---|
281 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 281 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
282 "http3 create push stream id:%uL", push_id); | 282 "http3 create push stream id:%uL", push_id); |
283 | 283 |
284 sc = ngx_quic_open_stream(c, 0); | 284 sc = ngx_quic_open_stream(c, 0); |
285 if (sc == NULL) { | 285 if (sc == NULL) { |
286 return NULL; | 286 goto failed; |
287 } | 287 } |
288 | 288 |
289 p = buf; | 289 p = buf; |
290 p = (u_char *) ngx_http_v3_encode_varlen_int(p, NGX_HTTP_V3_STREAM_PUSH); | 290 p = (u_char *) ngx_http_v3_encode_varlen_int(p, NGX_HTTP_V3_STREAM_PUSH); |
291 p = (u_char *) ngx_http_v3_encode_varlen_int(p, push_id); | 291 p = (u_char *) ngx_http_v3_encode_varlen_int(p, push_id); |
316 | 316 |
317 return sc; | 317 return sc; |
318 | 318 |
319 failed: | 319 failed: |
320 | 320 |
321 ngx_http_v3_close_uni_stream(sc); | 321 ngx_log_error(NGX_LOG_ERR, c->log, 0, "failed to create push stream"); |
322 | |
323 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR, | |
324 "failed to create push stream"); | |
325 if (sc) { | |
326 ngx_http_v3_close_uni_stream(sc); | |
327 } | |
322 | 328 |
323 return NULL; | 329 return NULL; |
324 } | 330 } |
325 | 331 |
326 | 332 |
366 } | 372 } |
367 } | 373 } |
368 | 374 |
369 sc = ngx_quic_open_stream(c, 0); | 375 sc = ngx_quic_open_stream(c, 0); |
370 if (sc == NULL) { | 376 if (sc == NULL) { |
371 return NULL; | 377 goto failed; |
372 } | 378 } |
373 | 379 |
374 sc->quic->cancelable = 1; | 380 sc->quic->cancelable = 1; |
375 | 381 |
376 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 382 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
403 | 409 |
404 return sc; | 410 return sc; |
405 | 411 |
406 failed: | 412 failed: |
407 | 413 |
408 ngx_http_v3_close_uni_stream(sc); | 414 ngx_log_error(NGX_LOG_ERR, c->log, 0, "failed to create server stream"); |
415 | |
416 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR, | |
417 "failed to create server stream"); | |
418 if (sc) { | |
419 ngx_http_v3_close_uni_stream(sc); | |
420 } | |
409 | 421 |
410 return NULL; | 422 return NULL; |
411 } | 423 } |
412 | 424 |
413 | 425 |
422 | 434 |
423 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 send settings"); | 435 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 send settings"); |
424 | 436 |
425 cc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_CONTROL); | 437 cc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_CONTROL); |
426 if (cc == NULL) { | 438 if (cc == NULL) { |
427 return NGX_DECLINED; | 439 return NGX_ERROR; |
428 } | 440 } |
429 | 441 |
430 h3scf = ngx_http_v3_get_module_srv_conf(c, ngx_http_v3_module); | 442 h3scf = ngx_http_v3_get_module_srv_conf(c, ngx_http_v3_module); |
431 | 443 |
432 n = ngx_http_v3_encode_varlen_int(NULL, | 444 n = ngx_http_v3_encode_varlen_int(NULL, |
455 | 467 |
456 return NGX_OK; | 468 return NGX_OK; |
457 | 469 |
458 failed: | 470 failed: |
459 | 471 |
472 ngx_log_error(NGX_LOG_ERR, c->log, 0, "failed to send settings"); | |
473 | |
474 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_EXCESSIVE_LOAD, | |
475 "failed to send settings"); | |
460 ngx_http_v3_close_uni_stream(cc); | 476 ngx_http_v3_close_uni_stream(cc); |
461 | 477 |
462 return NGX_ERROR; | 478 return NGX_ERROR; |
463 } | 479 } |
464 | 480 |
473 | 489 |
474 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 send goaway %uL", id); | 490 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 send goaway %uL", id); |
475 | 491 |
476 cc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_CONTROL); | 492 cc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_CONTROL); |
477 if (cc == NULL) { | 493 if (cc == NULL) { |
478 return NGX_DECLINED; | 494 return NGX_ERROR; |
479 } | 495 } |
480 | 496 |
481 n = ngx_http_v3_encode_varlen_int(NULL, id); | 497 n = ngx_http_v3_encode_varlen_int(NULL, id); |
482 p = (u_char *) ngx_http_v3_encode_varlen_int(buf, NGX_HTTP_V3_FRAME_GOAWAY); | 498 p = (u_char *) ngx_http_v3_encode_varlen_int(buf, NGX_HTTP_V3_FRAME_GOAWAY); |
483 p = (u_char *) ngx_http_v3_encode_varlen_int(p, n); | 499 p = (u_char *) ngx_http_v3_encode_varlen_int(p, n); |
493 | 509 |
494 return NGX_OK; | 510 return NGX_OK; |
495 | 511 |
496 failed: | 512 failed: |
497 | 513 |
514 ngx_log_error(NGX_LOG_ERR, c->log, 0, "failed to send goaway"); | |
515 | |
516 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_EXCESSIVE_LOAD, | |
517 "failed to send goaway"); | |
498 ngx_http_v3_close_uni_stream(cc); | 518 ngx_http_v3_close_uni_stream(cc); |
499 | 519 |
500 return NGX_ERROR; | 520 return NGX_ERROR; |
501 } | 521 } |
502 | 522 |
508 size_t n; | 528 size_t n; |
509 ngx_connection_t *dc; | 529 ngx_connection_t *dc; |
510 ngx_http_v3_session_t *h3c; | 530 ngx_http_v3_session_t *h3c; |
511 | 531 |
512 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 532 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
513 "http3 client ack section %ui", stream_id); | 533 "http3 send section acknowledgement %ui", stream_id); |
514 | 534 |
515 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER); | 535 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER); |
516 if (dc == NULL) { | 536 if (dc == NULL) { |
517 return NGX_ERROR; | 537 return NGX_ERROR; |
518 } | 538 } |
522 | 542 |
523 h3c = ngx_http_v3_get_session(c); | 543 h3c = ngx_http_v3_get_session(c); |
524 h3c->total_bytes += n; | 544 h3c->total_bytes += n; |
525 | 545 |
526 if (dc->send(dc, buf, n) != (ssize_t) n) { | 546 if (dc->send(dc, buf, n) != (ssize_t) n) { |
527 ngx_http_v3_close_uni_stream(dc); | 547 goto failed; |
528 return NGX_ERROR; | 548 } |
529 } | 549 |
530 | 550 return NGX_OK; |
531 return NGX_OK; | 551 |
552 failed: | |
553 | |
554 ngx_log_error(NGX_LOG_ERR, c->log, 0, | |
555 "failed to send section acknowledgement"); | |
556 | |
557 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_EXCESSIVE_LOAD, | |
558 "failed to send section acknowledgement"); | |
559 ngx_http_v3_close_uni_stream(dc); | |
560 | |
561 return NGX_ERROR; | |
532 } | 562 } |
533 | 563 |
534 | 564 |
535 ngx_int_t | 565 ngx_int_t |
536 ngx_http_v3_send_cancel_stream(ngx_connection_t *c, ngx_uint_t stream_id) | 566 ngx_http_v3_send_cancel_stream(ngx_connection_t *c, ngx_uint_t stream_id) |
539 size_t n; | 569 size_t n; |
540 ngx_connection_t *dc; | 570 ngx_connection_t *dc; |
541 ngx_http_v3_session_t *h3c; | 571 ngx_http_v3_session_t *h3c; |
542 | 572 |
543 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 573 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
544 "http3 client cancel stream %ui", stream_id); | 574 "http3 send stream cancellation %ui", stream_id); |
545 | 575 |
546 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER); | 576 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER); |
547 if (dc == NULL) { | 577 if (dc == NULL) { |
548 return NGX_ERROR; | 578 return NGX_ERROR; |
549 } | 579 } |
553 | 583 |
554 h3c = ngx_http_v3_get_session(c); | 584 h3c = ngx_http_v3_get_session(c); |
555 h3c->total_bytes += n; | 585 h3c->total_bytes += n; |
556 | 586 |
557 if (dc->send(dc, buf, n) != (ssize_t) n) { | 587 if (dc->send(dc, buf, n) != (ssize_t) n) { |
558 ngx_http_v3_close_uni_stream(dc); | 588 goto failed; |
559 return NGX_ERROR; | 589 } |
560 } | 590 |
561 | 591 return NGX_OK; |
562 return NGX_OK; | 592 |
593 failed: | |
594 | |
595 ngx_log_error(NGX_LOG_ERR, c->log, 0, "failed to send stream cancellation"); | |
596 | |
597 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_EXCESSIVE_LOAD, | |
598 "failed to send stream cancellation"); | |
599 ngx_http_v3_close_uni_stream(dc); | |
600 | |
601 return NGX_ERROR; | |
563 } | 602 } |
564 | 603 |
565 | 604 |
566 ngx_int_t | 605 ngx_int_t |
567 ngx_http_v3_send_inc_insert_count(ngx_connection_t *c, ngx_uint_t inc) | 606 ngx_http_v3_send_inc_insert_count(ngx_connection_t *c, ngx_uint_t inc) |
570 size_t n; | 609 size_t n; |
571 ngx_connection_t *dc; | 610 ngx_connection_t *dc; |
572 ngx_http_v3_session_t *h3c; | 611 ngx_http_v3_session_t *h3c; |
573 | 612 |
574 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 613 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
575 "http3 client increment insert count %ui", inc); | 614 "http3 send insert count increment %ui", inc); |
576 | 615 |
577 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER); | 616 dc = ngx_http_v3_get_uni_stream(c, NGX_HTTP_V3_STREAM_DECODER); |
578 if (dc == NULL) { | 617 if (dc == NULL) { |
579 return NGX_ERROR; | 618 return NGX_ERROR; |
580 } | 619 } |
584 | 623 |
585 h3c = ngx_http_v3_get_session(c); | 624 h3c = ngx_http_v3_get_session(c); |
586 h3c->total_bytes += n; | 625 h3c->total_bytes += n; |
587 | 626 |
588 if (dc->send(dc, buf, n) != (ssize_t) n) { | 627 if (dc->send(dc, buf, n) != (ssize_t) n) { |
589 ngx_http_v3_close_uni_stream(dc); | 628 goto failed; |
590 return NGX_ERROR; | 629 } |
591 } | 630 |
592 | 631 return NGX_OK; |
593 return NGX_OK; | 632 |
633 failed: | |
634 | |
635 ngx_log_error(NGX_LOG_ERR, c->log, 0, | |
636 "failed to send insert count increment"); | |
637 | |
638 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_EXCESSIVE_LOAD, | |
639 "failed to send insert count increment"); | |
640 ngx_http_v3_close_uni_stream(dc); | |
641 | |
642 return NGX_ERROR; | |
594 } | 643 } |
595 | 644 |
596 | 645 |
597 ngx_int_t | 646 ngx_int_t |
598 ngx_http_v3_set_max_push_id(ngx_connection_t *c, uint64_t max_push_id) | 647 ngx_http_v3_set_max_push_id(ngx_connection_t *c, uint64_t max_push_id) |