Mercurial > hg > nginx
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; |