diff --git a/src/event/ngx_event_quic.c b/src/event/ngx_event_quic.c index 4f380658d..62598d341 100644 --- 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_connection_t *c, 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, ngx_quic_header_t *pkt) 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, ngx_quic_header_t *pkt) 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); @@ -2141,6 +2146,26 @@ 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) +{ + 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) { diff --git a/src/event/ngx_event_quic_transport.c b/src/event/ngx_event_quic_transport.c index c7c8c46f2..7f9e49ff0 100644 --- 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_ack_frame_t *ack) 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_ack_frame_t *ack) 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); diff --git a/src/event/ngx_event_quic_transport.h b/src/event/ngx_event_quic_transport.h index 8aaec1bb0..661ffede1 100644 --- 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;