ngx_ssl_t *ssl;
+ ngx_event_t push;
ngx_event_t retry;
ngx_queue_t free_frames;
static void ngx_quic_retransmit_handler(ngx_event_t *ev);
static ngx_int_t ngx_quic_retransmit_ns(ngx_connection_t *c,
ngx_quic_namespace_t *ns, ngx_msec_t *waitp);
+static void ngx_quic_push_handler(ngx_event_t *ev);
static void ngx_quic_rbtree_insert_stream(ngx_rbtree_node_t *temp,
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
qc->retry.handler = ngx_quic_retransmit_handler;
qc->retry.cancelable = 1;
+ qc->push.log = c->log;
+ qc->push.data = c;
+ qc->push.handler = ngx_quic_push_handler;
+ qc->push.cancelable = 1;
+
c->quic = qc;
qc->ssl = ssl;
qc->tp = *tp;
return;
}
+ if (qc->push.timer_set) {
+ ngx_del_timer(&qc->push);
+ }
+
if (qc->retry.timer_set) {
ngx_del_timer(&qc->retry);
}
ngx_sprintf(ack_frame->info, "ACK for PN=%d from frame handler level=%d", pkt->pn, ack_frame->level);
ngx_quic_queue_frame(qc, ack_frame);
- return ngx_quic_output(c);
+ // TODO: call output() after processing some special frames?
+ return NGX_OK;
}
ns = &qc->ns[ngx_quic_ns(frame->level)];
ngx_queue_insert_tail(&ns->frames, &frame->queue);
+
+ /* TODO: check PUSH flag on stream and call output */
+
+ if (!qc->push.timer_set && !qc->closing) {
+ ngx_add_timer(&qc->push, qc->tp.max_ack_delay);
+ }
}
}
+static void
+ngx_quic_push_handler(ngx_event_t *ev)
+{
+ ngx_connection_t *c;
+ ngx_quic_connection_t *qc;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "push timer");
+
+ c = ev->data;
+ qc = c->quic;
+
+ if (ngx_quic_output(c) != NGX_OK) {
+ ngx_quic_close_connection(c);
+ return;
+ }
+
+ ngx_add_timer(&qc->push, qc->tp.max_ack_delay);
+}
+
+
static ngx_int_t
ngx_quic_retransmit_ns(ngx_connection_t *c, ngx_quic_namespace_t *ns,
ngx_msec_t *waitp)
ngx_quic_queue_frame(qc, frame);
- ngx_quic_output(pc);
-
return size;
}