diff options
author | Valentin Bartenev <vbart@nginx.com> | 2011-12-05 12:06:15 +0400 |
---|---|---|
committer | Valentin Bartenev <vbart@nginx.com> | 2011-12-05 12:06:15 +0400 |
commit | 92edf47ff998f174bab2d99c26f59991def2aa4e (patch) | |
tree | 6e514194ae2b9d4f43da303fe30d8ce6962e928b /src | |
parent | 1ea2eb56ef2e26873b71c951b34f5cb98c0a2c53 (diff) |
Added the "so_keepalive=" parameter to the "listen" directive.
The "so_keepalive" directive in mail module was deprecated.
Thanks to Vsevolod Stakhov for initial work.
Diffstat (limited to 'src')
-rw-r--r-- | src/core/ngx_connection.c | 51 | ||||
-rw-r--r-- | src/core/ngx_connection.h | 6 | ||||
-rw-r--r-- | src/http/ngx_http.c | 7 | ||||
-rw-r--r-- | src/http/ngx_http_core_module.c | 91 | ||||
-rw-r--r-- | src/http/ngx_http_core_module.h | 6 | ||||
-rw-r--r-- | src/mail/ngx_mail.c | 13 | ||||
-rw-r--r-- | src/mail/ngx_mail.h | 12 | ||||
-rw-r--r-- | src/mail/ngx_mail_core_module.c | 98 |
8 files changed, 283 insertions, 1 deletions
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c index 3674b9a74..9dc551090 100644 --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -462,6 +462,7 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle) void ngx_configure_listening_sockets(ngx_cycle_t *cycle) { + int keepalive; ngx_uint_t i; ngx_listening_t *ls; @@ -499,6 +500,56 @@ ngx_configure_listening_sockets(ngx_cycle_t *cycle) } } + if (ls[i].keepalive) { + keepalive = (ls[i].keepalive == 1) ? 1 : 0; + + if (setsockopt(ls[i].fd, SOL_SOCKET, SO_KEEPALIVE, + (const void *) &keepalive, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "setsockopt(SO_KEEPALIVE, %d) %V failed, ignored", + keepalive, &ls[i].addr_text); + } + } + +#if (NGX_HAVE_KEEPALIVE_TUNABLE) + + if (ls[i].keepidle) { + if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPIDLE, + (const void *) &ls[i].keepidle, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "setsockopt(TCP_KEEPIDLE, %d) %V failed, ignored", + ls[i].keepidle, &ls[i].addr_text); + } + } + + if (ls[i].keepintvl) { + if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPINTVL, + (const void *) &ls[i].keepintvl, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "setsockopt(TCP_KEEPINTVL, %d) %V failed, ignored", + ls[i].keepintvl, &ls[i].addr_text); + } + } + + if (ls[i].keepcnt) { + if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPCNT, + (const void *) &ls[i].keepcnt, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "setsockopt(TCP_KEEPCNT, %d) %V failed, ignored", + ls[i].keepcnt, &ls[i].addr_text); + } + } + +#endif + #if (NGX_HAVE_SETFIB) if (ls[i].setfib != -1) { if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SETFIB, diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h index f9bf50401..9e3ca52fb 100644 --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -27,6 +27,11 @@ struct ngx_listening_s { int backlog; int rcvbuf; int sndbuf; +#if (NGX_HAVE_KEEPALIVE_TUNABLE) + int keepidle; + int keepintvl; + int keepcnt; +#endif /* handler of accepted connection */ ngx_connection_handler_pt handler; @@ -60,6 +65,7 @@ struct ngx_listening_s { #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) unsigned ipv6only:2; #endif + unsigned keepalive:2; #if (NGX_HAVE_DEFERRED_ACCEPT) unsigned deferred_accept:1; diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c index 1eb22f81e..e10dbc88d 100644 --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -1762,6 +1762,13 @@ ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr) ls->rcvbuf = addr->opt.rcvbuf; ls->sndbuf = addr->opt.sndbuf; + ls->keepalive = addr->opt.so_keepalive; +#if (NGX_HAVE_KEEPALIVE_TUNABLE) + ls->keepidle = addr->opt.tcp_keepidle; + ls->keepintvl = addr->opt.tcp_keepintvl; + ls->keepcnt = addr->opt.tcp_keepcnt; +#endif + #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) ls->accept_filter = addr->opt.accept_filter; #endif diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 96be42369..e66682327 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -3815,6 +3815,97 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) #endif } + if (ngx_strncmp(value[n].data, "so_keepalive=", 13) == 0) { + + if (ngx_strcmp(&value[n].data[13], "on") == 0) { + lsopt.so_keepalive = 1; + + } else if (ngx_strcmp(&value[n].data[13], "off") == 0) { + lsopt.so_keepalive = 2; + + } else { + +#if (NGX_HAVE_KEEPALIVE_TUNABLE) + u_char *p, *end; + ngx_str_t s; + + end = value[n].data + value[n].len; + s.data = value[n].data + 13; + + p = ngx_strlchr(s.data, end, ':'); + if (p == NULL) { + p = end; + } + + if (p > s.data) { + s.len = p - s.data; + + lsopt.tcp_keepidle = ngx_parse_time(&s, 1); + if (lsopt.tcp_keepidle == NGX_ERROR) { + goto invalid_so_keepalive; + } + } + + s.data = (p < end) ? (p + 1) : end; + + p = ngx_strlchr(s.data, end, ':'); + if (p == NULL) { + p = end; + } + + if (p > s.data) { + s.len = p - s.data; + + lsopt.tcp_keepintvl = ngx_parse_time(&s, 1); + if (lsopt.tcp_keepintvl == NGX_ERROR) { + goto invalid_so_keepalive; + } + } + + s.data = (p < end) ? (p + 1) : end; + + if (s.data < end) { + s.len = end - s.data; + + lsopt.tcp_keepcnt = ngx_atoi(s.data, s.len); + if (lsopt.tcp_keepcnt == NGX_ERROR) { + goto invalid_so_keepalive; + } + } + + if (lsopt.tcp_keepidle == 0 && lsopt.tcp_keepintvl == 0 + && lsopt.tcp_keepcnt == 0) + { + goto invalid_so_keepalive; + } + + lsopt.so_keepalive = 1; + +#else + + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "the \"so_keepalive\" parameter accepts " + "only \"on\" or \"off\" on this platform"); + return NGX_CONF_ERROR; + +#endif + } + + lsopt.set = 1; + lsopt.bind = 1; + + continue; + +#if (NGX_HAVE_KEEPALIVE_TUNABLE) + invalid_so_keepalive: + + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid so_keepalive value: \"%s\"", + &value[n].data[13]); + return NGX_CONF_ERROR; +#endif + } + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[n]); return NGX_CONF_ERROR; diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index d2764fe0d..73e39e3b9 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -77,6 +77,7 @@ typedef struct { #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) unsigned ipv6only:2; #endif + unsigned so_keepalive:2; int backlog; int rcvbuf; @@ -84,6 +85,11 @@ typedef struct { #if (NGX_HAVE_SETFIB) int setfib; #endif +#if (NGX_HAVE_KEEPALIVE_TUNABLE) + int tcp_keepidle; + int tcp_keepintvl; + int tcp_keepcnt; +#endif #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) char *accept_filter; diff --git a/src/mail/ngx_mail.c b/src/mail/ngx_mail.c index 3eeb97fe0..0234d18ef 100644 --- a/src/mail/ngx_mail.c +++ b/src/mail/ngx_mail.c @@ -308,6 +308,12 @@ found: addr->ctx = listen->ctx; addr->bind = listen->bind; addr->wildcard = listen->wildcard; + addr->so_keepalive = listen->so_keepalive; +#if (NGX_HAVE_KEEPALIVE_TUNABLE) + addr->tcp_keepidle = listen->tcp_keepidle; + addr->tcp_keepintvl = listen->tcp_keepintvl; + addr->tcp_keepcnt = listen->tcp_keepcnt; +#endif #if (NGX_MAIL_SSL) addr->ssl = listen->ssl; #endif @@ -373,6 +379,13 @@ 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->keepalive = addr[i].so_keepalive; +#if (NGX_HAVE_KEEPALIVE_TUNABLE) + ls->keepidle = addr[i].tcp_keepidle; + ls->keepintvl = addr[i].tcp_keepintvl; + ls->keepcnt = addr[i].tcp_keepcnt; +#endif + #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) ls->ipv6only = addr[i].ipv6only; #endif diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h index fd6d318a5..ca78d0553 100644 --- a/src/mail/ngx_mail.h +++ b/src/mail/ngx_mail.h @@ -40,6 +40,12 @@ typedef struct { #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) unsigned ipv6only:2; #endif + unsigned so_keepalive:2; +#if (NGX_HAVE_KEEPALIVE_TUNABLE) + int tcp_keepidle; + int tcp_keepintvl; + int tcp_keepcnt; +#endif } ngx_mail_listen_t; @@ -95,6 +101,12 @@ typedef struct { #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) unsigned ipv6only:2; #endif + unsigned so_keepalive:2; +#if (NGX_HAVE_KEEPALIVE_TUNABLE) + int tcp_keepidle; + int tcp_keepintvl; + int tcp_keepcnt; +#endif } ngx_mail_conf_addr_t; diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c index 0088fbf26..530bc5d49 100644 --- a/src/mail/ngx_mail_core_module.c +++ b/src/mail/ngx_mail_core_module.c @@ -24,6 +24,12 @@ static char *ngx_mail_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static ngx_conf_deprecated_t ngx_conf_deprecated_so_keepalive = { + ngx_conf_deprecated, "so_keepalive", + "so_keepalive\" parameter of the \"listen" +}; + + static ngx_command_t ngx_mail_core_commands[] = { { ngx_string("server"), @@ -52,7 +58,7 @@ static ngx_command_t ngx_mail_core_commands[] = { ngx_conf_set_flag_slot, NGX_MAIL_SRV_CONF_OFFSET, offsetof(ngx_mail_core_srv_conf_t, so_keepalive), - NULL }, + &ngx_conf_deprecated_so_keepalive }, { ngx_string("timeout"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, @@ -446,6 +452,96 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) #endif } + if (ngx_strncmp(value[i].data, "so_keepalive=", 13) == 0) { + + if (ngx_strcmp(&value[i].data[13], "on") == 0) { + ls->so_keepalive = 1; + + } else if (ngx_strcmp(&value[i].data[13], "off") == 0) { + ls->so_keepalive = 2; + + } else { + +#if (NGX_HAVE_KEEPALIVE_TUNABLE) + u_char *p, *end; + ngx_str_t s; + + end = value[i].data + value[i].len; + s.data = value[i].data + 13; + + p = ngx_strlchr(s.data, end, ':'); + if (p == NULL) { + p = end; + } + + if (p > s.data) { + s.len = p - s.data; + + ls->tcp_keepidle = ngx_parse_time(&s, 1); + if (ls->tcp_keepidle == NGX_ERROR) { + goto invalid_so_keepalive; + } + } + + s.data = (p < end) ? (p + 1) : end; + + p = ngx_strlchr(s.data, end, ':'); + if (p == NULL) { + p = end; + } + + if (p > s.data) { + s.len = p - s.data; + + ls->tcp_keepintvl = ngx_parse_time(&s, 1); + if (ls->tcp_keepintvl == NGX_ERROR) { + goto invalid_so_keepalive; + } + } + + s.data = (p < end) ? (p + 1) : end; + + if (s.data < end) { + s.len = end - s.data; + + ls->tcp_keepcnt = ngx_atoi(s.data, s.len); + if (ls->tcp_keepcnt == NGX_ERROR) { + goto invalid_so_keepalive; + } + } + + if (ls->tcp_keepidle == 0 && ls->tcp_keepintvl == 0 + && ls->tcp_keepcnt == 0) + { + goto invalid_so_keepalive; + } + + ls->so_keepalive = 1; + +#else + + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "the \"so_keepalive\" parameter accepts " + "only \"on\" or \"off\" on this platform"); + return NGX_CONF_ERROR; + +#endif + } + + ls->bind = 1; + + continue; + +#if (NGX_HAVE_KEEPALIVE_TUNABLE) + invalid_so_keepalive: + + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid so_keepalive value: \"%s\"", + &value[i].data[13]); + return NGX_CONF_ERROR; +#endif + } + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the invalid \"%V\" parameter", &value[i]); return NGX_CONF_ERROR; |