Mercurial > hg > nginx-quic
comparison src/event/quic/ngx_event_quic_streams.c @ 8698:d041b8d6ab0b quic
QUIC: handle DATA_BLOCKED frame from client.
Previously the frame was not handled and connection was closed with an error.
Now, after receiving this frame, global flow control is updated and new
flow control credit is sent to client.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Wed, 17 Nov 2021 23:07:51 +0300 |
parents | e8cbbfabe547 |
children | d6ef13c5fd8e |
comparison
equal
deleted
inserted
replaced
8697:e8cbbfabe547 | 8698:d041b8d6ab0b |
---|---|
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 static ngx_int_t ngx_quic_update_max_stream_data(ngx_connection_t *c); |
35 static ngx_int_t ngx_quic_update_max_data(ngx_connection_t *c); | |
35 | 36 |
36 | 37 |
37 ngx_connection_t * | 38 ngx_connection_t * |
38 ngx_quic_open_stream(ngx_connection_t *c, ngx_uint_t bidi) | 39 ngx_quic_open_stream(ngx_connection_t *c, ngx_uint_t bidi) |
39 { | 40 { |
1186 return NGX_OK; | 1187 return NGX_OK; |
1187 } | 1188 } |
1188 | 1189 |
1189 | 1190 |
1190 ngx_int_t | 1191 ngx_int_t |
1192 ngx_quic_handle_data_blocked_frame(ngx_connection_t *c, | |
1193 ngx_quic_header_t *pkt, ngx_quic_data_blocked_frame_t *f) | |
1194 { | |
1195 return ngx_quic_update_max_data(c); | |
1196 } | |
1197 | |
1198 | |
1199 ngx_int_t | |
1191 ngx_quic_handle_stream_data_blocked_frame(ngx_connection_t *c, | 1200 ngx_quic_handle_stream_data_blocked_frame(ngx_connection_t *c, |
1192 ngx_quic_header_t *pkt, ngx_quic_stream_data_blocked_frame_t *f) | 1201 ngx_quic_header_t *pkt, ngx_quic_stream_data_blocked_frame_t *f) |
1193 { | 1202 { |
1194 ngx_quic_stream_t *qs; | 1203 ngx_quic_stream_t *qs; |
1195 ngx_quic_connection_t *qc; | 1204 ngx_quic_connection_t *qc; |
1542 ngx_quic_update_flow(ngx_connection_t *c, uint64_t last) | 1551 ngx_quic_update_flow(ngx_connection_t *c, uint64_t last) |
1543 { | 1552 { |
1544 uint64_t len; | 1553 uint64_t len; |
1545 ngx_event_t *rev; | 1554 ngx_event_t *rev; |
1546 ngx_connection_t *pc; | 1555 ngx_connection_t *pc; |
1547 ngx_quic_frame_t *frame; | |
1548 ngx_quic_stream_t *qs; | 1556 ngx_quic_stream_t *qs; |
1549 ngx_quic_connection_t *qc; | 1557 ngx_quic_connection_t *qc; |
1550 | 1558 |
1551 rev = c->read; | 1559 rev = c->read; |
1552 qs = c->quic; | 1560 qs = c->quic; |
1575 qc->streams.recv_offset += len; | 1583 qc->streams.recv_offset += len; |
1576 | 1584 |
1577 if (qc->streams.recv_max_data | 1585 if (qc->streams.recv_max_data |
1578 <= qc->streams.recv_offset + qc->streams.recv_window / 2) | 1586 <= qc->streams.recv_offset + qc->streams.recv_window / 2) |
1579 { | 1587 { |
1580 qc->streams.recv_max_data = qc->streams.recv_offset | 1588 if (ngx_quic_update_max_data(pc) != NGX_OK) { |
1581 + qc->streams.recv_window; | |
1582 | |
1583 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0, | |
1584 "quic flow update md:%uL", qc->streams.recv_max_data); | |
1585 | |
1586 frame = ngx_quic_alloc_frame(pc); | |
1587 if (frame == NULL) { | |
1588 return NGX_ERROR; | 1589 return NGX_ERROR; |
1589 } | 1590 } |
1590 | |
1591 frame->level = ssl_encryption_application; | |
1592 frame->type = NGX_QUIC_FT_MAX_DATA; | |
1593 frame->u.max_data.max_data = qc->streams.recv_max_data; | |
1594 | |
1595 ngx_quic_queue_frame(qc, frame); | |
1596 } | 1591 } |
1597 | 1592 |
1598 return NGX_OK; | 1593 return NGX_OK; |
1599 } | 1594 } |
1600 | 1595 |
1637 | 1632 |
1638 return NGX_OK; | 1633 return NGX_OK; |
1639 } | 1634 } |
1640 | 1635 |
1641 | 1636 |
1637 static ngx_int_t | |
1638 ngx_quic_update_max_data(ngx_connection_t *c) | |
1639 { | |
1640 uint64_t recv_max_data; | |
1641 ngx_quic_frame_t *frame; | |
1642 ngx_quic_connection_t *qc; | |
1643 | |
1644 qc = ngx_quic_get_connection(c); | |
1645 | |
1646 recv_max_data = qc->streams.recv_offset + qc->streams.recv_window; | |
1647 | |
1648 if (qc->streams.recv_max_data == recv_max_data) { | |
1649 return NGX_OK; | |
1650 } | |
1651 | |
1652 qc->streams.recv_max_data = recv_max_data; | |
1653 | |
1654 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1655 "quic flow update md:%uL", qc->streams.recv_max_data); | |
1656 | |
1657 frame = ngx_quic_alloc_frame(c); | |
1658 if (frame == NULL) { | |
1659 return NGX_ERROR; | |
1660 } | |
1661 | |
1662 frame->level = ssl_encryption_application; | |
1663 frame->type = NGX_QUIC_FT_MAX_DATA; | |
1664 frame->u.max_data.max_data = qc->streams.recv_max_data; | |
1665 | |
1666 ngx_quic_queue_frame(qc, frame); | |
1667 | |
1668 return NGX_OK; | |
1669 } | |
1670 | |
1671 | |
1642 ngx_int_t | 1672 ngx_int_t |
1643 ngx_quic_handle_read_event(ngx_event_t *rev, ngx_uint_t flags) | 1673 ngx_quic_handle_read_event(ngx_event_t *rev, ngx_uint_t flags) |
1644 { | 1674 { |
1645 if (!rev->active && !rev->ready) { | 1675 if (!rev->active && !rev->ready) { |
1646 rev->active = 1; | 1676 rev->active = 1; |