Mercurial > hg > nginx-quic
comparison src/event/ngx_event_quic.c @ 7815:0f9e9786b90d quic
Added primitive flow control mechanisms.
+ MAX_STREAM_DATA frame is sent when recv() is performed on stream
The new value is a sum of total bytes received by stream + free
space in a buffer;
The sending of MAX_STREM_DATA frame in response to STREAM_DATA_BLOCKED
frame is adjusted to follow the same logic as above.
+ MAX_DATA frame is sent when total amount of received data is 2x
of current limit. The limit is doubled.
+ Default values of transport parameters are adjusted to more meaningful
values:
initial stream limits are set to quic buffer size instead of
unrealistically small 255.
initial max data is decreased to 16 buffer sizes, in an assumption that
this is enough for a relatively short connection, instead of randomly
chosen big number.
All this allows to initiate a stable flow of streams that does not block
on stream/connection limits (tested with FF 77.0a1 and 100K requests)
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Wed, 15 Apr 2020 18:54:03 +0300 |
parents | ab443e80d9e4 |
children | aba84d9ab256 |
comparison
equal
deleted
inserted
replaced
7814:ab443e80d9e4 | 7815:0f9e9786b90d |
---|---|
45 ngx_rbtree_t tree; | 45 ngx_rbtree_t tree; |
46 ngx_rbtree_node_t sentinel; | 46 ngx_rbtree_node_t sentinel; |
47 ngx_connection_handler_pt handler; | 47 ngx_connection_handler_pt handler; |
48 | 48 |
49 ngx_uint_t id_counter; | 49 ngx_uint_t id_counter; |
50 | |
51 uint64_t total_received; | |
52 uint64_t max_data; | |
50 } ngx_quic_streams_t; | 53 } ngx_quic_streams_t; |
51 | 54 |
52 | 55 |
53 /* | 56 /* |
54 * 12.3. Packet Numbers | 57 * 12.3. Packet Numbers |
533 ctp = &qc->ctp; | 536 ctp = &qc->ctp; |
534 ctp->max_packet_size = NGX_QUIC_DEFAULT_MAX_PACKET_SIZE; | 537 ctp->max_packet_size = NGX_QUIC_DEFAULT_MAX_PACKET_SIZE; |
535 ctp->ack_delay_exponent = NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT; | 538 ctp->ack_delay_exponent = NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT; |
536 ctp->max_ack_delay = NGX_QUIC_DEFAULT_MAX_ACK_DELAY; | 539 ctp->max_ack_delay = NGX_QUIC_DEFAULT_MAX_ACK_DELAY; |
537 | 540 |
541 qc->streams.max_data = qc->tp.initial_max_data; | |
542 | |
538 qc->dcid.len = pkt->dcid.len; | 543 qc->dcid.len = pkt->dcid.len; |
539 qc->dcid.data = ngx_pnalloc(c->pool, pkt->dcid.len); | 544 qc->dcid.data = ngx_pnalloc(c->pool, pkt->dcid.len); |
540 if (qc->dcid.data == NULL) { | 545 if (qc->dcid.data == NULL) { |
541 return NGX_ERROR; | 546 return NGX_ERROR; |
542 } | 547 } |
1961 ngx_log_error(NGX_LOG_INFO, c->log, 0, "unknown stream id:%uL", f->id); | 1966 ngx_log_error(NGX_LOG_INFO, c->log, 0, "unknown stream id:%uL", f->id); |
1962 return NGX_ERROR; | 1967 return NGX_ERROR; |
1963 } | 1968 } |
1964 | 1969 |
1965 b = sn->b; | 1970 b = sn->b; |
1966 n = (b->pos - b->start) + (b->end - b->last); | 1971 n = sn->fs.received + (b->pos - b->start) + (b->end - b->last); |
1967 | 1972 |
1968 frame = ngx_quic_alloc_frame(c, 0); | 1973 frame = ngx_quic_alloc_frame(c, 0); |
1969 if (frame == NULL) { | 1974 if (frame == NULL) { |
1970 return NGX_ERROR; | 1975 return NGX_ERROR; |
1971 } | 1976 } |
2557 | 2562 |
2558 | 2563 |
2559 static ssize_t | 2564 static ssize_t |
2560 ngx_quic_stream_recv(ngx_connection_t *c, u_char *buf, size_t size) | 2565 ngx_quic_stream_recv(ngx_connection_t *c, u_char *buf, size_t size) |
2561 { | 2566 { |
2562 ssize_t len; | 2567 ssize_t len; |
2563 ngx_buf_t *b; | 2568 ngx_buf_t *b; |
2564 ngx_event_t *rev; | 2569 ngx_event_t *rev; |
2565 ngx_quic_stream_t *qs; | 2570 ngx_connection_t *pc; |
2571 ngx_quic_frame_t *frame; | |
2572 ngx_quic_stream_t *qs; | |
2573 ngx_quic_connection_t *qc; | |
2566 | 2574 |
2567 qs = c->qs; | 2575 qs = c->qs; |
2568 b = qs->b; | 2576 b = qs->b; |
2577 pc = qs->parent; | |
2578 qc = pc->quic; | |
2569 rev = c->read; | 2579 rev = c->read; |
2570 | 2580 |
2571 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | 2581 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
2572 "quic recv: eof:%d, avail:%z", | 2582 "quic recv: eof:%d, avail:%z", |
2573 rev->pending_eof, b->last - b->pos); | 2583 rev->pending_eof, b->last - b->pos); |
2587 len = ngx_min(b->last - b->pos, (ssize_t) size); | 2597 len = ngx_min(b->last - b->pos, (ssize_t) size); |
2588 | 2598 |
2589 ngx_memcpy(buf, b->pos, len); | 2599 ngx_memcpy(buf, b->pos, len); |
2590 | 2600 |
2591 b->pos += len; | 2601 b->pos += len; |
2602 qc->streams.total_received += len; | |
2592 | 2603 |
2593 if (b->pos == b->last) { | 2604 if (b->pos == b->last) { |
2594 b->pos = b->start; | 2605 b->pos = b->start; |
2595 b->last = b->start; | 2606 b->last = b->start; |
2596 rev->ready = rev->pending_eof; | 2607 rev->ready = rev->pending_eof; |
2597 } | 2608 } |
2598 | 2609 |
2599 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | 2610 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
2600 "quic recv: %z of %uz", len, size); | 2611 "quic recv: %z of %uz", len, size); |
2612 | |
2613 if (!rev->pending_eof) { | |
2614 frame = ngx_quic_alloc_frame(pc, 0); | |
2615 if (frame == NULL) { | |
2616 return NGX_ERROR; | |
2617 } | |
2618 | |
2619 frame->level = ssl_encryption_application; | |
2620 frame->type = NGX_QUIC_FT_MAX_STREAM_DATA; | |
2621 frame->u.max_stream_data.id = qs->id; | |
2622 frame->u.max_stream_data.limit = qs->fs.received + (b->pos - b->start) | |
2623 + (b->end - b->last); | |
2624 | |
2625 ngx_sprintf(frame->info, "MAX_STREAM_DATA id:%d limit:%d l=%d on recv", | |
2626 (int) frame->u.max_stream_data.id, | |
2627 (int) frame->u.max_stream_data.limit, | |
2628 frame->level); | |
2629 | |
2630 ngx_quic_queue_frame(pc->quic, frame); | |
2631 } | |
2632 | |
2633 if ((qc->streams.max_data / 2) < qc->streams.total_received) { | |
2634 | |
2635 frame = ngx_quic_alloc_frame(pc, 0); | |
2636 | |
2637 if (frame == NULL) { | |
2638 return NGX_ERROR; | |
2639 } | |
2640 | |
2641 qc->streams.max_data *= 2; | |
2642 | |
2643 frame->level = ssl_encryption_application; | |
2644 frame->type = NGX_QUIC_FT_MAX_DATA; | |
2645 frame->u.max_data.max_data = qc->streams.max_data; | |
2646 | |
2647 ngx_sprintf(frame->info, "MAX_DATA max_data:%d level=%d on recv", | |
2648 (int) frame->u.max_data.max_data, frame->level); | |
2649 | |
2650 ngx_quic_queue_frame(pc->quic, frame); | |
2651 | |
2652 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
2653 "quic recv: increased max data: %ui", | |
2654 qc->streams.max_data); | |
2655 } | |
2601 | 2656 |
2602 return len; | 2657 return len; |
2603 } | 2658 } |
2604 | 2659 |
2605 | 2660 |