Skip to content

Instantly share code, notes, and snippets.

@shankerwangmiao
Last active October 11, 2023 04:15
Show Gist options
  • Save shankerwangmiao/cfecc03174e8e67f20537dc4650ef3e8 to your computer and use it in GitHub Desktop.
Save shankerwangmiao/cfecc03174e8e67f20537dc4650ef3e8 to your computer and use it in GitHub Desktop.
nginx-ip-transp
diff --git a/auto/unix b/auto/unix
index 43d3b25..2b229f7 100644
--- a/auto/unix
+++ b/auto/unix
@@ -312,6 +312,17 @@ ngx_feature_test="cpu_set_t mask;
. auto/feature
+ngx_feature="IP_TRANSPARENT"
+ngx_feature_name="NGX_HAVE_TRANSPARENT"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/socket.h>
+ #include <netinet/in.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="setsockopt(0, SOL_IP, IP_TRANSPARENT, NULL, 0)"
+. auto/feature
+
+
ngx_feature="SO_SETFIB"
ngx_feature_name="NGX_HAVE_SETFIB"
ngx_feature_run=no
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index 3368253..55661e3 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -560,6 +560,25 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
}
#endif
+#if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT)
+
+ if (ls[i].transparent) {
+ int transparent;
+
+ transparent = (ls[i].transparent == 1);
+
+ if (setsockopt(s, SOL_IP, IP_TRANSPARENT,
+ (const void *) &transparent, sizeof(int))
+ == -1)
+ {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
+ "setsockopt(IP_TRANSPARENT) for %V failed, "
+ "ignored",
+ &ls[i].addr_text);
+ }
+ }
+#endif
+
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
if (ls[i].sockaddr->sa_family == AF_INET6) {
diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h
index 5405962..9055f96 100644
--- a/src/core/ngx_connection.h
+++ b/src/core/ngx_connection.h
@@ -90,6 +90,10 @@ struct ngx_listening_s {
int fastopen;
#endif
+#if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT)
+ unsigned transparent:1;
+#endif
+
};
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
index 4364240..2b0ae95 100644
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -212,8 +212,21 @@ ngx_event_accept(ngx_event_t *ev)
c->socklen = socklen;
c->listening = ls;
+#if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT)
+ if(ls->transparent) {
+ c->local_sockaddr = NULL;
+ c->local_socklen = 0;
+ if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
+ ngx_close_accepted_connection(c);
+ return;
+ }
+ }else{
+#endif
c->local_sockaddr = ls->sockaddr;
c->local_socklen = ls->socklen;
+#if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT)
+ }
+#endif
#if (NGX_HAVE_UNIX_DOMAIN)
if (c->sockaddr->sa_family == AF_UNIX) {
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
index 5e20226..b274e91 100644
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -1738,6 +1738,11 @@ ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
ls->sndbuf = addr->opt.sndbuf;
ls->keepalive = addr->opt.so_keepalive;
+
+#if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT)
+ ls->transparent = addr->opt.transparent;
+#endif
+
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
ls->keepidle = addr->opt.tcp_keepidle;
ls->keepintvl = addr->opt.tcp_keepintvl;
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index c57ec00..97d9a48 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -3913,6 +3913,18 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
+ if (ngx_strcmp(value[n].data, "transparent") == 0) {
+#if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT)
+ lsopt.transparent = 1;
+#else
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "transparent mode is not supported "
+ "on this platform, ignored",
+ &value[n]);
+#endif
+ continue;
+ }
+
if (ngx_strncmp(value[n].data, "ipv6only=o", 10) == 0) {
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
struct sockaddr *sa;
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 4c6da7c..a77e609 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -81,6 +81,9 @@ typedef struct {
unsigned reuseport:1;
unsigned so_keepalive:2;
unsigned proxy_protocol:1;
+#if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT)
+ unsigned transparent:1;
+#endif
int backlog;
int rcvbuf;
diff --git a/src/stream/ngx_stream.c b/src/stream/ngx_stream.c
index 4abe387..4bd8a5e 100644
--- a/src/stream/ngx_stream.c
+++ b/src/stream/ngx_stream.c
@@ -500,6 +500,11 @@ ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports)
ls->wildcard = addr[i].opt.wildcard;
ls->keepalive = addr[i].opt.so_keepalive;
+
+#if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT)
+ ls->transparent = addr[i].opt.transparent;
+#endif
+
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
ls->keepidle = addr[i].opt.tcp_keepidle;
ls->keepintvl = addr[i].opt.tcp_keepintvl;
diff --git a/src/stream/ngx_stream.h b/src/stream/ngx_stream.h
index 09d2459..a7baddd 100644
--- a/src/stream/ngx_stream.h
+++ b/src/stream/ngx_stream.h
@@ -56,6 +56,9 @@ typedef struct {
unsigned reuseport:1;
unsigned so_keepalive:2;
unsigned proxy_protocol:1;
+#if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT)
+ unsigned transparent:1;
+#endif
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
int tcp_keepidle;
int tcp_keepintvl;
diff --git a/src/stream/ngx_stream_core_module.c b/src/stream/ngx_stream_core_module.c
index 96e7c9a..b767807 100644
--- a/src/stream/ngx_stream_core_module.c
+++ b/src/stream/ngx_stream_core_module.c
@@ -617,6 +617,10 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ls->ipv6only = 1;
#endif
+#if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT)
+ ls->transparent = 0;
+#endif
+
backlog = 0;
for (i = 2; i < cf->args->nelts; i++) {
@@ -679,6 +683,17 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
+ if (ngx_strcmp(value[i].data, "transparent") == 0) {
+#if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT)
+ ls->transparent = 1;
+#else
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "transparent mode is not supported "
+ "on this platform, ignored",
+ &value[i]);
+#endif
+ continue;
+ }
if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) {
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment