Welcome! Log In Create A New Profile

Advanced

[nginx] Stream: added half-close support.

Vladimir Homutov
September 22, 2021 11:20AM
details: https://hg.nginx.org/nginx/rev/bfad703459b4
branches:
changeset: 7929:bfad703459b4
user: Vladimir Homutov <vl@nginx.com>
date: Wed Sep 22 10:20:00 2021 +0300
description:
Stream: added half-close support.

The "proxy_half_close" directive enables handling of TCP half close. If
enabled, connection to proxied server is kept open until both read ends get
EOF. Write end shutdown is properly transmitted via proxy.

diffstat:

src/stream/ngx_stream_proxy_module.c | 36 ++++++++++++++++++++++++++++++++++++
src/stream/ngx_stream_upstream.h | 1 +
2 files changed, 37 insertions(+), 0 deletions(-)

diffs (92 lines):

diff -r 97cf8284fd19 -r bfad703459b4 src/stream/ngx_stream_proxy_module.c
--- a/src/stream/ngx_stream_proxy_module.c Fri Sep 10 12:59:22 2021 +0300
+++ b/src/stream/ngx_stream_proxy_module.c Wed Sep 22 10:20:00 2021 +0300
@@ -31,6 +31,7 @@ typedef struct {
ngx_uint_t next_upstream_tries;
ngx_flag_t next_upstream;
ngx_flag_t proxy_protocol;
+ ngx_flag_t half_close;
ngx_stream_upstream_local_t *local;
ngx_flag_t socket_keepalive;

@@ -245,6 +246,13 @@ static ngx_command_t ngx_stream_proxy_c
offsetof(ngx_stream_proxy_srv_conf_t, proxy_protocol),
NULL },

+ { ngx_string("proxy_half_close"),
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ NGX_STREAM_SRV_CONF_OFFSET,
+ offsetof(ngx_stream_proxy_srv_conf_t, half_close),
+ NULL },
+
#if (NGX_STREAM_SSL)

{ ngx_string("proxy_ssl"),
@@ -1755,6 +1763,24 @@ ngx_stream_proxy_process(ngx_stream_sess
}

if (dst) {
+
+ if (dst->type == SOCK_STREAM && pscf->half_close
+ && src->read->eof && !u->half_closed && !dst->buffered)
+ {
+ if (ngx_shutdown_socket(dst->fd, NGX_WRITE_SHUTDOWN) == -1) {
+ ngx_connection_error(c, ngx_socket_errno,
+ ngx_shutdown_socket_n " failed");
+
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ u->half_closed = 1;
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "stream proxy %s socket shutdown",
+ from_upstream ? "client" : "upstream");
+ }
+
if (ngx_handle_write_event(dst->write, 0) != NGX_OK) {
ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
@@ -1833,6 +1859,13 @@ ngx_stream_proxy_test_finalize(ngx_strea
return NGX_DECLINED;
}

+ if (pscf->half_close) {
+ /* avoid closing live connections until both read ends get EOF */
+ if (!(c->read->eof && pc->read->eof && !c->buffered && !pc->buffered)) {
+ return NGX_DECLINED;
+ }
+ }
+
handler = c->log->handler;
c->log->handler = NULL;

@@ -2052,6 +2085,7 @@ ngx_stream_proxy_create_srv_conf(ngx_con
conf->proxy_protocol = NGX_CONF_UNSET;
conf->local = NGX_CONF_UNSET_PTR;
conf->socket_keepalive = NGX_CONF_UNSET;
+ conf->half_close = NGX_CONF_UNSET;

#if (NGX_STREAM_SSL)
conf->ssl_enable = NGX_CONF_UNSET;
@@ -2110,6 +2144,8 @@ ngx_stream_proxy_merge_srv_conf(ngx_conf
ngx_conf_merge_value(conf->socket_keepalive,
prev->socket_keepalive, 0);

+ ngx_conf_merge_value(conf->half_close, prev->half_close, 0);
+
#if (NGX_STREAM_SSL)

ngx_conf_merge_value(conf->ssl_enable, prev->ssl_enable, 0);
diff -r 97cf8284fd19 -r bfad703459b4 src/stream/ngx_stream_upstream.h
--- a/src/stream/ngx_stream_upstream.h Fri Sep 10 12:59:22 2021 +0300
+++ b/src/stream/ngx_stream_upstream.h Wed Sep 22 10:20:00 2021 +0300
@@ -142,6 +142,7 @@ typedef struct {
ngx_stream_upstream_state_t *state;
unsigned connected:1;
unsigned proxy_protocol:1;
+ unsigned half_closed:1;
} ngx_stream_upstream_t;


_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[nginx] Stream: added half-close support.

Vladimir Homutov 614 September 22, 2021 11:20AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 242
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready