Mercurial > hg > nginx-quic
comparison src/event/quic/ngx_event_quic_streams.c @ 8697:e8cbbfabe547 quic
QUIC: update stream flow control credit on STREAM_DATA_BLOCKED.
Previously, after receiving STREAM_DATA_BLOCKED, current flow control limit
was sent to client. Now, if the limit can be updated to the full window size,
it is updated and the new value is sent to client, otherwise nothing is sent.
The change lets client update flow control credit on demand. Also, it saves
traffic by not sending MAX_STREAM_DATA with the same value twice.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Wed, 17 Nov 2021 23:07:38 +0300 |
parents | 41caf5410110 |
children | d041b8d6ab0b |
comparison
equal
deleted
inserted
replaced
8696:122bfa14465b | 8697:e8cbbfabe547 |
---|---|
29 ngx_chain_t *in, off_t limit); | 29 ngx_chain_t *in, off_t limit); |
30 static size_t ngx_quic_max_stream_flow(ngx_connection_t *c); | 30 static size_t ngx_quic_max_stream_flow(ngx_connection_t *c); |
31 static void ngx_quic_stream_cleanup_handler(void *data); | 31 static void ngx_quic_stream_cleanup_handler(void *data); |
32 static ngx_int_t ngx_quic_control_flow(ngx_connection_t *c, uint64_t last); | 32 static ngx_int_t ngx_quic_control_flow(ngx_connection_t *c, uint64_t last); |
33 static ngx_int_t ngx_quic_update_flow(ngx_connection_t *c, uint64_t last); | 33 static ngx_int_t ngx_quic_update_flow(ngx_connection_t *c, uint64_t last); |
34 static ngx_int_t ngx_quic_update_max_stream_data(ngx_connection_t *c); | |
34 | 35 |
35 | 36 |
36 ngx_connection_t * | 37 ngx_connection_t * |
37 ngx_quic_open_stream(ngx_connection_t *c, ngx_uint_t bidi) | 38 ngx_quic_open_stream(ngx_connection_t *c, ngx_uint_t bidi) |
38 { | 39 { |
1188 | 1189 |
1189 ngx_int_t | 1190 ngx_int_t |
1190 ngx_quic_handle_stream_data_blocked_frame(ngx_connection_t *c, | 1191 ngx_quic_handle_stream_data_blocked_frame(ngx_connection_t *c, |
1191 ngx_quic_header_t *pkt, ngx_quic_stream_data_blocked_frame_t *f) | 1192 ngx_quic_header_t *pkt, ngx_quic_stream_data_blocked_frame_t *f) |
1192 { | 1193 { |
1193 uint64_t limit; | |
1194 ngx_quic_frame_t *frame; | |
1195 ngx_quic_stream_t *qs; | 1194 ngx_quic_stream_t *qs; |
1196 ngx_quic_connection_t *qc; | 1195 ngx_quic_connection_t *qc; |
1197 | 1196 |
1198 qc = ngx_quic_get_connection(c); | 1197 qc = ngx_quic_get_connection(c); |
1199 | 1198 |
1215 | 1214 |
1216 if (qs == NGX_QUIC_STREAM_GONE) { | 1215 if (qs == NGX_QUIC_STREAM_GONE) { |
1217 return NGX_OK; | 1216 return NGX_OK; |
1218 } | 1217 } |
1219 | 1218 |
1220 limit = qs->recv_max_data; | 1219 return ngx_quic_init_stream(qs); |
1221 | 1220 } |
1222 if (ngx_quic_init_stream(qs) != NGX_OK) { | 1221 |
1223 return NGX_ERROR; | 1222 return ngx_quic_update_max_stream_data(qs->connection); |
1224 } | |
1225 | |
1226 } else { | |
1227 limit = qs->recv_max_data; | |
1228 } | |
1229 | |
1230 frame = ngx_quic_alloc_frame(c); | |
1231 if (frame == NULL) { | |
1232 return NGX_ERROR; | |
1233 } | |
1234 | |
1235 frame->level = pkt->level; | |
1236 frame->type = NGX_QUIC_FT_MAX_STREAM_DATA; | |
1237 frame->u.max_stream_data.id = f->id; | |
1238 frame->u.max_stream_data.limit = limit; | |
1239 | |
1240 ngx_quic_queue_frame(qc, frame); | |
1241 | |
1242 return NGX_OK; | |
1243 } | 1223 } |
1244 | 1224 |
1245 | 1225 |
1246 ngx_int_t | 1226 ngx_int_t |
1247 ngx_quic_handle_max_stream_data_frame(ngx_connection_t *c, | 1227 ngx_quic_handle_max_stream_data_frame(ngx_connection_t *c, |
1585 qs->recv_offset += len; | 1565 qs->recv_offset += len; |
1586 | 1566 |
1587 if (!rev->pending_eof && !rev->error | 1567 if (!rev->pending_eof && !rev->error |
1588 && qs->recv_max_data <= qs->recv_offset + qs->recv_window / 2) | 1568 && qs->recv_max_data <= qs->recv_offset + qs->recv_window / 2) |
1589 { | 1569 { |
1590 qs->recv_max_data = qs->recv_offset + qs->recv_window; | 1570 if (ngx_quic_update_max_stream_data(c) != NGX_OK) { |
1591 | |
1592 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1593 "quic flow update msd:%uL", qs->recv_max_data); | |
1594 | |
1595 frame = ngx_quic_alloc_frame(pc); | |
1596 if (frame == NULL) { | |
1597 return NGX_ERROR; | 1571 return NGX_ERROR; |
1598 } | 1572 } |
1599 | |
1600 frame->level = ssl_encryption_application; | |
1601 frame->type = NGX_QUIC_FT_MAX_STREAM_DATA; | |
1602 frame->u.max_stream_data.id = qs->id; | |
1603 frame->u.max_stream_data.limit = qs->recv_max_data; | |
1604 | |
1605 ngx_quic_queue_frame(qc, frame); | |
1606 } | 1573 } |
1607 | 1574 |
1608 qc->streams.recv_offset += len; | 1575 qc->streams.recv_offset += len; |
1609 | 1576 |
1610 if (qc->streams.recv_max_data | 1577 if (qc->streams.recv_max_data |
1630 | 1597 |
1631 return NGX_OK; | 1598 return NGX_OK; |
1632 } | 1599 } |
1633 | 1600 |
1634 | 1601 |
1602 static ngx_int_t | |
1603 ngx_quic_update_max_stream_data(ngx_connection_t *c) | |
1604 { | |
1605 uint64_t recv_max_data; | |
1606 ngx_connection_t *pc; | |
1607 ngx_quic_frame_t *frame; | |
1608 ngx_quic_stream_t *qs; | |
1609 ngx_quic_connection_t *qc; | |
1610 | |
1611 qs = c->quic; | |
1612 pc = qs->parent; | |
1613 qc = ngx_quic_get_connection(pc); | |
1614 | |
1615 recv_max_data = qs->recv_offset + qs->recv_window; | |
1616 | |
1617 if (qs->recv_max_data == recv_max_data) { | |
1618 return NGX_OK; | |
1619 } | |
1620 | |
1621 qs->recv_max_data = recv_max_data; | |
1622 | |
1623 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1624 "quic flow update msd:%uL", qs->recv_max_data); | |
1625 | |
1626 frame = ngx_quic_alloc_frame(pc); | |
1627 if (frame == NULL) { | |
1628 return NGX_ERROR; | |
1629 } | |
1630 | |
1631 frame->level = ssl_encryption_application; | |
1632 frame->type = NGX_QUIC_FT_MAX_STREAM_DATA; | |
1633 frame->u.max_stream_data.id = qs->id; | |
1634 frame->u.max_stream_data.limit = qs->recv_max_data; | |
1635 | |
1636 ngx_quic_queue_frame(qc, frame); | |
1637 | |
1638 return NGX_OK; | |
1639 } | |
1640 | |
1641 | |
1635 ngx_int_t | 1642 ngx_int_t |
1636 ngx_quic_handle_read_event(ngx_event_t *rev, ngx_uint_t flags) | 1643 ngx_quic_handle_read_event(ngx_event_t *rev, ngx_uint_t flags) |
1637 { | 1644 { |
1638 if (!rev->active && !rev->ready) { | 1645 if (!rev->active && !rev->ready) { |
1639 rev->active = 1; | 1646 rev->active = 1; |