From fea078d000e18a9fc59767c845ff954e8f21d32e Mon Sep 17 00:00:00 2001
From: Miao Wang <shankerwangmiao@gmail.com>
Date: Fri, 20 Jul 2018 22:46:03 +0800
Subject: [PATCH] Add IP_TRANSPARENT support
---
auto/unix | 11 +++++++++++
src/core/ngx_connection.c | 19 +++++++++++++++++++
src/core/ngx_connection.h | 4 ++++
src/event/ngx_event_accept.c | 13 +++++++++++++
src/http/ngx_http.c | 5 +++++
src/http/ngx_http_core_module.c | 12 ++++++++++++
src/http/ngx_http_core_module.h | 3 +++
7 files changed, 67 insertions(+)
diff --git a/auto/unix b/auto/unix
index 43d3b25..2b229f7 100644
|
a
|
b
|
ngx_feature_test="cpu_set_t mask;
|
| 312 | 312 | . auto/feature |
| 313 | 313 | |
| 314 | 314 | |
| | 315 | ngx_feature="IP_TRANSPARENT" |
| | 316 | ngx_feature_name="NGX_HAVE_TRANSPARENT" |
| | 317 | ngx_feature_run=no |
| | 318 | ngx_feature_incs="#include <sys/socket.h> |
| | 319 | #include <netinet/in.h>" |
| | 320 | ngx_feature_path= |
| | 321 | ngx_feature_libs= |
| | 322 | ngx_feature_test="setsockopt(0, SOL_IP, IP_TRANSPARENT, NULL, 0)" |
| | 323 | . auto/feature |
| | 324 | |
| | 325 | |
| 315 | 326 | ngx_feature="SO_SETFIB" |
| 316 | 327 | ngx_feature_name="NGX_HAVE_SETFIB" |
| 317 | 328 | ngx_feature_run=no |
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index 3368253..55661e3 100644
|
a
|
b
|
ngx_open_listening_sockets(ngx_cycle_t *cycle)
|
| 560 | 560 | } |
| 561 | 561 | #endif |
| 562 | 562 | |
| | 563 | #if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT) |
| | 564 | |
| | 565 | if (ls[i].transparent) { |
| | 566 | int transparent; |
| | 567 | |
| | 568 | transparent = (ls[i].transparent == 1); |
| | 569 | |
| | 570 | if (setsockopt(s, SOL_IP, IP_TRANSPARENT, |
| | 571 | (const void *) &transparent, sizeof(int)) |
| | 572 | == -1) |
| | 573 | { |
| | 574 | ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, |
| | 575 | "setsockopt(IP_TRANSPARENT) for %V failed, " |
| | 576 | "ignored", |
| | 577 | &ls[i].addr_text); |
| | 578 | } |
| | 579 | } |
| | 580 | #endif |
| | 581 | |
| 563 | 582 | #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) |
| 564 | 583 | |
| 565 | 584 | 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
|
b
|
struct ngx_listening_s {
|
| 90 | 90 | int fastopen; |
| 91 | 91 | #endif |
| 92 | 92 | |
| | 93 | #if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT) |
| | 94 | unsigned transparent:1; |
| | 95 | #endif |
| | 96 | |
| 93 | 97 | }; |
| 94 | 98 | |
| 95 | 99 | |
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
index 4364240..2b0ae95 100644
|
a
|
b
|
ngx_event_accept(ngx_event_t *ev)
|
| 212 | 212 | |
| 213 | 213 | c->socklen = socklen; |
| 214 | 214 | c->listening = ls; |
| | 215 | #if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT) |
| | 216 | if(ls->transparent) { |
| | 217 | c->local_sockaddr = NULL; |
| | 218 | c->local_socklen = 0; |
| | 219 | if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) { |
| | 220 | ngx_close_accepted_connection(c); |
| | 221 | return; |
| | 222 | } |
| | 223 | }else{ |
| | 224 | #endif |
| 215 | 225 | c->local_sockaddr = ls->sockaddr; |
| 216 | 226 | c->local_socklen = ls->socklen; |
| | 227 | #if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT) |
| | 228 | } |
| | 229 | #endif |
| 217 | 230 | |
| 218 | 231 | #if (NGX_HAVE_UNIX_DOMAIN) |
| 219 | 232 | 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
|
b
|
ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
|
| 1738 | 1738 | ls->sndbuf = addr->opt.sndbuf; |
| 1739 | 1739 | |
| 1740 | 1740 | ls->keepalive = addr->opt.so_keepalive; |
| | 1741 | |
| | 1742 | #if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT) |
| | 1743 | ls->transparent = addr->opt.transparent; |
| | 1744 | #endif |
| | 1745 | |
| 1741 | 1746 | #if (NGX_HAVE_KEEPALIVE_TUNABLE) |
| 1742 | 1747 | ls->keepidle = addr->opt.tcp_keepidle; |
| 1743 | 1748 | 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
|
b
|
ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
| 3913 | 3913 | continue; |
| 3914 | 3914 | } |
| 3915 | 3915 | |
| | 3916 | if (ngx_strcmp(value[n].data, "transparent") == 0) { |
| | 3917 | #if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT) |
| | 3918 | lsopt.transparent = 1; |
| | 3919 | #else |
| | 3920 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| | 3921 | "transparent mode is not supported " |
| | 3922 | "on this platform, ignored", |
| | 3923 | &value[n]); |
| | 3924 | #endif |
| | 3925 | continue; |
| | 3926 | } |
| | 3927 | |
| 3916 | 3928 | if (ngx_strncmp(value[n].data, "ipv6only=o", 10) == 0) { |
| 3917 | 3929 | #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) |
| 3918 | 3930 | 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
|
b
|
typedef struct {
|
| 81 | 81 | unsigned reuseport:1; |
| 82 | 82 | unsigned so_keepalive:2; |
| 83 | 83 | unsigned proxy_protocol:1; |
| | 84 | #if (NGX_HAVE_TRANSPARENT && defined IP_TRANSPARENT) |
| | 85 | unsigned transparent:1; |
| | 86 | #endif |
| 84 | 87 | |
| 85 | 88 | int backlog; |
| 86 | 89 | int rcvbuf; |