[nginx] Mail: style.

2025-05-13 Thread Maxim Dounin
details:   http://freenginx.org/hg/nginx/rev/1e66d7bd556e
branches:  
changeset: 9357:1e66d7bd556e
user:  Maxim Dounin 
date:  Wed May 14 01:15:59 2025 +0300
description:
Mail: style.

There is no reason to use c->write as we already have wev, and it is
used elsewhere in ngx_mail_send().

diffstat:

 src/mail/ngx_mail_handler.c |  6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diffs (24 lines):

diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c
--- a/src/mail/ngx_mail_handler.c
+++ b/src/mail/ngx_mail_handler.c
@@ -1042,7 +1042,7 @@ ngx_mail_send(ngx_event_t *wev)
 }
 
 if (s->out.len == 0) {
-if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
+if (ngx_handle_write_event(wev, 0) != NGX_OK) {
 ngx_mail_close_connection(c);
 }
 
@@ -1086,9 +1086,9 @@ again:
 
 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
 
-ngx_add_timer(c->write, cscf->timeout);
+ngx_add_timer(wev, cscf->timeout);
 
-if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
+if (ngx_handle_write_event(wev, 0) != NGX_OK) {
 ngx_mail_close_connection(c);
 return;
 }


[nginx] Stream: style.

2025-05-13 Thread Maxim Dounin
details:   http://freenginx.org/hg/nginx/rev/54c96bb0bbfa
branches:  
changeset: 9353:54c96bb0bbfa
user:  Maxim Dounin 
date:  Wed May 14 01:15:05 2025 +0300
description:
Stream: style.

Moved SSL configuration parsing functions to the end of the file, where
configuration parsing should be.

diffstat:

 src/stream/ngx_stream_proxy_module.c |  82 ++-
 1 files changed, 43 insertions(+), 39 deletions(-)

diffs (110 lines):

diff --git a/src/stream/ngx_stream_proxy_module.c 
b/src/stream/ngx_stream_proxy_module.c
--- a/src/stream/ngx_stream_proxy_module.c
+++ b/src/stream/ngx_stream_proxy_module.c
@@ -94,10 +94,6 @@ static char *ngx_stream_proxy_bind(ngx_c
 #if (NGX_STREAM_SSL)
 
 static ngx_int_t ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s);
-static char *ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf,
-ngx_command_t *cmd, void *conf);
-static char *ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t *cf, void 
*post,
-void *data);
 static void ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s);
 static void ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc);
 static void ngx_stream_proxy_ssl_save_session(ngx_connection_t *c);
@@ -107,6 +103,10 @@ static ngx_int_t ngx_stream_proxy_merge_
 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,
 ngx_stream_proxy_srv_conf_t *pscf);
+static char *ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf,
+ngx_command_t *cmd, void *conf);
+static char *ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t *cf, void 
*post,
+void *data);
 
 
 static ngx_conf_bitmask_t  ngx_stream_proxy_ssl_protocols[] = {
@@ -1010,41 +1010,6 @@ ngx_stream_proxy_send_proxy_protocol(ngx
 }
 
 
-static char *
-ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
-void *conf)
-{
-ngx_stream_proxy_srv_conf_t *pscf = conf;
-
-ngx_str_t  *value;
-
-if (pscf->ssl_passwords != NGX_CONF_UNSET_PTR) {
-return "is duplicate";
-}
-
-value = cf->args->elts;
-
-pscf->ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]);
-
-if (pscf->ssl_passwords == NULL) {
-return NGX_CONF_ERROR;
-}
-
-return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
-{
-#ifndef SSL_CONF_FLAG_FILE
-return "is not supported on this platform";
-#else
-return NGX_CONF_OK;
-#endif
-}
-
-
 static void
 ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s)
 {
@@ -2518,3 +2483,42 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ng
 
 return NGX_CONF_OK;
 }
+
+
+#if (NGX_STREAM_SSL)
+
+static char *
+ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
+void *conf)
+{
+ngx_stream_proxy_srv_conf_t *pscf = conf;
+
+ngx_str_t  *value;
+
+if (pscf->ssl_passwords != NGX_CONF_UNSET_PTR) {
+return "is duplicate";
+}
+
+value = cf->args->elts;
+
+pscf->ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]);
+
+if (pscf->ssl_passwords == NULL) {
+return NGX_CONF_ERROR;
+}
+
+return NGX_CONF_OK;
+}
+
+
+static char *
+ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
+{
+#ifndef SSL_CONF_FLAG_FILE
+return "is not supported on this platform";
+#else
+return NGX_CONF_OK;
+#endif
+}
+
+#endif


[nginx] Stream: fixed timeout usage for proxy_protocol with SSL ...

2025-05-13 Thread Maxim Dounin
details:   http://freenginx.org/hg/nginx/rev/196e9f3db2b0
branches:  
changeset: 9355:196e9f3db2b0
user:  Maxim Dounin 
date:  Wed May 14 01:15:24 2025 +0300
description:
Stream: fixed timeout usage for proxy_protocol with SSL proxying.

Connection establishment with a proxied server includes SSL handshake,
and the relevant timeout is set with the proxy_connect_timeout directive.
Since proxy_protocol sending happens before SSL handshake, it should
use proxy_connect_timeout as well.  Further, the timeout should not be
rearmed if it's already set.

Additionally, read handler should be set as long as we are waiting
for events, since it can be triggered.

diffstat:

 src/stream/ngx_stream_proxy_module.c |  7 +--
 1 files changed, 5 insertions(+), 2 deletions(-)

diffs (17 lines):

diff --git a/src/stream/ngx_stream_proxy_module.c 
b/src/stream/ngx_stream_proxy_module.c
--- a/src/stream/ngx_stream_proxy_module.c
+++ b/src/stream/ngx_stream_proxy_module.c
@@ -977,8 +977,11 @@ ngx_stream_proxy_send_proxy_protocol(ngx
 
 pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
 
-ngx_add_timer(pc->write, pscf->timeout);
-
+if (!pc->write->timer_set) {
+ngx_add_timer(pc->write, pscf->connect_timeout);
+}
+
+pc->read->handler = ngx_stream_proxy_connect_handler;
 pc->write->handler = ngx_stream_proxy_connect_handler;
 
 return NGX_AGAIN;


[nginx] Conditional rearm of write timeouts.

2025-05-13 Thread Maxim Dounin
details:   http://freenginx.org/hg/nginx/rev/4c872940b19b
branches:  
changeset: 9358:4c872940b19b
user:  Maxim Dounin 
date:  Wed May 14 01:16:05 2025 +0300
description:
Conditional rearm of write timeouts.

When the network memory limit is hit on Linux, it is possible that
connections are reported as writable, yet writev() / sendfile() returns
no progress and EAGAIN.  This results in write timeouts being ineffective,
since they are rearmed on each write event.

In particular, such behaviour can be easily reproduced with SO_SNDBUF
explicitly set (via "listen ... sndbuf=...") and with poll or select
event methods.  Before kernel 6.0 and 5.19.2, this also can be easily
reproduced with epoll (849b425cd091e "tcp: fix possible freeze in tx
path under memory pressure").

With this change, write timeouts are only rearmed if some progress is
made, ensuring that timeouts work properly in such situations.

diffstat:

 src/event/ngx_event_pipe.c|   7 ++-
 src/http/ngx_http_request.c   |   5 -
 src/http/ngx_http_upstream.c  |  30 ++
 src/http/v2/ngx_http_v2.c |   8 +++-
 src/mail/ngx_mail_handler.c   |   7 ---
 src/mail/ngx_mail_proxy_module.c  |   4 +++-
 src/stream/ngx_stream_proxy_module.c  |  14 --
 src/stream/ngx_stream_return_module.c |   7 ++-
 8 files changed, 68 insertions(+), 14 deletions(-)

diffs (306 lines):

diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -22,10 +22,13 @@ static ngx_int_t ngx_event_pipe_drain_ch
 ngx_int_t
 ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write)
 {
+off_t sent;
 ngx_int_t rc;
 ngx_uint_tflags;
 ngx_event_t  *rev, *wev;
 
+sent = p->downstream->sent;
+
 for ( ;; ) {
 if (do_write) {
 p->log->action = "sending to client";
@@ -88,7 +91,9 @@ ngx_event_pipe(ngx_event_pipe_t *p, ngx_
 
 if (!wev->delayed) {
 if (wev->active && !wev->ready) {
-ngx_add_timer(wev, p->send_timeout);
+if (p->downstream->sent != sent || !wev->timer_set) {
+ngx_add_timer(wev, p->send_timeout);
+}
 
 } else if (wev->timer_set) {
 ngx_del_timer(wev);
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -2855,6 +2855,7 @@ ngx_http_set_write_handler(ngx_http_requ
 static void
 ngx_http_writer(ngx_http_request_t *r)
 {
+off_t  sent;
 ngx_int_t  rc;
 ngx_event_t   *wev;
 ngx_connection_t  *c;
@@ -2892,6 +2893,8 @@ ngx_http_writer(ngx_http_request_t *r)
 return;
 }
 
+sent = c->sent;
+
 rc = ngx_http_output_filter(r, NULL);
 
 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
@@ -2905,7 +2908,7 @@ ngx_http_writer(ngx_http_request_t *r)
 
 if (r->buffered || r->postponed || (r == r->main && c->buffered)) {
 
-if (!wev->delayed) {
+if (!wev->delayed && (c->sent != sent || !wev->timer_set)) {
 ngx_add_timer(wev, clcf->send_timeout);
 }
 
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -2103,6 +2103,7 @@ static void
 ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u,
 ngx_uint_t do_write)
 {
+off_t  sent;
 ngx_int_t  rc;
 ngx_connection_t  *c;
 
@@ -2120,6 +2121,12 @@ ngx_http_upstream_send_request(ngx_http_
 return;
 }
 
+sent = c->sent;
+
+if (!u->request_sent) {
+sent = -1;
+}
+
 c->log->action = "sending request to upstream";
 
 rc = ngx_http_upstream_send_request_body(r, u, do_write);
@@ -2136,7 +2143,9 @@ ngx_http_upstream_send_request(ngx_http_
 
 if (rc == NGX_AGAIN) {
 if (!c->write->ready || u->request_body_blocked) {
-ngx_add_timer(c->write, u->conf->send_timeout);
+if (c->sent != sent || !c->write->timer_set) {
+ngx_add_timer(c->write, u->conf->send_timeout);
+}
 
 } else if (c->write->timer_set) {
 ngx_del_timer(c->write);
@@ -3512,6 +3521,7 @@ static void
 ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
 ngx_uint_t from_upstream, ngx_uint_t do_write)
 {
+off_t  dsent, usent;
 size_t size;
 ssize_tn;
 ngx_buf_t *b;
@@ -3529,6 +3539,9 @@ ngx_http_upstream_process_upgraded(ngx_h
 downstream = c;
 upstream = u->peer.connection;
 
+dsent = downstream->sent;
+usent = upstream->sent;
+
 if (downstream->write->timedout) {
 c->timedout = 1;
 ngx_connection_error(c, NGX_ETIMEDOUT, "client tim

[nginx] Stream: fixed proxy_connect_timeout with SSL proxying.

2025-05-13 Thread Maxim Dounin
details:   http://freenginx.org/hg/nginx/rev/b29b2f2ffdc3
branches:  
changeset: 9356:b29b2f2ffdc3
user:  Maxim Dounin 
date:  Wed May 14 01:15:42 2025 +0300
description:
Stream: fixed proxy_connect_timeout with SSL proxying.

Connection establishment, including SSL handshake, is expected to complete
within the time set with the proxy_connect_timeout directive.  However,
previously corresponding timer was removed after TCP connect, and then
again added for SSL handshaking, resulting in 2x longer time allowed in
the worst case.

Fix is to remove the timer in ngx_stream_proxy_init_upstream() instead of
doing this in ngx_stream_proxy_connect_handler().

diffstat:

 src/stream/ngx_stream_proxy_module.c |  10 --
 1 files changed, 4 insertions(+), 6 deletions(-)

diffs (34 lines):

diff --git a/src/stream/ngx_stream_proxy_module.c 
b/src/stream/ngx_stream_proxy_module.c
--- a/src/stream/ngx_stream_proxy_module.c
+++ b/src/stream/ngx_stream_proxy_module.c
@@ -929,6 +929,10 @@ ngx_stream_proxy_init_upstream(ngx_strea
 pc->read->handler = ngx_stream_proxy_upstream_handler;
 pc->write->handler = ngx_stream_proxy_upstream_handler;
 
+if (pc->write->timer_set) {
+ngx_del_timer(pc->write);
+}
+
 if (pc->read->ready) {
 ngx_post_event(pc->read, &ngx_posted_events);
 }
@@ -1113,10 +1117,6 @@ ngx_stream_proxy_ssl_handshake(ngx_conne
 }
 }
 
-if (pc->write->timer_set) {
-ngx_del_timer(pc->write);
-}
-
 ngx_stream_proxy_init_upstream(s);
 
 return;
@@ -1494,8 +1494,6 @@ ngx_stream_proxy_connect_handler(ngx_eve
 return;
 }
 
-ngx_del_timer(c->write);
-
 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
"stream proxy connect upstream");
 


[nginx] Stream: style.

2025-05-13 Thread Maxim Dounin
details:   http://freenginx.org/hg/nginx/rev/85a9b0bb5b3c
branches:  
changeset: 9354:85a9b0bb5b3c
user:  Maxim Dounin 
date:  Wed May 14 01:15:13 2025 +0300
description:
Stream: style.

Unless actually required for some reason, line continuation should be
in column 79, not 80.

diffstat:

 src/stream/ngx_stream.h |  16 
 1 files changed, 8 insertions(+), 8 deletions(-)

diffs (32 lines):

diff --git a/src/stream/ngx_stream.h b/src/stream/ngx_stream.h
--- a/src/stream/ngx_stream.h
+++ b/src/stream/ngx_stream.h
@@ -264,20 +264,20 @@ typedef struct {
 #define ngx_stream_delete_ctx(s, module)   s->ctx[module.ctx_index] = NULL;
 
 
-#define ngx_stream_get_module_main_conf(s, module) 
\
+#define ngx_stream_get_module_main_conf(s, module)\
 (s)->main_conf[module.ctx_index]
-#define ngx_stream_get_module_srv_conf(s, module)  
\
+#define ngx_stream_get_module_srv_conf(s, module) \
 (s)->srv_conf[module.ctx_index]
 
-#define ngx_stream_conf_get_module_main_conf(cf, module)   
\
+#define ngx_stream_conf_get_module_main_conf(cf, module)  \
 ((ngx_stream_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index]
-#define ngx_stream_conf_get_module_srv_conf(cf, module)
\
+#define ngx_stream_conf_get_module_srv_conf(cf, module)   \
 ((ngx_stream_conf_ctx_t *) cf->ctx)->srv_conf[module.ctx_index]
 
-#define ngx_stream_cycle_get_module_main_conf(cycle, module)   
\
-(cycle->conf_ctx[ngx_stream_module.index] ?
\
-((ngx_stream_conf_ctx_t *) cycle->conf_ctx[ngx_stream_module.index])   
\
-->main_conf[module.ctx_index]: 
\
+#define ngx_stream_cycle_get_module_main_conf(cycle, module)  \
+(cycle->conf_ctx[ngx_stream_module.index] ?   \
+((ngx_stream_conf_ctx_t *) cycle->conf_ctx[ngx_stream_module.index])  \
+->main_conf[module.ctx_index]:\
 NULL)