pull/931/merge
Sergey Kandaurov 2 days ago committed by GitHub
commit 6d8bf3ea59
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      contrib/vim/syntax/nginx.vim
  2. 111
      src/core/ngx_connection.c
  3. 3
      src/core/ngx_connection.h
  4. 10
      src/core/ngx_cycle.c
  5. 1
      src/http/ngx_http.c
  6. 17
      src/http/ngx_http_core_module.c
  7. 1
      src/http/ngx_http_core_module.h
  8. 1
      src/mail/ngx_mail.c
  9. 1
      src/mail/ngx_mail.h
  10. 11
      src/mail/ngx_mail_core_module.c
  11. 34
      src/os/unix/ngx_socket.c
  12. 19
      src/os/unix/ngx_socket.h
  13. 1
      src/stream/ngx_stream.c
  14. 1
      src/stream/ngx_stream.h
  15. 17
      src/stream/ngx_stream_core_module.c

@ -65,7 +65,7 @@ syn match ngxListenComment '#.*$'
\ contained
\ nextgroup=@ngxListenParams skipwhite skipempty
syn keyword ngxListenOptions contained
\ default_server ssl quic proxy_protocol
\ default_server ssl quic proxy_protocol multipath
\ setfib fastopen backlog rcvbuf sndbuf accept_filter deferred bind
\ ipv6only reuseport so_keepalive
\ nextgroup=@ngxListenParams skipwhite skipempty

@ -315,6 +315,27 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
continue;
}
#ifdef SO_PROTOCOL
olen = sizeof(int);
if (getsockopt(ls[i].fd, SOL_SOCKET, SO_PROTOCOL,
(void *) &ls[i].protocol, &olen)
== -1)
{
ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
"getsockopt(SO_PROTOCOL) %V failed",
&ls[i].addr_text);
ls[i].ignore = 1;
continue;
}
if (ls[i].protocol == IPPROTO_TCP) {
ls[i].protocol = 0;
}
#endif
#if (NGX_HAVE_TCP_FASTOPEN)
olen = sizeof(int);
@ -436,45 +457,28 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
#if (NGX_HAVE_REUSEPORT)
if (ls[i].add_reuseport) {
if (ls[i].add_reuseport || ls[i].change_protocol) {
/*
* to allow transition from a socket without SO_REUSEPORT
* to multiple sockets with SO_REUSEPORT, we have to set
* SO_REUSEPORT on the old socket before opening new ones
*
* to allow socket protocol change (e.g. IPPROTO_MPTCP),
* SO_REUSEPORT is set temporarily on both sockets
*/
int reuseport = 1;
#ifdef SO_REUSEPORT_LB
if (setsockopt(ls[i].fd, SOL_SOCKET, SO_REUSEPORT_LB,
(const void *) &reuseport, sizeof(int))
== -1)
{
if (ngx_reuseport(ls[i].fd) == -1) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
"setsockopt(SO_REUSEPORT_LB) %V failed, "
"ignored",
ngx_reuseport_n " %V failed, ignored",
&ls[i].addr_text);
}
#else
if (setsockopt(ls[i].fd, SOL_SOCKET, SO_REUSEPORT,
(const void *) &reuseport, sizeof(int))
== -1)
{
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
"setsockopt(SO_REUSEPORT) %V failed, ignored",
&ls[i].addr_text);
}
#endif
ls[i].add_reuseport = 0;
}
#endif
if (ls[i].fd != (ngx_socket_t) -1) {
if (ls[i].fd != (ngx_socket_t) -1 && !ls[i].change_protocol) {
continue;
}
@ -487,7 +491,8 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
continue;
}
s = ngx_socket(ls[i].sockaddr->sa_family, ls[i].type, 0);
s = ngx_socket(ls[i].sockaddr->sa_family, ls[i].type,
ls[i].protocol);
if (s == (ngx_socket_t) -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
@ -517,38 +522,12 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
#if (NGX_HAVE_REUSEPORT)
if (ls[i].reuseport && !ngx_test_config) {
int reuseport;
reuseport = 1;
#ifdef SO_REUSEPORT_LB
if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT_LB,
(const void *) &reuseport, sizeof(int))
== -1)
{
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
"setsockopt(SO_REUSEPORT_LB) %V failed",
&ls[i].addr_text);
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
ngx_close_socket_n " %V failed",
&ls[i].addr_text);
}
return NGX_ERROR;
}
#else
if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT,
(const void *) &reuseport, sizeof(int))
== -1)
{
if ((ls[i].reuseport || ls[i].change_protocol)
&& !ngx_test_config)
{
if (ngx_reuseport(s) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
"setsockopt(SO_REUSEPORT) %V failed",
ngx_reuseport_n " %V failed",
&ls[i].addr_text);
if (ngx_close_socket(s) == -1) {
@ -559,7 +538,6 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
return NGX_ERROR;
}
#endif
}
#endif
@ -686,6 +664,25 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
continue;
}
#if (NGX_HAVE_REUSEPORT)
if (!ls[i].reuseport && ls[i].change_protocol && !ngx_test_config) {
if (ngx_noreuseport(s) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
ngx_noreuseport_n " %V failed",
&ls[i].addr_text);
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
ngx_close_socket_n " %V failed",
&ls[i].addr_text);
}
return NGX_ERROR;
}
}
#endif
ls[i].listen = 1;
ls[i].fd = s;

@ -24,6 +24,7 @@ struct ngx_listening_s {
ngx_str_t addr_text;
int type;
int protocol;
int backlog;
int rcvbuf;
@ -75,6 +76,8 @@ struct ngx_listening_s {
unsigned keepalive:2;
unsigned quic:1;
unsigned change_protocol:1;
unsigned deferred_accept:1;
unsigned delete_deferred:1;
unsigned add_deferred:1;

@ -535,9 +535,15 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
== NGX_OK)
{
nls[n].fd = ls[i].fd;
nls[n].inherited = ls[i].inherited;
nls[n].previous = &ls[i];
ls[i].remain = 1;
if (ls[i].protocol != nls[n].protocol) {
nls[n].change_protocol = 1;
} else {
nls[n].inherited = ls[i].inherited;
ls[i].remain = 1;
}
if (ls[i].backlog != nls[n].backlog) {
nls[n].listen = 1;

@ -1846,6 +1846,7 @@ ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
#endif
ls->type = addr->opt.type;
ls->protocol = addr->opt.protocol;
ls->backlog = addr->opt.backlog;
ls->rcvbuf = addr->opt.rcvbuf;
ls->sndbuf = addr->opt.sndbuf;

@ -4361,6 +4361,17 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
if (ngx_strcmp(value[n].data, "multipath") == 0) {
#ifdef IPPROTO_MPTCP
lsopt.protocol = IPPROTO_MPTCP;
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"multipath is not supported "
"on this platform, ignored");
#endif
continue;
}
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid parameter \"%V\"", &value[n]);
return NGX_CONF_ERROR;
@ -4408,6 +4419,12 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (lsopt.proxy_protocol) {
return "\"proxy_protocol\" parameter is incompatible with \"quic\"";
}
#ifdef IPPROTO_MPTCP
if (lsopt.protocol == IPPROTO_MPTCP) {
return "\"multipath\" parameter is incompatible with \"quic\"";
}
#endif
}
for (n = 0; n < u.naddrs; n++) {

@ -88,6 +88,7 @@ typedef struct {
int rcvbuf;
int sndbuf;
int type;
int protocol;
#if (NGX_HAVE_SETFIB)
int setfib;
#endif

@ -332,6 +332,7 @@ ngx_mail_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports)
ls->log.data = &ls->addr_text;
ls->log.handler = ngx_accept_log_error;
ls->protocol = addr[i].opt.protocol;
ls->backlog = addr[i].opt.backlog;
ls->rcvbuf = addr[i].opt.rcvbuf;
ls->sndbuf = addr[i].opt.sndbuf;

@ -47,6 +47,7 @@ typedef struct {
int tcp_keepintvl;
int tcp_keepcnt;
#endif
int protocol;
int backlog;
int rcvbuf;
int sndbuf;

@ -563,6 +563,17 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
if (ngx_strcmp(value[i].data, "multipath") == 0) {
#ifdef IPPROTO_MPTCP
ls->protocol = IPPROTO_MPTCP;
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"multipath is not supported "
"on this platform, ignored");
#endif
continue;
}
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid parameter \"%V\"", &value[i]);
return NGX_CONF_ERROR;

@ -114,3 +114,37 @@ ngx_tcp_push(ngx_socket_t s)
}
#endif
#if (NGX_HAVE_REUSEPORT)
int
ngx_reuseport(ngx_socket_t s)
{
int reuseport = 1;
#ifdef SO_REUSEPORT_LB
return setsockopt(s, SOL_SOCKET, SO_REUSEPORT_LB,
(const void *) &reuseport, sizeof(int));
#else
return setsockopt(s, SOL_SOCKET, SO_REUSEPORT,
(const void *) &reuseport, sizeof(int));
#endif
}
int
ngx_noreuseport(ngx_socket_t s)
{
int reuseport = 0;
#ifdef SO_REUSEPORT_LB
return setsockopt(s, SOL_SOCKET, SO_REUSEPORT_LB,
(const void *) &reuseport, sizeof(int));
#else
return setsockopt(s, SOL_SOCKET, SO_REUSEPORT,
(const void *) &reuseport, sizeof(int));
#endif
}
#endif

@ -63,6 +63,25 @@ int ngx_tcp_push(ngx_socket_t s);
#endif
#if (NGX_HAVE_REUSEPORT)
int ngx_reuseport(ngx_socket_t s);
int ngx_noreuseport(ngx_socket_t s);
#ifdef SO_REUSEPORT_LB
#define ngx_reuseport_n "setsockopt(SO_REUSEPORT_LB)"
#define ngx_noreuseport_n "setsockopt(!SO_REUSEPORT_LB)"
#else
#define ngx_reuseport_n "setsockopt(SO_REUSEPORT)"
#define ngx_noreuseport_n "setsockopt(!SO_REUSEPORT)"
#endif
#endif
#define ngx_shutdown_socket shutdown
#define ngx_shutdown_socket_n "shutdown()"

@ -1010,6 +1010,7 @@ ngx_stream_add_listening(ngx_conf_t *cf, ngx_stream_conf_addr_t *addr)
ls->log.handler = ngx_accept_log_error;
ls->type = addr->opt.type;
ls->protocol = addr->opt.protocol;
ls->backlog = addr->opt.backlog;
ls->rcvbuf = addr->opt.rcvbuf;
ls->sndbuf = addr->opt.sndbuf;

@ -62,6 +62,7 @@ typedef struct {
int rcvbuf;
int sndbuf;
int type;
int protocol;
#if (NGX_HAVE_SETFIB)
int setfib;
#endif

@ -1310,6 +1310,17 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
if (ngx_strcmp(value[i].data, "multipath") == 0) {
#ifdef IPPROTO_MPTCP
lsopt.protocol = IPPROTO_MPTCP;
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"multipath is not supported "
"on this platform, ignored");
#endif
continue;
}
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid parameter \"%V\"", &value[i]);
return NGX_CONF_ERROR;
@ -1351,6 +1362,12 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (lsopt.proxy_protocol) {
return "\"proxy_protocol\" parameter is incompatible with \"udp\"";
}
#ifdef IPPROTO_MPTCP
if (lsopt.protocol == IPPROTO_MPTCP) {
return "\"multipath\" parameter is incompatible with \"udp\"";
}
#endif
}
for (n = 0; n < u.naddrs; n++) {

Loading…
Cancel
Save