Mercurial > hg > nginx-quic
comparison src/event/quic/ngx_event_quic_streams.c @ 8984:2e51cf3ffd90 quic
QUIC: defer stream removal until all its data is acked.
Previously, stream was kept alive until all its data is sent. This resulted
in disabling retransmission of final part of stream when QUIC connection
was closed right after closing stream connection.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Mon, 22 Aug 2022 15:33:23 +0400 |
parents | 37d5dddabaea |
children | 740d7d6e8ff0 |
comparison
equal
deleted
inserted
replaced
8983:37d5dddabaea | 8984:2e51cf3ffd90 |
---|---|
885 return NGX_CHAIN_ERROR; | 885 return NGX_CHAIN_ERROR; |
886 } | 886 } |
887 | 887 |
888 qs->send_state = NGX_QUIC_STREAM_SEND_SEND; | 888 qs->send_state = NGX_QUIC_STREAM_SEND_SEND; |
889 | 889 |
890 flow = qs->acked + qc->conf->stream_buffer_size - c->sent; | 890 flow = qs->acked + qc->conf->stream_buffer_size - qs->sent; |
891 | 891 |
892 if (flow == 0) { | 892 if (flow == 0) { |
893 wev->ready = 0; | 893 wev->ready = 0; |
894 return in; | 894 return in; |
895 } | 895 } |
898 limit = flow; | 898 limit = flow; |
899 } | 899 } |
900 | 900 |
901 n = qs->send.size; | 901 n = qs->send.size; |
902 | 902 |
903 in = ngx_quic_write_buffer(pc, &qs->send, in, limit, c->sent); | 903 in = ngx_quic_write_buffer(pc, &qs->send, in, limit, qs->sent); |
904 if (in == NGX_CHAIN_ERROR) { | 904 if (in == NGX_CHAIN_ERROR) { |
905 return NGX_CHAIN_ERROR; | 905 return NGX_CHAIN_ERROR; |
906 } | 906 } |
907 | 907 |
908 n = qs->send.size - n; | 908 n = qs->send.size - n; |
909 c->sent += n; | 909 c->sent += n; |
910 qs->sent += n; | |
910 qc->streams.sent += n; | 911 qc->streams.sent += n; |
911 | 912 |
912 if (flow == n) { | 913 if (flow == n) { |
913 wev->ready = 0; | 914 wev->ready = 0; |
914 } | 915 } |
1043 qc = ngx_quic_get_connection(pc); | 1044 qc = ngx_quic_get_connection(pc); |
1044 | 1045 |
1045 if (!qc->closing) { | 1046 if (!qc->closing) { |
1046 /* make sure everything is sent and final size is received */ | 1047 /* make sure everything is sent and final size is received */ |
1047 | 1048 |
1048 if (qs->recv_state == NGX_QUIC_STREAM_RECV_RECV | 1049 if (qs->recv_state == NGX_QUIC_STREAM_RECV_RECV) { |
1049 || qs->send_state == NGX_QUIC_STREAM_SEND_READY | 1050 return NGX_OK; |
1050 || qs->send_state == NGX_QUIC_STREAM_SEND_SEND) | 1051 } |
1052 | |
1053 if (qs->send_state != NGX_QUIC_STREAM_SEND_DATA_RECVD | |
1054 && qs->send_state != NGX_QUIC_STREAM_SEND_RESET_RECVD) | |
1051 { | 1055 { |
1052 return NGX_OK; | 1056 return NGX_OK; |
1053 } | 1057 } |
1054 } | 1058 } |
1055 | 1059 |
1486 | 1490 |
1487 | 1491 |
1488 void | 1492 void |
1489 ngx_quic_handle_stream_ack(ngx_connection_t *c, ngx_quic_frame_t *f) | 1493 ngx_quic_handle_stream_ack(ngx_connection_t *c, ngx_quic_frame_t *f) |
1490 { | 1494 { |
1491 uint64_t sent, unacked; | 1495 uint64_t acked; |
1492 ngx_quic_stream_t *qs; | 1496 ngx_quic_stream_t *qs; |
1493 ngx_quic_connection_t *qc; | 1497 ngx_quic_connection_t *qc; |
1494 | 1498 |
1495 qc = ngx_quic_get_connection(c); | 1499 qc = ngx_quic_get_connection(c); |
1496 | 1500 |
1497 qs = ngx_quic_find_stream(&qc->streams.tree, f->u.stream.stream_id); | 1501 switch (f->type) { |
1498 if (qs == NULL) { | 1502 |
1503 case NGX_QUIC_FT_RESET_STREAM: | |
1504 | |
1505 qs = ngx_quic_find_stream(&qc->streams.tree, f->u.reset_stream.id); | |
1506 if (qs == NULL) { | |
1507 return; | |
1508 } | |
1509 | |
1510 qs->send_state = NGX_QUIC_STREAM_SEND_RESET_RECVD; | |
1511 | |
1512 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1513 "quic stream id:0x%xL ack reset final_size:%uL", | |
1514 qs->id, f->u.reset_stream.final_size); | |
1515 | |
1516 break; | |
1517 | |
1518 case NGX_QUIC_FT_STREAM: | |
1519 | |
1520 qs = ngx_quic_find_stream(&qc->streams.tree, f->u.stream.stream_id); | |
1521 if (qs == NULL) { | |
1522 return; | |
1523 } | |
1524 | |
1525 acked = qs->acked; | |
1526 qs->acked += f->u.stream.length; | |
1527 | |
1528 if (f->u.stream.fin) { | |
1529 qs->fin_acked = 1; | |
1530 } | |
1531 | |
1532 if (qs->send_state == NGX_QUIC_STREAM_SEND_DATA_SENT | |
1533 && qs->acked == qs->sent && qs->fin_acked) | |
1534 { | |
1535 qs->send_state = NGX_QUIC_STREAM_SEND_DATA_RECVD; | |
1536 } | |
1537 | |
1538 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1539 "quic stream id:0x%xL ack len:%uL fin:%d unacked:%uL", | |
1540 qs->id, f->u.stream.length, f->u.stream.fin, | |
1541 qs->sent - qs->acked); | |
1542 | |
1543 if (qs->connection | |
1544 && qs->sent - acked == qc->conf->stream_buffer_size | |
1545 && f->u.stream.length > 0) | |
1546 { | |
1547 ngx_quic_set_event(qs->connection->write); | |
1548 } | |
1549 | |
1550 break; | |
1551 | |
1552 default: | |
1499 return; | 1553 return; |
1500 } | 1554 } |
1501 | 1555 |
1502 if (qs->connection == NULL) { | 1556 if (qs->connection == NULL) { |
1503 qs->acked += f->u.stream.length; | 1557 ngx_quic_close_stream(qs); |
1504 return; | 1558 } |
1505 } | |
1506 | |
1507 sent = qs->connection->sent; | |
1508 unacked = sent - qs->acked; | |
1509 qs->acked += f->u.stream.length; | |
1510 | |
1511 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1512 "quic stream id:0x%xL ack len:%uL acked:%uL unacked:%uL", | |
1513 qs->id, f->u.stream.length, qs->acked, sent - qs->acked); | |
1514 | |
1515 if (unacked != qc->conf->stream_buffer_size) { | |
1516 /* not blocked on buffer size */ | |
1517 return; | |
1518 } | |
1519 | |
1520 ngx_quic_set_event(qs->connection->write); | |
1521 } | 1559 } |
1522 | 1560 |
1523 | 1561 |
1524 static ngx_int_t | 1562 static ngx_int_t |
1525 ngx_quic_control_flow(ngx_quic_stream_t *qs, uint64_t last) | 1563 ngx_quic_control_flow(ngx_quic_stream_t *qs, uint64_t last) |