comparison src/event/quic/ngx_event_quic_streams.c @ 8909: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
8908:e8cbbfabe547 8909: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;