QUIC: err_quic_protocol_error

На этот раз log файл вышел большим - 12 Mb.

на vl at wbsrv.ru

Готово, отправил.

Как я изначально предполагал, вы сталкиваетесь с этим случаем:
https://mailman.nginx.org/pipermail/nginx-devel/2021-May/014066.html

В последнем присланном логе все указанные файлы были успешно загружены
в рамках одного quic-соединения, после чего прошел 30-секундный keepalive_timeout,
и angie закрыл соединение close фреймом с соответствующим кодом ошибки.

conns/746.754.log:2024/04/05 23:02:38 [debug] 17028#17028: *754 http3 request line: "GET /emoji/269b.svg HTTP/3.0"
...                                                                             
conns/746.754.log:2024/04/05 23:02:38 [debug] 17028#17028: *754 http3 output header: ":status: 200"
... 

Потом всё это отсылается клиенту, он подвтерждает все quic фреймы:

2024/04/05 23:02:39 [debug] 17028#17028: *746 quic frame tx app:1731 PING       
2024/04/05 23:02:39 [debug] 17028#17028: *746 quic frame rx app:235 ACK n:2 delay:2 1731 1729-1727 1725-1604

И в конце закрытие:

2024/04/05 23:03:08 [debug] 17028#17028: *746 quic close handler                                  
2024/04/05 23:03:08 [debug] 17028#17028: *746 quic close initiated rc:0 c:00006C7AA8DB2820        
2024/04/05 23:03:08 [debug] 17028#17028: *746 quic close immediate term:0 drain:0 app error:256 "keepalive timeout"                                               
2024/04/05 23:03:08 [debug] 17028#17028: *746 quic sendto app packet max:1446 min:0  
2024/04/05 23:03:08 [debug] 17028#17028: *746 quic frame tx app:1734 CONNECTION_CLOSE_APP err:256 keepalive timeout

Случайность появления ошибки в том, что в quic значение keepalive timeout используется в качестве idle timeout, и словить срабатывание именно keepalive timeout с посылкой соответствующего фрейма довольно сложно.

При повторном подключении к известному серверу, chrome умеет слать запросы в режиме early data, поэтому это влияет на тайминг, равно как и использование другой ssl-библиотеки.

В nginx код в данном месте аналогичный, и это дело случая, что там это случается в вашем случае реже.

(патч, который я выше предлагал - валиден, он чинит случай, когда соединение в случае early data может иногд закрываться раньше, чем нужно из-за того, что не снимается один таймер).

Когда-то давно, значение keepalive_requests было маленькое по-умолчанию, и вам приходилось его поднимать. Потом оно было увеличено до 100, и эта настройка более не влияет.

Сейчас вы натыкатесь на keepalive_timeout. Попробуйте подобрать какое-нибудь значение, с которым будет лучше, чем сейчас. Но вообще это проблема хрома.

1 Like

Увеличение таймаута до 240s не помогает, а в косоли браузера запрос висит 6.4 мин и выдаёт ошибку.

При увеличении таймайта до 480s в консоли браузера уже висит 25 мин и выдаёт ошибку.

Chromium - багрепорт в Chrome, похоже на текущую ошибку.

Попробуйте, пожалуйста, ещё вот такой патч:

# HG changeset patch
# User Vladimir Khomutov <vl@wbsrv.ru>
# Date 1712821253 -10800
#      Thu Apr 11 10:40:53 2024 +0300
# Node ID 70ad418a7563f8ee9b4164f16c19442d7747014e
# Parent  430191689657a5e27a6eb62b39e5f26d7ab99a20
imported patch fix_early_close

diff --git a/src/event/quic/ngx_event_quic_streams.c b/src/event/quic/ngx_event_quic_streams.c
--- a/src/event/quic/ngx_event_quic_streams.c
+++ b/src/event/quic/ngx_event_quic_streams.c
@@ -243,7 +243,13 @@ ngx_quic_close_streams(ngx_connection_t 
 ngx_int_t
 ngx_quic_reset_stream(ngx_connection_t *c, ngx_uint_t err)
 {
-    if (!c->quic->parent->ssl->handshaked) {
+    ngx_connection_t       *pc;
+    ngx_quic_connection_t  *qc;
+
+    pc = c->quic->parent;
+    qc = ngx_quic_get_connection(pc);
+
+    if (qc->client && !pc->ssl->handshaked) {
         /* the stream was created early, do not try to send anything */
         return NGX_OK;
     }
@@ -301,11 +307,13 @@ ngx_quic_do_reset_stream(ngx_quic_stream
 ngx_int_t
 ngx_quic_shutdown_stream(ngx_connection_t *c, int how)
 {
-    ngx_connection_t  *pc;
+    ngx_connection_t       *pc;
+    ngx_quic_connection_t  *qc;
 
     pc = c->quic->parent;
-
-    if (!pc->ssl->handshaked) {
+    qc = ngx_quic_get_connection(pc);
+
+    if (qc->client && !pc->ssl->handshaked) {
         /* the stream was created early, do not try to send anything */
         return NGX_OK;
     }
1 Like

За несколько часов ошибок не наблюдаю!
Похоже, что работает!
Благодарю!

Больше ошибок не было.

Все эти исправления вошли в 1.5.1: История версий Angie — документация Angie 1.5.1

1 Like

Благодарю.
Уже увидел давно в истории коммитов :slight_smile: