comparison src/event/ngx_event_quic.c @ 8309:7ea2c68735f9 quic

Output buffering. Currently, the output is called periodically, each 200 ms to invoke ngx_quic_output() that will push all pending frames into packets. TODO: implement flags a-là Nagle & co (NO_DELAY/NO_PUSH...)
author Vladimir Homutov <vl@nginx.com>
date Wed, 01 Apr 2020 17:09:11 +0300
parents e10b4c61420f
children 6aceb85c5bed
comparison
equal deleted inserted replaced
8308:e10b4c61420f 8309:7ea2c68735f9
67 ngx_quic_secrets_t keys[NGX_QUIC_ENCRYPTION_LAST]; 67 ngx_quic_secrets_t keys[NGX_QUIC_ENCRYPTION_LAST];
68 uint64_t crypto_offset[NGX_QUIC_ENCRYPTION_LAST]; 68 uint64_t crypto_offset[NGX_QUIC_ENCRYPTION_LAST];
69 69
70 ngx_ssl_t *ssl; 70 ngx_ssl_t *ssl;
71 71
72 ngx_event_t push;
72 ngx_event_t retry; 73 ngx_event_t retry;
73 ngx_queue_t free_frames; 74 ngx_queue_t free_frames;
74 75
75 #if (NGX_DEBUG) 76 #if (NGX_DEBUG)
76 ngx_uint_t nframes; 77 ngx_uint_t nframes;
143 static void ngx_quic_free_frames(ngx_connection_t *c, ngx_queue_t *frames); 144 static void ngx_quic_free_frames(ngx_connection_t *c, ngx_queue_t *frames);
144 static ngx_int_t ngx_quic_send_frames(ngx_connection_t *c, ngx_queue_t *frames); 145 static ngx_int_t ngx_quic_send_frames(ngx_connection_t *c, ngx_queue_t *frames);
145 static void ngx_quic_retransmit_handler(ngx_event_t *ev); 146 static void ngx_quic_retransmit_handler(ngx_event_t *ev);
146 static ngx_int_t ngx_quic_retransmit_ns(ngx_connection_t *c, 147 static ngx_int_t ngx_quic_retransmit_ns(ngx_connection_t *c,
147 ngx_quic_namespace_t *ns, ngx_msec_t *waitp); 148 ngx_quic_namespace_t *ns, ngx_msec_t *waitp);
149 static void ngx_quic_push_handler(ngx_event_t *ev);
148 150
149 static void ngx_quic_rbtree_insert_stream(ngx_rbtree_node_t *temp, 151 static void ngx_quic_rbtree_insert_stream(ngx_rbtree_node_t *temp,
150 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); 152 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
151 static ngx_quic_stream_t *ngx_quic_find_stream(ngx_rbtree_t *rbtree, 153 static ngx_quic_stream_t *ngx_quic_find_stream(ngx_rbtree_t *rbtree,
152 uint64_t id); 154 uint64_t id);
462 qc->retry.log = c->log; 464 qc->retry.log = c->log;
463 qc->retry.data = c; 465 qc->retry.data = c;
464 qc->retry.handler = ngx_quic_retransmit_handler; 466 qc->retry.handler = ngx_quic_retransmit_handler;
465 qc->retry.cancelable = 1; 467 qc->retry.cancelable = 1;
466 468
469 qc->push.log = c->log;
470 qc->push.data = c;
471 qc->push.handler = ngx_quic_push_handler;
472 qc->push.cancelable = 1;
473
467 c->quic = qc; 474 c->quic = qc;
468 qc->ssl = ssl; 475 qc->ssl = ssl;
469 qc->tp = *tp; 476 qc->tp = *tp;
470 qc->streams.handler = handler; 477 qc->streams.handler = handler;
471 478
711 718
712 qc->closing = 1; 719 qc->closing = 1;
713 return; 720 return;
714 } 721 }
715 722
723 if (qc->push.timer_set) {
724 ngx_del_timer(&qc->push);
725 }
726
716 if (qc->retry.timer_set) { 727 if (qc->retry.timer_set) {
717 ngx_del_timer(&qc->retry); 728 ngx_del_timer(&qc->retry);
718 } 729 }
719 } 730 }
720 731
1161 ack_frame->u.ack.first_range = 0; 1172 ack_frame->u.ack.first_range = 0;
1162 1173
1163 ngx_sprintf(ack_frame->info, "ACK for PN=%d from frame handler level=%d", pkt->pn, ack_frame->level); 1174 ngx_sprintf(ack_frame->info, "ACK for PN=%d from frame handler level=%d", pkt->pn, ack_frame->level);
1164 ngx_quic_queue_frame(qc, ack_frame); 1175 ngx_quic_queue_frame(qc, ack_frame);
1165 1176
1166 return ngx_quic_output(c); 1177 // TODO: call output() after processing some special frames?
1178 return NGX_OK;
1167 } 1179 }
1168 1180
1169 1181
1170 static ngx_int_t 1182 static ngx_int_t
1171 ngx_quic_handle_ack_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, 1183 ngx_quic_handle_ack_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
1469 ngx_quic_namespace_t *ns; 1481 ngx_quic_namespace_t *ns;
1470 1482
1471 ns = &qc->ns[ngx_quic_ns(frame->level)]; 1483 ns = &qc->ns[ngx_quic_ns(frame->level)];
1472 1484
1473 ngx_queue_insert_tail(&ns->frames, &frame->queue); 1485 ngx_queue_insert_tail(&ns->frames, &frame->queue);
1486
1487 /* TODO: check PUSH flag on stream and call output */
1488
1489 if (!qc->push.timer_set && !qc->closing) {
1490 ngx_add_timer(&qc->push, qc->tp.max_ack_delay);
1491 }
1474 } 1492 }
1475 1493
1476 1494
1477 static ngx_int_t 1495 static ngx_int_t
1478 ngx_quic_output(ngx_connection_t *c) 1496 ngx_quic_output(ngx_connection_t *c)
1740 ngx_add_timer(&qc->retry, wait); 1758 ngx_add_timer(&qc->retry, wait);
1741 } 1759 }
1742 } 1760 }
1743 1761
1744 1762
1763 static void
1764 ngx_quic_push_handler(ngx_event_t *ev)
1765 {
1766 ngx_connection_t *c;
1767 ngx_quic_connection_t *qc;
1768
1769 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "push timer");
1770
1771 c = ev->data;
1772 qc = c->quic;
1773
1774 if (ngx_quic_output(c) != NGX_OK) {
1775 ngx_quic_close_connection(c);
1776 return;
1777 }
1778
1779 ngx_add_timer(&qc->push, qc->tp.max_ack_delay);
1780 }
1781
1782
1745 static ngx_int_t 1783 static ngx_int_t
1746 ngx_quic_retransmit_ns(ngx_connection_t *c, ngx_quic_namespace_t *ns, 1784 ngx_quic_retransmit_ns(ngx_connection_t *c, ngx_quic_namespace_t *ns,
1747 ngx_msec_t *waitp) 1785 ngx_msec_t *waitp)
1748 { 1786 {
1749 uint64_t pn; 1787 uint64_t pn;
2058 ngx_sprintf(frame->info, "stream %xi len=%ui level=%d", 2096 ngx_sprintf(frame->info, "stream %xi len=%ui level=%d",
2059 qs->id, size, frame->level); 2097 qs->id, size, frame->level);
2060 2098
2061 ngx_quic_queue_frame(qc, frame); 2099 ngx_quic_queue_frame(qc, frame);
2062 2100
2063 ngx_quic_output(pc);
2064
2065 return size; 2101 return size;
2066 } 2102 }
2067 2103
2068 2104
2069 static void 2105 static void