Latest update - 9194
This commit is contained in:
@@ -265,16 +265,16 @@ ngx_quic_handle_ack_frame_range(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx,
|
||||
}
|
||||
|
||||
if (f->pnum == max) {
|
||||
st->max_pn = f->last;
|
||||
st->max_pn = f->send_time;
|
||||
}
|
||||
|
||||
/* save earliest and latest send times of frames ack'ed */
|
||||
if (st->oldest == NGX_TIMER_INFINITE || f->last < st->oldest) {
|
||||
st->oldest = f->last;
|
||||
if (st->oldest == NGX_TIMER_INFINITE || f->send_time < st->oldest) {
|
||||
st->oldest = f->send_time;
|
||||
}
|
||||
|
||||
if (st->newest == NGX_TIMER_INFINITE || f->last > st->newest) {
|
||||
st->newest = f->last;
|
||||
if (st->newest == NGX_TIMER_INFINITE || f->send_time > st->newest) {
|
||||
st->newest = f->send_time;
|
||||
}
|
||||
|
||||
ngx_queue_remove(&f->queue);
|
||||
@@ -329,7 +329,7 @@ ngx_quic_congestion_ack(ngx_connection_t *c, ngx_quic_frame_t *f)
|
||||
|
||||
cg->in_flight -= f->plen;
|
||||
|
||||
timer = f->last - cg->recovery_start;
|
||||
timer = f->send_time - cg->recovery_start;
|
||||
|
||||
if ((ngx_msec_int_t) timer <= 0) {
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
@@ -465,7 +465,7 @@ ngx_quic_detect_lost(ngx_connection_t *c, ngx_quic_ack_stat_t *st)
|
||||
break;
|
||||
}
|
||||
|
||||
wait = start->last + thr - now;
|
||||
wait = start->send_time + thr - now;
|
||||
|
||||
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"quic detect_lost pnum:%uL thr:%M wait:%i level:%d",
|
||||
@@ -477,14 +477,14 @@ ngx_quic_detect_lost(ngx_connection_t *c, ngx_quic_ack_stat_t *st)
|
||||
break;
|
||||
}
|
||||
|
||||
if (start->last > qc->first_rtt) {
|
||||
if (start->send_time > qc->first_rtt) {
|
||||
|
||||
if (oldest == NGX_TIMER_INFINITE || start->last < oldest) {
|
||||
oldest = start->last;
|
||||
if (oldest == NGX_TIMER_INFINITE || start->send_time < oldest) {
|
||||
oldest = start->send_time;
|
||||
}
|
||||
|
||||
if (newest == NGX_TIMER_INFINITE || start->last > newest) {
|
||||
newest = start->last;
|
||||
if (newest == NGX_TIMER_INFINITE || start->send_time > newest) {
|
||||
newest = start->send_time;
|
||||
}
|
||||
|
||||
nlost++;
|
||||
@@ -593,6 +593,7 @@ ngx_quic_resend_frames(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx)
|
||||
break;
|
||||
|
||||
case NGX_QUIC_FT_PING:
|
||||
case NGX_QUIC_FT_PATH_CHALLENGE:
|
||||
case NGX_QUIC_FT_PATH_RESPONSE:
|
||||
case NGX_QUIC_FT_CONNECTION_CLOSE:
|
||||
ngx_quic_free_frame(c, f);
|
||||
@@ -671,7 +672,7 @@ ngx_quic_congestion_lost(ngx_connection_t *c, ngx_quic_frame_t *f)
|
||||
cg->in_flight -= f->plen;
|
||||
f->plen = 0;
|
||||
|
||||
timer = f->last - cg->recovery_start;
|
||||
timer = f->send_time - cg->recovery_start;
|
||||
|
||||
if ((ngx_msec_int_t) timer <= 0) {
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
@@ -729,7 +730,8 @@ ngx_quic_set_lost_timer(ngx_connection_t *c)
|
||||
if (ctx->largest_ack != NGX_QUIC_UNSET_PN) {
|
||||
q = ngx_queue_head(&ctx->sent);
|
||||
f = ngx_queue_data(q, ngx_quic_frame_t, queue);
|
||||
w = (ngx_msec_int_t) (f->last + ngx_quic_lost_threshold(qc) - now);
|
||||
w = (ngx_msec_int_t)
|
||||
(f->send_time + ngx_quic_lost_threshold(qc) - now);
|
||||
|
||||
if (f->pnum <= ctx->largest_ack) {
|
||||
if (w < 0 || ctx->largest_ack - f->pnum >= NGX_QUIC_PKT_THR) {
|
||||
@@ -744,8 +746,8 @@ ngx_quic_set_lost_timer(ngx_connection_t *c)
|
||||
|
||||
q = ngx_queue_last(&ctx->sent);
|
||||
f = ngx_queue_data(q, ngx_quic_frame_t, queue);
|
||||
w = (ngx_msec_int_t) (f->last + (ngx_quic_pto(c, ctx) << qc->pto_count)
|
||||
- now);
|
||||
w = (ngx_msec_int_t)
|
||||
(f->send_time + (ngx_quic_pto(c, ctx) << qc->pto_count) - now);
|
||||
|
||||
if (w < 0) {
|
||||
w = 0;
|
||||
@@ -824,11 +826,12 @@ void ngx_quic_lost_handler(ngx_event_t *ev)
|
||||
void
|
||||
ngx_quic_pto_handler(ngx_event_t *ev)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
ngx_uint_t i, n;
|
||||
ngx_msec_t now;
|
||||
ngx_queue_t *q;
|
||||
ngx_msec_int_t w;
|
||||
ngx_connection_t *c;
|
||||
ngx_quic_frame_t *f, frame;
|
||||
ngx_quic_frame_t *f;
|
||||
ngx_quic_send_ctx_t *ctx;
|
||||
ngx_quic_connection_t *qc;
|
||||
|
||||
@@ -848,6 +851,8 @@ ngx_quic_pto_handler(ngx_event_t *ev)
|
||||
|
||||
q = ngx_queue_last(&ctx->sent);
|
||||
f = ngx_queue_data(q, ngx_quic_frame_t, queue);
|
||||
w = (ngx_msec_int_t)
|
||||
(f->send_time + (ngx_quic_pto(c, ctx) << qc->pto_count) - now);
|
||||
|
||||
if (f->pnum <= ctx->largest_ack
|
||||
&& ctx->largest_ack != NGX_QUIC_UNSET_PN)
|
||||
@@ -855,9 +860,7 @@ ngx_quic_pto_handler(ngx_event_t *ev)
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((ngx_msec_int_t) (f->last + (ngx_quic_pto(c, ctx) << qc->pto_count)
|
||||
- now) > 0)
|
||||
{
|
||||
if (w > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -865,16 +868,20 @@ ngx_quic_pto_handler(ngx_event_t *ev)
|
||||
"quic pto %s pto_count:%ui",
|
||||
ngx_quic_level_name(ctx->level), qc->pto_count);
|
||||
|
||||
ngx_memzero(&frame, sizeof(ngx_quic_frame_t));
|
||||
for (n = 0; n < 2; n++) {
|
||||
|
||||
frame.level = ctx->level;
|
||||
frame.type = NGX_QUIC_FT_PING;
|
||||
f = ngx_quic_alloc_frame(c);
|
||||
if (f == NULL) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (ngx_quic_frame_sendto(c, &frame, 0, qc->path) != NGX_OK
|
||||
|| ngx_quic_frame_sendto(c, &frame, 0, qc->path) != NGX_OK)
|
||||
{
|
||||
ngx_quic_close_connection(c, NGX_ERROR);
|
||||
return;
|
||||
f->level = ctx->level;
|
||||
f->type = NGX_QUIC_FT_PING;
|
||||
f->ignore_congestion = 1;
|
||||
|
||||
if (ngx_quic_frame_sendto(c, f, 0, qc->path) == NGX_ERROR) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -883,6 +890,13 @@ ngx_quic_pto_handler(ngx_event_t *ev)
|
||||
ngx_quic_set_lost_timer(c);
|
||||
|
||||
ngx_quic_connstate_dbg(c);
|
||||
|
||||
return;
|
||||
|
||||
failed:
|
||||
|
||||
ngx_quic_close_connection(c, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -106,13 +106,13 @@ struct ngx_quic_path_s {
|
||||
size_t max_mtu;
|
||||
off_t sent;
|
||||
off_t received;
|
||||
u_char challenge1[8];
|
||||
u_char challenge2[8];
|
||||
u_char challenge[2][8];
|
||||
uint64_t seqnum;
|
||||
uint64_t mtu_pnum[NGX_QUIC_PATH_RETRIES];
|
||||
ngx_str_t addr_text;
|
||||
u_char text[NGX_SOCKADDR_STRLEN];
|
||||
ngx_uint_t validated; /* unsigned validated:1; */
|
||||
unsigned validated:1;
|
||||
unsigned mtu_unvalidated:1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -36,16 +36,28 @@ ngx_int_t
|
||||
ngx_quic_handle_path_challenge_frame(ngx_connection_t *c,
|
||||
ngx_quic_header_t *pkt, ngx_quic_path_challenge_frame_t *f)
|
||||
{
|
||||
ngx_quic_frame_t frame, *fp;
|
||||
size_t min;
|
||||
ngx_quic_frame_t *fp;
|
||||
ngx_quic_connection_t *qc;
|
||||
|
||||
if (pkt->level != ssl_encryption_application || pkt->path_challenged) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"quic ignoring PATH_CHALLENGE");
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
pkt->path_challenged = 1;
|
||||
|
||||
qc = ngx_quic_get_connection(c);
|
||||
|
||||
ngx_memzero(&frame, sizeof(ngx_quic_frame_t));
|
||||
fp = ngx_quic_alloc_frame(c);
|
||||
if (fp == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
frame.level = ssl_encryption_application;
|
||||
frame.type = NGX_QUIC_FT_PATH_RESPONSE;
|
||||
frame.u.path_response = *f;
|
||||
fp->level = ssl_encryption_application;
|
||||
fp->type = NGX_QUIC_FT_PATH_RESPONSE;
|
||||
fp->u.path_response = *f;
|
||||
|
||||
/*
|
||||
* RFC 9000, 8.2.2. Path Validation Responses
|
||||
@@ -57,8 +69,14 @@ ngx_quic_handle_path_challenge_frame(ngx_connection_t *c,
|
||||
/*
|
||||
* An endpoint MUST expand datagrams that contain a PATH_RESPONSE frame
|
||||
* to at least the smallest allowed maximum datagram size of 1200 bytes.
|
||||
* ...
|
||||
* However, an endpoint MUST NOT expand the datagram containing the
|
||||
* PATH_RESPONSE if the resulting data exceeds the anti-amplification limit.
|
||||
*/
|
||||
if (ngx_quic_frame_sendto(c, &frame, 1200, pkt->path) == NGX_ERROR) {
|
||||
|
||||
min = (ngx_quic_path_limit(c, pkt->path, 1200) < 1200) ? 0 : 1200;
|
||||
|
||||
if (ngx_quic_frame_sendto(c, fp, min, pkt->path) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@@ -113,8 +131,8 @@ ngx_quic_handle_path_response_frame(ngx_connection_t *c,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_memcmp(path->challenge1, f->data, sizeof(f->data)) == 0
|
||||
|| ngx_memcmp(path->challenge2, f->data, sizeof(f->data)) == 0)
|
||||
if (ngx_memcmp(path->challenge[0], f->data, sizeof(f->data)) == 0
|
||||
|| ngx_memcmp(path->challenge[1], f->data, sizeof(f->data)) == 0)
|
||||
{
|
||||
goto valid;
|
||||
}
|
||||
@@ -151,6 +169,7 @@ valid:
|
||||
|
||||
path->mtu = prev->mtu;
|
||||
path->max_mtu = prev->max_mtu;
|
||||
path->mtu_unvalidated = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,6 +183,13 @@ valid:
|
||||
qc->congestion.recovery_start = ngx_current_msec;
|
||||
}
|
||||
|
||||
path->validated = 1;
|
||||
|
||||
if (path->mtu_unvalidated) {
|
||||
path->mtu_unvalidated = 0;
|
||||
return ngx_quic_validate_path(c, path);
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 9000, 9.3. Responding to Connection Migration
|
||||
*
|
||||
@@ -181,8 +207,6 @@ valid:
|
||||
|
||||
ngx_quic_path_dbg(c, "is validated", path);
|
||||
|
||||
path->validated = 1;
|
||||
|
||||
ngx_quic_discover_path_mtu(c, path);
|
||||
|
||||
return NGX_OK;
|
||||
@@ -510,11 +534,7 @@ ngx_quic_validate_path(ngx_connection_t *c, ngx_quic_path_t *path)
|
||||
|
||||
path->tries = 0;
|
||||
|
||||
if (RAND_bytes(path->challenge1, 8) != 1) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (RAND_bytes(path->challenge2, 8) != 1) {
|
||||
if (RAND_bytes((u_char *) path->challenge, sizeof(path->challenge)) != 1) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@@ -535,18 +555,25 @@ ngx_quic_validate_path(ngx_connection_t *c, ngx_quic_path_t *path)
|
||||
static ngx_int_t
|
||||
ngx_quic_send_path_challenge(ngx_connection_t *c, ngx_quic_path_t *path)
|
||||
{
|
||||
ngx_quic_frame_t frame;
|
||||
size_t min;
|
||||
ngx_uint_t n;
|
||||
ngx_quic_frame_t *frame;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"quic path seq:%uL send path_challenge tries:%ui",
|
||||
path->seqnum, path->tries);
|
||||
|
||||
ngx_memzero(&frame, sizeof(ngx_quic_frame_t));
|
||||
for (n = 0; n < 2; n++) {
|
||||
|
||||
frame.level = ssl_encryption_application;
|
||||
frame.type = NGX_QUIC_FT_PATH_CHALLENGE;
|
||||
frame = ngx_quic_alloc_frame(c);
|
||||
if (frame == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(frame.u.path_challenge.data, path->challenge1, 8);
|
||||
frame->level = ssl_encryption_application;
|
||||
frame->type = NGX_QUIC_FT_PATH_CHALLENGE;
|
||||
|
||||
ngx_memcpy(frame->u.path_challenge.data, path->challenge[n], 8);
|
||||
|
||||
/*
|
||||
* RFC 9000, 8.2.1. Initiating Path Validation
|
||||
@@ -557,16 +584,20 @@ ngx_quic_send_path_challenge(ngx_connection_t *c, ngx_quic_path_t *path)
|
||||
* sending a datagram of this size.
|
||||
*/
|
||||
|
||||
/* same applies to PATH_RESPONSE frames */
|
||||
if (ngx_quic_frame_sendto(c, &frame, 1200, path) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
if (path->mtu_unvalidated
|
||||
|| ngx_quic_path_limit(c, path, 1200) < 1200)
|
||||
{
|
||||
min = 0;
|
||||
path->mtu_unvalidated = 1;
|
||||
|
||||
} else {
|
||||
min = 1200;
|
||||
}
|
||||
|
||||
ngx_memcpy(frame.u.path_challenge.data, path->challenge2, 8);
|
||||
|
||||
if (ngx_quic_frame_sendto(c, &frame, 1200, path) == NGX_ERROR) {
|
||||
if (ngx_quic_frame_sendto(c, frame, min, path) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
@@ -869,16 +900,20 @@ ngx_quic_expire_path_mtu_discovery(ngx_connection_t *c, ngx_quic_path_t *path)
|
||||
static ngx_int_t
|
||||
ngx_quic_send_path_mtu_probe(ngx_connection_t *c, ngx_quic_path_t *path)
|
||||
{
|
||||
size_t mtu;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t log_error;
|
||||
ngx_quic_frame_t frame;
|
||||
ngx_quic_frame_t *frame;
|
||||
ngx_quic_send_ctx_t *ctx;
|
||||
ngx_quic_connection_t *qc;
|
||||
|
||||
ngx_memzero(&frame, sizeof(ngx_quic_frame_t));
|
||||
frame = ngx_quic_alloc_frame(c);
|
||||
if (frame == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
frame.level = ssl_encryption_application;
|
||||
frame.type = NGX_QUIC_FT_PING;
|
||||
frame->level = ssl_encryption_application;
|
||||
frame->type = NGX_QUIC_FT_PING;
|
||||
|
||||
qc = ngx_quic_get_connection(c);
|
||||
ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application);
|
||||
@@ -892,7 +927,12 @@ ngx_quic_send_path_mtu_probe(ngx_connection_t *c, ngx_quic_path_t *path)
|
||||
log_error = c->log_error;
|
||||
c->log_error = NGX_ERROR_IGNORE_EMSGSIZE;
|
||||
|
||||
rc = ngx_quic_frame_sendto(c, &frame, path->mtud, path);
|
||||
mtu = path->mtu;
|
||||
path->mtu = path->mtud;
|
||||
|
||||
rc = ngx_quic_frame_sendto(c, frame, path->mtud, path);
|
||||
|
||||
path->mtu = mtu;
|
||||
c->log_error = log_error;
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
|
||||
@@ -63,8 +63,6 @@ static ssize_t ngx_quic_send(ngx_connection_t *c, u_char *buf, size_t len,
|
||||
struct sockaddr *sockaddr, socklen_t socklen);
|
||||
static void ngx_quic_set_packet_number(ngx_quic_header_t *pkt,
|
||||
ngx_quic_send_ctx_t *ctx);
|
||||
static size_t ngx_quic_path_limit(ngx_connection_t *c, ngx_quic_path_t *path,
|
||||
size_t size);
|
||||
|
||||
|
||||
ngx_int_t
|
||||
@@ -588,8 +586,7 @@ ngx_quic_output_packet(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx,
|
||||
}
|
||||
|
||||
f->pnum = ctx->pnum;
|
||||
f->first = now;
|
||||
f->last = now;
|
||||
f->send_time = now;
|
||||
f->plen = 0;
|
||||
|
||||
ngx_quic_log_frame(c->log, f, 1);
|
||||
@@ -846,7 +843,7 @@ ngx_quic_send_stateless_reset(ngx_connection_t *c, ngx_quic_conf_t *conf,
|
||||
ngx_int_t
|
||||
ngx_quic_send_cc(ngx_connection_t *c)
|
||||
{
|
||||
ngx_quic_frame_t frame;
|
||||
ngx_quic_frame_t *frame;
|
||||
ngx_quic_connection_t *qc;
|
||||
|
||||
qc = ngx_quic_get_connection(c);
|
||||
@@ -862,22 +859,27 @@ ngx_quic_send_cc(ngx_connection_t *c)
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ngx_memzero(&frame, sizeof(ngx_quic_frame_t));
|
||||
frame = ngx_quic_alloc_frame(c);
|
||||
if (frame == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
frame.level = qc->error_level;
|
||||
frame.type = qc->error_app ? NGX_QUIC_FT_CONNECTION_CLOSE_APP
|
||||
frame->level = qc->error_level;
|
||||
frame->type = qc->error_app ? NGX_QUIC_FT_CONNECTION_CLOSE_APP
|
||||
: NGX_QUIC_FT_CONNECTION_CLOSE;
|
||||
frame.u.close.error_code = qc->error;
|
||||
frame.u.close.frame_type = qc->error_ftype;
|
||||
frame->u.close.error_code = qc->error;
|
||||
frame->u.close.frame_type = qc->error_ftype;
|
||||
|
||||
if (qc->error_reason) {
|
||||
frame.u.close.reason.len = ngx_strlen(qc->error_reason);
|
||||
frame.u.close.reason.data = (u_char *) qc->error_reason;
|
||||
frame->u.close.reason.len = ngx_strlen(qc->error_reason);
|
||||
frame->u.close.reason.data = (u_char *) qc->error_reason;
|
||||
}
|
||||
|
||||
frame->ignore_congestion = 1;
|
||||
|
||||
qc->last_cc = ngx_current_msec;
|
||||
|
||||
return ngx_quic_frame_sendto(c, &frame, 0, qc->path);
|
||||
return ngx_quic_frame_sendto(c, frame, 0, qc->path);
|
||||
}
|
||||
|
||||
|
||||
@@ -1183,28 +1185,49 @@ ngx_int_t
|
||||
ngx_quic_frame_sendto(ngx_connection_t *c, ngx_quic_frame_t *frame,
|
||||
size_t min, ngx_quic_path_t *path)
|
||||
{
|
||||
size_t min_payload, pad;
|
||||
size_t max, max_payload, min_payload, pad;
|
||||
ssize_t len, sent;
|
||||
ngx_str_t res;
|
||||
ngx_msec_t now;
|
||||
ngx_quic_header_t pkt;
|
||||
ngx_quic_send_ctx_t *ctx;
|
||||
ngx_quic_congestion_t *cg;
|
||||
ngx_quic_connection_t *qc;
|
||||
|
||||
static u_char src[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
|
||||
static u_char dst[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
|
||||
|
||||
qc = ngx_quic_get_connection(c);
|
||||
cg = &qc->congestion;
|
||||
ctx = ngx_quic_get_send_ctx(qc, frame->level);
|
||||
|
||||
now = ngx_current_msec;
|
||||
|
||||
max = ngx_quic_path_limit(c, path, path->mtu);
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"quic sendto %s packet max:%uz min:%uz",
|
||||
ngx_quic_level_name(ctx->level), max, min);
|
||||
|
||||
if (cg->in_flight >= cg->window && !frame->ignore_congestion) {
|
||||
ngx_quic_free_frame(c, frame);
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
ngx_quic_init_packet(c, ctx, &pkt, path);
|
||||
|
||||
min = ngx_quic_path_limit(c, path, min);
|
||||
|
||||
min_payload = min ? ngx_quic_payload_size(&pkt, min) : 0;
|
||||
min_payload = ngx_quic_payload_size(&pkt, min);
|
||||
max_payload = ngx_quic_payload_size(&pkt, max);
|
||||
|
||||
/* RFC 9001, 5.4.2. Header Protection Sample */
|
||||
pad = 4 - pkt.num_len;
|
||||
min_payload = ngx_max(min_payload, pad);
|
||||
|
||||
if (min_payload > max_payload) {
|
||||
ngx_quic_free_frame(c, frame);
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
frame->pnum = pkt.number;
|
||||
#endif
|
||||
@@ -1212,12 +1235,14 @@ ngx_quic_frame_sendto(ngx_connection_t *c, ngx_quic_frame_t *frame,
|
||||
ngx_quic_log_frame(c->log, frame, 1);
|
||||
|
||||
len = ngx_quic_create_frame(NULL, frame);
|
||||
if (len > NGX_QUIC_MAX_UDP_PAYLOAD_SIZE) {
|
||||
return NGX_ERROR;
|
||||
if ((size_t) len > max_payload) {
|
||||
ngx_quic_free_frame(c, frame);
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
len = ngx_quic_create_frame(src, frame);
|
||||
if (len == -1) {
|
||||
ngx_quic_free_frame(c, frame);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@@ -1234,23 +1259,49 @@ ngx_quic_frame_sendto(ngx_connection_t *c, ngx_quic_frame_t *frame,
|
||||
ngx_quic_log_packet(c->log, &pkt);
|
||||
|
||||
if (ngx_quic_encrypt(&pkt, &res) != NGX_OK) {
|
||||
ngx_quic_free_frame(c, frame);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
frame->pnum = ctx->pnum;
|
||||
frame->send_time = now;
|
||||
frame->plen = res.len;
|
||||
|
||||
ctx->pnum++;
|
||||
|
||||
sent = ngx_quic_send(c, res.data, res.len, path->sockaddr, path->socklen);
|
||||
if (sent < 0) {
|
||||
ngx_quic_free_frame(c, frame);
|
||||
return sent;
|
||||
}
|
||||
|
||||
path->sent += sent;
|
||||
|
||||
if (frame->need_ack && !qc->closing) {
|
||||
ngx_queue_insert_tail(&ctx->sent, &frame->queue);
|
||||
|
||||
cg->in_flight += frame->plen;
|
||||
|
||||
} else {
|
||||
ngx_quic_free_frame(c, frame);
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"quic congestion send if:%uz", cg->in_flight);
|
||||
|
||||
if (!qc->send_timer_set) {
|
||||
qc->send_timer_set = 1;
|
||||
ngx_add_timer(c->read, qc->tp.max_idle_timeout);
|
||||
}
|
||||
|
||||
ngx_quic_set_lost_timer(c);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
size_t
|
||||
ngx_quic_path_limit(ngx_connection_t *c, ngx_quic_path_t *path, size_t size)
|
||||
{
|
||||
off_t max;
|
||||
@@ -1260,8 +1311,6 @@ ngx_quic_path_limit(ngx_connection_t *c, ngx_quic_path_t *path, size_t size)
|
||||
max = (path->sent >= max) ? 0 : max - path->sent;
|
||||
|
||||
if ((off_t) size > max) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"quic path limit %uz - %O", size, max);
|
||||
return max;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,5 +34,7 @@ ngx_int_t ngx_quic_send_ack_range(ngx_connection_t *c,
|
||||
|
||||
ngx_int_t ngx_quic_frame_sendto(ngx_connection_t *c, ngx_quic_frame_t *frame,
|
||||
size_t min, ngx_quic_path_t *path);
|
||||
size_t ngx_quic_path_limit(ngx_connection_t *c, ngx_quic_path_t *path,
|
||||
size_t size);
|
||||
|
||||
#endif /* _NGX_EVENT_QUIC_OUTPUT_H_INCLUDED_ */
|
||||
@@ -266,11 +266,11 @@ struct ngx_quic_frame_s {
|
||||
ngx_queue_t queue;
|
||||
uint64_t pnum;
|
||||
size_t plen;
|
||||
ngx_msec_t first;
|
||||
ngx_msec_t last;
|
||||
ngx_msec_t send_time;
|
||||
ssize_t len;
|
||||
unsigned need_ack:1;
|
||||
unsigned pkt_need_ack:1;
|
||||
unsigned ignore_congestion:1;
|
||||
|
||||
ngx_chain_t *data;
|
||||
union {
|
||||
@@ -336,6 +336,7 @@ typedef struct {
|
||||
unsigned retried:1;
|
||||
unsigned first:1;
|
||||
unsigned rebound:1;
|
||||
unsigned path_challenged:1;
|
||||
} ngx_quic_header_t;
|
||||
|
||||
|
||||
|
||||
@@ -451,19 +451,16 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
||||
|
||||
switch (ch) {
|
||||
case '/':
|
||||
r->port_end = p;
|
||||
r->uri_start = p;
|
||||
state = sw_after_slash_in_uri;
|
||||
break;
|
||||
case '?':
|
||||
r->port_end = p;
|
||||
r->uri_start = p;
|
||||
r->args_start = p + 1;
|
||||
r->empty_path_in_uri = 1;
|
||||
state = sw_uri;
|
||||
break;
|
||||
case ' ':
|
||||
r->port_end = p;
|
||||
/*
|
||||
* use single "/" from request line to preserve pointers,
|
||||
* if request line will be copied to large client buffer
|
||||
|
||||
@@ -1718,15 +1718,24 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
|
||||
r->request_end = new + (r->request_end - old);
|
||||
}
|
||||
|
||||
if (r->method_end) {
|
||||
r->method_end = new + (r->method_end - old);
|
||||
}
|
||||
|
||||
if (r->uri_start) {
|
||||
r->uri_start = new + (r->uri_start - old);
|
||||
}
|
||||
|
||||
if (r->uri_end) {
|
||||
r->uri_end = new + (r->uri_end - old);
|
||||
}
|
||||
|
||||
if (r->schema_start) {
|
||||
r->schema_start = new + (r->schema_start - old);
|
||||
if (r->schema_end) {
|
||||
r->schema_end = new + (r->schema_end - old);
|
||||
}
|
||||
}
|
||||
|
||||
if (r->host_start) {
|
||||
r->host_start = new + (r->host_start - old);
|
||||
@@ -1735,11 +1744,6 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
|
||||
}
|
||||
}
|
||||
|
||||
if (r->port_start) {
|
||||
r->port_start = new + (r->port_start - old);
|
||||
r->port_end = new + (r->port_end - old);
|
||||
}
|
||||
|
||||
if (r->uri_ext) {
|
||||
r->uri_ext = new + (r->uri_ext - old);
|
||||
}
|
||||
@@ -1754,10 +1758,19 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
|
||||
|
||||
} else {
|
||||
r->header_name_start = new;
|
||||
|
||||
if (r->header_name_end) {
|
||||
r->header_name_end = new + (r->header_name_end - old);
|
||||
}
|
||||
|
||||
if (r->header_start) {
|
||||
r->header_start = new + (r->header_start - old);
|
||||
}
|
||||
|
||||
if (r->header_end) {
|
||||
r->header_end = new + (r->header_end - old);
|
||||
}
|
||||
}
|
||||
|
||||
r->header_in = b;
|
||||
|
||||
|
||||
@@ -597,8 +597,6 @@ struct ngx_http_request_s {
|
||||
u_char *schema_end;
|
||||
u_char *host_start;
|
||||
u_char *host_end;
|
||||
u_char *port_start;
|
||||
u_char *port_end;
|
||||
|
||||
unsigned http_minor:16;
|
||||
unsigned http_major:16;
|
||||
|
||||
Reference in New Issue
Block a user