From: Sergey Kandaurov Date: Mon, 10 Aug 2026 16:53:44 +0000 (+0400) Subject: Stream: PROXY protocol v2 support to backends X-Git-Tag: release-1.31.4~2 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=11d11b5f0d3d8ace5215e1a77918e9dc219ce7db;p=nginx.git Stream: PROXY protocol v2 support to backends Version 1 remains the default. This may be changed with the "proxy_protocol v2;" directive. --- diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c index 38c2b2489..3f896a116 100644 --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c @@ -30,7 +30,7 @@ typedef struct { ngx_uint_t responses; ngx_uint_t next_upstream_tries; ngx_flag_t next_upstream; - ngx_flag_t proxy_protocol; + ngx_uint_t proxy_protocol; ngx_flag_t half_close; ngx_stream_upstream_local_t *local; ngx_flag_t socket_keepalive; @@ -145,6 +145,14 @@ static ngx_conf_deprecated_t ngx_conf_deprecated_proxy_upstream_buffer = { }; +static ngx_conf_enum_t ngx_stream_proxy_protocol_versions[] = { + { ngx_string("off"), 0 }, + { ngx_string("on"), 1 }, + { ngx_string("v2"), 2 }, + { ngx_null_string, 0 } +}; + + static ngx_command_t ngx_stream_proxy_commands[] = { { ngx_string("proxy_pass"), @@ -267,11 +275,11 @@ static ngx_command_t ngx_stream_proxy_commands[] = { NULL }, { ngx_string("proxy_protocol"), - NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_enum_slot, NGX_STREAM_SRV_CONF_OFFSET, offsetof(ngx_stream_proxy_srv_conf_t, proxy_protocol), - NULL }, + &ngx_stream_proxy_protocol_versions }, { ngx_string("proxy_half_close"), NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, @@ -847,12 +855,14 @@ static void ngx_stream_proxy_init_upstream(ngx_stream_session_t *s) { u_char *p; + size_t size; ngx_chain_t *cl; ngx_connection_t *c, *pc; ngx_log_handler_pt handler; ngx_stream_upstream_t *u; ngx_stream_core_srv_conf_t *cscf; ngx_stream_proxy_srv_conf_t *pscf; + static u_char buf[NGX_PROXY_PROTOCOL_MAX_HEADER]; u = s->upstream; pc = u->peer.connection; @@ -956,28 +966,37 @@ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s) ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, "stream proxy add PROXY protocol header"); - cl = ngx_chain_get_free_buf(c->pool, &u->free); - if (cl == NULL) { + if (u->proxy_protocol == 2) { + p = ngx_proxy_protocol_v2_write(c, buf, buf + sizeof(buf), NULL); + + } else { + p = ngx_proxy_protocol_write(c, buf, buf + sizeof(buf)); + } + + if (p == NULL) { ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); return; } - p = ngx_pnalloc(c->pool, NGX_PROXY_PROTOCOL_V1_MAX_HEADER); + size = p - buf; + + p = ngx_pnalloc(c->pool, size); if (p == NULL) { ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); return; } - cl->buf->pos = p; + ngx_memcpy(p, buf, size); - p = ngx_proxy_protocol_write(c, p, - p + NGX_PROXY_PROTOCOL_V1_MAX_HEADER); - if (p == NULL) { + cl = ngx_chain_get_free_buf(c->pool, &u->free); + if (cl == NULL) { ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); return; } - cl->buf->last = p; + cl->buf->pos = p; + cl->buf->last = p + size; + cl->buf->temporary = 1; cl->buf->flush = 0; cl->buf->last_buf = 0; @@ -1011,26 +1030,32 @@ static ngx_int_t ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s) { u_char *p; - ssize_t n, size; + size_t size; + ssize_t n; ngx_connection_t *c, *pc; ngx_stream_upstream_t *u; ngx_stream_proxy_srv_conf_t *pscf; - u_char buf[NGX_PROXY_PROTOCOL_V1_MAX_HEADER]; + static u_char buf[NGX_PROXY_PROTOCOL_MAX_HEADER]; c = s->connection; ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, "stream proxy send PROXY protocol header"); - p = ngx_proxy_protocol_write(c, buf, - buf + NGX_PROXY_PROTOCOL_V1_MAX_HEADER); + u = s->upstream; + + if (u->proxy_protocol == 2) { + p = ngx_proxy_protocol_v2_write(c, buf, buf + sizeof(buf), NULL); + + } else { + p = ngx_proxy_protocol_write(c, buf, buf + sizeof(buf)); + } + if (p == NULL) { ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); return NGX_ERROR; } - u = s->upstream; - pc = u->peer.connection; size = p - buf; @@ -1057,7 +1082,7 @@ ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s) return NGX_ERROR; } - if (n != size) { + if (n != (ssize_t) size) { /* * PROXY protocol specification: @@ -2402,7 +2427,7 @@ ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf) conf->responses = NGX_CONF_UNSET_UINT; conf->next_upstream_tries = NGX_CONF_UNSET_UINT; conf->next_upstream = NGX_CONF_UNSET; - conf->proxy_protocol = NGX_CONF_UNSET; + conf->proxy_protocol = NGX_CONF_UNSET_UINT; conf->local = NGX_CONF_UNSET_PTR; conf->socket_keepalive = NGX_CONF_UNSET; conf->socket_rcvbuf = NGX_CONF_UNSET_SIZE; @@ -2461,7 +2486,7 @@ ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_value(conf->next_upstream, prev->next_upstream, 1); - ngx_conf_merge_value(conf->proxy_protocol, prev->proxy_protocol, 0); + ngx_conf_merge_uint_value(conf->proxy_protocol, prev->proxy_protocol, 0); ngx_conf_merge_ptr_value(conf->local, prev->local, NULL); diff --git a/src/stream/ngx_stream_upstream.h b/src/stream/ngx_stream_upstream.h index 0e6aad623..bb0ca4fc3 100644 --- a/src/stream/ngx_stream_upstream.h +++ b/src/stream/ngx_stream_upstream.h @@ -150,7 +150,7 @@ typedef struct { ngx_stream_upstream_resolved_t *resolved; ngx_stream_upstream_state_t *state; unsigned connected:1; - unsigned proxy_protocol:1; + unsigned proxy_protocol:2; unsigned half_closed:1; } ngx_stream_upstream_t;