]> git.kaiwu.me - nginx.git/commitdiff
Mail: PROXY protocol v2 support to backends
authorSergey Kandaurov <pluknet@nginx.com>
Mon, 10 Aug 2026 16:53:52 +0000 (20:53 +0400)
committerSergey Kandaurov <s.kandaurov@f5.com>
Tue, 11 Aug 2026 19:39:53 +0000 (23:39 +0400)
Version 1 remains the default.  This may be changed with the
"proxy_protocol v2;" directive.

src/mail/ngx_mail.h
src/mail/ngx_mail_proxy_module.c

index 221faf67d5d90bb92c716fc603fdc27477dfac32..1cdca113e99f0cd528175ff9ee0da69cb3ce2eab 100644 (file)
@@ -181,7 +181,7 @@ typedef enum {
 typedef struct {
     ngx_peer_connection_t   upstream;
     ngx_buf_t              *buffer;
-    ngx_uint_t              proxy_protocol;  /* unsigned  proxy_protocol:1; */
+    ngx_uint_t              proxy_protocol;  /* unsigned  proxy_protocol:2; */
 } ngx_mail_proxy_ctx_t;
 
 
index aa3baeb7e3caa571abb7b60c7d48adffdcb9e5a3..f42c9e2a1a51a8b1e75ee6993f3745a57179ef97 100644 (file)
@@ -17,7 +17,7 @@ typedef struct {
     ngx_flag_t  pass_error_message;
     ngx_flag_t  xclient;
     ngx_flag_t  smtp_auth;
-    ngx_flag_t  proxy_protocol;
+    ngx_uint_t  proxy_protocol;
     size_t      buffer_size;
     ngx_msec_t  timeout;
 } ngx_mail_proxy_conf_t;
@@ -40,6 +40,14 @@ static char *ngx_mail_proxy_merge_conf(ngx_conf_t *cf, void *parent,
     void *child);
 
 
+static ngx_conf_enum_t  ngx_mail_proxy_protocol_versions[] = {
+    { ngx_string("off"), 0 },
+    { ngx_string("on"), 1 },
+    { ngx_string("v2"), 2 },
+    { ngx_null_string, 0 }
+};
+
+
 static ngx_command_t  ngx_mail_proxy_commands[] = {
 
     { ngx_string("proxy"),
@@ -85,11 +93,11 @@ static ngx_command_t  ngx_mail_proxy_commands[] = {
       NULL },
 
     { ngx_string("proxy_protocol"),
-      NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
-      ngx_conf_set_flag_slot,
+      NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_enum_slot,
       NGX_MAIL_SRV_CONF_OFFSET,
       offsetof(ngx_mail_proxy_conf_t, proxy_protocol),
-      NULL },
+      &ngx_mail_proxy_protocol_versions },
 
       ngx_null_command
 };
@@ -907,17 +915,25 @@ static ngx_int_t
 ngx_mail_proxy_send_proxy_protocol(ngx_mail_session_t *s)
 {
     u_char            *p;
-    ssize_t            n, size;
+    size_t             size;
+    ssize_t            n;
     ngx_connection_t  *c;
-    u_char             buf[NGX_PROXY_PROTOCOL_V1_MAX_HEADER];
+    static u_char      buf[NGX_PROXY_PROTOCOL_MAX_HEADER];
 
     s->connection->log->action = "sending PROXY protocol header to upstream";
 
     ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
                    "mail proxy send PROXY protocol header");
 
-    p = ngx_proxy_protocol_write(s->connection, buf,
-                                 buf + NGX_PROXY_PROTOCOL_V1_MAX_HEADER);
+    if (s->proxy->proxy_protocol == 2) {
+        p = ngx_proxy_protocol_v2_write(s->connection, buf,
+                                        buf + sizeof(buf), NULL);
+
+    } else {
+        p = ngx_proxy_protocol_write(s->connection, buf,
+                                     buf + sizeof(buf));
+    }
+
     if (p == NULL) {
         ngx_mail_proxy_internal_server_error(s);
         return NGX_ERROR;
@@ -943,7 +959,7 @@ ngx_mail_proxy_send_proxy_protocol(ngx_mail_session_t *s)
         return NGX_ERROR;
     }
 
-    if (n != size) {
+    if (n != (ssize_t) size) {
 
         /*
          * PROXY protocol specification:
@@ -1385,7 +1401,7 @@ ngx_mail_proxy_create_conf(ngx_conf_t *cf)
     pcf->pass_error_message = NGX_CONF_UNSET;
     pcf->xclient = NGX_CONF_UNSET;
     pcf->smtp_auth = NGX_CONF_UNSET;
-    pcf->proxy_protocol = NGX_CONF_UNSET;
+    pcf->proxy_protocol = NGX_CONF_UNSET_UINT;
     pcf->buffer_size = NGX_CONF_UNSET_SIZE;
     pcf->timeout = NGX_CONF_UNSET_MSEC;
 
@@ -1403,7 +1419,7 @@ ngx_mail_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_conf_merge_value(conf->pass_error_message, prev->pass_error_message, 0);
     ngx_conf_merge_value(conf->xclient, prev->xclient, 1);
     ngx_conf_merge_value(conf->smtp_auth, prev->smtp_auth, 0);
-    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_size_value(conf->buffer_size, prev->buffer_size,
                               (size_t) ngx_pagesize);
     ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 24 * 60 * 60000);