comparison src/event/ngx_event_quic.c @ 8495:455a8536eaa7 quic

QUIC: limited the number of server-initiated streams. Also, ngx_quic_create_uni_stream() is replaced with ngx_quic_open_stream() which is capable of creating a bidi stream.
author Roman Arutyunyan <arut@nginx.com>
date Mon, 27 Jul 2020 18:51:42 +0300
parents d0ac4449a07f
children c5324bb3a704
comparison
equal deleted inserted replaced
8494:e334ca1b23ba 8495:455a8536eaa7
37 37
38 typedef struct { 38 typedef struct {
39 ngx_rbtree_t tree; 39 ngx_rbtree_t tree;
40 ngx_rbtree_node_t sentinel; 40 ngx_rbtree_node_t sentinel;
41 41
42 ngx_uint_t id_counter;
43
44 uint64_t received; 42 uint64_t received;
45 uint64_t sent; 43 uint64_t sent;
46 uint64_t recv_max_data; 44 uint64_t recv_max_data;
47 uint64_t send_max_data; 45 uint64_t send_max_data;
46
47 uint64_t server_max_streams_uni;
48 uint64_t server_max_streams_bidi;
49 uint64_t server_streams_uni;
50 uint64_t server_streams_bidi;
48 } ngx_quic_streams_t; 51 } ngx_quic_streams_t;
49 52
50 53
51 typedef struct { 54 typedef struct {
52 size_t in_flight; 55 size_t in_flight;
241 ngx_quic_header_t *pkt, ngx_quic_max_stream_data_frame_t *f); 244 ngx_quic_header_t *pkt, ngx_quic_max_stream_data_frame_t *f);
242 static ngx_int_t ngx_quic_handle_reset_stream_frame(ngx_connection_t *c, 245 static ngx_int_t ngx_quic_handle_reset_stream_frame(ngx_connection_t *c,
243 ngx_quic_header_t *pkt, ngx_quic_reset_stream_frame_t *f); 246 ngx_quic_header_t *pkt, ngx_quic_reset_stream_frame_t *f);
244 static ngx_int_t ngx_quic_handle_stop_sending_frame(ngx_connection_t *c, 247 static ngx_int_t ngx_quic_handle_stop_sending_frame(ngx_connection_t *c,
245 ngx_quic_header_t *pkt, ngx_quic_stop_sending_frame_t *f); 248 ngx_quic_header_t *pkt, ngx_quic_stop_sending_frame_t *f);
249 static ngx_int_t ngx_quic_handle_max_streams_frame(ngx_connection_t *c,
250 ngx_quic_header_t *pkt, ngx_quic_max_streams_frame_t *f);
246 251
247 static void ngx_quic_queue_frame(ngx_quic_connection_t *qc, 252 static void ngx_quic_queue_frame(ngx_quic_connection_t *qc,
248 ngx_quic_frame_t *frame); 253 ngx_quic_frame_t *frame);
249 254
250 static ngx_int_t ngx_quic_output(ngx_connection_t *c); 255 static ngx_int_t ngx_quic_output(ngx_connection_t *c);
492 "mismatch"); 497 "mismatch");
493 return 0; 498 return 0;
494 } 499 }
495 #endif 500 #endif
496 501
502 qc->streams.server_max_streams_bidi = qc->ctp.initial_max_streams_bidi;
503 qc->streams.server_max_streams_uni = qc->ctp.initial_max_streams_uni;
504
497 qc->client_tp_done = 1; 505 qc->client_tp_done = 1;
498 } 506 }
499 507
500 /* 508 /*
501 * we need to fit at least 1 frame into a packet, thus account head/tail; 509 * we need to fit at least 1 frame into a packet, thus account head/tail;
2098 return NGX_ERROR; 2106 return NGX_ERROR;
2099 } 2107 }
2100 2108
2101 break; 2109 break;
2102 2110
2111 case NGX_QUIC_FT_MAX_STREAMS:
2112 case NGX_QUIC_FT_MAX_STREAMS2:
2113
2114 if (ngx_quic_handle_max_streams_frame(c, pkt, &frame.u.max_streams)
2115 != NGX_OK)
2116 {
2117 return NGX_ERROR;
2118 }
2119
2120 break;
2121
2103 case NGX_QUIC_FT_NEW_CONNECTION_ID: 2122 case NGX_QUIC_FT_NEW_CONNECTION_ID:
2104 case NGX_QUIC_FT_RETIRE_CONNECTION_ID: 2123 case NGX_QUIC_FT_RETIRE_CONNECTION_ID:
2105 case NGX_QUIC_FT_PATH_CHALLENGE: 2124 case NGX_QUIC_FT_PATH_CHALLENGE:
2106 case NGX_QUIC_FT_PATH_RESPONSE: 2125 case NGX_QUIC_FT_PATH_RESPONSE:
2107 2126
3271 3290
3272 return NGX_OK; 3291 return NGX_OK;
3273 } 3292 }
3274 3293
3275 3294
3295 static ngx_int_t
3296 ngx_quic_handle_max_streams_frame(ngx_connection_t *c,
3297 ngx_quic_header_t *pkt, ngx_quic_max_streams_frame_t *f)
3298 {
3299 ngx_quic_connection_t *qc;
3300
3301 qc = c->quic;
3302
3303 if (f->bidi) {
3304 if (qc->streams.server_max_streams_bidi < f->limit) {
3305 qc->streams.server_max_streams_bidi = f->limit;
3306
3307 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
3308 "quic max_streams_bidi:%uL", f->limit);
3309 }
3310
3311 } else {
3312 if (qc->streams.server_max_streams_uni < f->limit) {
3313 qc->streams.server_max_streams_uni = f->limit;
3314
3315 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
3316 "quic max_streams_uni:%uL", f->limit);
3317 }
3318 }
3319
3320 return NGX_OK;
3321 }
3322
3323
3276 static void 3324 static void
3277 ngx_quic_queue_frame(ngx_quic_connection_t *qc, ngx_quic_frame_t *frame) 3325 ngx_quic_queue_frame(ngx_quic_connection_t *qc, ngx_quic_frame_t *frame)
3278 { 3326 {
3279 ngx_quic_send_ctx_t *ctx; 3327 ngx_quic_send_ctx_t *ctx;
3280 3328
3748 return NGX_OK; 3796 return NGX_OK;
3749 } 3797 }
3750 3798
3751 3799
3752 ngx_connection_t * 3800 ngx_connection_t *
3753 ngx_quic_create_uni_stream(ngx_connection_t *c) 3801 ngx_quic_open_stream(ngx_connection_t *c, ngx_uint_t bidi)
3754 { 3802 {
3755 ngx_uint_t id; 3803 size_t rcvbuf_size;
3804 uint64_t id;
3756 ngx_quic_stream_t *qs, *sn; 3805 ngx_quic_stream_t *qs, *sn;
3757 ngx_quic_connection_t *qc; 3806 ngx_quic_connection_t *qc;
3758 3807
3759 qs = c->qs; 3808 qs = c->qs;
3760 qc = qs->parent->quic; 3809 qc = qs->parent->quic;
3761 3810
3762 id = (qc->streams.id_counter << 2) 3811 if (bidi) {
3763 | NGX_QUIC_STREAM_SERVER_INITIATED 3812 if (qc->streams.server_streams_bidi
3764 | NGX_QUIC_STREAM_UNIDIRECTIONAL; 3813 >= qc->streams.server_max_streams_bidi)
3765 3814 {
3766 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, 3815 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
3767 "quic creating server uni stream #%ui id %ui", 3816 "quic too many server bidi streams: %uL",
3768 qc->streams.id_counter, id); 3817 qc->streams.server_streams_bidi);
3769 3818 return NULL;
3770 qc->streams.id_counter++; 3819 }
3771 3820
3772 sn = ngx_quic_create_stream(qs->parent, id, 0); 3821 id = (qc->streams.server_streams_bidi << 2)
3822 | NGX_QUIC_STREAM_SERVER_INITIATED;
3823
3824 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
3825 "quic creating server bidi stream %uL/%uL id:%uL",
3826 qc->streams.server_streams_bidi,
3827 qc->streams.server_max_streams_bidi, id);
3828
3829 qc->streams.server_streams_bidi++;
3830 rcvbuf_size = qc->tp.initial_max_stream_data_bidi_local;
3831
3832 } else {
3833 if (qc->streams.server_streams_uni
3834 >= qc->streams.server_max_streams_uni)
3835 {
3836 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
3837 "quic too many server uni streams: %uL",
3838 qc->streams.server_streams_uni);
3839 return NULL;
3840 }
3841
3842 id = (qc->streams.server_streams_uni << 2)
3843 | NGX_QUIC_STREAM_SERVER_INITIATED
3844 | NGX_QUIC_STREAM_UNIDIRECTIONAL;
3845
3846 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
3847 "quic creating server uni stream %uL/%uL id:%uL",
3848 qc->streams.server_streams_uni,
3849 qc->streams.server_max_streams_uni, id);
3850
3851 qc->streams.server_streams_uni++;
3852 rcvbuf_size = 0;
3853 }
3854
3855 sn = ngx_quic_create_stream(qs->parent, id, rcvbuf_size);
3773 if (sn == NULL) { 3856 if (sn == NULL) {
3774 return NULL; 3857 return NULL;
3775 } 3858 }
3776 3859
3777 return sn->c; 3860 return sn->c;