changeset 8470:0d1ad81dd65c quic

QUIC: delay field of an ACK frame is now calculated.
author Vladimir Homutov <vl@nginx.com>
date Fri, 10 Jul 2020 15:33:51 +0300
parents 3b107aadc9f6
children 9ed4c12ec948
files src/event/ngx_event_quic.c src/event/ngx_event_quic_transport.c src/event/ngx_event_quic_transport.h
diffstat 3 files changed, 28 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/event/ngx_event_quic.c
+++ b/src/event/ngx_event_quic.c
@@ -188,6 +188,8 @@ static ngx_int_t ngx_quic_app_input(ngx_
 static ngx_int_t ngx_quic_payload_handler(ngx_connection_t *c,
     ngx_quic_header_t *pkt);
 static ngx_int_t ngx_quic_send_ack(ngx_connection_t *c, ngx_quic_header_t *pkt);
+static ngx_int_t ngx_quic_ack_delay(ngx_connection_t *c,
+    struct timeval *received, enum ssl_encryption_level_t level);
 static ngx_int_t ngx_quic_send_cc(ngx_connection_t *c);
 static ngx_int_t ngx_quic_send_new_token(ngx_connection_t *c);
 
@@ -1877,6 +1879,8 @@ ngx_quic_app_input(ngx_connection_t *c, 
         return rc;
     }
 
+    ngx_gettimeofday(&pkt->received);
+
     /* switch keys on Key Phase change */
 
     if (pkt->key_update) {
@@ -2132,6 +2136,7 @@ ngx_quic_send_ack(ngx_connection_t *c, n
 
     frame->type = NGX_QUIC_FT_ACK;
     frame->u.ack.largest = pkt->pn;
+    frame->u.ack.delay = ngx_quic_ack_delay(c, &pkt->received, frame->level);
 
     ngx_sprintf(frame->info, "ACK for PN=%d from frame handler level=%d",
                 pkt->pn, frame->level);
@@ -2142,6 +2147,26 @@ ngx_quic_send_ack(ngx_connection_t *c, n
 
 
 static ngx_int_t
+ngx_quic_ack_delay(ngx_connection_t *c, struct timeval *received,
+    enum ssl_encryption_level_t level)
+{
+    ngx_int_t       ack_delay;
+    struct timeval  tv;
+
+    ack_delay = 0;
+
+    if (level == ssl_encryption_application) {
+        ngx_gettimeofday(&tv);
+        ack_delay = (tv.tv_sec - received->tv_sec) * 1000000
+                    + tv.tv_usec - received->tv_usec;
+        ack_delay >>= c->quic->ctp.ack_delay_exponent;
+    }
+
+    return ack_delay;
+}
+
+
+static ngx_int_t
 ngx_quic_send_cc(ngx_connection_t *c)
 {
     ngx_quic_frame_t       *frame;
--- a/src/event/ngx_event_quic_transport.c
+++ b/src/event/ngx_event_quic_transport.c
@@ -1203,7 +1203,7 @@ ngx_quic_create_ack(u_char *p, ngx_quic_
     if (p == NULL) {
         len = ngx_quic_varint_len(NGX_QUIC_FT_ACK);
         len += ngx_quic_varint_len(ack->largest);
-        len += ngx_quic_varint_len(0);
+        len += ngx_quic_varint_len(ack->delay);
         len += ngx_quic_varint_len(0);
         len += ngx_quic_varint_len(ack->first_range);
 
@@ -1214,7 +1214,7 @@ ngx_quic_create_ack(u_char *p, ngx_quic_
 
     ngx_quic_build_int(&p, NGX_QUIC_FT_ACK);
     ngx_quic_build_int(&p, ack->largest);
-    ngx_quic_build_int(&p, 0);
+    ngx_quic_build_int(&p, ack->delay);
     ngx_quic_build_int(&p, 0);
     ngx_quic_build_int(&p, ack->first_range);
 
--- a/src/event/ngx_event_quic_transport.h
+++ b/src/event/ngx_event_quic_transport.h
@@ -283,6 +283,7 @@ typedef struct {
 
     struct ngx_quic_secret_s                   *secret;
     struct ngx_quic_secret_s                   *next;
+    struct timeval                              received;
     uint64_t                                    number;
     uint8_t                                     num_len;
     uint32_t                                    trunc;