Mercurial > hg > nginx
comparison src/event/ngx_event_quic.c @ 8314:de8981bf2dd5 quic
Advertizing MAX_STREAMS (0x12) credit in advance.
This makes sending large number of bidirectional stream work within ngtcp2,
which doesn't bother sending optional STREAMS_BLOCKED when exhausted.
This also introduces tracking currently opened and maximum allowed streams.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Fri, 03 Apr 2020 13:49:44 +0300 |
parents | 053fa468b044 |
children | fdda518d10ba |
comparison
equal
deleted
inserted
replaced
8313:c625bde6cb77 | 8314:de8981bf2dd5 |
---|---|
20 ((level) == ssl_encryption_initial) ? 0 \ | 20 ((level) == ssl_encryption_initial) ? 0 \ |
21 : (((level) == ssl_encryption_handshake) ? 1 : 2) | 21 : (((level) == ssl_encryption_handshake) ? 1 : 2) |
22 | 22 |
23 #define NGX_QUIC_NAMESPACE_LAST (NGX_QUIC_ENCRYPTION_LAST - 1) | 23 #define NGX_QUIC_NAMESPACE_LAST (NGX_QUIC_ENCRYPTION_LAST - 1) |
24 | 24 |
25 #define NGX_QUIC_STREAMS_INC 16 | |
26 #define NGX_QUIC_STREAMS_LIMIT (1ULL < 60) | |
27 | |
25 | 28 |
26 typedef enum { | 29 typedef enum { |
27 NGX_QUIC_ST_INITIAL, /* connection just created */ | 30 NGX_QUIC_ST_INITIAL, /* connection just created */ |
28 NGX_QUIC_ST_HANDSHAKE, /* handshake started */ | 31 NGX_QUIC_ST_HANDSHAKE, /* handshake started */ |
29 NGX_QUIC_ST_EARLY_DATA, /* handshake in progress */ | 32 NGX_QUIC_ST_EARLY_DATA, /* handshake in progress */ |
77 ngx_uint_t nframes; | 80 ngx_uint_t nframes; |
78 #endif | 81 #endif |
79 | 82 |
80 ngx_quic_streams_t streams; | 83 ngx_quic_streams_t streams; |
81 ngx_uint_t max_data; | 84 ngx_uint_t max_data; |
85 | |
86 uint64_t cur_streams; | |
87 uint64_t max_streams; | |
82 | 88 |
83 unsigned send_timer_set:1; | 89 unsigned send_timer_set:1; |
84 unsigned closing:1; | 90 unsigned closing:1; |
85 }; | 91 }; |
86 | 92 |
128 ngx_quic_header_t *pkt, ngx_quic_ack_frame_t *f); | 134 ngx_quic_header_t *pkt, ngx_quic_ack_frame_t *f); |
129 static ngx_int_t ngx_quic_handle_crypto_frame(ngx_connection_t *c, | 135 static ngx_int_t ngx_quic_handle_crypto_frame(ngx_connection_t *c, |
130 ngx_quic_header_t *pkt, ngx_quic_crypto_frame_t *frame); | 136 ngx_quic_header_t *pkt, ngx_quic_crypto_frame_t *frame); |
131 static ngx_int_t ngx_quic_handle_stream_frame(ngx_connection_t *c, | 137 static ngx_int_t ngx_quic_handle_stream_frame(ngx_connection_t *c, |
132 ngx_quic_header_t *pkt, ngx_quic_stream_frame_t *frame); | 138 ngx_quic_header_t *pkt, ngx_quic_stream_frame_t *frame); |
139 static ngx_int_t ngx_quic_handle_max_streams(ngx_connection_t *c); | |
133 static ngx_int_t ngx_quic_handle_streams_blocked_frame(ngx_connection_t *c, | 140 static ngx_int_t ngx_quic_handle_streams_blocked_frame(ngx_connection_t *c, |
134 ngx_quic_header_t *pkt, ngx_quic_streams_blocked_frame_t *f); | 141 ngx_quic_header_t *pkt, ngx_quic_streams_blocked_frame_t *f); |
135 static ngx_int_t ngx_quic_handle_stream_data_blocked_frame(ngx_connection_t *c, | 142 static ngx_int_t ngx_quic_handle_stream_data_blocked_frame(ngx_connection_t *c, |
136 ngx_quic_header_t *pkt, ngx_quic_stream_data_blocked_frame_t *f); | 143 ngx_quic_header_t *pkt, ngx_quic_stream_data_blocked_frame_t *f); |
137 | 144 |
580 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 587 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
581 "SSL_set_quic_transport_params() failed"); | 588 "SSL_set_quic_transport_params() failed"); |
582 return NGX_ERROR; | 589 return NGX_ERROR; |
583 } | 590 } |
584 | 591 |
592 qc->max_streams = qc->tp.initial_max_streams_bidi; | |
585 qc->state = NGX_QUIC_ST_HANDSHAKE; | 593 qc->state = NGX_QUIC_ST_HANDSHAKE; |
586 | 594 |
587 n = SSL_do_handshake(ssl_conn); | 595 n = SSL_do_handshake(ssl_conn); |
588 | 596 |
589 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); | 597 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); |
1398 | 1406 |
1399 if (f->fin) { | 1407 if (f->fin) { |
1400 rev->pending_eof = 1; | 1408 rev->pending_eof = 1; |
1401 } | 1409 } |
1402 | 1410 |
1411 if ((f->stream_id & NGX_QUIC_STREAM_UNIDIRECTIONAL) == 0) { | |
1412 ngx_quic_handle_max_streams(c); | |
1413 } | |
1414 | |
1403 qc->streams.handler(sn->c); | 1415 qc->streams.handler(sn->c); |
1416 | |
1417 return NGX_OK; | |
1418 } | |
1419 | |
1420 | |
1421 static ngx_int_t | |
1422 ngx_quic_handle_max_streams(ngx_connection_t *c) | |
1423 { | |
1424 ngx_quic_frame_t *frame; | |
1425 ngx_quic_connection_t *qc; | |
1426 | |
1427 qc = c->quic; | |
1428 qc->cur_streams++; | |
1429 | |
1430 if (qc->cur_streams + NGX_QUIC_STREAMS_INC / 2 < qc->max_streams) { | |
1431 return NGX_OK; | |
1432 } | |
1433 | |
1434 frame = ngx_quic_alloc_frame(c, 0); | |
1435 if (frame == NULL) { | |
1436 return NGX_ERROR; | |
1437 } | |
1438 | |
1439 qc->max_streams = ngx_max(qc->max_streams + NGX_QUIC_STREAMS_INC, | |
1440 NGX_QUIC_STREAMS_LIMIT); | |
1441 | |
1442 frame->level = ssl_encryption_application; | |
1443 frame->type = NGX_QUIC_FT_MAX_STREAMS; | |
1444 frame->u.max_streams.limit = qc->max_streams; | |
1445 frame->u.max_streams.bidi = 1; | |
1446 | |
1447 ngx_sprintf(frame->info, "MAX_STREAMS limit:%d bidi:%d level=%d", | |
1448 (int) frame->u.max_streams.limit, | |
1449 (int) frame->u.max_streams.bidi, | |
1450 frame->level); | |
1451 | |
1452 ngx_quic_queue_frame(qc, frame); | |
1404 | 1453 |
1405 return NGX_OK; | 1454 return NGX_OK; |
1406 } | 1455 } |
1407 | 1456 |
1408 | 1457 |
1417 return NGX_ERROR; | 1466 return NGX_ERROR; |
1418 } | 1467 } |
1419 | 1468 |
1420 frame->level = pkt->level; | 1469 frame->level = pkt->level; |
1421 frame->type = NGX_QUIC_FT_MAX_STREAMS; | 1470 frame->type = NGX_QUIC_FT_MAX_STREAMS; |
1422 frame->u.max_streams.limit = f->limit * 2; | 1471 frame->u.max_streams.limit = ngx_max(f->limit * 2, NGX_QUIC_STREAMS_LIMIT); |
1423 frame->u.max_streams.bidi = f->bidi; | 1472 frame->u.max_streams.bidi = f->bidi; |
1473 | |
1474 c->quic->max_streams = frame->u.max_streams.limit; | |
1424 | 1475 |
1425 ngx_sprintf(frame->info, "MAX_STREAMS limit:%d bidi:%d level=%d", | 1476 ngx_sprintf(frame->info, "MAX_STREAMS limit:%d bidi:%d level=%d", |
1426 (int) frame->u.max_streams.limit, | 1477 (int) frame->u.max_streams.limit, |
1427 (int) frame->u.max_streams.bidi, | 1478 (int) frame->u.max_streams.bidi, |
1428 frame->level); | 1479 frame->level); |