Latest update - GitHub 020b1db7e

This commit is contained in:
2025-04-22 21:10:22 +09:00
parent f35d500e17
commit 5a9ef13268
31 changed files with 683 additions and 162 deletions
+4
View File
@@ -26,6 +26,10 @@ ngx_msvc_ver=`echo $NGX_MSVC_VER | sed -e 's/^\([0-9]*\).*/\1/'`
case "$NGX_MSVC_VER" in case "$NGX_MSVC_VER" in
*ARM64)
NGX_MACHINE=arm64
;;
*x64) *x64)
NGX_MACHINE=amd64 NGX_MACHINE=amd64
;; ;;
+4
View File
@@ -13,6 +13,10 @@ case "$CC" in
OPENSSL_TARGET=VC-WIN64A OPENSSL_TARGET=VC-WIN64A
;; ;;
arm64)
OPENSSL_TARGET=VC-WIN64-ARM
;;
*) *)
OPENSSL_TARGET=VC-WIN32 OPENSSL_TARGET=VC-WIN32
;; ;;
+71
View File
@@ -5,6 +5,77 @@
<change_log title="nginx"> <change_log title="nginx">
<changes ver="1.27.5" date="2025-04-16">
<change type="feature">
<para lang="ru">
контроль перегрузки CUBIC в соединениях QUIC.
</para>
<para lang="en">
CUBIC congestion control in QUIC connections.
</para>
</change>
<change type="change">
<para lang="ru">
ограничение на максимальный размер кешируемых в разделяемой памяти
SSL-сессий поднято до 8192.
</para>
<para lang="en">
the maximum size limit for SSL sessions cached in shared memory
has been raised to 8192.
</para>
</change>
<change type="bugfix">
<para lang="ru">
в директивах grpc_ssl_password_file, proxy_ssl_password_file и
uwsgi_ssl_password_file
при загрузке SSL-сертификатов и зашифрованных ключей из переменных;
ошибка появилась в 1.23.1.
</para>
<para lang="en">
in the "grpc_ssl_password_file", "proxy_ssl_password_file", and
"uwsgi_ssl_password_file" directives
when loading SSL certificates and encrypted keys from variables;
the bug had appeared in 1.23.1.
</para>
</change>
<change type="bugfix">
<para lang="ru">
в переменных $ssl_curve и $ssl_curves
при использовании подключаемых кривых в OpenSSL.
</para>
<para lang="en">
in the $ssl_curve and $ssl_curves variables
when using pluggable curves in OpenSSL.
</para>
</change>
<change type="bugfix">
<para lang="ru">
nginx не собирался с musl libc.<br/>
Спасибо Piotr Sikora.
</para>
<para lang="en">
nginx could not be built with musl libc.<br/>
Thanks to Piotr Sikora.
</para>
</change>
<change>
<para lang="ru">
Улучшения производительности и исправления в HTTP/3.
</para>
<para lang="en">
Performance improvements and bugfixes in HTTP/3.
</para>
</change>
</changes>
<changes ver="1.27.4" date="2025-02-05"> <changes ver="1.27.4" date="2025-02-05">
<change type="security"> <change type="security">
+2 -2
View File
@@ -9,8 +9,8 @@
#define _NGINX_H_INCLUDED_ #define _NGINX_H_INCLUDED_
#define nginx_version 1027005 #define nginx_version 1027006
#define NGINX_VERSION "1.27.5" #define NGINX_VERSION "1.27.6"
#define NGINX_VER "nginx/" NGINX_VERSION " by Hakase" #define NGINX_VER "nginx/" NGINX_VERSION " by Hakase"
#ifndef NGINX_SERVER #ifndef NGINX_SERVER
+1 -1
View File
@@ -94,7 +94,7 @@ typedef intptr_t ngx_flag_t;
#ifndef NGX_ALIGNMENT #ifndef NGX_ALIGNMENT
#define NGX_ALIGNMENT sizeof(unsigned long) /* platform word */ #define NGX_ALIGNMENT sizeof(uintptr_t) /* platform word */
#endif #endif
#define ngx_align(d, a) (((d) + (a - 1)) & ~(a - 1)) #define ngx_align(d, a) (((d) + (a - 1)) & ~(a - 1))
+28 -3
View File
@@ -5080,6 +5080,7 @@ ngx_ssl_get_curve(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
#ifdef SSL_get_negotiated_group #ifdef SSL_get_negotiated_group
int nid; int nid;
const char *name;
nid = SSL_get_negotiated_group(c->ssl->connection); nid = SSL_get_negotiated_group(c->ssl->connection);
@@ -5091,14 +5092,24 @@ ngx_ssl_get_curve(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
return NGX_OK; return NGX_OK;
} }
s->len = sizeof("0x0000") - 1; #if (OPENSSL_VERSION_NUMBER >= 0x3000000fL)
name = SSL_group_to_name(c->ssl->connection, nid);
#else
name = NULL;
#endif
s->len = name ? ngx_strlen(name) : sizeof("0x0000") - 1;
s->data = ngx_pnalloc(pool, s->len); s->data = ngx_pnalloc(pool, s->len);
if (s->data == NULL) { if (s->data == NULL) {
return NGX_ERROR; return NGX_ERROR;
} }
if (name) {
ngx_memcpy(s->data, name, s->len);
} else {
ngx_sprintf(s->data, "0x%04xd", nid & 0xffff); ngx_sprintf(s->data, "0x%04xd", nid & 0xffff);
}
return NGX_OK; return NGX_OK;
} }
@@ -5118,6 +5129,7 @@ ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
int *curves, n, i, nid; int *curves, n, i, nid;
u_char *p; u_char *p;
size_t len; size_t len;
const char *name;
n = SSL_get1_curves(c->ssl->connection, NULL); n = SSL_get1_curves(c->ssl->connection, NULL);
@@ -5138,7 +5150,13 @@ ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
nid = curves[i]; nid = curves[i];
if (nid & TLSEXT_nid_unknown) { if (nid & TLSEXT_nid_unknown) {
len += sizeof("0x0000") - 1; #if (OPENSSL_VERSION_NUMBER >= 0x3000000fL)
name = SSL_group_to_name(c->ssl->connection, nid);
#else
name = NULL;
#endif
len += name ? ngx_strlen(name) : sizeof("0x0000") - 1;
} else { } else {
len += ngx_strlen(OBJ_nid2sn(nid)); len += ngx_strlen(OBJ_nid2sn(nid));
@@ -5158,7 +5176,14 @@ ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
nid = curves[i]; nid = curves[i];
if (nid & TLSEXT_nid_unknown) { if (nid & TLSEXT_nid_unknown) {
p = ngx_sprintf(p, "0x%04xd", nid & 0xffff); #if (OPENSSL_VERSION_NUMBER >= 0x3000000fL)
name = SSL_group_to_name(c->ssl->connection, nid);
#else
name = NULL;
#endif
p = name ? ngx_cpymem(p, name, ngx_strlen(name))
: ngx_sprintf(p, "0x%04xd", nid & 0xffff);
} else { } else {
p = ngx_sprintf(p, "%s", OBJ_nid2sn(nid)); p = ngx_sprintf(p, "%s", OBJ_nid2sn(nid));
+8 -3
View File
@@ -308,11 +308,16 @@ ngx_quic_new_connection(ngx_connection_t *c, ngx_quic_conf_t *conf,
qc->streams.client_max_streams_uni = qc->tp.initial_max_streams_uni; qc->streams.client_max_streams_uni = qc->tp.initial_max_streams_uni;
qc->streams.client_max_streams_bidi = qc->tp.initial_max_streams_bidi; qc->streams.client_max_streams_bidi = qc->tp.initial_max_streams_bidi;
qc->congestion.window = ngx_min(10 * qc->tp.max_udp_payload_size, qc->congestion.window = ngx_min(10 * NGX_QUIC_MIN_INITIAL_SIZE,
ngx_max(2 * qc->tp.max_udp_payload_size, ngx_max(2 * NGX_QUIC_MIN_INITIAL_SIZE,
14720)); 14720));
qc->congestion.ssthresh = (size_t) -1; qc->congestion.ssthresh = (size_t) -1;
qc->congestion.recovery_start = ngx_current_msec; qc->congestion.mtu = NGX_QUIC_MIN_INITIAL_SIZE;
qc->congestion.recovery_start = ngx_current_msec - 1;
qc->max_frames = (conf->max_concurrent_streams_uni
+ conf->max_concurrent_streams_bidi)
* conf->stream_buffer_size / 2000;
if (pkt->validated && pkt->retried) { if (pkt->validated && pkt->retried) {
qc->tp.retry_scid.len = pkt->dcid.len; qc->tp.retry_scid.len = pkt->dcid.len;
+314 -45
View File
@@ -20,6 +20,10 @@
/* RFC 9002, 7.6.1. Duration: kPersistentCongestionThreshold */ /* RFC 9002, 7.6.1. Duration: kPersistentCongestionThreshold */
#define NGX_QUIC_PERSISTENT_CONGESTION_THR 3 #define NGX_QUIC_PERSISTENT_CONGESTION_THR 3
/* CUBIC parameters x10 */
#define NGX_QUIC_CUBIC_BETA 7
#define MGX_QUIC_CUBIC_C 4
/* send time of ACK'ed packets */ /* send time of ACK'ed packets */
typedef struct { typedef struct {
@@ -29,18 +33,22 @@ typedef struct {
} ngx_quic_ack_stat_t; } ngx_quic_ack_stat_t;
static ngx_inline ngx_msec_t ngx_quic_lost_threshold(ngx_quic_connection_t *qc); static ngx_inline ngx_msec_t ngx_quic_time_threshold(ngx_quic_connection_t *qc);
static uint64_t ngx_quic_packet_threshold(ngx_quic_send_ctx_t *ctx);
static void ngx_quic_rtt_sample(ngx_connection_t *c, ngx_quic_ack_frame_t *ack, static void ngx_quic_rtt_sample(ngx_connection_t *c, ngx_quic_ack_frame_t *ack,
enum ssl_encryption_level_t level, ngx_msec_t send_time); enum ssl_encryption_level_t level, ngx_msec_t send_time);
static ngx_int_t ngx_quic_handle_ack_frame_range(ngx_connection_t *c, static ngx_int_t ngx_quic_handle_ack_frame_range(ngx_connection_t *c,
ngx_quic_send_ctx_t *ctx, uint64_t min, uint64_t max, ngx_quic_send_ctx_t *ctx, uint64_t min, uint64_t max,
ngx_quic_ack_stat_t *st); ngx_quic_ack_stat_t *st);
static size_t ngx_quic_congestion_cubic(ngx_connection_t *c);
static void ngx_quic_drop_ack_ranges(ngx_connection_t *c, static void ngx_quic_drop_ack_ranges(ngx_connection_t *c,
ngx_quic_send_ctx_t *ctx, uint64_t pn); ngx_quic_send_ctx_t *ctx, uint64_t pn);
static ngx_int_t ngx_quic_detect_lost(ngx_connection_t *c, static ngx_int_t ngx_quic_detect_lost(ngx_connection_t *c,
ngx_quic_ack_stat_t *st); ngx_quic_ack_stat_t *st);
static ngx_msec_t ngx_quic_congestion_cubic_time(ngx_connection_t *c);
static ngx_msec_t ngx_quic_pcg_duration(ngx_connection_t *c); static ngx_msec_t ngx_quic_pcg_duration(ngx_connection_t *c);
static void ngx_quic_persistent_congestion(ngx_connection_t *c); static void ngx_quic_persistent_congestion(ngx_connection_t *c);
static ngx_msec_t ngx_quic_oldest_sent_packet(ngx_connection_t *c);
static void ngx_quic_congestion_lost(ngx_connection_t *c, static void ngx_quic_congestion_lost(ngx_connection_t *c,
ngx_quic_frame_t *frame); ngx_quic_frame_t *frame);
static void ngx_quic_lost_handler(ngx_event_t *ev); static void ngx_quic_lost_handler(ngx_event_t *ev);
@@ -48,7 +56,7 @@ static void ngx_quic_lost_handler(ngx_event_t *ev);
/* RFC 9002, 6.1.2. Time Threshold: kTimeThreshold, kGranularity */ /* RFC 9002, 6.1.2. Time Threshold: kTimeThreshold, kGranularity */
static ngx_inline ngx_msec_t static ngx_inline ngx_msec_t
ngx_quic_lost_threshold(ngx_quic_connection_t *qc) ngx_quic_time_threshold(ngx_quic_connection_t *qc)
{ {
ngx_msec_t thr; ngx_msec_t thr;
@@ -59,6 +67,29 @@ ngx_quic_lost_threshold(ngx_quic_connection_t *qc)
} }
static uint64_t
ngx_quic_packet_threshold(ngx_quic_send_ctx_t *ctx)
{
uint64_t pkt_thr;
ngx_queue_t *q;
ngx_quic_frame_t *f;
if (ngx_queue_empty(&ctx->sent)) {
return NGX_QUIC_PKT_THR;
}
q = ngx_queue_head(&ctx->sent);
f = ngx_queue_data(q, ngx_quic_frame_t, queue);
pkt_thr = (ctx->pnum - f->pnum) / 2;
if (pkt_thr <= NGX_QUIC_PKT_THR) {
return NGX_QUIC_PKT_THR;
}
return pkt_thr;
}
ngx_int_t ngx_int_t
ngx_quic_handle_ack_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, ngx_quic_handle_ack_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
ngx_quic_frame_t *f) ngx_quic_frame_t *f)
@@ -313,8 +344,9 @@ ngx_quic_handle_ack_frame_range(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx,
void void
ngx_quic_congestion_ack(ngx_connection_t *c, ngx_quic_frame_t *f) ngx_quic_congestion_ack(ngx_connection_t *c, ngx_quic_frame_t *f)
{ {
size_t w_cubic;
ngx_uint_t blocked; ngx_uint_t blocked;
ngx_msec_t timer; ngx_msec_t now, timer;
ngx_quic_congestion_t *cg; ngx_quic_congestion_t *cg;
ngx_quic_connection_t *qc; ngx_quic_connection_t *qc;
@@ -329,16 +361,34 @@ ngx_quic_congestion_ack(ngx_connection_t *c, ngx_quic_frame_t *f)
return; return;
} }
now = ngx_current_msec;
blocked = (cg->in_flight >= cg->window) ? 1 : 0; blocked = (cg->in_flight >= cg->window) ? 1 : 0;
cg->in_flight -= f->plen; cg->in_flight -= f->plen;
/* prevent recovery_start from wrapping */
timer = now - cg->recovery_start;
if ((ngx_msec_int_t) timer < 0) {
cg->recovery_start = ngx_quic_oldest_sent_packet(c) - 1;
}
timer = f->send_time - cg->recovery_start; timer = f->send_time - cg->recovery_start;
if ((ngx_msec_int_t) timer <= 0) { if ((ngx_msec_int_t) timer <= 0) {
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic congestion ack recovery win:%uz ss:%z if:%uz", "quic congestion ack rec t:%M win:%uz if:%uz",
cg->window, cg->ssthresh, cg->in_flight); now, cg->window, cg->in_flight);
goto done;
}
if (cg->idle) {
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic congestion ack idle t:%M win:%uz if:%uz",
now, cg->window, cg->in_flight);
goto done; goto done;
} }
@@ -346,24 +396,51 @@ ngx_quic_congestion_ack(ngx_connection_t *c, ngx_quic_frame_t *f)
if (cg->window < cg->ssthresh) { if (cg->window < cg->ssthresh) {
cg->window += f->plen; cg->window += f->plen;
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic congestion slow start win:%uz ss:%z if:%uz", "quic congestion ack ss t:%M win:%uz ss:%z if:%uz",
cg->window, cg->ssthresh, cg->in_flight); now, cg->window, cg->ssthresh, cg->in_flight);
} else { } else {
cg->window += qc->tp.max_udp_payload_size * f->plen / cg->window;
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, /* RFC 9438, 4.2. Window Increase Function */
"quic congestion avoidance win:%uz ss:%z if:%uz",
cg->window, cg->ssthresh, cg->in_flight); w_cubic = ngx_quic_congestion_cubic(c);
if (cg->window < cg->w_prior) {
cg->w_est += (uint64_t) cg->mtu * f->plen
* 3 * (10 - NGX_QUIC_CUBIC_BETA)
/ (10 + NGX_QUIC_CUBIC_BETA) / cg->window;
} else {
cg->w_est += (uint64_t) cg->mtu * f->plen / cg->window;
} }
/* prevent recovery_start from wrapping */ if (w_cubic < cg->w_est) {
cg->window = cg->w_est;
timer = cg->recovery_start - ngx_current_msec + qc->tp.max_idle_timeout * 2; ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic congestion ack reno t:%M win:%uz c:%uz if:%uz",
now, cg->window, w_cubic, cg->in_flight);
if ((ngx_msec_int_t) timer < 0) { } else if (w_cubic > cg->window) {
cg->recovery_start = ngx_current_msec - qc->tp.max_idle_timeout * 2;
if (w_cubic >= cg->window * 3 / 2) {
cg->window += cg->mtu / 2;
} else {
cg->window += (uint64_t) cg->mtu * (w_cubic - cg->window)
/ cg->window;
}
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic congestion ack cubic t:%M win:%uz c:%uz if:%uz",
now, cg->window, w_cubic, cg->in_flight);
} else {
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic congestion ack skip t:%M win:%uz c:%uz if:%uz",
now, cg->window, w_cubic, cg->in_flight);
}
} }
done: done:
@@ -374,6 +451,87 @@ done:
} }
static size_t
ngx_quic_congestion_cubic(ngx_connection_t *c)
{
int64_t w, t, cc;
ngx_msec_t now;
ngx_quic_congestion_t *cg;
ngx_quic_connection_t *qc;
qc = ngx_quic_get_connection(c);
cg = &qc->congestion;
ngx_quic_congestion_idle(c, cg->idle);
now = ngx_current_msec;
t = (ngx_msec_int_t) (now - cg->k);
if (t > 1000000) {
w = NGX_MAX_SIZE_T_VALUE;
goto done;
}
if (t < -1000000) {
w = 0;
goto done;
}
/*
* RFC 9438, Figure 1
*
* w_cubic = C * (t_msec / 1000) ^ 3 * mtu + w_max
*/
cc = 10000000000ll / (int64_t) cg->mtu / MGX_QUIC_CUBIC_C;
w = t * t * t / cc + (int64_t) cg->w_max;
if (w > NGX_MAX_SIZE_T_VALUE) {
w = NGX_MAX_SIZE_T_VALUE;
}
if (w < 0) {
w = 0;
}
done:
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic cubic t:%L w:%L wm:%uz", t, w, cg->w_max);
return w;
}
void
ngx_quic_congestion_idle(ngx_connection_t *c, ngx_uint_t idle)
{
ngx_msec_t now;
ngx_quic_congestion_t *cg;
ngx_quic_connection_t *qc;
qc = ngx_quic_get_connection(c);
cg = &qc->congestion;
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic congestion idle:%ui", idle);
if (cg->window >= cg->ssthresh) {
/* RFC 9438, 5.8. Behavior for Application-Limited Flows */
now = ngx_current_msec;
if (cg->idle) {
cg->k += now - cg->idle_start;
}
cg->idle_start = now;
}
cg->idle = idle;
}
static void static void
ngx_quic_drop_ack_ranges(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, ngx_quic_drop_ack_ranges(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx,
uint64_t pn) uint64_t pn)
@@ -435,6 +593,7 @@ ngx_quic_drop_ack_ranges(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx,
static ngx_int_t static ngx_int_t
ngx_quic_detect_lost(ngx_connection_t *c, ngx_quic_ack_stat_t *st) ngx_quic_detect_lost(ngx_connection_t *c, ngx_quic_ack_stat_t *st)
{ {
uint64_t pkt_thr;
ngx_uint_t i, nlost; ngx_uint_t i, nlost;
ngx_msec_t now, wait, thr, oldest, newest; ngx_msec_t now, wait, thr, oldest, newest;
ngx_queue_t *q; ngx_queue_t *q;
@@ -444,11 +603,12 @@ ngx_quic_detect_lost(ngx_connection_t *c, ngx_quic_ack_stat_t *st)
qc = ngx_quic_get_connection(c); qc = ngx_quic_get_connection(c);
now = ngx_current_msec; now = ngx_current_msec;
thr = ngx_quic_lost_threshold(qc); thr = ngx_quic_time_threshold(qc);
/* send time of lost packets across all send contexts */ #if (NGX_SUPPRESS_WARN)
oldest = NGX_TIMER_INFINITE; oldest = now;
newest = NGX_TIMER_INFINITE; newest = now;
#endif
nlost = 0; nlost = 0;
@@ -460,6 +620,8 @@ ngx_quic_detect_lost(ngx_connection_t *c, ngx_quic_ack_stat_t *st)
continue; continue;
} }
pkt_thr = ngx_quic_packet_threshold(ctx);
while (!ngx_queue_empty(&ctx->sent)) { while (!ngx_queue_empty(&ctx->sent)) {
q = ngx_queue_head(&ctx->sent); q = ngx_queue_head(&ctx->sent);
@@ -471,23 +633,27 @@ ngx_quic_detect_lost(ngx_connection_t *c, ngx_quic_ack_stat_t *st)
wait = start->send_time + thr - now; wait = start->send_time + thr - now;
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic detect_lost pnum:%uL thr:%M wait:%i level:%d", "quic detect_lost pnum:%uL thr:%M pthr:%uL wait:%i level:%d",
start->pnum, thr, (ngx_int_t) wait, start->level); start->pnum, thr, pkt_thr, (ngx_int_t) wait, start->level);
if ((ngx_msec_int_t) wait > 0 if ((ngx_msec_int_t) wait > 0
&& ctx->largest_ack - start->pnum < NGX_QUIC_PKT_THR) && ctx->largest_ack - start->pnum < pkt_thr)
{ {
break; break;
} }
if (start->send_time > qc->first_rtt) { if ((ngx_msec_int_t) (start->send_time - qc->first_rtt) > 0) {
if (oldest == NGX_TIMER_INFINITE || start->send_time < oldest) { if (nlost == 0
|| (ngx_msec_int_t) (start->send_time - oldest) < 0)
{
oldest = start->send_time; oldest = start->send_time;
} }
if (newest == NGX_TIMER_INFINITE || start->send_time > newest) { if (nlost == 0
|| (ngx_msec_int_t) (start->send_time - newest) > 0)
{
newest = start->send_time; newest = start->send_time;
} }
@@ -508,8 +674,9 @@ ngx_quic_detect_lost(ngx_connection_t *c, ngx_quic_ack_stat_t *st)
* latest ACK frame. * latest ACK frame.
*/ */
if (st && nlost >= 2 && (st->newest < oldest || st->oldest > newest)) { if (st && nlost >= 2 && ((ngx_msec_int_t) (st->newest - oldest) < 0
|| (ngx_msec_int_t) (st->oldest - newest) > 0))
{
if (newest - oldest > ngx_quic_pcg_duration(c)) { if (newest - oldest > ngx_quic_pcg_duration(c)) {
ngx_quic_persistent_congestion(c); ngx_quic_persistent_congestion(c);
} }
@@ -547,11 +714,43 @@ ngx_quic_persistent_congestion(ngx_connection_t *c)
qc = ngx_quic_get_connection(c); qc = ngx_quic_get_connection(c);
cg = &qc->congestion; cg = &qc->congestion;
cg->recovery_start = ngx_current_msec; cg->mtu = qc->path->mtu;
cg->window = qc->tp.max_udp_payload_size * 2; cg->recovery_start = ngx_quic_oldest_sent_packet(c) - 1;
cg->window = cg->mtu * 2;
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic persistent congestion win:%uz", cg->window); "quic congestion persistent t:%M win:%uz",
ngx_current_msec, cg->window);
}
static ngx_msec_t
ngx_quic_oldest_sent_packet(ngx_connection_t *c)
{
ngx_msec_t oldest;
ngx_uint_t i;
ngx_queue_t *q;
ngx_quic_frame_t *start;
ngx_quic_send_ctx_t *ctx;
ngx_quic_connection_t *qc;
qc = ngx_quic_get_connection(c);
oldest = ngx_current_msec;
for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
ctx = &qc->send_ctx[i];
if (!ngx_queue_empty(&ctx->sent)) {
q = ngx_queue_head(&ctx->sent);
start = ngx_queue_data(q, ngx_quic_frame_t, queue);
if ((ngx_msec_int_t) (start->send_time - oldest) < 0) {
oldest = start->send_time;
}
}
}
return oldest;
} }
@@ -659,7 +858,7 @@ static void
ngx_quic_congestion_lost(ngx_connection_t *c, ngx_quic_frame_t *f) ngx_quic_congestion_lost(ngx_connection_t *c, ngx_quic_frame_t *f)
{ {
ngx_uint_t blocked; ngx_uint_t blocked;
ngx_msec_t timer; ngx_msec_t now, timer;
ngx_quic_congestion_t *cg; ngx_quic_congestion_t *cg;
ngx_quic_connection_t *qc; ngx_quic_connection_t *qc;
@@ -681,26 +880,41 @@ ngx_quic_congestion_lost(ngx_connection_t *c, ngx_quic_frame_t *f)
timer = f->send_time - cg->recovery_start; timer = f->send_time - cg->recovery_start;
now = ngx_current_msec;
if ((ngx_msec_int_t) timer <= 0) { if ((ngx_msec_int_t) timer <= 0) {
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic congestion lost recovery win:%uz ss:%z if:%uz", "quic congestion lost rec t:%M win:%uz if:%uz",
cg->window, cg->ssthresh, cg->in_flight); now, cg->window, cg->in_flight);
goto done; goto done;
} }
cg->recovery_start = ngx_current_msec; if (f->ignore_loss) {
cg->window /= 2; ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic congestion lost ignore t:%M win:%uz if:%uz",
now, cg->window, cg->in_flight);
if (cg->window < qc->tp.max_udp_payload_size * 2) { goto done;
cg->window = qc->tp.max_udp_payload_size * 2;
} }
cg->ssthresh = cg->window; /* RFC 9438, 4.6. Multiplicative Decrease */
cg->mtu = qc->path->mtu;
cg->recovery_start = now;
cg->w_prior = cg->window;
/* RFC 9438, 4.7. Fast Convergence */
cg->w_max = (cg->window < cg->w_max)
? cg->window * (10 + NGX_QUIC_CUBIC_BETA) / 20 : cg->window;
cg->ssthresh = cg->in_flight * NGX_QUIC_CUBIC_BETA / 10;
cg->window = ngx_max(cg->ssthresh, cg->mtu * 2);
cg->w_est = cg->window;
cg->k = now + ngx_quic_congestion_cubic_time(c);
cg->idle_start = now;
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic congestion lost win:%uz ss:%z if:%uz", "quic congestion lost t:%M win:%uz if:%uz",
cg->window, cg->ssthresh, cg->in_flight); now, cg->window, cg->in_flight);
done: done:
@@ -710,9 +924,62 @@ done:
} }
static ngx_msec_t
ngx_quic_congestion_cubic_time(ngx_connection_t *c)
{
int64_t v, x, d, cc;
ngx_uint_t n;
ngx_quic_congestion_t *cg;
ngx_quic_connection_t *qc;
qc = ngx_quic_get_connection(c);
cg = &qc->congestion;
/*
* RFC 9438, Figure 2
*
* k_msec = ((w_max - cwnd_epoch) / C / mtu) ^ 1/3 * 1000
*/
if (cg->w_max <= cg->window) {
return 0;
}
cc = 10000000000ll / (int64_t) cg->mtu / MGX_QUIC_CUBIC_C;
v = (int64_t) (cg->w_max - cg->window) * cc;
/*
* Newton-Raphson method for x ^ 3 = v:
*
* x_next = (2 * x_prev + v / x_prev ^ 2) / 3
*/
x = 5000;
for (n = 1; n <= 10; n++) {
d = (v / x / x - x) / 3;
x += d;
if (ngx_abs(d) <= 100) {
break;
}
}
if (x > NGX_MAX_SIZE_T_VALUE) {
return NGX_MAX_SIZE_T_VALUE;
}
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic cubic time:%L n:%ui", x, n);
return x;
}
void void
ngx_quic_set_lost_timer(ngx_connection_t *c) ngx_quic_set_lost_timer(ngx_connection_t *c)
{ {
uint64_t pkt_thr;
ngx_uint_t i; ngx_uint_t i;
ngx_msec_t now; ngx_msec_t now;
ngx_queue_t *q; ngx_queue_t *q;
@@ -738,10 +1005,12 @@ ngx_quic_set_lost_timer(ngx_connection_t *c)
q = ngx_queue_head(&ctx->sent); q = ngx_queue_head(&ctx->sent);
f = ngx_queue_data(q, ngx_quic_frame_t, queue); f = ngx_queue_data(q, ngx_quic_frame_t, queue);
w = (ngx_msec_int_t) w = (ngx_msec_int_t)
(f->send_time + ngx_quic_lost_threshold(qc) - now); (f->send_time + ngx_quic_time_threshold(qc) - now);
if (f->pnum <= ctx->largest_ack) { if (f->pnum <= ctx->largest_ack) {
if (w < 0 || ctx->largest_ack - f->pnum >= NGX_QUIC_PKT_THR) { pkt_thr = ngx_quic_packet_threshold(ctx);
if (w < 0 || ctx->largest_ack - f->pnum >= pkt_thr) {
w = 0; w = 0;
} }
+1
View File
@@ -17,6 +17,7 @@ ngx_int_t ngx_quic_handle_ack_frame(ngx_connection_t *c,
void ngx_quic_congestion_ack(ngx_connection_t *c, void ngx_quic_congestion_ack(ngx_connection_t *c,
ngx_quic_frame_t *frame); ngx_quic_frame_t *frame);
void ngx_quic_congestion_idle(ngx_connection_t *c, ngx_uint_t idle);
void ngx_quic_resend_frames(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx); void ngx_quic_resend_frames(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx);
void ngx_quic_set_lost_timer(ngx_connection_t *c); void ngx_quic_set_lost_timer(ngx_connection_t *c);
void ngx_quic_pto_handler(ngx_event_t *ev); void ngx_quic_pto_handler(ngx_event_t *ev);
@@ -168,7 +168,14 @@ typedef struct {
size_t in_flight; size_t in_flight;
size_t window; size_t window;
size_t ssthresh; size_t ssthresh;
size_t w_max;
size_t w_est;
size_t w_prior;
size_t mtu;
ngx_msec_t recovery_start; ngx_msec_t recovery_start;
ngx_msec_t idle_start;
ngx_msec_t k;
ngx_uint_t idle; /* unsigned idle:1; */
} ngx_quic_congestion_t; } ngx_quic_congestion_t;
@@ -254,6 +261,7 @@ struct ngx_quic_connection_s {
ngx_buf_t *free_shadow_bufs; ngx_buf_t *free_shadow_bufs;
ngx_uint_t nframes; ngx_uint_t nframes;
ngx_uint_t max_frames;
#ifdef NGX_QUIC_DEBUG_ALLOC #ifdef NGX_QUIC_DEBUG_ALLOC
ngx_uint_t nbufs; ngx_uint_t nbufs;
ngx_uint_t nshadowbufs; ngx_uint_t nshadowbufs;
+1 -1
View File
@@ -214,7 +214,7 @@ ngx_quic_alloc_frame(ngx_connection_t *c)
"quic reuse frame n:%ui", qc->nframes); "quic reuse frame n:%ui", qc->nframes);
#endif #endif
} else if (qc->nframes < 10000) { } else if (qc->nframes < qc->max_frames) {
frame = ngx_palloc(c->pool, sizeof(ngx_quic_frame_t)); frame = ngx_palloc(c->pool, sizeof(ngx_quic_frame_t));
if (frame == NULL) { if (frame == NULL) {
return NULL; return NULL;
+6 -3
View File
@@ -182,11 +182,12 @@ valid:
ngx_memzero(&qc->congestion, sizeof(ngx_quic_congestion_t)); ngx_memzero(&qc->congestion, sizeof(ngx_quic_congestion_t));
qc->congestion.window = ngx_min(10 * qc->tp.max_udp_payload_size, qc->congestion.window = ngx_min(10 * NGX_QUIC_MIN_INITIAL_SIZE,
ngx_max(2 * qc->tp.max_udp_payload_size, ngx_max(2 * NGX_QUIC_MIN_INITIAL_SIZE,
14720)); 14720));
qc->congestion.ssthresh = (size_t) -1; qc->congestion.ssthresh = (size_t) -1;
qc->congestion.recovery_start = ngx_current_msec; qc->congestion.mtu = NGX_QUIC_MIN_INITIAL_SIZE;
qc->congestion.recovery_start = ngx_current_msec - 1;
ngx_quic_init_rtt(qc); ngx_quic_init_rtt(qc);
} }
@@ -923,6 +924,8 @@ ngx_quic_send_path_mtu_probe(ngx_connection_t *c, ngx_quic_path_t *path)
frame->level = ssl_encryption_application; frame->level = ssl_encryption_application;
frame->type = NGX_QUIC_FT_PING; frame->type = NGX_QUIC_FT_PING;
frame->ignore_loss = 1;
frame->ignore_congestion = 1;
qc = ngx_quic_get_connection(c); qc = ngx_quic_get_connection(c);
ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application); ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application);
+49 -29
View File
@@ -45,9 +45,9 @@
static ngx_int_t ngx_quic_create_datagrams(ngx_connection_t *c); static ngx_int_t ngx_quic_create_datagrams(ngx_connection_t *c);
static void ngx_quic_commit_send(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx); static void ngx_quic_commit_send(ngx_connection_t *c);
static void ngx_quic_revert_send(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, static void ngx_quic_revert_send(ngx_connection_t *c,
uint64_t pnum); uint64_t preserved_pnum[NGX_QUIC_SEND_CTX_LAST]);
#if ((NGX_HAVE_UDP_SEGMENT) && (NGX_HAVE_MSGHDR_MSG_CONTROL)) #if ((NGX_HAVE_UDP_SEGMENT) && (NGX_HAVE_MSGHDR_MSG_CONTROL))
static ngx_uint_t ngx_quic_allow_segmentation(ngx_connection_t *c); static ngx_uint_t ngx_quic_allow_segmentation(ngx_connection_t *c);
static ngx_int_t ngx_quic_create_segments(ngx_connection_t *c); static ngx_int_t ngx_quic_create_segments(ngx_connection_t *c);
@@ -127,6 +127,10 @@ ngx_quic_create_datagrams(ngx_connection_t *c)
cg = &qc->congestion; cg = &qc->congestion;
path = qc->path; path = qc->path;
#if (NGX_SUPPRESS_WARN)
ngx_memzero(preserved_pnum, sizeof(preserved_pnum));
#endif
while (cg->in_flight < cg->window) { while (cg->in_flight < cg->window) {
p = dst; p = dst;
@@ -150,12 +154,7 @@ ngx_quic_create_datagrams(ngx_connection_t *c)
if (min > len) { if (min > len) {
/* padding can't be applied - avoid sending the packet */ /* padding can't be applied - avoid sending the packet */
ngx_quic_revert_send(c, preserved_pnum);
while (i-- > 0) {
ctx = &qc->send_ctx[i];
ngx_quic_revert_send(c, ctx, preserved_pnum[i]);
}
return NGX_OK; return NGX_OK;
} }
@@ -180,17 +179,12 @@ ngx_quic_create_datagrams(ngx_connection_t *c)
} }
if (n == NGX_AGAIN) { if (n == NGX_AGAIN) {
for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { ngx_quic_revert_send(c, preserved_pnum);
ngx_quic_revert_send(c, &qc->send_ctx[i], preserved_pnum[i]);
}
ngx_add_timer(&qc->push, NGX_QUIC_SOCKET_RETRY_DELAY); ngx_add_timer(&qc->push, NGX_QUIC_SOCKET_RETRY_DELAY);
break; break;
} }
for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { ngx_quic_commit_send(c);
ngx_quic_commit_send(c, &qc->send_ctx[i]);
}
path->sent += len; path->sent += len;
} }
@@ -200,17 +194,27 @@ ngx_quic_create_datagrams(ngx_connection_t *c)
static void static void
ngx_quic_commit_send(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx) ngx_quic_commit_send(ngx_connection_t *c)
{ {
ngx_uint_t i, idle;
ngx_queue_t *q; ngx_queue_t *q;
ngx_quic_frame_t *f; ngx_quic_frame_t *f;
ngx_quic_send_ctx_t *ctx;
ngx_quic_congestion_t *cg; ngx_quic_congestion_t *cg;
ngx_quic_connection_t *qc; ngx_quic_connection_t *qc;
qc = ngx_quic_get_connection(c); qc = ngx_quic_get_connection(c);
cg = &qc->congestion; cg = &qc->congestion;
idle = 1;
for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
ctx = &qc->send_ctx[i];
if (!ngx_queue_empty(&ctx->frames)) {
idle = 0;
}
while (!ngx_queue_empty(&ctx->sending)) { while (!ngx_queue_empty(&ctx->sending)) {
q = ngx_queue_head(&ctx->sending); q = ngx_queue_head(&ctx->sending);
@@ -227,26 +231,42 @@ ngx_quic_commit_send(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx)
ngx_quic_free_frame(c, f); ngx_quic_free_frame(c, f);
} }
} }
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic congestion send if:%uz", cg->in_flight); "quic congestion send if:%uz", cg->in_flight);
ngx_quic_congestion_idle(c, idle);
} }
static void static void
ngx_quic_revert_send(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx, ngx_quic_revert_send(ngx_connection_t *c, uint64_t pnum[NGX_QUIC_SEND_CTX_LAST])
uint64_t pnum)
{ {
ngx_uint_t i;
ngx_queue_t *q; ngx_queue_t *q;
ngx_quic_send_ctx_t *ctx;
ngx_quic_connection_t *qc;
while (!ngx_queue_empty(&ctx->sending)) { qc = ngx_quic_get_connection(c);
for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
ctx = &qc->send_ctx[i];
if (ngx_queue_empty(&ctx->sending)) {
continue;
}
do {
q = ngx_queue_last(&ctx->sending); q = ngx_queue_last(&ctx->sending);
ngx_queue_remove(q); ngx_queue_remove(q);
ngx_queue_insert_head(&ctx->frames, q); ngx_queue_insert_head(&ctx->frames, q);
} while (!ngx_queue_empty(&ctx->sending));
ctx->pnum = pnum[i];
} }
ctx->pnum = pnum; ngx_quic_congestion_idle(c, 1);
} }
@@ -311,13 +331,13 @@ ngx_quic_create_segments(ngx_connection_t *c)
size_t len, segsize; size_t len, segsize;
ssize_t n; ssize_t n;
u_char *p, *end; u_char *p, *end;
uint64_t preserved_pnum; ngx_uint_t nseg, level;
ngx_uint_t nseg;
ngx_quic_path_t *path; ngx_quic_path_t *path;
ngx_quic_send_ctx_t *ctx; ngx_quic_send_ctx_t *ctx;
ngx_quic_congestion_t *cg; ngx_quic_congestion_t *cg;
ngx_quic_connection_t *qc; ngx_quic_connection_t *qc;
static u_char dst[NGX_QUIC_MAX_UDP_SEGMENT_BUF]; static u_char dst[NGX_QUIC_MAX_UDP_SEGMENT_BUF];
static uint64_t preserved_pnum[NGX_QUIC_SEND_CTX_LAST];
qc = ngx_quic_get_connection(c); qc = ngx_quic_get_connection(c);
cg = &qc->congestion; cg = &qc->congestion;
@@ -335,7 +355,8 @@ ngx_quic_create_segments(ngx_connection_t *c)
nseg = 0; nseg = 0;
preserved_pnum = ctx->pnum; level = ctx - qc->send_ctx;
preserved_pnum[level] = ctx->pnum;
for ( ;; ) { for ( ;; ) {
@@ -369,19 +390,18 @@ ngx_quic_create_segments(ngx_connection_t *c)
} }
if (n == NGX_AGAIN) { if (n == NGX_AGAIN) {
ngx_quic_revert_send(c, ctx, preserved_pnum); ngx_quic_revert_send(c, preserved_pnum);
ngx_add_timer(&qc->push, NGX_QUIC_SOCKET_RETRY_DELAY); ngx_add_timer(&qc->push, NGX_QUIC_SOCKET_RETRY_DELAY);
break; break;
} }
ngx_quic_commit_send(c, ctx); ngx_quic_commit_send(c);
path->sent += n; path->sent += n;
p = dst; p = dst;
nseg = 0; nseg = 0;
preserved_pnum = ctx->pnum; preserved_pnum[level] = ctx->pnum;
} }
} }
+7 -5
View File
@@ -125,9 +125,10 @@ ngx_quic_keys_set_initial_secret(ngx_quic_keys_t *keys, ngx_str_t *secret,
ngx_quic_secret_t *client, *server; ngx_quic_secret_t *client, *server;
ngx_quic_ciphers_t ciphers; ngx_quic_ciphers_t ciphers;
static const uint8_t salt[20] = static const uint8_t salt[20] = {
"\x38\x76\x2c\xf7\xf5\x59\x34\xb3\x4d\x17" 0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17,
"\x9a\xe6\xa4\xc8\x0c\xad\xcc\xbb\x7f\x0a"; 0x9a, 0xe6, 0xa4, 0xc8, 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a
};
client = &keys->secrets[ssl_encryption_initial].client; client = &keys->secrets[ssl_encryption_initial].client;
server = &keys->secrets[ssl_encryption_initial].server; server = &keys->secrets[ssl_encryption_initial].server;
@@ -958,8 +959,9 @@ ngx_quic_create_retry_packet(ngx_quic_header_t *pkt, ngx_str_t *res)
/* 5.8. Retry Packet Integrity */ /* 5.8. Retry Packet Integrity */
static ngx_quic_md_t key = ngx_quic_md( static ngx_quic_md_t key = ngx_quic_md(
"\xbe\x0c\x69\x0b\x9f\x66\x57\x5a\x1d\x76\x6b\x54\xe3\x68\xc8\x4e"); "\xbe\x0c\x69\x0b\x9f\x66\x57\x5a\x1d\x76\x6b\x54\xe3\x68\xc8\x4e");
static const u_char nonce[NGX_QUIC_IV_LEN] = static const u_char nonce[NGX_QUIC_IV_LEN] = {
"\x46\x15\x99\xd3\x5d\x63\x2b\xf2\x23\x98\x25\xbb"; 0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb
};
static ngx_str_t in = ngx_string(""); static ngx_str_t in = ngx_string("");
ad.data = res->data; ad.data = res->data;
+1 -1
View File
@@ -1773,7 +1773,7 @@ ngx_quic_parse_transport_params(u_char *p, u_char *end, ngx_quic_tp_t *tp,
} }
if (rc == NGX_DECLINED) { if (rc == NGX_DECLINED) {
ngx_log_error(NGX_LOG_INFO, log, 0, ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
"quic %s transport param id:0x%xL, skipped", "quic %s transport param id:0x%xL, skipped",
(id % 31 == 27) ? "reserved" : "unknown", id); (id % 31 == 27) ? "reserved" : "unknown", id);
} }
@@ -271,6 +271,7 @@ struct ngx_quic_frame_s {
unsigned need_ack:1; unsigned need_ack:1;
unsigned pkt_need_ack:1; unsigned pkt_need_ack:1;
unsigned ignore_congestion:1; unsigned ignore_congestion:1;
unsigned ignore_loss:1;
ngx_chain_t *data; ngx_chain_t *data;
union { union {
@@ -1332,6 +1332,12 @@ ngx_http_charset_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
table = ctx->table; table = ctx->table;
if (ctx->charset->utf8) { if (ctx->charset->utf8) {
if (value[1].len / 2 > NGX_UTF_LEN - 1) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid value \"%V\"", &value[1]);
return NGX_CONF_ERROR;
}
p = &table->src2dst[src * NGX_UTF_LEN]; p = &table->src2dst[src * NGX_UTF_LEN];
*p++ = (u_char) (value[1].len / 2); *p++ = (u_char) (value[1].len / 2);
+9 -11
View File
@@ -4509,8 +4509,13 @@ ngx_http_grpc_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
prev->upstream.ssl_certificate_key, NULL); prev->upstream.ssl_certificate_key, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate_cache, ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate_cache,
prev->upstream.ssl_certificate_cache, NULL); prev->upstream.ssl_certificate_cache, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_passwords,
prev->upstream.ssl_passwords, NULL); if (ngx_http_upstream_merge_ssl_passwords(cf, &conf->upstream,
&prev->upstream)
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
ngx_conf_merge_ptr_value(conf->ssl_conf_commands, ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
prev->ssl_conf_commands, NULL); prev->ssl_conf_commands, NULL);
@@ -5077,16 +5082,9 @@ ngx_http_grpc_set_ssl(ngx_conf_t *cf, ngx_http_grpc_loc_conf_t *glcf)
return NGX_ERROR; return NGX_ERROR;
} }
if (glcf->upstream.ssl_certificate->lengths if (glcf->upstream.ssl_certificate->lengths == NULL
|| glcf->upstream.ssl_certificate_key->lengths) && glcf->upstream.ssl_certificate_key->lengths == NULL)
{ {
glcf->upstream.ssl_passwords =
ngx_ssl_preserve_passwords(cf, glcf->upstream.ssl_passwords);
if (glcf->upstream.ssl_passwords == NULL) {
return NGX_ERROR;
}
} else {
if (ngx_ssl_certificate(cf, glcf->upstream.ssl, if (ngx_ssl_certificate(cf, glcf->upstream.ssl,
&glcf->upstream.ssl_certificate->value, &glcf->upstream.ssl_certificate->value,
&glcf->upstream.ssl_certificate_key->value, &glcf->upstream.ssl_certificate_key->value,
+9 -11
View File
@@ -3767,8 +3767,13 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
prev->upstream.ssl_certificate_key, NULL); prev->upstream.ssl_certificate_key, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate_cache, ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate_cache,
prev->upstream.ssl_certificate_cache, NULL); prev->upstream.ssl_certificate_cache, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_passwords,
prev->upstream.ssl_passwords, NULL); if (ngx_http_upstream_merge_ssl_passwords(cf, &conf->upstream,
&prev->upstream)
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
ngx_conf_merge_ptr_value(conf->ssl_conf_commands, ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
prev->ssl_conf_commands, NULL); prev->ssl_conf_commands, NULL);
@@ -5128,16 +5133,9 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf)
return NGX_ERROR; return NGX_ERROR;
} }
if (plcf->upstream.ssl_certificate->lengths if (plcf->upstream.ssl_certificate->lengths == NULL
|| plcf->upstream.ssl_certificate_key->lengths) && plcf->upstream.ssl_certificate_key->lengths == NULL)
{ {
plcf->upstream.ssl_passwords =
ngx_ssl_preserve_passwords(cf, plcf->upstream.ssl_passwords);
if (plcf->upstream.ssl_passwords == NULL) {
return NGX_ERROR;
}
} else {
if (ngx_ssl_certificate(cf, plcf->upstream.ssl, if (ngx_ssl_certificate(cf, plcf->upstream.ssl,
&plcf->upstream.ssl_certificate->value, &plcf->upstream.ssl_certificate->value,
&plcf->upstream.ssl_certificate_key->value, &plcf->upstream.ssl_certificate_key->value,
@@ -419,13 +419,13 @@ ngx_http_slice_range_variable(ngx_http_request_t *r,
return NGX_ERROR; return NGX_ERROR;
} }
ngx_http_set_ctx(r, ctx, ngx_http_slice_filter_module);
p = ngx_pnalloc(r->pool, sizeof("bytes=-") - 1 + 2 * NGX_OFF_T_LEN); p = ngx_pnalloc(r->pool, sizeof("bytes=-") - 1 + 2 * NGX_OFF_T_LEN);
if (p == NULL) { if (p == NULL) {
return NGX_ERROR; return NGX_ERROR;
} }
ngx_http_set_ctx(r, ctx, ngx_http_slice_filter_module);
ctx->start = slcf->size * (ngx_http_slice_get_start(r) / slcf->size); ctx->start = slcf->size * (ngx_http_slice_get_start(r) / slcf->size);
ctx->range.data = p; ctx->range.data = p;
+9 -11
View File
@@ -1933,8 +1933,13 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
prev->upstream.ssl_certificate_key, NULL); prev->upstream.ssl_certificate_key, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate_cache, ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate_cache,
prev->upstream.ssl_certificate_cache, NULL); prev->upstream.ssl_certificate_cache, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_passwords,
prev->upstream.ssl_passwords, NULL); if (ngx_http_upstream_merge_ssl_passwords(cf, &conf->upstream,
&prev->upstream)
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
ngx_conf_merge_ptr_value(conf->ssl_conf_commands, ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
prev->ssl_conf_commands, NULL); prev->ssl_conf_commands, NULL);
@@ -2685,16 +2690,9 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf)
return NGX_ERROR; return NGX_ERROR;
} }
if (uwcf->upstream.ssl_certificate->lengths if (uwcf->upstream.ssl_certificate->lengths == NULL
|| uwcf->upstream.ssl_certificate_key->lengths) && uwcf->upstream.ssl_certificate_key->lengths == NULL)
{ {
uwcf->upstream.ssl_passwords =
ngx_ssl_preserve_passwords(cf, uwcf->upstream.ssl_passwords);
if (uwcf->upstream.ssl_passwords == NULL) {
return NGX_ERROR;
}
} else {
if (ngx_ssl_certificate(cf, uwcf->upstream.ssl, if (ngx_ssl_certificate(cf, uwcf->upstream.ssl,
&uwcf->upstream.ssl_certificate->value, &uwcf->upstream.ssl_certificate->value,
&uwcf->upstream.ssl_certificate_key->value, &uwcf->upstream.ssl_certificate_key->value,
+55
View File
@@ -6921,6 +6921,61 @@ ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
} }
#if (NGX_HTTP_SSL)
ngx_int_t
ngx_http_upstream_merge_ssl_passwords(ngx_conf_t *cf,
ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev)
{
ngx_uint_t preserve;
ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
if (conf->ssl_certificate == NULL
|| conf->ssl_certificate->value.len == 0
|| conf->ssl_certificate_key == NULL)
{
return NGX_OK;
}
if (conf->ssl_certificate->lengths == NULL
&& conf->ssl_certificate_key->lengths == NULL)
{
if (conf->ssl_passwords && conf->ssl_passwords->pool == NULL) {
/* un-preserve empty password list */
conf->ssl_passwords = NULL;
}
return NGX_OK;
}
if (conf->ssl_passwords && conf->ssl_passwords->pool != cf->temp_pool) {
/* already preserved */
return NGX_OK;
}
preserve = (conf->ssl_passwords == prev->ssl_passwords) ? 1 : 0;
conf->ssl_passwords = ngx_ssl_preserve_passwords(cf, conf->ssl_passwords);
if (conf->ssl_passwords == NULL) {
return NGX_ERROR;
}
/*
* special handling to keep a preserved ssl_passwords copy
* in the previous configuration to inherit it to all children
*/
if (preserve) {
prev->ssl_passwords = conf->ssl_passwords;
}
return NGX_OK;
}
#endif
static void * static void *
ngx_http_upstream_create_main_conf(ngx_conf_t *cf) ngx_http_upstream_create_main_conf(ngx_conf_t *cf)
{ {
+4
View File
@@ -437,6 +437,10 @@ char *ngx_http_upstream_param_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
ngx_int_t ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf, ngx_int_t ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev, ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,
ngx_str_t *default_hide_headers, ngx_hash_init_t *hash); ngx_str_t *default_hide_headers, ngx_hash_init_t *hash);
#if (NGX_HTTP_SSL)
ngx_int_t ngx_http_upstream_merge_ssl_passwords(ngx_conf_t *cf,
ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev);
#endif
#define ngx_http_conf_upstream_srv_conf(uscf, module) \ #define ngx_http_conf_upstream_srv_conf(uscf, module) \
+3 -2
View File
@@ -148,8 +148,9 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
u_char addr[NGX_SOCKADDR_STRLEN]; u_char addr[NGX_SOCKADDR_STRLEN];
#if (NGX_HTTP_GZIP) #if (NGX_HTTP_GZIP)
static const u_char accept_encoding[12] = static const u_char accept_encoding[12] = {
"\x8b\x84\x84\x2d\x69\x5b\x05\x44\x3c\x86\xaa\x6f"; 0x8b, 0x84, 0x84, 0x2d, 0x69, 0x5b, 0x05, 0x44, 0x3c, 0x86, 0xaa, 0x6f
};
#endif #endif
static size_t nginx_len = ngx_http_v2_literal_size(NGINX_SERVER); static size_t nginx_len = ngx_http_v2_literal_size(NGINX_SERVER);
+1 -1
View File
@@ -70,7 +70,7 @@ ngx_http_v3_keepalive_handler(ngx_event_t *ev)
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 keepalive handler"); ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 keepalive handler");
ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_NO_ERROR, ngx_http_v3_shutdown_connection(c, NGX_HTTP_V3_ERR_NO_ERROR,
"keepalive timeout"); "keepalive timeout");
} }
+1 -1
View File
@@ -23,7 +23,7 @@
#define NGX_HTTP_V3_HQ_ALPN_PROTO "\x0Ahq-interop" #define NGX_HTTP_V3_HQ_ALPN_PROTO "\x0Ahq-interop"
#define NGX_HTTP_V3_HQ_PROTO "hq-interop" #define NGX_HTTP_V3_HQ_PROTO "hq-interop"
#define NGX_HTTP_V3_VARLEN_INT_LEN 4 #define NGX_HTTP_V3_VARLEN_INT_LEN 8
#define NGX_HTTP_V3_PREFIX_INT_LEN 11 #define NGX_HTTP_V3_PREFIX_INT_LEN 11
#define NGX_HTTP_V3_STREAM_CONTROL 0x00 #define NGX_HTTP_V3_STREAM_CONTROL 0x00
+58 -10
View File
@@ -108,6 +108,8 @@ static ngx_int_t ngx_stream_proxy_ssl_name(ngx_stream_session_t *s);
static ngx_int_t ngx_stream_proxy_ssl_certificate(ngx_stream_session_t *s); static ngx_int_t ngx_stream_proxy_ssl_certificate(ngx_stream_session_t *s);
static ngx_int_t ngx_stream_proxy_merge_ssl(ngx_conf_t *cf, static ngx_int_t ngx_stream_proxy_merge_ssl(ngx_conf_t *cf,
ngx_stream_proxy_srv_conf_t *conf, ngx_stream_proxy_srv_conf_t *prev); ngx_stream_proxy_srv_conf_t *conf, ngx_stream_proxy_srv_conf_t *prev);
static ngx_int_t ngx_stream_proxy_merge_ssl_passwords(ngx_conf_t *cf,
ngx_stream_proxy_srv_conf_t *conf, ngx_stream_proxy_srv_conf_t *prev);
static ngx_int_t ngx_stream_proxy_set_ssl(ngx_conf_t *cf, static ngx_int_t ngx_stream_proxy_set_ssl(ngx_conf_t *cf,
ngx_stream_proxy_srv_conf_t *pscf); ngx_stream_proxy_srv_conf_t *pscf);
@@ -2315,7 +2317,9 @@ ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_ptr_value(conf->ssl_certificate_cache, ngx_conf_merge_ptr_value(conf->ssl_certificate_cache,
prev->ssl_certificate_cache, NULL); prev->ssl_certificate_cache, NULL);
ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL); if (ngx_stream_proxy_merge_ssl_passwords(cf, conf, prev) != NGX_OK) {
return NGX_CONF_ERROR;
}
ngx_conf_merge_ptr_value(conf->ssl_conf_commands, ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
prev->ssl_conf_commands, NULL); prev->ssl_conf_commands, NULL);
@@ -2381,6 +2385,57 @@ ngx_stream_proxy_merge_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *conf,
} }
static ngx_int_t
ngx_stream_proxy_merge_ssl_passwords(ngx_conf_t *cf,
ngx_stream_proxy_srv_conf_t *conf, ngx_stream_proxy_srv_conf_t *prev)
{
ngx_uint_t preserve;
ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
if (conf->ssl_certificate == NULL
|| conf->ssl_certificate->value.len == 0
|| conf->ssl_certificate_key == NULL)
{
return NGX_OK;
}
if (conf->ssl_certificate->lengths == NULL
&& conf->ssl_certificate_key->lengths == NULL)
{
if (conf->ssl_passwords && conf->ssl_passwords->pool == NULL) {
/* un-preserve empty password list */
conf->ssl_passwords = NULL;
}
return NGX_OK;
}
if (conf->ssl_passwords && conf->ssl_passwords->pool != cf->temp_pool) {
/* already preserved */
return NGX_OK;
}
preserve = (conf->ssl_passwords == prev->ssl_passwords) ? 1 : 0;
conf->ssl_passwords = ngx_ssl_preserve_passwords(cf, conf->ssl_passwords);
if (conf->ssl_passwords == NULL) {
return NGX_ERROR;
}
/*
* special handling to keep a preserved ssl_passwords copy
* in the previous configuration to inherit it to all children
*/
if (preserve) {
prev->ssl_passwords = conf->ssl_passwords;
}
return NGX_OK;
}
static ngx_int_t static ngx_int_t
ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf) ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf)
{ {
@@ -2418,16 +2473,9 @@ ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf)
return NGX_ERROR; return NGX_ERROR;
} }
if (pscf->ssl_certificate->lengths if (pscf->ssl_certificate->lengths == NULL
|| pscf->ssl_certificate_key->lengths) && pscf->ssl_certificate_key->lengths == NULL)
{ {
pscf->ssl_passwords =
ngx_ssl_preserve_passwords(cf, pscf->ssl_passwords);
if (pscf->ssl_passwords == NULL) {
return NGX_ERROR;
}
} else {
if (ngx_ssl_certificate(cf, pscf->ssl, if (ngx_ssl_certificate(cf, pscf->ssl,
&pscf->ssl_certificate->value, &pscf->ssl_certificate->value,
&pscf->ssl_certificate_key->value, &pscf->ssl_certificate_key->value,