Changes of Revision 91
[-] | Changed | nginx.spec |
x 1
2 %define nps_version 1.9.32.3 3 %define slowfs_version 1.5 4 #%define waf_version 2.8.0 5 -%define openssl_version 1.0.2a 6 +%define openssl_version 1.0.2d 7 %define ngxpurge_version 2.3 8 9 Name: nginx 10 -Version: 1.9.1 11 +Version: 1.9.3 12 Release: 1 13 Summary: Robust, small and high performance http and reverse proxy server 14 Group: System Environment/Daemons 15 |
||
[+] | Deleted | nginx-1.9.1.tar.gz/src/http/ngx_http_parse_time.c ^ |
@@ -1,277 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) Nginx, Inc. - */ - - -#include <ngx_config.h> -#include <ngx_core.h> -#include <ngx_http.h> - - -static ngx_uint_t mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - -time_t -ngx_http_parse_time(u_char *value, size_t len) -{ - u_char *p, *end; - ngx_int_t month; - ngx_uint_t day, year, hour, min, sec; - uint64_t time; - enum { - no = 0, - rfc822, /* Tue, 10 Nov 2002 23:50:13 */ - rfc850, /* Tuesday, 10-Dec-02 23:50:13 */ - isoc /* Tue Dec 10 23:50:13 2002 */ - } fmt; - - fmt = 0; - end = value + len; - -#if (NGX_SUPPRESS_WARN) - day = 32; - year = 2038; -#endif - - for (p = value; p < end; p++) { - if (*p == ',') { - break; - } - - if (*p == ' ') { - fmt = isoc; - break; - } - } - - for (p++; p < end; p++) - if (*p != ' ') { - break; - } - - if (end - p < 18) { - return NGX_ERROR; - } - - if (fmt != isoc) { - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { - return NGX_ERROR; - } - - day = (*p - '0') * 10 + *(p + 1) - '0'; - p += 2; - - if (*p == ' ') { - if (end - p < 18) { - return NGX_ERROR; - } - fmt = rfc822; - - } else if (*p == '-') { - fmt = rfc850; - - } else { - return NGX_ERROR; - } - - p++; - } - - switch (*p) { - - case 'J': - month = *(p + 1) == 'a' ? 0 : *(p + 2) == 'n' ? 5 : 6; - break; - - case 'F': - month = 1; - break; - - case 'M': - month = *(p + 2) == 'r' ? 2 : 4; - break; - - case 'A': - month = *(p + 1) == 'p' ? 3 : 7; - break; - - case 'S': - month = 8; - break; - - case 'O': - month = 9; - break; - - case 'N': - month = 10; - break; - - case 'D': - month = 11; - break; - - default: - return NGX_ERROR; - } - - p += 3; - - if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-')) { - return NGX_ERROR; - } - - p++; - - if (fmt == rfc822) { - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9' - || *(p + 2) < '0' || *(p + 2) > '9' - || *(p + 3) < '0' || *(p + 3) > '9') - { - return NGX_ERROR; - } - - year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100 - + (*(p + 2) - '0') * 10 + *(p + 3) - '0'; - p += 4; - - } else if (fmt == rfc850) { - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { - return NGX_ERROR; - } - - year = (*p - '0') * 10 + *(p + 1) - '0'; - year += (year < 70) ? 2000 : 1900; - p += 2; - } - - if (fmt == isoc) { - if (*p == ' ') { - p++; - } - - if (*p < '0' || *p > '9') { - return NGX_ERROR; - } - - day = *p++ - '0'; - - if (*p != ' ') { - if (*p < '0' || *p > '9') { - return NGX_ERROR; - } - - day = day * 10 + *p++ - '0'; - } - - if (end - p < 14) { - return NGX_ERROR; - } - } - - if (*p++ != ' ') { - return NGX_ERROR; - } - - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { - return NGX_ERROR; - } - - hour = (*p - '0') * 10 + *(p + 1) - '0'; - p += 2; - - if (*p++ != ':') { - return NGX_ERROR; - } - - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { - return NGX_ERROR; - } - - min = (*p - '0') * 10 + *(p + 1) - '0'; - p += 2; - - if (*p++ != ':') { - return NGX_ERROR; - } - - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { - return NGX_ERROR; - } - - sec = (*p - '0') * 10 + *(p + 1) - '0'; - - if (fmt == isoc) { - p += 2; - - if (*p++ != ' ') { - return NGX_ERROR; - } - - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9' - || *(p + 2) < '0' || *(p + 2) > '9' - || *(p + 3) < '0' || *(p + 3) > '9') - { - return NGX_ERROR; - } - - year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100 - + (*(p + 2) - '0') * 10 + *(p + 3) - '0'; - } - - if (hour > 23 || min > 59 || sec > 59) { - return NGX_ERROR; - } - - if (day == 29 && month == 1) { - if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0)) { - return NGX_ERROR; - } - - } else if (day > mday[month]) { - return NGX_ERROR; - } - - /* - * shift new year to March 1 and start months from 1 (not 0), - * it is needed for Gauss' formula - */ - - if (--month <= 0) { - month += 12; - year -= 1; - } - - /* Gauss' formula for Gregorian days since March 1, 1 BC */ - - time = (uint64_t) ( - /* days in years including leap years since March 1, 1 BC */ - - 365 * year + year / 4 - year / 100 + year / 400 - - /* days before the month */ - - + 367 * month / 12 - 30 - - /* days before the day */ - - + day - 1 - - /* - * 719527 days were between March 1, 1 BC and March 1, 1970, - * 31 and 28 days were in January and February 1970 - */ - - - 719527 + 31 + 28) * 86400 + hour * 3600 + min * 60 + sec; - -#if (NGX_TIME_T_SIZE <= 4) - - if (time > 0x7fffffff) { - return NGX_ERROR; - } - -#endif - - return (time_t) time; -} | ||
[+] | Changed | nginx-1.9.3.tar.gz/CHANGES ^ |
@@ -1,4 +1,55 @@ +Changes with nginx 1.9.3 14 Jul 2015 + + *) Change: duplicate "http", "mail", and "stream" blocks are now + disallowed. + + *) Feature: connection limiting in the stream module. + + *) Feature: data rate limiting in the stream module. + + *) Bugfix: the "zone" directive inside the "upstream" block did not work + on Windows. + + *) Bugfix: compatibility with LibreSSL in the stream module. + Thanks to Piotr Sikora. + + *) Bugfix: in the "--builddir" configure parameter. + Thanks to Piotr Sikora. + + *) Bugfix: the "ssl_stapling_file" directive did not work; the bug had + appeared in 1.9.2. + Thanks to Faidon Liambotis and Brandon Black. + + *) Bugfix: a segmentation fault might occur in a worker process if the + "ssl_stapling" directive was used; the bug had appeared in 1.9.2. + Thanks to Matthew Baldwin. + + +Changes with nginx 1.9.2 16 Jun 2015 + + *) Feature: the "backlog" parameter of the "listen" directives of the + mail proxy and stream modules. + + *) Feature: the "allow" and "deny" directives in the stream module. + + *) Feature: the "proxy_bind" directive in the stream module. + + *) Feature: the "proxy_protocol" directive in the stream module. + + *) Feature: the -T switch. + + *) Feature: the REQUEST_SCHEME parameter added to the fastcgi.conf, + fastcgi_params, scgi_params, and uwsgi_params standard configuration + files. + + *) Bugfix: the "reuseport" parameter of the "listen" directive of the + stream module did not work. + + *) Bugfix: OCSP stapling might return an expired OCSP response in some + cases. + + Changes with nginx 1.9.1 26 May 2015 *) Change: now SSLv3 protocol is disabled by default. @@ -1467,7 +1518,7 @@ Changes with nginx 1.1.10 30 Nov 2011 - *) Bugfix: a segmentation fault occured in a worker process if AIO was + *) Bugfix: a segmentation fault occurred in a worker process if AIO was used on Linux; the bug had appeared in 1.1.9. @@ -1744,7 +1795,7 @@ and proxies to an HTTPS backend. Thanks to Maxim Dounin. - *) Bugfix: in parameter validaiton of a "proxy_pass" directive with + *) Bugfix: in parameter validation of a "proxy_pass" directive with variables. Thanks to Lanshun Zhou. @@ -4509,7 +4560,7 @@ Changes with nginx 0.5.21 28 May 2007 *) Bugfix: if server has more than about ten locations, then regex - locations might be choosen not in that order as they were specified. + locations might be chosen not in that order as they were specified. *) Bugfix: a worker process may got caught in an endless loop on 64-bit platform, if the 33-rd or next in succession backend has failed. @@ -4595,7 +4646,7 @@ *) Bugfix: in the HTTPS protocol in the "proxy_pass" directive. - *) Bugfix: in some cases non-cachable variables (such as $uri variable) + *) Bugfix: in some cases non-cacheable variables (such as $uri variable) returned old cached value. @@ -4620,7 +4671,7 @@ Changes with nginx 0.5.15 19 Mar 2007 *) Feature: the mail proxy supports authenticated SMTP proxying and the - "smtp_auth", "smtp_capablities", and "xclient" directives. + "smtp_auth", "smtp_capabilities", and "xclient" directives. Thanks to Anton Yuzhaninov and Maxim Dounin. *) Feature: now the keep-alive connections are closed just after @@ -5721,7 +5772,7 @@ *) Feature: the ngx_http_perl_module. - *) Change: the "valid_referers" directive allows the referreres without + *) Change: the "valid_referers" directive allows the referrers without URI part. @@ -5821,7 +5872,7 @@ *) Feature: the "so_keepalive" directive in IMAP/POP3 proxy. *) Bugfix: if there are unclosed connection nginx now calls abort() only - on gracefull quit and active "debug_points" directive. + on graceful quit and active "debug_points" directive. Changes with nginx 0.3.14 05 Dec 2005 @@ -6362,7 +6413,7 @@ *) Bugfix: the responses may be transferred not completely, if many parts or the big parts were included by SSI. - *) Bugfix: if all backends had returned the 404 reponse and the + *) Bugfix: if all backends had returned the 404 response and the "http_404" parameter of the "proxy_next_upstream" or "fastcgi_next_upstream" directives was used, then nginx started to request all backends again. | ||
[+] | Changed | nginx-1.9.3.tar.gz/CHANGES.ru ^ |
@@ -1,4 +1,53 @@ +Изменения в nginx 1.9.3 14.07.2015 + + *) Изменение: дублирующиеся блоки http, mail и stream теперь запрещены. + + *) Добавление: ограничение количества соединений в модуле stream. + + *) Добавление: органичение скорости в модуле stream. + + *) Исправление: директива zone в блоке upstream не работала на Windows. + + *) Исправление: совместимость с LibreSSL в модуле stream. + Спасибо Piotr Sikora. + + *) Исправление: в параметре --builddir в configure. + Спасибо Piotr Sikora. + + *) Исправление: директива ssl_stapling_file не работала; ошибка + появилась в 1.9.2. + Спасибо Faidon Liambotis и Brandon Black. + + *) Исправление: при использовании директивы ssl_stapling в рабочем + процессе мог произойти segmentation fault; ошибка появилась в 1.9.2. + Спасибо Matthew Baldwin. + + +Изменения в nginx 1.9.2 16.06.2015 + + *) Добавление: параметр backlog директивы listen в почтовом + прокси-сервере и модуле stream. + + *) Добавление: директивы allow и deny в модуле stream. + + *) Добавление: директива proxy_bind в модуле stream. + + *) Добавление: директива proxy_protocol в модуле stream. + + *) Добавление: ключ -T. + + *) Добавление: параметр REQUEST_SCHEME добавлен в стандартные + конфигурационные файлы fastcgi.conf, fastcgi_params, scgi_params и + uwsgi_params. + + *) Исправление: параметр reuseport директивы listen в модуле stream не + работал. + + *) Исправление: OCSP stapling в некоторых случаях мог вернуть устаревший + OCSP-ответ. + + Изменения в nginx 1.9.1 26.05.2015 *) Изменение: теперь протокол SSLv3 по умолчанию запрещён. @@ -83,7 +132,7 @@ прокси-сервере. Спасибо Sven Peter, Franck Levionnois и Filipe Da Silva. - *) Добавление: уменьшение времени запуска при использовании дирекивы + *) Добавление: уменьшение времени запуска при использовании директивы "hash ... consistent" в блоке upstream. Спасибо Wai Keen Woon. @@ -4721,7 +4770,8 @@ Изменения в nginx 0.5.15 19.03.2007 *) Добавление: почтовый прокси-сервер поддерживает аутентифицированное - SMTP-проксирование и директивы smtp_auth, smtp_capablities и xclient. + SMTP-проксирование и директивы smtp_auth, smtp_capabilities и + xclient. Спасибо Антону Южанинову и Максиму Дунину. *) Добавление: теперь keep-alive соединения закрываются сразу же по @@ -5926,7 +5976,7 @@ *) Добавление: директива so_keepalive в IMAP/POP3 прокси. *) Исправление: nginx теперь вызывает abort() при обнаружении незакрытых - соединений только при планом выходе и включённой директиве + соединений только при плавном выходе и включённой директиве debug_points. | ||
[+] | Changed | nginx-1.9.3.tar.gz/auto/cc/gcc ^ |
@@ -153,7 +153,7 @@ case "$NGX_GCC_VER" in - 3.* | 4.* ) + [3-5].*) # we have a lot of the unused function arguments CFLAGS="$CFLAGS -Wno-unused-parameter" # 4.2.1 shows the warning in wrong places | ||
[+] | Changed | nginx-1.9.3.tar.gz/auto/install ^ |
@@ -20,10 +20,6 @@ ./*) ;; - .) - NGX_SBIN_PATH=$NGX_PREFIX/sbin/nginx - ;; - *) NGX_SBIN_PATH=$NGX_PREFIX/$NGX_SBIN_PATH ;; | ||
[+] | Changed | nginx-1.9.3.tar.gz/auto/lib/openssl/conf ^ |
@@ -55,6 +55,54 @@ ngx_feature_test="SSL_library_init()" . auto/feature + if [ $ngx_found = no ]; then + + # FreeBSD port + + ngx_feature="OpenSSL library in /usr/local/" + ngx_feature_path="/usr/local/include" + + if [ $NGX_RPATH = YES ]; then + ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lssl -lcrypto" + else + ngx_feature_libs="-L/usr/local/lib -lssl -lcrypto" + fi + + . auto/feature + fi + + if [ $ngx_found = no ]; then + + # NetBSD port + + ngx_feature="OpenSSL library in /usr/pkg/" + ngx_feature_path="/usr/pkg/include" + + if [ $NGX_RPATH = YES ]; then + ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lssl -lcrypto" + else + ngx_feature_libs="-L/usr/pkg/lib -lssl -lcrypto" + fi + + . auto/feature + fi + + if [ $ngx_found = no ]; then + + # MacPorts + + ngx_feature="OpenSSL library in /opt/local/" + ngx_feature_path="/opt/local/include" + + if [ $NGX_RPATH = YES ]; then + ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lssl -lcrypto" + else + ngx_feature_libs="-L/opt/local/lib -lssl -lcrypto" + fi + + . auto/feature + fi + if [ $ngx_found = yes ]; then have=NGX_SSL . auto/have CORE_LIBS="$CORE_LIBS $ngx_feature_libs $NGX_LIBDL" | ||
[+] | Changed | nginx-1.9.3.tar.gz/auto/make ^ |
@@ -50,7 +50,7 @@ ngx_all_srcs="$CORE_SRCS" -# the core dependences and include paths +# the core dependencies and include paths ngx_deps=`echo $CORE_DEPS $NGX_AUTO_CONFIG_H $NGX_PCH \ | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \ @@ -70,7 +70,7 @@ END -# the http dependences and include paths +# the http dependencies and include paths if [ $HTTP = YES ]; then @@ -96,7 +96,7 @@ fi -# the mail dependences and include paths +# the mail dependencies and include paths if [ $MAIL = YES ]; then @@ -122,7 +122,7 @@ fi -# the stream dependences and include paths +# the stream dependencies and include paths if [ $STREAM = YES ]; then | ||
[+] | Changed | nginx-1.9.3.tar.gz/auto/modules ^ |
@@ -514,6 +514,16 @@ STREAM_SRCS="$STREAM_SRCS $STREAM_SSL_SRCS" fi + if [ $STREAM_LIMIT_CONN = YES ]; then + modules="$modules $STREAM_LIMIT_CONN_MODULE" + STREAM_SRCS="$STREAM_SRCS $STREAM_LIMIT_CONN_SRCS" + fi + + if [ $STREAM_ACCESS = YES ]; then + modules="$modules $STREAM_ACCESS_MODULE" + STREAM_SRCS="$STREAM_SRCS $STREAM_ACCESS_SRCS" + fi + if [ $STREAM_UPSTREAM_HASH = YES ]; then modules="$modules $STREAM_UPSTREAM_HASH_MODULE" STREAM_SRCS="$STREAM_SRCS $STREAM_UPSTREAM_HASH_SRCS" | ||
[+] | Changed | nginx-1.9.3.tar.gz/auto/options ^ |
@@ -113,6 +113,8 @@ STREAM=NO STREAM_SSL=NO +STREAM_LIMIT_CONN=YES +STREAM_ACCESS=YES STREAM_UPSTREAM_HASH=YES STREAM_UPSTREAM_LEAST_CONN=YES STREAM_UPSTREAM_ZONE=YES @@ -282,6 +284,9 @@ --with-stream) STREAM=YES ;; --with-stream_ssl_module) STREAM_SSL=YES ;; + --without-stream_limit_conn_module) + STREAM_LIMIT_CONN=NO ;; + --without-stream_access_module) STREAM_ACCESS=NO ;; --without-stream_upstream_hash_module) STREAM_UPSTREAM_HASH=NO ;; --without-stream_upstream_least_conn_module) @@ -450,6 +455,8 @@ --with-stream enable TCP proxy module --with-stream_ssl_module enable ngx_stream_ssl_module + --without-stream_limit_conn_module disable ngx_stream_limit_conn_module + --without-stream_access_module disable ngx_stream_access_module --without-stream_upstream_hash_module disable ngx_stream_upstream_hash_module --without-stream_upstream_least_conn_module @@ -522,6 +529,7 @@ fi +NGX_SBIN_PATH=${NGX_SBIN_PATH:-sbin/nginx} NGX_CONF_PATH=${NGX_CONF_PATH:-conf/nginx.conf} NGX_CONF_PREFIX=`dirname $NGX_CONF_PATH` NGX_PID_PATH=${NGX_PID_PATH:-logs/nginx.pid} | ||
[+] | Changed | nginx-1.9.3.tar.gz/auto/sources ^ |
@@ -19,6 +19,7 @@ src/core/ngx_queue.h \ src/core/ngx_string.h \ src/core/ngx_parse.h \ + src/core/ngx_parse_time.h \ src/core/ngx_inet.h \ src/core/ngx_file.h \ src/core/ngx_crc.h \ @@ -53,6 +54,7 @@ src/core/ngx_output_chain.c \ src/core/ngx_string.c \ src/core/ngx_parse.c \ + src/core/ngx_parse_time.c \ src/core/ngx_inet.c \ src/core/ngx_file.c \ src/core/ngx_crc32.c \ @@ -303,7 +305,6 @@ src/http/ngx_http_script.c \ src/http/ngx_http_upstream.c \ src/http/ngx_http_upstream_round_robin.c \ - src/http/ngx_http_parse_time.c \ src/http/modules/ngx_http_static_module.c \ src/http/modules/ngx_http_index_module.c \ src/http/modules/ngx_http_chunked_filter_module.c \ @@ -567,6 +568,12 @@ STREAM_SSL_DEPS="src/stream/ngx_stream_ssl_module.h" STREAM_SSL_SRCS="src/stream/ngx_stream_ssl_module.c" +STREAM_LIMIT_CONN_MODULE=ngx_stream_limit_conn_module +STREAM_LIMIT_CONN_SRCS=src/stream/ngx_stream_limit_conn_module.c + +STREAM_ACCESS_MODULE=ngx_stream_access_module +STREAM_ACCESS_SRCS=src/stream/ngx_stream_access_module.c + STREAM_UPSTREAM_HASH_MODULE=ngx_stream_upstream_hash_module STREAM_UPSTREAM_HASH_SRCS=src/stream/ngx_stream_upstream_hash_module.c | ||
[+] | Changed | nginx-1.9.3.tar.gz/auto/unix ^ |
@@ -505,14 +505,7 @@ # POSIX types -case "$NGX_AUTO_CONFIG_H" in - /*) - NGX_INCLUDE_AUTO_CONFIG_H="#include \"$NGX_AUTO_CONFIG_H\"" - ;; - *) - NGX_INCLUDE_AUTO_CONFIG_H="#include \"../$NGX_AUTO_CONFIG_H\"" - ;; -esac +NGX_INCLUDE_AUTO_CONFIG_H="#include \"ngx_auto_config.h\"" ngx_type="uint64_t"; ngx_types="u_int64_t"; . auto/types/typedef | ||
[+] | Changed | nginx-1.9.3.tar.gz/conf/fastcgi.conf ^ |
@@ -10,6 +10,7 @@ fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; +fastcgi_param REQUEST_SCHEME $scheme; fastcgi_param HTTPS $https if_not_empty; fastcgi_param GATEWAY_INTERFACE CGI/1.1; | ||
[+] | Changed | nginx-1.9.3.tar.gz/conf/fastcgi_params ^ |
@@ -9,6 +9,7 @@ fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; +fastcgi_param REQUEST_SCHEME $scheme; fastcgi_param HTTPS $https if_not_empty; fastcgi_param GATEWAY_INTERFACE CGI/1.1; | ||
[+] | Changed | nginx-1.9.3.tar.gz/conf/scgi_params ^ |
@@ -8,6 +8,7 @@ scgi_param DOCUMENT_ROOT $document_root; scgi_param SCGI 1; scgi_param SERVER_PROTOCOL $server_protocol; +scgi_param REQUEST_SCHEME $scheme; scgi_param HTTPS $https if_not_empty; scgi_param REMOTE_ADDR $remote_addr; | ||
[+] | Changed | nginx-1.9.3.tar.gz/conf/uwsgi_params ^ |
@@ -8,6 +8,7 @@ uwsgi_param PATH_INFO $document_uri; uwsgi_param DOCUMENT_ROOT $document_root; uwsgi_param SERVER_PROTOCOL $server_protocol; +uwsgi_param REQUEST_SCHEME $scheme; uwsgi_param HTTPS $https if_not_empty; uwsgi_param REMOTE_ADDR $remote_addr; | ||
[+] | Changed | nginx-1.9.3.tar.gz/configure ^ |
@@ -11,7 +11,7 @@ . auto/init . auto/sources -test -d $NGX_OBJS || mkdir $NGX_OBJS +test -d $NGX_OBJS || mkdir -p $NGX_OBJS echo > $NGX_AUTO_HEADERS_H echo > $NGX_AUTOCONF_ERR | ||
[+] | Changed | nginx-1.9.3.tar.gz/man/nginx.8 ^ |
@@ -25,7 +25,7 @@ .\" SUCH DAMAGE. .\" .\" -.Dd March 6, 2012 +.Dd June 16, 2015 .Dt NGINX 8 .Os .Sh NAME @@ -33,7 +33,7 @@ .Nd "HTTP and reverse proxy server, mail proxy server" .Sh SYNOPSIS .Nm -.Op Fl ?hqtVv +.Op Fl ?hqTtVv .Op Fl c Ar file .Op Fl g Ar directives .Op Fl p Ar prefix @@ -87,6 +87,10 @@ .Nm checks the configuration file syntax and then tries to open files referenced in the configuration file. +.It Fl T +Same as +.Fl t , +but additionally dump configuration files to standard output. .It Fl V Print the .Nm | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/core/nginx.c ^ |
@@ -176,9 +176,11 @@ int ngx_cdecl main(int argc, char *const *argv) { - ngx_int_t i; + ngx_buf_t *b; ngx_log_t *log; + ngx_uint_t i; ngx_cycle_t *cycle, init_cycle; + ngx_conf_dump_t *cd; ngx_core_conf_t *ccf; ngx_debug_init(); @@ -196,7 +198,7 @@ if (ngx_show_help) { ngx_write_stderr( - "Usage: nginx [-?hvVtq] [-s signal] [-c filename] " + "Usage: nginx [-?hvVtTq] [-s signal] [-c filename] " "[-p prefix] [-g directives]" NGX_LINEFEED NGX_LINEFEED "Options:" NGX_LINEFEED @@ -205,6 +207,8 @@ " -V : show version and configure options then exit" NGX_LINEFEED " -t : test configuration and exit" NGX_LINEFEED + " -T : test configuration, dump it and exit" + NGX_LINEFEED " -q : suppress non-error messages " "during configuration testing" NGX_LINEFEED " -s signal : send signal to a master process: " @@ -333,6 +337,23 @@ cycle->conf_file.data); } + if (ngx_dump_config) { + cd = cycle->config_dump.elts; + + for (i = 0; i < cycle->config_dump.nelts; i++) { + + ngx_write_stdout("# configuration file "); + (void) ngx_write_fd(ngx_stdout, cd[i].name.data, + cd[i].name.len); + ngx_write_stdout(":" NGX_LINEFEED); + + b = cd[i].buffer; + + (void) ngx_write_fd(ngx_stdout, b->pos, b->last - b->pos); + ngx_write_stdout(NGX_LINEFEED); + } + } + return 0; } @@ -689,6 +710,11 @@ ngx_test_config = 1; break; + case 'T': + ngx_test_config = 1; + ngx_dump_config = 1; + break; + case 'q': ngx_quiet_mode = 1; break; | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/core/nginx.h ^ |
@@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1009001 -#define NGINX_VERSION "1.9.1" +#define nginx_version 1009003 +#define NGINX_VERSION "1.9.3" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/core/ngx_conf_file.c ^ |
@@ -101,10 +101,13 @@ ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename) { char *rv; + u_char *p; + off_t size; ngx_fd_t fd; ngx_int_t rc; - ngx_buf_t buf; + ngx_buf_t buf, *tbuf; ngx_conf_file_t *prev, conf_file; + ngx_conf_dump_t *cd; enum { parse_file = 0, parse_block, @@ -158,6 +161,39 @@ type = parse_file; + if (ngx_dump_config +#if (NGX_DEBUG) + || 1 +#endif + ) + { + p = ngx_pstrdup(cf->cycle->pool, filename); + if (p == NULL) { + goto failed; + } + + size = ngx_file_size(&cf->conf_file->file.info); + + tbuf = ngx_create_temp_buf(cf->cycle->pool, (size_t) size); + if (tbuf == NULL) { + goto failed; + } + + cd = ngx_array_push(&cf->cycle->config_dump); + if (cd == NULL) { + goto failed; + } + + cd->name.len = filename->len; + cd->name.data = p; + cd->buffer = tbuf; + + cf->conf_file->dump = tbuf; + + } else { + cf->conf_file->dump = NULL; + } + } else if (cf->conf_file->file.fd != NGX_INVALID_FILE) { type = parse_block; @@ -437,7 +473,7 @@ ngx_uint_t found, need_space, last_space, sharp_comment, variable; ngx_uint_t quoted, s_quoted, d_quoted, start_line; ngx_str_t *word; - ngx_buf_t *b; + ngx_buf_t *b, *dump; found = 0; need_space = 0; @@ -450,6 +486,7 @@ cf->args->nelts = 0; b = cf->conf_file->buffer; + dump = cf->conf_file->dump; start = b->pos; start_line = cf->conf_file->line; @@ -531,6 +568,10 @@ b->pos = b->start + len; b->last = b->pos + n; start = b->start; + + if (dump) { + dump->last = ngx_cpymem(dump->last, b->pos, size); + } } ch = *b->pos++; @@ -680,7 +721,7 @@ return NGX_ERROR; } - word->data = ngx_pnalloc(cf->pool, b->pos - start + 1); + word->data = ngx_pnalloc(cf->pool, b->pos - 1 - start + 1); if (word->data == NULL) { return NGX_ERROR; } | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/core/ngx_conf_file.h ^ |
@@ -146,10 +146,17 @@ typedef struct { ngx_file_t file; ngx_buf_t *buffer; + ngx_buf_t *dump; ngx_uint_t line; } ngx_conf_file_t; +typedef struct { + ngx_str_t name; + ngx_buf_t *buffer; +} ngx_conf_dump_t; + + typedef char *(*ngx_conf_handler_pt)(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/core/ngx_core.h ^ |
@@ -54,6 +54,7 @@ #include <ngx_process.h> #include <ngx_user.h> #include <ngx_parse.h> +#include <ngx_parse_time.h> #include <ngx_log.h> #include <ngx_alloc.h> #include <ngx_palloc.h> | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/core/ngx_cycle.c ^ |
@@ -24,6 +24,7 @@ static ngx_event_t ngx_cleaner_event; ngx_uint_t ngx_test_config; +ngx_uint_t ngx_dump_config; ngx_uint_t ngx_quiet_mode; @@ -124,6 +125,13 @@ cycle->paths.pool = pool; + if (ngx_array_init(&cycle->config_dump, pool, 1, sizeof(ngx_conf_dump_t)) + != NGX_OK) + { + ngx_destroy_pool(pool); + return NULL; + } + if (old_cycle->open_files.part.nelts) { n = old_cycle->open_files.part.nelts; for (part = old_cycle->open_files.part.next; part; part = part->next) { | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/core/ngx_cycle.h ^ |
@@ -52,6 +52,7 @@ ngx_array_t listening; ngx_array_t paths; + ngx_array_t config_dump; ngx_list_t open_files; ngx_list_t shared_memory; @@ -124,6 +125,7 @@ extern ngx_array_t ngx_old_cycles; extern ngx_module_t ngx_core_module; extern ngx_uint_t ngx_test_config; +extern ngx_uint_t ngx_dump_config; extern ngx_uint_t ngx_quiet_mode; | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/core/ngx_log.h ^ |
@@ -111,7 +111,7 @@ /*********************************/ -#else /* NO VARIADIC MACROS */ +#else /* no variadic macros */ #define NGX_HAVE_VARIADIC_MACROS 0 @@ -123,7 +123,7 @@ const char *fmt, ...); -#endif /* VARIADIC MACROS */ +#endif /* variadic macros */ /*********************************/ @@ -166,7 +166,7 @@ arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) -#else /* NO VARIADIC MACROS */ +#else /* no variadic macros */ #define ngx_log_debug0(level, log, err, fmt) \ if ((log)->log_level & level) \ @@ -211,7 +211,7 @@ #endif -#else /* NO NGX_DEBUG */ +#else /* !NGX_DEBUG */ #define ngx_log_debug0(level, log, err, fmt) #define ngx_log_debug1(level, log, err, fmt, arg1) @@ -255,6 +255,13 @@ } +static ngx_inline void +ngx_write_stdout(char *text) +{ + (void) ngx_write_fd(ngx_stdout, text, ngx_strlen(text)); +} + + extern ngx_module_t ngx_errlog_module; extern ngx_uint_t ngx_use_stderr; | ||
[+] | Added | nginx-1.9.3.tar.gz/src/core/ngx_parse_time.c ^ |
@@ -0,0 +1,276 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) Nginx, Inc. + */ + + +#include <ngx_config.h> +#include <ngx_core.h> + + +static ngx_uint_t mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + +time_t +ngx_parse_http_time(u_char *value, size_t len) +{ + u_char *p, *end; + ngx_int_t month; + ngx_uint_t day, year, hour, min, sec; + uint64_t time; + enum { + no = 0, + rfc822, /* Tue, 10 Nov 2002 23:50:13 */ + rfc850, /* Tuesday, 10-Dec-02 23:50:13 */ + isoc /* Tue Dec 10 23:50:13 2002 */ + } fmt; + + fmt = 0; + end = value + len; + +#if (NGX_SUPPRESS_WARN) + day = 32; + year = 2038; +#endif + + for (p = value; p < end; p++) { + if (*p == ',') { + break; + } + + if (*p == ' ') { + fmt = isoc; + break; + } + } + + for (p++; p < end; p++) + if (*p != ' ') { + break; + } + + if (end - p < 18) { + return NGX_ERROR; + } + + if (fmt != isoc) { + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { + return NGX_ERROR; + } + + day = (*p - '0') * 10 + *(p + 1) - '0'; + p += 2; + + if (*p == ' ') { + if (end - p < 18) { + return NGX_ERROR; + } + fmt = rfc822; + + } else if (*p == '-') { + fmt = rfc850; + + } else { + return NGX_ERROR; + } + + p++; + } + + switch (*p) { + + case 'J': + month = *(p + 1) == 'a' ? 0 : *(p + 2) == 'n' ? 5 : 6; + break; + + case 'F': + month = 1; + break; + + case 'M': + month = *(p + 2) == 'r' ? 2 : 4; + break; + + case 'A': + month = *(p + 1) == 'p' ? 3 : 7; + break; + + case 'S': + month = 8; + break; + + case 'O': + month = 9; + break; + + case 'N': + month = 10; + break; + + case 'D': + month = 11; + break; + + default: + return NGX_ERROR; + } + + p += 3; + + if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-')) { + return NGX_ERROR; + } + + p++; + + if (fmt == rfc822) { + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9' + || *(p + 2) < '0' || *(p + 2) > '9' + || *(p + 3) < '0' || *(p + 3) > '9') + { + return NGX_ERROR; + } + + year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100 + + (*(p + 2) - '0') * 10 + *(p + 3) - '0'; + p += 4; + + } else if (fmt == rfc850) { + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { + return NGX_ERROR; + } + + year = (*p - '0') * 10 + *(p + 1) - '0'; + year += (year < 70) ? 2000 : 1900; + p += 2; + } + + if (fmt == isoc) { + if (*p == ' ') { + p++; + } + + if (*p < '0' || *p > '9') { + return NGX_ERROR; + } + + day = *p++ - '0'; + + if (*p != ' ') { + if (*p < '0' || *p > '9') { + return NGX_ERROR; + } + + day = day * 10 + *p++ - '0'; + } + + if (end - p < 14) { + return NGX_ERROR; + } + } + + if (*p++ != ' ') { + return NGX_ERROR; + } + + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { + return NGX_ERROR; + } + + hour = (*p - '0') * 10 + *(p + 1) - '0'; + p += 2; + + if (*p++ != ':') { + return NGX_ERROR; + } + + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { + return NGX_ERROR; + } + + min = (*p - '0') * 10 + *(p + 1) - '0'; + p += 2; + + if (*p++ != ':') { + return NGX_ERROR; + } + + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { + return NGX_ERROR; + } + + sec = (*p - '0') * 10 + *(p + 1) - '0'; + + if (fmt == isoc) { + p += 2; + + if (*p++ != ' ') { + return NGX_ERROR; + } + + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9' + || *(p + 2) < '0' || *(p + 2) > '9' + || *(p + 3) < '0' || *(p + 3) > '9') + { + return NGX_ERROR; + } + + year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100 + + (*(p + 2) - '0') * 10 + *(p + 3) - '0'; + } + + if (hour > 23 || min > 59 || sec > 59) { + return NGX_ERROR; + } + + if (day == 29 && month == 1) { + if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0)) { + return NGX_ERROR; + } + + } else if (day > mday[month]) { + return NGX_ERROR; + } + + /* + * shift new year to March 1 and start months from 1 (not 0), + * it is needed for Gauss' formula + */ + + if (--month <= 0) { + month += 12; + year -= 1; + } + + /* Gauss' formula for Gregorian days since March 1, 1 BC */ + + time = (uint64_t) ( + /* days in years including leap years since March 1, 1 BC */ + + 365 * year + year / 4 - year / 100 + year / 400 + + /* days before the month */ + + + 367 * month / 12 - 30 + + /* days before the day */ + + + day - 1 + + /* + * 719527 days were between March 1, 1 BC and March 1, 1970, + * 31 and 28 days were in January and February 1970 + */ + + - 719527 + 31 + 28) * 86400 + hour * 3600 + min * 60 + sec; + +#if (NGX_TIME_T_SIZE <= 4) + + if (time > 0x7fffffff) { + return NGX_ERROR; + } + +#endif + + return (time_t) time; +} | ||
[+] | Added | nginx-1.9.3.tar.gz/src/core/ngx_parse_time.h ^ |
@@ -0,0 +1,22 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) Nginx, Inc. + */ + + +#ifndef _NGX_PARSE_TIME_H_INCLUDED_ +#define _NGX_PARSE_TIME_H_INCLUDED_ + + +#include <ngx_config.h> +#include <ngx_core.h> + + +time_t ngx_parse_http_time(u_char *value, size_t len); + +/* compatibility */ +#define ngx_http_parse_time(value, len) ngx_parse_http_time(value, len) + + +#endif /* _NGX_PARSE_TIME_H_INCLUDED_ */ | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/core/ngx_proxy_protocol.c ^ |
@@ -10,7 +10,7 @@ u_char * -ngx_proxy_protocol_parse(ngx_connection_t *c, u_char *buf, u_char *last) +ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last) { size_t len; u_char ch, *p, *addr; @@ -89,3 +89,52 @@ return NULL; } + + +u_char * +ngx_proxy_protocol_write(ngx_connection_t *c, u_char *buf, u_char *last) +{ + ngx_uint_t port, lport; + + if (last - buf < NGX_PROXY_PROTOCOL_MAX_HEADER) { + return NULL; + } + + if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) { + return NULL; + } + + switch (c->sockaddr->sa_family) { + + case AF_INET: + buf = ngx_cpymem(buf, "PROXY TCP4 ", sizeof("PROXY TCP4 ") - 1); + + port = ntohs(((struct sockaddr_in *) c->sockaddr)->sin_port); + lport = ntohs(((struct sockaddr_in *) c->local_sockaddr)->sin_port); + + break; + +#if (NGX_HAVE_INET6) + case AF_INET6: + buf = ngx_cpymem(buf, "PROXY TCP6 ", sizeof("PROXY TCP6 ") - 1); + + port = ntohs(((struct sockaddr_in6 *) c->sockaddr)->sin6_port); + lport = ntohs(((struct sockaddr_in6 *) c->local_sockaddr)->sin6_port); + + break; +#endif + + default: + return ngx_cpymem(buf, "PROXY UNKNOWN" CRLF, + sizeof("PROXY UNKNOWN" CRLF) - 1); + } + + buf += ngx_sock_ntop(c->sockaddr, c->socklen, buf, last - buf, 0); + + *buf++ = ' '; + + buf += ngx_sock_ntop(c->local_sockaddr, c->local_socklen, buf, last - buf, + 0); + + return ngx_slprintf(buf, last, " %ui %ui" CRLF, port, lport); +} | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/core/ngx_proxy_protocol.h ^ |
@@ -16,7 +16,9 @@ #define NGX_PROXY_PROTOCOL_MAX_HEADER 107 -u_char *ngx_proxy_protocol_parse(ngx_connection_t *c, u_char *buf, +u_char *ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, + u_char *last); +u_char *ngx_proxy_protocol_write(ngx_connection_t *c, u_char *buf, u_char *last); | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/core/ngx_resolver.c ^ |
@@ -71,6 +71,7 @@ static void ngx_resolver_resend_handler(ngx_event_t *ev); static time_t ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue); +static ngx_uint_t ngx_resolver_resend_empty(ngx_resolver_t *r); static void ngx_resolver_read_response(ngx_event_t *rev); static void ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n); @@ -463,6 +464,10 @@ ngx_resolver_free_locked(r, ctx); /* unlock alloc mutex */ + + if (r->event->timer_set && ngx_resolver_resend_empty(r)) { + ngx_del_timer(r->event); + } } @@ -1016,6 +1021,10 @@ ngx_resolver_free_locked(r, ctx); /* unlock alloc mutex */ + + if (r->event->timer_set && ngx_resolver_resend_empty(r)) { + ngx_del_timer(r->event); + } } @@ -1225,6 +1234,17 @@ } +static ngx_uint_t +ngx_resolver_resend_empty(ngx_resolver_t *r) +{ + return ngx_queue_empty(&r->name_resend_queue) +#if (NGX_HAVE_INET6) + && ngx_queue_empty(&r->addr6_resend_queue) +#endif + && ngx_queue_empty(&r->addr_resend_queue); +} + + static void ngx_resolver_read_response(ngx_event_t *rev) { | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/event/ngx_event.c ^ |
@@ -927,8 +927,9 @@ *cf = pcf; - if (rv != NGX_CONF_OK) + if (rv != NGX_CONF_OK) { return rv; + } for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->type != NGX_EVENT_MODULE) { | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/event/ngx_event_openssl_stapling.c ^ |
@@ -32,6 +32,7 @@ X509 *issuer; time_t valid; + time_t refresh; unsigned verify:1; unsigned loading:1; @@ -93,6 +94,8 @@ static void ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple); static void ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx); +static time_t ngx_ssl_stapling_time(ASN1_GENERALIZEDTIME *asn1time); + static void ngx_ssl_stapling_cleanup(void *data); static ngx_ssl_ocsp_ctx_t *ngx_ssl_ocsp_start(void); @@ -242,6 +245,7 @@ staple->staple.data = buf; staple->staple.len = len; + staple->valid = NGX_MAX_TIME_T_VALUE; return NGX_OK; @@ -462,7 +466,9 @@ staple = data; rc = SSL_TLSEXT_ERR_NOACK; - if (staple->staple.len) { + if (staple->staple.len + && staple->valid >= ngx_time()) + { /* we have to copy ocsp response as OpenSSL will free it by itself */ p = OPENSSL_malloc(staple->staple.len); @@ -490,7 +496,7 @@ ngx_ssl_ocsp_ctx_t *ctx; if (staple->host.len == 0 - || staple->loading || staple->valid >= ngx_time()) + || staple->loading || staple->refresh >= ngx_time()) { return; } @@ -532,6 +538,7 @@ u_char *p; int n; size_t len; + time_t now, valid; ngx_str_t response; X509_STORE *store; STACK_OF(X509) *chain; @@ -542,6 +549,7 @@ ASN1_GENERALIZEDTIME *thisupdate, *nextupdate; staple = ctx->data; + now = ngx_time(); ocsp = NULL; basic = NULL; id = NULL; @@ -629,17 +637,33 @@ goto error; } + if (nextupdate) { + valid = ngx_ssl_stapling_time(nextupdate); + if (valid == (time_t) NGX_ERROR) { + ngx_log_error(NGX_LOG_ERR, ctx->log, 0, + "invalid nextUpdate time in certificate status"); + goto error; + } + + } else { + valid = NGX_MAX_TIME_T_VALUE; + } + OCSP_CERTID_free(id); OCSP_BASICRESP_free(basic); OCSP_RESPONSE_free(ocsp); + id = NULL; + basic = NULL; + ocsp = NULL; + /* copy the response to memory not in ctx->pool */ response.len = len; response.data = ngx_alloc(response.len, ctx->log); if (response.data == NULL) { - goto done; + goto error; } ngx_memcpy(response.data, ctx->response->pos, response.len); @@ -653,11 +677,15 @@ } staple->staple = response; + staple->valid = valid; -done: + /* + * refresh before the response expires, + * but not earlier than in 5 minutes, and at least in an hour + */ staple->loading = 0; - staple->valid = ngx_time() + 3600; /* ssl_stapling_valid */ + staple->refresh = ngx_max(ngx_min(valid - 300, now + 3600), now + 300); ngx_ssl_ocsp_done(ctx); return; @@ -665,7 +693,7 @@ error: staple->loading = 0; - staple->valid = ngx_time() + 300; /* ssl_stapling_err_valid */ + staple->refresh = now + 300; if (id) { OCSP_CERTID_free(id); @@ -683,6 +711,40 @@ } +static time_t +ngx_ssl_stapling_time(ASN1_GENERALIZEDTIME *asn1time) +{ + u_char *value; + size_t len; + time_t time; + BIO *bio; + + /* + * OpenSSL doesn't provide a way to convert ASN1_GENERALIZEDTIME + * into time_t. To do this, we use ASN1_GENERALIZEDTIME_print(), + * which uses the "MMM DD HH:MM:SS YYYY [GMT]" format (e.g., + * "Feb 3 00:55:52 2015 GMT"), and parse the result. + */ + + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) { + return NGX_ERROR; + } + + /* fake weekday prepended to match C asctime() format */ + + BIO_write(bio, "Tue ", sizeof("Tue ") - 1); + ASN1_GENERALIZEDTIME_print(bio, asn1time); + len = BIO_get_mem_data(bio, &value); + + time = ngx_parse_http_time(value, len); + + BIO_free(bio); + + return time; +} + + static void ngx_ssl_stapling_cleanup(void *data) { | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/event/ngx_event_pipe.c ^ |
@@ -22,8 +22,8 @@ ngx_int_t ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write) { - u_int flags; ngx_int_t rc; + ngx_uint_t flags; ngx_event_t *rev, *wev; for ( ;; ) { | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/http/modules/ngx_http_dav_module.c ^ |
@@ -255,7 +255,7 @@ ext.log = r->connection->log; if (r->headers_in.date) { - date = ngx_http_parse_time(r->headers_in.date->value.data, + date = ngx_parse_http_time(r->headers_in.date->value.data, r->headers_in.date->value.len); if (date != NGX_ERROR) { | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/http/modules/ngx_http_headers_filter_module.c ^ |
@@ -498,7 +498,7 @@ } r->headers_out.last_modified_time = - (value->len) ? ngx_http_parse_time(value->data, value->len) : -1; + (value->len) ? ngx_parse_http_time(value->data, value->len) : -1; return NGX_OK; } | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/http/modules/ngx_http_not_modified_filter_module.c ^ |
@@ -118,7 +118,7 @@ return 0; } - iums = ngx_http_parse_time(r->headers_in.if_unmodified_since->value.data, + iums = ngx_parse_http_time(r->headers_in.if_unmodified_since->value.data, r->headers_in.if_unmodified_since->value.len); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -148,7 +148,7 @@ return 1; } - ims = ngx_http_parse_time(r->headers_in.if_modified_since->value.data, + ims = ngx_parse_http_time(r->headers_in.if_modified_since->value.data, r->headers_in.if_modified_since->value.len); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/http/modules/ngx_http_range_filter_module.c ^ |
@@ -204,7 +204,7 @@ goto next_filter; } - if_range_time = ngx_http_parse_time(if_range->data, if_range->len); + if_range_time = ngx_parse_http_time(if_range->data, if_range->len); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http ir:%d lm:%d", | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/http/modules/ngx_http_upstream_keepalive_module.c ^ |
@@ -25,6 +25,18 @@ typedef struct { ngx_http_upstream_keepalive_srv_conf_t *conf; + ngx_queue_t queue; + ngx_connection_t *connection; + + socklen_t socklen; + u_char sockaddr[NGX_SOCKADDRLEN]; + +} ngx_http_upstream_keepalive_cache_t; + + +typedef struct { + ngx_http_upstream_keepalive_srv_conf_t *conf; + ngx_http_upstream_t *upstream; void *data; @@ -40,18 +52,6 @@ } ngx_http_upstream_keepalive_peer_data_t; -typedef struct { - ngx_http_upstream_keepalive_srv_conf_t *conf; - - ngx_queue_t queue; - ngx_connection_t *connection; - - socklen_t socklen; - u_char sockaddr[NGX_SOCKADDRLEN]; - -} ngx_http_upstream_keepalive_cache_t; - - static ngx_int_t ngx_http_upstream_init_keepalive_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us); static ngx_int_t ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc, @@ -63,7 +63,6 @@ static void ngx_http_upstream_keepalive_close_handler(ngx_event_t *ev); static void ngx_http_upstream_keepalive_close(ngx_connection_t *c); - #if (NGX_HTTP_SSL) static ngx_int_t ngx_http_upstream_keepalive_set_session( ngx_peer_connection_t *pc, void *data); @@ -244,24 +243,28 @@ ngx_queue_remove(q); ngx_queue_insert_head(&kp->conf->free, q); - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, - "get keepalive peer: using connection %p", c); - - c->idle = 0; - c->sent = 0; - c->log = pc->log; - c->read->log = pc->log; - c->write->log = pc->log; - c->pool->log = pc->log; - - pc->connection = c; - pc->cached = 1; - - return NGX_DONE; + goto found; } } return NGX_OK; + +found: + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, + "get keepalive peer: using connection %p", c); + + c->idle = 0; + c->sent = 0; + c->log = pc->log; + c->read->log = pc->log; + c->write->log = pc->log; + c->pool->log = pc->log; + + pc->connection = c; + pc->cached = 1; + + return NGX_DONE; } @@ -322,9 +325,10 @@ item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue); } - item->connection = c; ngx_queue_insert_head(&kp->conf->cache, q); + item->connection = c; + pc->connection = NULL; if (c->read->timer_set) { @@ -470,10 +474,9 @@ * * conf->original_init_upstream = NULL; * conf->original_init_peer = NULL; + * conf->max_cached = 0; */ - conf->max_cached = 1; - return conf; } @@ -487,18 +490,10 @@ ngx_int_t n; ngx_str_t *value; - uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module); - - if (kcf->original_init_upstream) { + if (kcf->max_cached) { return "is duplicate"; } - kcf->original_init_upstream = uscf->peer.init_upstream - ? uscf->peer.init_upstream - : ngx_http_upstream_init_round_robin; - - uscf->peer.init_upstream = ngx_http_upstream_init_keepalive; - /* read options */ value = cf->args->elts; @@ -514,5 +509,13 @@ kcf->max_cached = n; + uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module); + + kcf->original_init_upstream = uscf->peer.init_upstream + ? uscf->peer.init_upstream + : ngx_http_upstream_init_round_robin; + + uscf->peer.init_upstream = ngx_http_upstream_init_keepalive; + return NGX_CONF_OK; } | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/http/modules/ngx_http_upstream_zone_module.c ^ |
@@ -14,8 +14,8 @@ void *conf); static ngx_int_t ngx_http_upstream_init_zone(ngx_shm_zone_t *shm_zone, void *data); -static ngx_int_t ngx_http_upstream_zone_copy_peers(ngx_slab_pool_t *shpool, - ngx_http_upstream_srv_conf_t *uscf); +static ngx_http_upstream_rr_peers_t *ngx_http_upstream_zone_copy_peers( + ngx_slab_pool_t *shpool, ngx_http_upstream_srv_conf_t *uscf); static ngx_command_t ngx_http_upstream_zone_commands[] = { @@ -121,13 +121,29 @@ size_t len; ngx_uint_t i; ngx_slab_pool_t *shpool; + ngx_http_upstream_rr_peers_t *peers, **peersp; ngx_http_upstream_srv_conf_t *uscf, **uscfp; ngx_http_upstream_main_conf_t *umcf; shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; + umcf = shm_zone->data; + uscfp = umcf->upstreams.elts; if (shm_zone->shm.exists) { - return NGX_ERROR; + peers = shpool->data; + + for (i = 0; i < umcf->upstreams.nelts; i++) { + uscf = uscfp[i]; + + if (uscf->shm_zone != shm_zone) { + continue; + } + + uscf->peer.data = peers; + peers = peers->zone_next; + } + + return NGX_OK; } len = sizeof(" in upstream zone \"\"") + shm_zone->shm.name.len; @@ -143,8 +159,7 @@ /* copy peers to shared memory */ - umcf = shm_zone->data; - uscfp = umcf->upstreams.elts; + peersp = (ngx_http_upstream_rr_peers_t **) &shpool->data; for (i = 0; i < umcf->upstreams.nelts; i++) { uscf = uscfp[i]; @@ -153,16 +168,20 @@ continue; } - if (ngx_http_upstream_zone_copy_peers(shpool, uscf) != NGX_OK) { + peers = ngx_http_upstream_zone_copy_peers(shpool, uscf); + if (peers == NULL) { return NGX_ERROR; } + + *peersp = peers; + peersp = &peers->zone_next; } return NGX_OK; } -static ngx_int_t +static ngx_http_upstream_rr_peers_t * ngx_http_upstream_zone_copy_peers(ngx_slab_pool_t *shpool, ngx_http_upstream_srv_conf_t *uscf) { @@ -171,7 +190,7 @@ peers = ngx_slab_alloc(shpool, sizeof(ngx_http_upstream_rr_peers_t)); if (peers == NULL) { - return NGX_ERROR; + return NULL; } ngx_memcpy(peers, uscf->peer.data, sizeof(ngx_http_upstream_rr_peers_t)); @@ -183,7 +202,7 @@ peer = ngx_slab_calloc_locked(shpool, sizeof(ngx_http_upstream_rr_peer_t)); if (peer == NULL) { - return NGX_ERROR; + return NULL; } ngx_memcpy(peer, *peerp, sizeof(ngx_http_upstream_rr_peer_t)); @@ -197,7 +216,7 @@ backup = ngx_slab_alloc(shpool, sizeof(ngx_http_upstream_rr_peers_t)); if (backup == NULL) { - return NGX_ERROR; + return NULL; } ngx_memcpy(backup, peers->next, sizeof(ngx_http_upstream_rr_peers_t)); @@ -209,7 +228,7 @@ peer = ngx_slab_calloc_locked(shpool, sizeof(ngx_http_upstream_rr_peer_t)); if (peer == NULL) { - return NGX_ERROR; + return NULL; } ngx_memcpy(peer, *peerp, sizeof(ngx_http_upstream_rr_peer_t)); @@ -223,5 +242,5 @@ uscf->peer.data = peers; - return NGX_OK; + return peers; } | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/http/ngx_http.c ^ |
@@ -128,6 +128,10 @@ ngx_http_core_srv_conf_t **cscfp; ngx_http_core_main_conf_t *cmcf; + if (*(ngx_http_conf_ctx_t **) conf) { + return "is duplicate"; + } + /* the main http context */ ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/http/ngx_http.h ^ |
@@ -148,11 +148,6 @@ void ngx_http_clean_header(ngx_http_request_t *r); -time_t ngx_http_parse_time(u_char *value, size_t len); -size_t ngx_http_get_time(char *buf, time_t t); - - - ngx_int_t ngx_http_discard_request_body(ngx_http_request_t *r); void ngx_http_discarded_request_body_handler(ngx_http_request_t *r); void ngx_http_block_reading(ngx_http_request_t *r); | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/http/ngx_http_core_module.c ^ |
@@ -2195,7 +2195,7 @@ return NGX_DECLINED; } - expires = ngx_http_parse_time(e->value.data, e->value.len); + expires = ngx_parse_http_time(e->value.data, e->value.len); if (expires == NGX_ERROR) { return NGX_DECLINED; } @@ -2203,7 +2203,7 @@ d = r->headers_out.date; if (d) { - date = ngx_http_parse_time(d->value.data, d->value.len); + date = ngx_parse_http_time(d->value.data, d->value.len); if (date == NGX_ERROR) { return NGX_DECLINED; } | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/http/ngx_http_request.c ^ |
@@ -467,7 +467,7 @@ if (hc->proxy_protocol) { hc->proxy_protocol = 0; - p = ngx_proxy_protocol_parse(c, b->pos, b->last); + p = ngx_proxy_protocol_read(c, b->pos, b->last); if (p == NULL) { ngx_http_close_connection(c); @@ -675,7 +675,7 @@ if (hc->proxy_protocol) { hc->proxy_protocol = 0; - p = ngx_proxy_protocol_parse(c, buf, buf + n); + p = ngx_proxy_protocol_read(c, buf, buf + n); if (p == NULL) { ngx_http_close_connection(c); | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/http/ngx_http_spdy.c ^ |
@@ -866,7 +866,7 @@ log = sc->connection->log; log->action = "reading PROXY protocol"; - pos = ngx_proxy_protocol_parse(sc->connection, pos, end); + pos = ngx_proxy_protocol_read(sc->connection, pos, end); log->action = "processing SPDY"; | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/http/ngx_http_upstream.c ^ |
@@ -3731,7 +3731,7 @@ if (u->headers_in.last_modified) { - lm = ngx_http_parse_time(u->headers_in.last_modified->value.data, + lm = ngx_parse_http_time(u->headers_in.last_modified->value.data, u->headers_in.last_modified->value.len); if (lm != NGX_ERROR) { @@ -4128,7 +4128,7 @@ #if (NGX_HTTP_CACHE) if (u->cacheable) { - u->headers_in.last_modified_time = ngx_http_parse_time(h->value.data, + u->headers_in.last_modified_time = ngx_parse_http_time(h->value.data, h->value.len); } @@ -4292,7 +4292,7 @@ return NGX_OK; } - expires = ngx_http_parse_time(h->value.data, h->value.len); + expires = ngx_parse_http_time(h->value.data, h->value.len); if (expires == NGX_ERROR || expires < ngx_time()) { u->cacheable = 0; | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/http/ngx_http_upstream_round_robin.h ^ |
@@ -58,6 +58,7 @@ #if (NGX_HTTP_UPSTREAM_ZONE) ngx_slab_pool_t *shpool; ngx_atomic_t rwlock; + ngx_http_upstream_rr_peers_t *zone_next; #endif ngx_uint_t total_weight; | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/mail/ngx_mail.c ^ |
@@ -76,6 +76,10 @@ ngx_mail_core_srv_conf_t **cscfp; ngx_mail_core_main_conf_t *cmcf; + if (*(ngx_mail_conf_ctx_t **) conf) { + return "is duplicate"; + } + /* the main mail context */ ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t)); @@ -238,13 +242,13 @@ struct sockaddr_in6 *sin6; #endif - sa = (struct sockaddr *) &listen->sockaddr; + sa = &listen->u.sockaddr; switch (sa->sa_family) { #if (NGX_HAVE_INET6) case AF_INET6: - sin6 = (struct sockaddr_in6 *) sa; + sin6 = &listen->u.sockaddr_in6; p = sin6->sin6_port; break; #endif @@ -256,7 +260,7 @@ #endif default: /* AF_INET */ - sin = (struct sockaddr_in *) sa; + sin = &listen->u.sockaddr_in; p = sin->sin_port; break; } @@ -296,23 +300,7 @@ return NGX_ERROR; } - addr->sockaddr = (struct sockaddr *) &listen->sockaddr; - addr->socklen = listen->socklen; - 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 -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) - addr->ipv6only = listen->ipv6only; -#endif + addr->opt = *listen; return NGX_OK; } @@ -342,8 +330,8 @@ * to the "*:port" only and ignore the other bindings */ - if (addr[last - 1].wildcard) { - addr[last - 1].bind = 1; + if (addr[last - 1].opt.wildcard) { + addr[last - 1].opt.bind = 1; bind_wildcard = 1; } else { @@ -354,12 +342,13 @@ while (i < last) { - if (bind_wildcard && !addr[i].bind) { + if (bind_wildcard && !addr[i].opt.bind) { i++; continue; } - ls = ngx_create_listening(cf, addr[i].sockaddr, addr[i].socklen); + ls = ngx_create_listening(cf, &addr[i].opt.u.sockaddr, + addr[i].opt.socklen); if (ls == NULL) { return NGX_CONF_ERROR; } @@ -368,21 +357,23 @@ ls->handler = ngx_mail_init_connection; ls->pool_size = 256; - cscf = addr->ctx->srv_conf[ngx_mail_core_module.ctx_index]; + cscf = addr->opt.ctx->srv_conf[ngx_mail_core_module.ctx_index]; ls->logp = cscf->error_log; ls->log.data = &ls->addr_text; ls->log.handler = ngx_accept_log_error; - ls->keepalive = addr[i].so_keepalive; + ls->backlog = addr[i].opt.backlog; + + ls->keepalive = addr[i].opt.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; + ls->keepidle = addr[i].opt.tcp_keepidle; + ls->keepintvl = addr[i].opt.tcp_keepintvl; + ls->keepcnt = addr[i].opt.tcp_keepcnt; #endif #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) - ls->ipv6only = addr[i].ipv6only; + ls->ipv6only = addr[i].opt.ipv6only; #endif mport = ngx_palloc(cf->pool, sizeof(ngx_mail_port_t)); @@ -439,15 +430,15 @@ for (i = 0; i < mport->naddrs; i++) { - sin = (struct sockaddr_in *) addr[i].sockaddr; + sin = &addr[i].opt.u.sockaddr_in; addrs[i].addr = sin->sin_addr.s_addr; - addrs[i].conf.ctx = addr[i].ctx; + addrs[i].conf.ctx = addr[i].opt.ctx; #if (NGX_MAIL_SSL) - addrs[i].conf.ssl = addr[i].ssl; + addrs[i].conf.ssl = addr[i].opt.ssl; #endif - len = ngx_sock_ntop(addr[i].sockaddr, addr[i].socklen, buf, + len = ngx_sock_ntop(&addr[i].opt.u.sockaddr, addr[i].opt.socklen, buf, NGX_SOCKADDR_STRLEN, 1); p = ngx_pnalloc(cf->pool, len); @@ -488,15 +479,15 @@ for (i = 0; i < mport->naddrs; i++) { - sin6 = (struct sockaddr_in6 *) addr[i].sockaddr; + sin6 = &addr[i].opt.u.sockaddr_in6; addrs6[i].addr6 = sin6->sin6_addr; - addrs6[i].conf.ctx = addr[i].ctx; + addrs6[i].conf.ctx = addr[i].opt.ctx; #if (NGX_MAIL_SSL) - addrs6[i].conf.ssl = addr[i].ssl; + addrs6[i].conf.ssl = addr[i].opt.ssl; #endif - len = ngx_sock_ntop(addr[i].sockaddr, addr[i].socklen, buf, + len = ngx_sock_ntop(&addr[i].opt.u.sockaddr, addr[i].opt.socklen, buf, NGX_SOCKADDR_STRLEN, 1); p = ngx_pnalloc(cf->pool, len); @@ -524,22 +515,22 @@ first = (ngx_mail_conf_addr_t *) one; second = (ngx_mail_conf_addr_t *) two; - if (first->wildcard) { + if (first->opt.wildcard) { /* a wildcard must be the last resort, shift it to the end */ return 1; } - if (second->wildcard) { + if (second->opt.wildcard) { /* a wildcard must be the last resort, shift it to the end */ return -1; } - if (first->bind && !second->bind) { + if (first->opt.bind && !second->opt.bind) { /* shift explicit bind()ed addresses to the start */ return -1; } - if (!first->bind && second->bind) { + if (!first->opt.bind && second->opt.bind) { /* shift explicit bind()ed addresses to the start */ return 1; } | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/mail/ngx_mail.h ^ |
@@ -27,7 +27,18 @@ typedef struct { - u_char sockaddr[NGX_SOCKADDRLEN]; + union { + struct sockaddr sockaddr; + struct sockaddr_in sockaddr_in; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 sockaddr_in6; +#endif +#if (NGX_HAVE_UNIX_DOMAIN) + struct sockaddr_un sockaddr_un; +#endif + u_char sockaddr_data[NGX_SOCKADDRLEN]; + } u; + socklen_t socklen; /* server ctx */ @@ -47,6 +58,7 @@ int tcp_keepintvl; int tcp_keepcnt; #endif + int backlog; } ngx_mail_listen_t; @@ -89,25 +101,7 @@ typedef struct { - struct sockaddr *sockaddr; - socklen_t socklen; - - ngx_mail_conf_ctx_t *ctx; - - unsigned bind:1; - unsigned wildcard:1; -#if (NGX_MAIL_SSL) - unsigned ssl:1; -#endif -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) - unsigned ipv6only:1; -#endif - unsigned so_keepalive:2; -#if (NGX_HAVE_KEEPALIVE_TUNABLE) - int tcp_keepidle; - int tcp_keepintvl; - int tcp_keepcnt; -#endif + ngx_mail_listen_t opt; } ngx_mail_conf_addr_t; | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/mail/ngx_mail_core_module.c ^ |
@@ -325,7 +325,7 @@ for (i = 0; i < cmcf->listen.nelts; i++) { - sa = (struct sockaddr *) ls[i].sockaddr; + sa = &ls[i].u.sockaddr; if (sa->sa_family != u.family) { continue; @@ -337,7 +337,7 @@ case AF_INET6: off = offsetof(struct sockaddr_in6, sin6_addr); len = 16; - sin6 = (struct sockaddr_in6 *) sa; + sin6 = &ls[i].u.sockaddr_in6; port = ntohs(sin6->sin6_port); break; #endif @@ -353,12 +353,14 @@ default: /* AF_INET */ off = offsetof(struct sockaddr_in, sin_addr); len = 4; - sin = (struct sockaddr_in *) sa; + sin = &ls[i].u.sockaddr_in; port = ntohs(sin->sin_port); break; } - if (ngx_memcmp(ls[i].sockaddr + off, u.sockaddr + off, len) != 0) { + if (ngx_memcmp(ls[i].u.sockaddr_data + off, u.sockaddr + off, len) + != 0) + { continue; } @@ -378,9 +380,10 @@ ngx_memzero(ls, sizeof(ngx_mail_listen_t)); - ngx_memcpy(ls->sockaddr, u.sockaddr, u.socklen); + ngx_memcpy(&ls->u.sockaddr, u.sockaddr, u.socklen); ls->socklen = u.socklen; + ls->backlog = NGX_LISTEN_BACKLOG; ls->wildcard = u.wildcard; ls->ctx = cf->ctx; @@ -416,12 +419,25 @@ continue; } + if (ngx_strncmp(value[i].data, "backlog=", 8) == 0) { + ls->backlog = ngx_atoi(value[i].data + 8, value[i].len - 8); + ls->bind = 1; + + if (ls->backlog == NGX_ERROR || ls->backlog == 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid backlog \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + continue; + } + if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) { #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) struct sockaddr *sa; u_char buf[NGX_SOCKADDR_STRLEN]; - sa = (struct sockaddr *) ls->sockaddr; + sa = &ls->u.sockaddr; if (sa->sa_family == AF_INET6) { | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/os/unix/ngx_files.h ^ |
@@ -368,6 +368,7 @@ #endif +#define ngx_stdout STDOUT_FILENO #define ngx_stderr STDERR_FILENO #define ngx_set_stderr(fd) dup2(fd, STDERR_FILENO) #define ngx_set_stderr_n "dup2(STDERR_FILENO)" | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/stream/ngx_stream.c ^ |
@@ -76,6 +76,10 @@ ngx_stream_core_srv_conf_t **cscfp; ngx_stream_core_main_conf_t *cmcf; + if (*(ngx_stream_conf_ctx_t **) conf) { + return "is duplicate"; + } + /* the main stream context */ ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_conf_ctx_t)); @@ -204,6 +208,20 @@ } } + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_STREAM_MODULE) { + continue; + } + + module = ngx_modules[m]->ctx; + + if (module->postconfiguration) { + if (module->postconfiguration(cf) != NGX_OK) { + return NGX_CONF_ERROR; + } + } + } + *cf = pcf; @@ -239,13 +257,13 @@ struct sockaddr_in6 *sin6; #endif - sa = (struct sockaddr *) &listen->sockaddr; + sa = &listen->u.sockaddr; switch (sa->sa_family) { #if (NGX_HAVE_INET6) case AF_INET6: - sin6 = (struct sockaddr_in6 *) sa; + sin6 = &listen->u.sockaddr_in6; p = sin6->sin6_port; break; #endif @@ -257,7 +275,7 @@ #endif default: /* AF_INET */ - sin = (struct sockaddr_in *) sa; + sin = &listen->u.sockaddr_in; p = sin->sin_port; break; } @@ -297,23 +315,7 @@ return NGX_ERROR; } - addr->sockaddr = (struct sockaddr *) &listen->sockaddr; - addr->socklen = listen->socklen; - 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_STREAM_SSL) - addr->ssl = listen->ssl; -#endif -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) - addr->ipv6only = listen->ipv6only; -#endif + addr->opt = *listen; return NGX_OK; } @@ -343,8 +345,8 @@ * to the "*:port" only and ignore the other bindings */ - if (addr[last - 1].wildcard) { - addr[last - 1].bind = 1; + if (addr[last - 1].opt.wildcard) { + addr[last - 1].opt.bind = 1; bind_wildcard = 1; } else { @@ -355,12 +357,13 @@ while (i < last) { - if (bind_wildcard && !addr[i].bind) { + if (bind_wildcard && !addr[i].opt.bind) { i++; continue; } - ls = ngx_create_listening(cf, addr[i].sockaddr, addr[i].socklen); + ls = ngx_create_listening(cf, &addr[i].opt.u.sockaddr, + addr[i].opt.socklen); if (ls == NULL) { return NGX_CONF_ERROR; } @@ -369,21 +372,27 @@ ls->handler = ngx_stream_init_connection; ls->pool_size = 256; - cscf = addr->ctx->srv_conf[ngx_stream_core_module.ctx_index]; + cscf = addr->opt.ctx->srv_conf[ngx_stream_core_module.ctx_index]; ls->logp = cscf->error_log; ls->log.data = &ls->addr_text; ls->log.handler = ngx_accept_log_error; - ls->keepalive = addr[i].so_keepalive; + ls->backlog = addr[i].opt.backlog; + + ls->keepalive = addr[i].opt.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; + ls->keepidle = addr[i].opt.tcp_keepidle; + ls->keepintvl = addr[i].opt.tcp_keepintvl; + ls->keepcnt = addr[i].opt.tcp_keepcnt; #endif #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) - ls->ipv6only = addr[i].ipv6only; + ls->ipv6only = addr[i].opt.ipv6only; +#endif + +#if (NGX_HAVE_REUSEPORT) + ls->reuseport = addr[i].opt.reuseport; #endif stport = ngx_palloc(cf->pool, sizeof(ngx_stream_port_t)); @@ -444,15 +453,15 @@ for (i = 0; i < stport->naddrs; i++) { - sin = (struct sockaddr_in *) addr[i].sockaddr; + sin = &addr[i].opt.u.sockaddr_in; addrs[i].addr = sin->sin_addr.s_addr; - addrs[i].conf.ctx = addr[i].ctx; + addrs[i].conf.ctx = addr[i].opt.ctx; #if (NGX_STREAM_SSL) - addrs[i].conf.ssl = addr[i].ssl; + addrs[i].conf.ssl = addr[i].opt.ssl; #endif - len = ngx_sock_ntop(addr[i].sockaddr, addr[i].socklen, buf, + len = ngx_sock_ntop(&addr[i].opt.u.sockaddr, addr[i].opt.socklen, buf, NGX_SOCKADDR_STRLEN, 1); p = ngx_pnalloc(cf->pool, len); @@ -493,15 +502,15 @@ for (i = 0; i < stport->naddrs; i++) { - sin6 = (struct sockaddr_in6 *) addr[i].sockaddr; + sin6 = &addr[i].opt.u.sockaddr_in6; addrs6[i].addr6 = sin6->sin6_addr; - addrs6[i].conf.ctx = addr[i].ctx; + addrs6[i].conf.ctx = addr[i].opt.ctx; #if (NGX_STREAM_SSL) - addrs6[i].conf.ssl = addr[i].ssl; + addrs6[i].conf.ssl = addr[i].opt.ssl; #endif - len = ngx_sock_ntop(addr[i].sockaddr, addr[i].socklen, buf, + len = ngx_sock_ntop(&addr[i].opt.u.sockaddr, addr[i].opt.socklen, buf, NGX_SOCKADDR_STRLEN, 1); p = ngx_pnalloc(cf->pool, len); @@ -529,22 +538,22 @@ first = (ngx_stream_conf_addr_t *) one; second = (ngx_stream_conf_addr_t *) two; - if (first->wildcard) { + if (first->opt.wildcard) { /* a wildcard must be the last resort, shift it to the end */ return 1; } - if (second->wildcard) { + if (second->opt.wildcard) { /* a wildcard must be the last resort, shift it to the end */ return -1; } - if (first->bind && !second->bind) { + if (first->opt.bind && !second->opt.bind) { /* shift explicit bind()ed addresses to the start */ return -1; } - if (!first->bind && second->bind) { + if (!first->opt.bind && second->opt.bind) { /* shift explicit bind()ed addresses to the start */ return 1; } | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/stream/ngx_stream.h ^ |
@@ -31,7 +31,18 @@ typedef struct { - u_char sockaddr[NGX_SOCKADDRLEN]; + union { + struct sockaddr sockaddr; + struct sockaddr_in sockaddr_in; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 sockaddr_in6; +#endif +#if (NGX_HAVE_UNIX_DOMAIN) + struct sockaddr_un sockaddr_un; +#endif + u_char sockaddr_data[NGX_SOCKADDRLEN]; + } u; + socklen_t socklen; /* server ctx */ @@ -54,6 +65,7 @@ int tcp_keepintvl; int tcp_keepcnt; #endif + int backlog; } ngx_stream_listen_t; @@ -96,31 +108,18 @@ typedef struct { - struct sockaddr *sockaddr; - socklen_t socklen; + ngx_stream_listen_t opt; +} ngx_stream_conf_addr_t; - ngx_stream_conf_ctx_t *ctx; - unsigned bind:1; - unsigned wildcard:1; -#if (NGX_STREAM_SSL) - unsigned ssl:1; -#endif -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) - unsigned ipv6only:1; -#endif - unsigned so_keepalive:2; -#if (NGX_HAVE_KEEPALIVE_TUNABLE) - int tcp_keepidle; - int tcp_keepintvl; - int tcp_keepcnt; -#endif -} ngx_stream_conf_addr_t; +typedef ngx_int_t (*ngx_stream_access_pt)(ngx_stream_session_t *s); typedef struct { ngx_array_t servers; /* ngx_stream_core_srv_conf_t */ ngx_array_t listen; /* ngx_stream_listen_t */ + ngx_stream_access_pt limit_conn_handler; + ngx_stream_access_pt access_handler; } ngx_stream_core_main_conf_t; @@ -154,6 +153,8 @@ typedef struct { + ngx_int_t (*postconfiguration)(ngx_conf_t *cf); + void *(*create_main_conf)(ngx_conf_t *cf); char *(*init_main_conf)(ngx_conf_t *cf, void *conf); | ||
[+] | Added | nginx-1.9.3.tar.gz/src/stream/ngx_stream_access_module.c ^ |
@@ -0,0 +1,451 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) Nginx, Inc. + */ + + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_stream.h> + + +typedef struct { + in_addr_t mask; + in_addr_t addr; + ngx_uint_t deny; /* unsigned deny:1; */ +} ngx_stream_access_rule_t; + +#if (NGX_HAVE_INET6) + +typedef struct { + struct in6_addr addr; + struct in6_addr mask; + ngx_uint_t deny; /* unsigned deny:1; */ +} ngx_stream_access_rule6_t; + +#endif + +#if (NGX_HAVE_UNIX_DOMAIN) + +typedef struct { + ngx_uint_t deny; /* unsigned deny:1; */ +} ngx_stream_access_rule_un_t; + +#endif + +typedef struct { + ngx_array_t *rules; /* array of ngx_stream_access_rule_t */ +#if (NGX_HAVE_INET6) + ngx_array_t *rules6; /* array of ngx_stream_access_rule6_t */ +#endif +#if (NGX_HAVE_UNIX_DOMAIN) + ngx_array_t *rules_un; /* array of ngx_stream_access_rule_un_t */ +#endif +} ngx_stream_access_srv_conf_t; + + +static ngx_int_t ngx_stream_access_handler(ngx_stream_session_t *s); +static ngx_int_t ngx_stream_access_inet(ngx_stream_session_t *s, + ngx_stream_access_srv_conf_t *ascf, in_addr_t addr); +#if (NGX_HAVE_INET6) +static ngx_int_t ngx_stream_access_inet6(ngx_stream_session_t *s, + ngx_stream_access_srv_conf_t *ascf, u_char *p); +#endif +#if (NGX_HAVE_UNIX_DOMAIN) +static ngx_int_t ngx_stream_access_unix(ngx_stream_session_t *s, + ngx_stream_access_srv_conf_t *ascf); +#endif +static ngx_int_t ngx_stream_access_found(ngx_stream_session_t *s, + ngx_uint_t deny); +static char *ngx_stream_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); +static void *ngx_stream_access_create_srv_conf(ngx_conf_t *cf); +static char *ngx_stream_access_merge_srv_conf(ngx_conf_t *cf, + void *parent, void *child); +static ngx_int_t ngx_stream_access_init(ngx_conf_t *cf); + + +static ngx_command_t ngx_stream_access_commands[] = { + + { ngx_string("allow"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, + ngx_stream_access_rule, + NGX_STREAM_SRV_CONF_OFFSET, + 0, + NULL }, + + { ngx_string("deny"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, + ngx_stream_access_rule, + NGX_STREAM_SRV_CONF_OFFSET, + 0, + NULL }, + + ngx_null_command +}; + + + +static ngx_stream_module_t ngx_stream_access_module_ctx = { + ngx_stream_access_init, /* postconfiguration */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + ngx_stream_access_create_srv_conf, /* create server configuration */ + ngx_stream_access_merge_srv_conf /* merge server configuration */ +}; + + +ngx_module_t ngx_stream_access_module = { + NGX_MODULE_V1, + &ngx_stream_access_module_ctx, /* module context */ + ngx_stream_access_commands, /* module directives */ + NGX_STREAM_MODULE, /* module type */ + NULL, /* init master */ + NULL, /* init module */ + NULL, /* init process */ + NULL, /* init thread */ + NULL, /* exit thread */ + NULL, /* exit process */ + NULL, /* exit master */ + NGX_MODULE_V1_PADDING +}; + + +static ngx_int_t +ngx_stream_access_handler(ngx_stream_session_t *s) +{ + struct sockaddr_in *sin; + ngx_stream_access_srv_conf_t *ascf; +#if (NGX_HAVE_INET6) + u_char *p; + in_addr_t addr; + struct sockaddr_in6 *sin6; +#endif + + ascf = ngx_stream_get_module_srv_conf(s, ngx_stream_access_module); + + switch (s->connection->sockaddr->sa_family) { + + case AF_INET: + if (ascf->rules) { + sin = (struct sockaddr_in *) s->connection->sockaddr; + return ngx_stream_access_inet(s, ascf, sin->sin_addr.s_addr); + } + break; + +#if (NGX_HAVE_INET6) + + case AF_INET6: + sin6 = (struct sockaddr_in6 *) s->connection->sockaddr; + p = sin6->sin6_addr.s6_addr; + + if (ascf->rules && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { + addr = p[12] << 24; + addr += p[13] << 16; + addr += p[14] << 8; + addr += p[15]; + return ngx_stream_access_inet(s, ascf, htonl(addr)); + } + + if (ascf->rules6) { + return ngx_stream_access_inet6(s, ascf, p); + } + + break; + +#endif + +#if (NGX_HAVE_UNIX_DOMAIN) + + case AF_UNIX: + if (ascf->rules_un) { + return ngx_stream_access_unix(s, ascf); + } + + break; + +#endif + } + + return NGX_DECLINED; +} + + +static ngx_int_t +ngx_stream_access_inet(ngx_stream_session_t *s, + ngx_stream_access_srv_conf_t *ascf, in_addr_t addr) +{ + ngx_uint_t i; + ngx_stream_access_rule_t *rule; + + rule = ascf->rules->elts; + for (i = 0; i < ascf->rules->nelts; i++) { + + ngx_log_debug3(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, + "access: %08XD %08XD %08XD", + addr, rule[i].mask, rule[i].addr); + + if ((addr & rule[i].mask) == rule[i].addr) { + return ngx_stream_access_found(s, rule[i].deny); + } + } + + return NGX_DECLINED; +} + + +#if (NGX_HAVE_INET6) + +static ngx_int_t +ngx_stream_access_inet6(ngx_stream_session_t *s, + ngx_stream_access_srv_conf_t *ascf, u_char *p) +{ + ngx_uint_t n; + ngx_uint_t i; + ngx_stream_access_rule6_t *rule6; + + rule6 = ascf->rules6->elts; + for (i = 0; i < ascf->rules6->nelts; i++) { + +#if (NGX_DEBUG) + { + size_t cl, ml, al; + u_char ct[NGX_INET6_ADDRSTRLEN]; + u_char mt[NGX_INET6_ADDRSTRLEN]; + u_char at[NGX_INET6_ADDRSTRLEN]; + + cl = ngx_inet6_ntop(p, ct, NGX_INET6_ADDRSTRLEN); + ml = ngx_inet6_ntop(rule6[i].mask.s6_addr, mt, NGX_INET6_ADDRSTRLEN); + al = ngx_inet6_ntop(rule6[i].addr.s6_addr, at, NGX_INET6_ADDRSTRLEN); + + ngx_log_debug6(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, + "access: %*s %*s %*s", cl, ct, ml, mt, al, at); + } +#endif + + for (n = 0; n < 16; n++) { + if ((p[n] & rule6[i].mask.s6_addr[n]) != rule6[i].addr.s6_addr[n]) { + goto next; + } + } + + return ngx_stream_access_found(s, rule6[i].deny); + + next: + continue; + } + + return NGX_DECLINED; +} + +#endif + + +#if (NGX_HAVE_UNIX_DOMAIN) + +static ngx_int_t +ngx_stream_access_unix(ngx_stream_session_t *s, + ngx_stream_access_srv_conf_t *ascf) +{ + ngx_uint_t i; + ngx_stream_access_rule_un_t *rule_un; + + rule_un = ascf->rules_un->elts; + for (i = 0; i < ascf->rules_un->nelts; i++) { + + /* TODO: check path */ + if (1) { + return ngx_stream_access_found(s, rule_un[i].deny); + } + } + + return NGX_DECLINED; +} + +#endif + + +static ngx_int_t +ngx_stream_access_found(ngx_stream_session_t *s, ngx_uint_t deny) +{ + if (deny) { + ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, + "access forbidden by rule"); + return NGX_ABORT; + } + + return NGX_OK; +} + + +static char * +ngx_stream_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_stream_access_srv_conf_t *ascf = conf; + + ngx_int_t rc; + ngx_uint_t all; + ngx_str_t *value; + ngx_cidr_t cidr; + ngx_stream_access_rule_t *rule; +#if (NGX_HAVE_INET6) + ngx_stream_access_rule6_t *rule6; +#endif +#if (NGX_HAVE_UNIX_DOMAIN) + ngx_stream_access_rule_un_t *rule_un; +#endif + + ngx_memzero(&cidr, sizeof(ngx_cidr_t)); + + value = cf->args->elts; + + all = (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0); + + if (!all) { + +#if (NGX_HAVE_UNIX_DOMAIN) + + if (value[1].len == 5 && ngx_strcmp(value[1].data, "unix:") == 0) { + cidr.family = AF_UNIX; + rc = NGX_OK; + + } else { + rc = ngx_ptocidr(&value[1], &cidr); + } + +#else + rc = ngx_ptocidr(&value[1], &cidr); +#endif + + if (rc == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid parameter \"%V\"", &value[1]); + return NGX_CONF_ERROR; + } + + if (rc == NGX_DONE) { + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "low address bits of %V are meaningless", &value[1]); + } + } + + if (cidr.family == AF_INET || all) { + + if (ascf->rules == NULL) { + ascf->rules = ngx_array_create(cf->pool, 4, + sizeof(ngx_stream_access_rule_t)); + if (ascf->rules == NULL) { + return NGX_CONF_ERROR; + } + } + + rule = ngx_array_push(ascf->rules); + if (rule == NULL) { + return NGX_CONF_ERROR; + } + + rule->mask = cidr.u.in.mask; + rule->addr = cidr.u.in.addr; + rule->deny = (value[0].data[0] == 'd') ? 1 : 0; + } + +#if (NGX_HAVE_INET6) + if (cidr.family == AF_INET6 || all) { + + if (ascf->rules6 == NULL) { + ascf->rules6 = ngx_array_create(cf->pool, 4, + sizeof(ngx_stream_access_rule6_t)); + if (ascf->rules6 == NULL) { + return NGX_CONF_ERROR; + } + } + + rule6 = ngx_array_push(ascf->rules6); + if (rule6 == NULL) { + return NGX_CONF_ERROR; + } + + rule6->mask = cidr.u.in6.mask; + rule6->addr = cidr.u.in6.addr; + rule6->deny = (value[0].data[0] == 'd') ? 1 : 0; + } +#endif + +#if (NGX_HAVE_UNIX_DOMAIN) + if (cidr.family == AF_UNIX || all) { + + if (ascf->rules_un == NULL) { + ascf->rules_un = ngx_array_create(cf->pool, 1, + sizeof(ngx_stream_access_rule_un_t)); + if (ascf->rules_un == NULL) { + return NGX_CONF_ERROR; + } + } + + rule_un = ngx_array_push(ascf->rules_un); + if (rule_un == NULL) { + return NGX_CONF_ERROR; + } + + rule_un->deny = (value[0].data[0] == 'd') ? 1 : 0; + } +#endif + + return NGX_CONF_OK; +} + + +static void * +ngx_stream_access_create_srv_conf(ngx_conf_t *cf) +{ + ngx_stream_access_srv_conf_t *conf; + + conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_access_srv_conf_t)); + if (conf == NULL) { + return NULL; + } + + return conf; +} + + +static char * +ngx_stream_access_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) +{ + ngx_stream_access_srv_conf_t *prev = parent; + ngx_stream_access_srv_conf_t *conf = child; + + if (conf->rules == NULL +#if (NGX_HAVE_INET6) + && conf->rules6 == NULL +#endif +#if (NGX_HAVE_UNIX_DOMAIN) + && conf->rules_un == NULL +#endif + ) { + conf->rules = prev->rules; +#if (NGX_HAVE_INET6) + conf->rules6 = prev->rules6; +#endif +#if (NGX_HAVE_UNIX_DOMAIN) + conf->rules_un = prev->rules_un; +#endif + } + + return NGX_CONF_OK; +} + + +static ngx_int_t +ngx_stream_access_init(ngx_conf_t *cf) +{ + ngx_stream_core_main_conf_t *cmcf; + + cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); + cmcf->access_handler = ngx_stream_access_handler; + + return NGX_OK; +} | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/stream/ngx_stream_core_module.c ^ |
@@ -50,6 +50,8 @@ static ngx_stream_module_t ngx_stream_core_module_ctx = { + NULL, /* postconfiguration */ + ngx_stream_core_create_main_conf, /* create main configuration */ NULL, /* init main configuration */ @@ -272,7 +274,7 @@ for (i = 0; i < cmcf->listen.nelts; i++) { - sa = (struct sockaddr *) ls[i].sockaddr; + sa = &ls[i].u.sockaddr; if (sa->sa_family != u.family) { continue; @@ -284,7 +286,7 @@ case AF_INET6: off = offsetof(struct sockaddr_in6, sin6_addr); len = 16; - sin6 = (struct sockaddr_in6 *) sa; + sin6 = &ls[i].u.sockaddr_in6; port = sin6->sin6_port; break; #endif @@ -300,12 +302,14 @@ default: /* AF_INET */ off = offsetof(struct sockaddr_in, sin_addr); len = 4; - sin = (struct sockaddr_in *) sa; + sin = &ls[i].u.sockaddr_in; port = sin->sin_port; break; } - if (ngx_memcmp(ls[i].sockaddr + off, u.sockaddr + off, len) != 0) { + if (ngx_memcmp(ls[i].u.sockaddr_data + off, u.sockaddr + off, len) + != 0) + { continue; } @@ -325,9 +329,10 @@ ngx_memzero(ls, sizeof(ngx_stream_listen_t)); - ngx_memcpy(ls->sockaddr, u.sockaddr, u.socklen); + ngx_memcpy(&ls->u.sockaddr, u.sockaddr, u.socklen); ls->socklen = u.socklen; + ls->backlog = NGX_LISTEN_BACKLOG; ls->wildcard = u.wildcard; ls->ctx = cf->ctx; @@ -342,12 +347,25 @@ continue; } + if (ngx_strncmp(value[i].data, "backlog=", 8) == 0) { + ls->backlog = ngx_atoi(value[i].data + 8, value[i].len - 8); + ls->bind = 1; + + if (ls->backlog == NGX_ERROR || ls->backlog == 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid backlog \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + continue; + } + if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) { #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) struct sockaddr *sa; u_char buf[NGX_SOCKADDR_STRLEN]; - sa = (struct sockaddr *) ls->sockaddr; + sa = &ls->u.sockaddr; if (sa->sa_family == AF_INET6) { | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/stream/ngx_stream_handler.c ^ |
@@ -23,20 +23,22 @@ void ngx_stream_init_connection(ngx_connection_t *c) { - u_char text[NGX_SOCKADDR_STRLEN]; - size_t len; - ngx_uint_t i; - struct sockaddr *sa; - ngx_stream_port_t *port; - struct sockaddr_in *sin; - ngx_stream_in_addr_t *addr; - ngx_stream_session_t *s; - ngx_stream_addr_conf_t *addr_conf; + u_char text[NGX_SOCKADDR_STRLEN]; + size_t len; + ngx_int_t rc; + ngx_uint_t i; + struct sockaddr *sa; + ngx_stream_port_t *port; + struct sockaddr_in *sin; + ngx_stream_in_addr_t *addr; + ngx_stream_session_t *s; + ngx_stream_addr_conf_t *addr_conf; #if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; - ngx_stream_in6_addr_t *addr6; + struct sockaddr_in6 *sin6; + ngx_stream_in6_addr_t *addr6; #endif - ngx_stream_core_srv_conf_t *cscf; + ngx_stream_core_srv_conf_t *cscf; + ngx_stream_core_main_conf_t *cmcf; /* find the server configuration for the address:port */ @@ -143,6 +145,26 @@ c->log->action = "initializing connection"; c->log_error = NGX_ERROR_INFO; + cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); + + if (cmcf->limit_conn_handler) { + rc = cmcf->limit_conn_handler(s); + + if (rc != NGX_DECLINED) { + ngx_stream_close_connection(c); + return; + } + } + + if (cmcf->access_handler) { + rc = cmcf->access_handler(s); + + if (rc != NGX_OK && rc != NGX_DECLINED) { + ngx_stream_close_connection(c); + return; + } + } + #if (NGX_STREAM_SSL) { ngx_stream_ssl_conf_t *sslcf; | ||
[+] | Added | nginx-1.9.3.tar.gz/src/stream/ngx_stream_limit_conn_module.c ^ |
@@ -0,0 +1,632 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) Nginx, Inc. + */ + + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_stream.h> + + +typedef struct { + u_char color; + u_char len; + u_short conn; + u_char data[1]; +} ngx_stream_limit_conn_node_t; + + +typedef struct { + ngx_shm_zone_t *shm_zone; + ngx_rbtree_node_t *node; +} ngx_stream_limit_conn_cleanup_t; + + +typedef struct { + ngx_rbtree_t *rbtree; +} ngx_stream_limit_conn_ctx_t; + + +typedef struct { + ngx_shm_zone_t *shm_zone; + ngx_uint_t conn; +} ngx_stream_limit_conn_limit_t; + + +typedef struct { + ngx_array_t limits; + ngx_uint_t log_level; +} ngx_stream_limit_conn_conf_t; + + +static ngx_rbtree_node_t *ngx_stream_limit_conn_lookup(ngx_rbtree_t *rbtree, + ngx_str_t *key, uint32_t hash); +static void ngx_stream_limit_conn_cleanup(void *data); +static ngx_inline void ngx_stream_limit_conn_cleanup_all(ngx_pool_t *pool); + +static void *ngx_stream_limit_conn_create_conf(ngx_conf_t *cf); +static char *ngx_stream_limit_conn_merge_conf(ngx_conf_t *cf, void *parent, + void *child); +static char *ngx_stream_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); +static char *ngx_stream_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); +static ngx_int_t ngx_stream_limit_conn_init(ngx_conf_t *cf); + + +static ngx_conf_enum_t ngx_stream_limit_conn_log_levels[] = { + { ngx_string("info"), NGX_LOG_INFO }, + { ngx_string("notice"), NGX_LOG_NOTICE }, + { ngx_string("warn"), NGX_LOG_WARN }, + { ngx_string("error"), NGX_LOG_ERR }, + { ngx_null_string, 0 } +}; + + +static ngx_command_t ngx_stream_limit_conn_commands[] = { + + { ngx_string("limit_conn_zone"), + NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE2, + ngx_stream_limit_conn_zone, + 0, + 0, + NULL }, + + { ngx_string("limit_conn"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE2, + ngx_stream_limit_conn, + NGX_STREAM_SRV_CONF_OFFSET, + 0, + NULL }, + + { ngx_string("limit_conn_log_level"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_enum_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_limit_conn_conf_t, log_level), + &ngx_stream_limit_conn_log_levels }, + + ngx_null_command +}; + + +static ngx_stream_module_t ngx_stream_limit_conn_module_ctx = { + ngx_stream_limit_conn_init, /* postconfiguration */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + ngx_stream_limit_conn_create_conf, /* create server configuration */ + ngx_stream_limit_conn_merge_conf, /* merge server configuration */ +}; + + +ngx_module_t ngx_stream_limit_conn_module = { + NGX_MODULE_V1, + &ngx_stream_limit_conn_module_ctx, /* module context */ + ngx_stream_limit_conn_commands, /* module directives */ + NGX_STREAM_MODULE, /* module type */ + NULL, /* init master */ + NULL, /* init module */ + NULL, /* init process */ + NULL, /* init thread */ + NULL, /* exit thread */ + NULL, /* exit process */ + NULL, /* exit master */ + NGX_MODULE_V1_PADDING +}; + + +static ngx_int_t +ngx_stream_limit_conn_handler(ngx_stream_session_t *s) +{ + size_t n; + uint32_t hash; + ngx_str_t key; + ngx_uint_t i; + ngx_slab_pool_t *shpool; + ngx_rbtree_node_t *node; + ngx_pool_cleanup_t *cln; + struct sockaddr_in *sin; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; +#endif + ngx_stream_limit_conn_ctx_t *ctx; + ngx_stream_limit_conn_node_t *lc; + ngx_stream_limit_conn_conf_t *lccf; + ngx_stream_limit_conn_limit_t *limits; + ngx_stream_limit_conn_cleanup_t *lccln; + + switch (s->connection->sockaddr->sa_family) { + + case AF_INET: + sin = (struct sockaddr_in *) s->connection->sockaddr; + + key.len = sizeof(in_addr_t); + key.data = (u_char *) &sin->sin_addr; + + break; + +#if (NGX_HAVE_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *) s->connection->sockaddr; + + key.len = sizeof(struct in6_addr); + key.data = sin6->sin6_addr.s6_addr; + + break; +#endif + + default: + return NGX_DECLINED; + } + + hash = ngx_crc32_short(key.data, key.len); + + lccf = ngx_stream_get_module_srv_conf(s, ngx_stream_limit_conn_module); + limits = lccf->limits.elts; + + for (i = 0; i < lccf->limits.nelts; i++) { + ctx = limits[i].shm_zone->data; + + shpool = (ngx_slab_pool_t *) limits[i].shm_zone->shm.addr; + + ngx_shmtx_lock(&shpool->mutex); + + node = ngx_stream_limit_conn_lookup(ctx->rbtree, &key, hash); + + if (node == NULL) { + + n = offsetof(ngx_rbtree_node_t, color) + + offsetof(ngx_stream_limit_conn_node_t, data) + + key.len; + + node = ngx_slab_alloc_locked(shpool, n); + + if (node == NULL) { + ngx_shmtx_unlock(&shpool->mutex); + ngx_stream_limit_conn_cleanup_all(s->connection->pool); + return NGX_ABORT; + } + + lc = (ngx_stream_limit_conn_node_t *) &node->color; + + node->key = hash; + lc->len = (u_char) key.len; + lc->conn = 1; + ngx_memcpy(lc->data, key.data, key.len); + + ngx_rbtree_insert(ctx->rbtree, node); + + } else { + + lc = (ngx_stream_limit_conn_node_t *) &node->color; + + if ((ngx_uint_t) lc->conn >= limits[i].conn) { + + ngx_shmtx_unlock(&shpool->mutex); + + ngx_log_error(lccf->log_level, s->connection->log, 0, + "limiting connections by zone \"%V\"", + &limits[i].shm_zone->shm.name); + + ngx_stream_limit_conn_cleanup_all(s->connection->pool); + return NGX_ABORT; + } + + lc->conn++; + } + + ngx_log_debug2(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, + "limit conn: %08XD %d", node->key, lc->conn); + + ngx_shmtx_unlock(&shpool->mutex); + + cln = ngx_pool_cleanup_add(s->connection->pool, + sizeof(ngx_stream_limit_conn_cleanup_t)); + if (cln == NULL) { + return NGX_ERROR; + } + + cln->handler = ngx_stream_limit_conn_cleanup; + lccln = cln->data; + + lccln->shm_zone = limits[i].shm_zone; + lccln->node = node; + } + + return NGX_DECLINED; +} + + +static void +ngx_stream_limit_conn_rbtree_insert_value(ngx_rbtree_node_t *temp, + ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) +{ + ngx_rbtree_node_t **p; + ngx_stream_limit_conn_node_t *lcn, *lcnt; + + for ( ;; ) { + + if (node->key < temp->key) { + + p = &temp->left; + + } else if (node->key > temp->key) { + + p = &temp->right; + + } else { /* node->key == temp->key */ + + lcn = (ngx_stream_limit_conn_node_t *) &node->color; + lcnt = (ngx_stream_limit_conn_node_t *) &temp->color; + + p = (ngx_memn2cmp(lcn->data, lcnt->data, lcn->len, lcnt->len) < 0) + ? &temp->left : &temp->right; + } + + if (*p == sentinel) { + break; + } + + temp = *p; + } + + *p = node; + node->parent = temp; + node->left = sentinel; + node->right = sentinel; + ngx_rbt_red(node); +} + + +static ngx_rbtree_node_t * +ngx_stream_limit_conn_lookup(ngx_rbtree_t *rbtree, ngx_str_t *key, + uint32_t hash) +{ + ngx_int_t rc; + ngx_rbtree_node_t *node, *sentinel; + ngx_stream_limit_conn_node_t *lcn; + + node = rbtree->root; + sentinel = rbtree->sentinel; + + while (node != sentinel) { + + if (hash < node->key) { + node = node->left; + continue; + } + + if (hash > node->key) { + node = node->right; + continue; + } + + /* hash == node->key */ + + lcn = (ngx_stream_limit_conn_node_t *) &node->color; + + rc = ngx_memn2cmp(key->data, lcn->data, key->len, (size_t) lcn->len); + + if (rc == 0) { + return node; + } + + node = (rc < 0) ? node->left : node->right; + } + + return NULL; +} + + +static void +ngx_stream_limit_conn_cleanup(void *data) +{ + ngx_stream_limit_conn_cleanup_t *lccln = data; + + ngx_slab_pool_t *shpool; + ngx_rbtree_node_t *node; + ngx_stream_limit_conn_ctx_t *ctx; + ngx_stream_limit_conn_node_t *lc; + + ctx = lccln->shm_zone->data; + shpool = (ngx_slab_pool_t *) lccln->shm_zone->shm.addr; + node = lccln->node; + lc = (ngx_stream_limit_conn_node_t *) &node->color; + + ngx_shmtx_lock(&shpool->mutex); + + ngx_log_debug2(NGX_LOG_DEBUG_STREAM, lccln->shm_zone->shm.log, 0, + "limit conn cleanup: %08XD %d", node->key, lc->conn); + + lc->conn--; + + if (lc->conn == 0) { + ngx_rbtree_delete(ctx->rbtree, node); + ngx_slab_free_locked(shpool, node); + } + + ngx_shmtx_unlock(&shpool->mutex); +} + + +static ngx_inline void +ngx_stream_limit_conn_cleanup_all(ngx_pool_t *pool) +{ + ngx_pool_cleanup_t *cln; + + cln = pool->cleanup; + + while (cln && cln->handler == ngx_stream_limit_conn_cleanup) { + ngx_stream_limit_conn_cleanup(cln->data); + cln = cln->next; + } + + pool->cleanup = cln; +} + + +static ngx_int_t +ngx_stream_limit_conn_init_zone(ngx_shm_zone_t *shm_zone, void *data) +{ + ngx_stream_limit_conn_ctx_t *octx = data; + + size_t len; + ngx_slab_pool_t *shpool; + ngx_rbtree_node_t *sentinel; + ngx_stream_limit_conn_ctx_t *ctx; + + ctx = shm_zone->data; + + if (octx) { + ctx->rbtree = octx->rbtree; + + return NGX_OK; + } + + shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; + + if (shm_zone->shm.exists) { + ctx->rbtree = shpool->data; + + return NGX_OK; + } + + ctx->rbtree = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_t)); + if (ctx->rbtree == NULL) { + return NGX_ERROR; + } + + shpool->data = ctx->rbtree; + + sentinel = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_node_t)); + if (sentinel == NULL) { + return NGX_ERROR; + } + + ngx_rbtree_init(ctx->rbtree, sentinel, + ngx_stream_limit_conn_rbtree_insert_value); + + len = sizeof(" in limit_conn_zone \"\"") + shm_zone->shm.name.len; + + shpool->log_ctx = ngx_slab_alloc(shpool, len); + if (shpool->log_ctx == NULL) { + return NGX_ERROR; + } + + ngx_sprintf(shpool->log_ctx, " in limit_conn_zone \"%V\"%Z", + &shm_zone->shm.name); + + return NGX_OK; +} + + +static void * +ngx_stream_limit_conn_create_conf(ngx_conf_t *cf) +{ + ngx_stream_limit_conn_conf_t *conf; + + conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_limit_conn_conf_t)); + if (conf == NULL) { + return NULL; + } + + /* + * set by ngx_pcalloc(): + * + * conf->limits.elts = NULL; + */ + + conf->log_level = NGX_CONF_UNSET_UINT; + + return conf; +} + + +static char * +ngx_stream_limit_conn_merge_conf(ngx_conf_t *cf, void *parent, void *child) +{ + ngx_stream_limit_conn_conf_t *prev = parent; + ngx_stream_limit_conn_conf_t *conf = child; + + if (conf->limits.elts == NULL) { + conf->limits = prev->limits; + } + + ngx_conf_merge_uint_value(conf->log_level, prev->log_level, NGX_LOG_ERR); + + return NGX_CONF_OK; +} + + +static char * +ngx_stream_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + u_char *p; + ssize_t size; + ngx_str_t *value, name, s; + ngx_uint_t i; + ngx_shm_zone_t *shm_zone; + ngx_stream_limit_conn_ctx_t *ctx; + + value = cf->args->elts; + + ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_limit_conn_ctx_t)); + if (ctx == NULL) { + return NGX_CONF_ERROR; + } + + size = 0; + name.len = 0; + + for (i = 2; i < cf->args->nelts; i++) { + + if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { + + name.data = value[i].data + 5; + + p = (u_char *) ngx_strchr(name.data, ':'); + + if (p == NULL) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid zone size \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + name.len = p - name.data; + + s.data = p + 1; + s.len = value[i].data + value[i].len - s.data; + + size = ngx_parse_size(&s); + + if (size == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid zone size \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + if (size < (ssize_t) (8 * ngx_pagesize)) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "zone \"%V\" is too small", &value[i]); + return NGX_CONF_ERROR; + } + + continue; + } + + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid parameter \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + if (name.len == 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"%V\" must have \"zone\" parameter", + &cmd->name); + return NGX_CONF_ERROR; + } + + shm_zone = ngx_shared_memory_add(cf, &name, size, + &ngx_stream_limit_conn_module); + if (shm_zone == NULL) { + return NGX_CONF_ERROR; + } + + if (shm_zone->data) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "%V \"%V\" is already bound to key " + "\"$binary_remote_addr\"", + &cmd->name, &name); + return NGX_CONF_ERROR; + } + + if (ngx_strcmp(value[1].data, "$binary_remote_addr") != 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "unsupported key \"%V\", use " + "$binary_remote_addr", &value[1]); + return NGX_CONF_ERROR; + } + + shm_zone->init = ngx_stream_limit_conn_init_zone; + shm_zone->data = ctx; + + return NGX_CONF_OK; +} + + +static char * +ngx_stream_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_shm_zone_t *shm_zone; + ngx_stream_limit_conn_conf_t *lccf = conf; + ngx_stream_limit_conn_limit_t *limit, *limits; + + ngx_str_t *value; + ngx_int_t n; + ngx_uint_t i; + + value = cf->args->elts; + + shm_zone = ngx_shared_memory_add(cf, &value[1], 0, + &ngx_stream_limit_conn_module); + if (shm_zone == NULL) { + return NGX_CONF_ERROR; + } + + limits = lccf->limits.elts; + + if (limits == NULL) { + if (ngx_array_init(&lccf->limits, cf->pool, 1, + sizeof(ngx_stream_limit_conn_limit_t)) + != NGX_OK) + { + return NGX_CONF_ERROR; + } + } + + for (i = 0; i < lccf->limits.nelts; i++) { + if (shm_zone == limits[i].shm_zone) { + return "is duplicate"; + } + } + + n = ngx_atoi(value[2].data, value[2].len); + if (n <= 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid number of connections \"%V\"", &value[2]); + return NGX_CONF_ERROR; + } + + if (n > 65535) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "connection limit must be less 65536"); + return NGX_CONF_ERROR; + } + + limit = ngx_array_push(&lccf->limits); + if (limit == NULL) { + return NGX_CONF_ERROR; + } + + limit->conn = n; + limit->shm_zone = shm_zone; + + return NGX_CONF_OK; +} + + +static ngx_int_t +ngx_stream_limit_conn_init(ngx_conf_t *cf) +{ + ngx_stream_core_main_conf_t *cmcf; + + cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); + + cmcf->limit_conn_handler = ngx_stream_limit_conn_handler; + + return NGX_OK; +} | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/stream/ngx_stream_proxy_module.c ^ |
@@ -18,9 +18,13 @@ ngx_msec_t timeout; ngx_msec_t next_upstream_timeout; size_t downstream_buf_size; + size_t upload_rate; size_t upstream_buf_size; + size_t download_rate; ngx_uint_t next_upstream_tries; ngx_flag_t next_upstream; + ngx_flag_t proxy_protocol; + ngx_addr_t *local; #if (NGX_STREAM_SSL) ngx_flag_t ssl_enable; @@ -50,6 +54,8 @@ static void ngx_stream_proxy_init_upstream(ngx_stream_session_t *s); static void ngx_stream_proxy_upstream_handler(ngx_event_t *ev); static void ngx_stream_proxy_downstream_handler(ngx_event_t *ev); +static void ngx_stream_proxy_process_connection(ngx_event_t *ev, + ngx_uint_t from_upstream); static void ngx_stream_proxy_connect_handler(ngx_event_t *ev); static ngx_int_t ngx_stream_proxy_test_connect(ngx_connection_t *c); static ngx_int_t ngx_stream_proxy_process(ngx_stream_session_t *s, @@ -64,6 +70,9 @@ void *child); static char *ngx_stream_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); +static ngx_int_t ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s); #if (NGX_STREAM_SSL) @@ -97,6 +106,13 @@ 0, NULL }, + { ngx_string("proxy_bind"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, + ngx_stream_proxy_bind, + NGX_STREAM_SRV_CONF_OFFSET, + 0, + NULL }, + { ngx_string("proxy_connect_timeout"), NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, @@ -118,6 +134,13 @@ offsetof(ngx_stream_proxy_srv_conf_t, downstream_buf_size), NULL }, + { ngx_string("proxy_upload_rate"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_size_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_proxy_srv_conf_t, upload_rate), + NULL }, + { ngx_string("proxy_upstream_buffer"), NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, @@ -125,6 +148,13 @@ offsetof(ngx_stream_proxy_srv_conf_t, upstream_buf_size), NULL }, + { ngx_string("proxy_download_rate"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_size_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_proxy_srv_conf_t, download_rate), + NULL }, + { ngx_string("proxy_next_upstream"), NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, @@ -146,6 +176,13 @@ offsetof(ngx_stream_proxy_srv_conf_t, next_upstream_timeout), NULL }, + { ngx_string("proxy_protocol"), + 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, proxy_protocol), + NULL }, + #if (NGX_STREAM_SSL) { ngx_string("proxy_ssl"), @@ -246,6 +283,8 @@ static ngx_stream_module_t ngx_stream_proxy_module_ctx = { + NULL, /* postconfiguration */ + NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -299,6 +338,8 @@ u->peer.log = c->log; u->peer.log_error = NGX_ERROR_ERR; + u->peer.local = pscf->local; + uscf = pscf->upstream; if (uscf->peer.init(s, uscf) != NGX_OK) { @@ -314,6 +355,9 @@ u->peer.tries = pscf->next_upstream_tries; } + u->proxy_protocol = pscf->proxy_protocol; + u->start_sec = ngx_time(); + p = ngx_pnalloc(c->pool, pscf->downstream_buf_size); if (p == NULL) { ngx_stream_proxy_finalize(s, NGX_ERROR); @@ -328,6 +372,29 @@ c->write->handler = ngx_stream_proxy_downstream_handler; c->read->handler = ngx_stream_proxy_downstream_handler; + if (u->proxy_protocol +#if (NGX_STREAM_SSL) + && pscf->ssl == NULL +#endif + && pscf->downstream_buf_size >= NGX_PROXY_PROTOCOL_MAX_HEADER + ) + { + /* optimization for a typical case */ + + ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, + "stream proxy send PROXY protocol header"); + + p = ngx_proxy_protocol_write(c, u->downstream_buf.last, + u->downstream_buf.end); + if (p == NULL) { + ngx_stream_proxy_finalize(s, NGX_ERROR); + return; + } + + u->downstream_buf.last = p; + u->proxy_protocol = 0; + } + if (ngx_stream_proxy_process(s, 0, 0) != NGX_OK) { return; } @@ -403,10 +470,18 @@ ngx_stream_upstream_t *u; ngx_stream_proxy_srv_conf_t *pscf; - pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); - u = s->upstream; + if (u->proxy_protocol) { + if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) { + return; + } + + u->proxy_protocol = 0; + } + + pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); + pc = u->peer.connection; #if (NGX_STREAM_SSL) @@ -449,6 +524,8 @@ u->upstream_buf.pos = p; u->upstream_buf.last = p; + u->connected = 1; + pc->read->handler = ngx_stream_proxy_upstream_handler; pc->write->handler = ngx_stream_proxy_upstream_handler; @@ -460,6 +537,76 @@ } +static ngx_int_t +ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s) +{ + u_char *p; + ssize_t n, size; + ngx_connection_t *c, *pc; + ngx_stream_upstream_t *u; + ngx_stream_proxy_srv_conf_t *pscf; + u_char buf[NGX_PROXY_PROTOCOL_MAX_HEADER]; + + c = s->connection; + + ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, + "stream proxy send PROXY protocol header"); + + p = ngx_proxy_protocol_write(c, buf, buf + NGX_PROXY_PROTOCOL_MAX_HEADER); + if (p == NULL) { + ngx_stream_proxy_finalize(s, NGX_ERROR); + return NGX_ERROR; + } + + u = s->upstream; + + pc = u->peer.connection; + + size = p - buf; + + n = pc->send(pc, buf, size); + + if (n == NGX_AGAIN) { + if (ngx_handle_write_event(pc->write, 0) != NGX_OK) { + ngx_stream_proxy_finalize(s, NGX_ERROR); + return NGX_ERROR; + } + + pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); + + ngx_add_timer(pc->write, pscf->timeout); + + pc->write->handler = ngx_stream_proxy_connect_handler; + + return NGX_AGAIN; + } + + if (n == NGX_ERROR) { + ngx_stream_proxy_finalize(s, NGX_DECLINED); + return NGX_ERROR; + } + + if (n != size) { + + /* + * PROXY protocol specification: + * The sender must always ensure that the header + * is sent at once, so that the transport layer + * maintains atomicity along the path to the receiver. + */ + + ngx_log_error(NGX_LOG_ERR, c->log, 0, + "could not send PROXY protocol header at once"); + + ngx_stream_proxy_finalize(s, NGX_DECLINED); + + return NGX_ERROR; + } + + return NGX_OK; +} + + #if (NGX_STREAM_SSL) static char * @@ -689,48 +836,78 @@ static void ngx_stream_proxy_downstream_handler(ngx_event_t *ev) { - ngx_connection_t *c; - ngx_stream_session_t *s; - ngx_stream_upstream_t *u; + ngx_stream_proxy_process_connection(ev, ev->write); +} + + +static void +ngx_stream_proxy_upstream_handler(ngx_event_t *ev) +{ + ngx_stream_proxy_process_connection(ev, !ev->write); +} + + +static void +ngx_stream_proxy_process_connection(ngx_event_t *ev, ngx_uint_t from_upstream) +{ + ngx_connection_t *c, *pc; + ngx_stream_session_t *s; + ngx_stream_upstream_t *u; + ngx_stream_proxy_srv_conf_t *pscf; c = ev->data; s = c->data; + u = s->upstream; if (ev->timedout) { - ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out"); - ngx_stream_proxy_finalize(s, NGX_DECLINED); - return; - } - u = s->upstream; + if (ev->delayed) { - if (!ev->write) { - ngx_stream_proxy_process(s, 0, 0); + ev->timedout = 0; + ev->delayed = 0; - } else if (u->upstream_buf.start) { - ngx_stream_proxy_process(s, 1, 1); - } -} + if (!ev->ready) { + if (ngx_handle_read_event(ev, 0) != NGX_OK) { + ngx_stream_proxy_finalize(s, NGX_ERROR); + return; + } + if (u->connected) { + pc = u->peer.connection; -static void -ngx_stream_proxy_upstream_handler(ngx_event_t *ev) -{ - ngx_connection_t *c; - ngx_stream_session_t *s; - ngx_stream_upstream_t *u; + if (!c->read->delayed && !pc->read->delayed) { + pscf = ngx_stream_get_module_srv_conf(s, + ngx_stream_proxy_module); + ngx_add_timer(c->write, pscf->timeout); + } + } - c = ev->data; - s = c->data; + return; + } - u = s->upstream; + } else { + ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out"); + ngx_stream_proxy_finalize(s, NGX_DECLINED); + return; + } + + } else if (ev->delayed) { + + ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, + "stream connection delayed"); + + if (ngx_handle_read_event(ev, 0) != NGX_OK) { + ngx_stream_proxy_finalize(s, NGX_ERROR); + } - if (ev->write) { - ngx_stream_proxy_process(s, 0, 1); + return; + } - } else if (u->upstream_buf.start) { - ngx_stream_proxy_process(s, 1, 0); + if (from_upstream && !u->connected) { + return; } + + ngx_stream_proxy_process(s, from_upstream, ev->write); } @@ -811,10 +988,12 @@ ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream, ngx_uint_t do_write) { - size_t size; + off_t *received, limit; + size_t size, limit_rate; ssize_t n; ngx_buf_t *b; ngx_uint_t flags; + ngx_msec_t delay; ngx_connection_t *c, *pc, *src, *dst; ngx_log_handler_pt handler; ngx_stream_upstream_t *u; @@ -823,17 +1002,23 @@ u = s->upstream; c = s->connection; - pc = u->upstream_buf.start ? u->peer.connection : NULL; + pc = u->connected ? u->peer.connection : NULL; + + pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); if (from_upstream) { src = pc; dst = c; b = &u->upstream_buf; + limit_rate = pscf->download_rate; + received = &u->received; } else { src = c; dst = pc; b = &u->downstream_buf; + limit_rate = pscf->upload_rate; + received = &s->received; } for ( ;; ) { @@ -864,7 +1049,23 @@ size = b->end - b->last; - if (size && src->read->ready) { + if (size && src->read->ready && !src->read->delayed) { + + if (limit_rate) { + limit = (off_t) limit_rate * (ngx_time() - u->start_sec + 1) + - *received; + + if (limit <= 0) { + src->read->delayed = 1; + delay = (ngx_msec_t) (- limit * 1000 / limit_rate + 1); + ngx_add_timer(src->read, delay); + break; + } + + if ((off_t) size > limit) { + size = (size_t) limit; + } + } n = src->recv(src, b->last, size); @@ -873,15 +1074,19 @@ } if (n > 0) { - if (from_upstream) { - u->received += n; + if (limit_rate) { + delay = (ngx_msec_t) (n * 1000 / limit_rate); - } else { - s->received += n; + if (delay > 0) { + src->read->delayed = 1; + ngx_add_timer(src->read, delay); + } } - do_write = 1; + *received += n; b->last += n; + do_write = 1; + continue; } @@ -893,8 +1098,6 @@ break; } - pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); - if (src->read->eof && (b->pos == b->last || (dst && dst->read->eof))) { handler = c->log->handler; c->log->handler = NULL; @@ -925,7 +1128,12 @@ return NGX_ERROR; } - ngx_add_timer(c->read, pscf->timeout); + if (!c->read->delayed && !pc->read->delayed) { + ngx_add_timer(c->write, pscf->timeout); + + } else if (c->write->timer_set) { + ngx_del_timer(c->write); + } } return NGX_OK; @@ -1088,9 +1296,13 @@ conf->timeout = NGX_CONF_UNSET_MSEC; conf->next_upstream_timeout = NGX_CONF_UNSET_MSEC; conf->downstream_buf_size = NGX_CONF_UNSET_SIZE; + conf->upload_rate = NGX_CONF_UNSET_SIZE; conf->upstream_buf_size = NGX_CONF_UNSET_SIZE; + conf->download_rate = NGX_CONF_UNSET_SIZE; conf->next_upstream_tries = NGX_CONF_UNSET_UINT; conf->next_upstream = NGX_CONF_UNSET; + conf->proxy_protocol = NGX_CONF_UNSET; + conf->local = NGX_CONF_UNSET_PTR; #if (NGX_STREAM_SSL) conf->ssl_enable = NGX_CONF_UNSET; @@ -1123,14 +1335,24 @@ ngx_conf_merge_size_value(conf->downstream_buf_size, prev->downstream_buf_size, 16384); + ngx_conf_merge_size_value(conf->upload_rate, + prev->upload_rate, 0); + ngx_conf_merge_size_value(conf->upstream_buf_size, prev->upstream_buf_size, 16384); + ngx_conf_merge_size_value(conf->download_rate, + prev->download_rate, 0); + ngx_conf_merge_uint_value(conf->next_upstream_tries, prev->next_upstream_tries, 0); ngx_conf_merge_value(conf->next_upstream, prev->next_upstream, 1); + ngx_conf_merge_value(conf->proxy_protocol, prev->proxy_protocol, 0); + + ngx_conf_merge_ptr_value(conf->local, prev->local, NULL); + #if (NGX_STREAM_SSL) ngx_conf_merge_value(conf->ssl_enable, prev->ssl_enable, 0); @@ -1288,3 +1510,45 @@ return NGX_CONF_OK; } + + +static char * +ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_stream_proxy_srv_conf_t *pscf = conf; + + ngx_int_t rc; + ngx_str_t *value; + + if (pscf->local != NGX_CONF_UNSET_PTR) { + return "is duplicate"; + } + + value = cf->args->elts; + + if (ngx_strcmp(value[1].data, "off") == 0) { + pscf->local = NULL; + return NGX_CONF_OK; + } + + pscf->local = ngx_palloc(cf->pool, sizeof(ngx_addr_t)); + if (pscf->local == NULL) { + return NGX_CONF_ERROR; + } + + rc = ngx_parse_addr(cf->pool, pscf->local, value[1].data, value[1].len); + + switch (rc) { + case NGX_OK: + pscf->local->name = value[1]; + return NGX_CONF_OK; + + case NGX_DECLINED: + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid address \"%V\"", &value[1]); + /* fall through */ + + default: + return NGX_CONF_ERROR; + } +} | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/stream/ngx_stream_ssl_module.c ^ |
@@ -132,6 +132,8 @@ static ngx_stream_module_t ngx_stream_ssl_module_ctx = { + NULL, /* postconfiguration */ + NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -274,7 +276,9 @@ SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); } +#ifndef LIBRESSL_VERSION_NUMBER SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); +#endif if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/stream/ngx_stream_upstream.c ^ |
@@ -39,6 +39,8 @@ static ngx_stream_module_t ngx_stream_upstream_module_ctx = { + NULL, /* postconfiguration */ + ngx_stream_upstream_create_main_conf, /* create main configuration */ ngx_stream_upstream_init_main_conf, /* init main configuration */ | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/stream/ngx_stream_upstream.h ^ |
@@ -83,9 +83,12 @@ ngx_buf_t downstream_buf; ngx_buf_t upstream_buf; off_t received; + time_t start_sec; #if (NGX_STREAM_SSL) ngx_str_t ssl_name; #endif + unsigned connected:1; + unsigned proxy_protocol:1; } ngx_stream_upstream_t; | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/stream/ngx_stream_upstream_hash_module.c ^ |
@@ -76,6 +76,8 @@ static ngx_stream_module_t ngx_stream_upstream_hash_module_ctx = { + NULL, /* postconfiguration */ + NULL, /* create main configuration */ NULL, /* init main configuration */ | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/stream/ngx_stream_upstream_least_conn_module.c ^ |
@@ -32,6 +32,8 @@ static ngx_stream_module_t ngx_stream_upstream_least_conn_module_ctx = { + NULL, /* postconfiguration */ + NULL, /* create main configuration */ NULL, /* init main configuration */ | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/stream/ngx_stream_upstream_round_robin.h ^ |
@@ -58,6 +58,7 @@ #if (NGX_STREAM_UPSTREAM_ZONE) ngx_slab_pool_t *shpool; ngx_atomic_t rwlock; + ngx_stream_upstream_rr_peers_t *zone_next; #endif ngx_uint_t total_weight; | ||
[+] | Changed | nginx-1.9.3.tar.gz/src/stream/ngx_stream_upstream_zone_module.c ^ |
@@ -14,8 +14,8 @@ void *conf); static ngx_int_t ngx_stream_upstream_init_zone(ngx_shm_zone_t *shm_zone, void *data); -static ngx_int_t ngx_stream_upstream_zone_copy_peers(ngx_slab_pool_t *shpool, - ngx_stream_upstream_srv_conf_t *uscf); +static ngx_stream_upstream_rr_peers_t *ngx_stream_upstream_zone_copy_peers( + ngx_slab_pool_t *shpool, ngx_stream_upstream_srv_conf_t *uscf); static ngx_command_t ngx_stream_upstream_zone_commands[] = { @@ -32,6 +32,8 @@ static ngx_stream_module_t ngx_stream_upstream_zone_module_ctx = { + NULL, /* postconfiguration */ + NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -115,13 +117,29 @@ size_t len; ngx_uint_t i; ngx_slab_pool_t *shpool; + ngx_stream_upstream_rr_peers_t *peers, **peersp; ngx_stream_upstream_srv_conf_t *uscf, **uscfp; ngx_stream_upstream_main_conf_t *umcf; shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; + umcf = shm_zone->data; + uscfp = umcf->upstreams.elts; if (shm_zone->shm.exists) { - return NGX_ERROR; + peers = shpool->data; + + for (i = 0; i < umcf->upstreams.nelts; i++) { + uscf = uscfp[i]; + + if (uscf->shm_zone != shm_zone) { + continue; + } + + uscf->peer.data = peers; + peers = peers->zone_next; + } + + return NGX_OK; } len = sizeof(" in upstream zone \"\"") + shm_zone->shm.name.len; @@ -137,8 +155,7 @@ /* copy peers to shared memory */ - umcf = shm_zone->data; - uscfp = umcf->upstreams.elts; + peersp = (ngx_stream_upstream_rr_peers_t **) &shpool->data; for (i = 0; i < umcf->upstreams.nelts; i++) { uscf = uscfp[i]; @@ -147,16 +164,20 @@ continue; } - if (ngx_stream_upstream_zone_copy_peers(shpool, uscf) != NGX_OK) { + peers = ngx_stream_upstream_zone_copy_peers(shpool, uscf); + if (peers == NULL) { return NGX_ERROR; } + + *peersp = peers; + peersp = &peers->zone_next; } return NGX_OK; } -static ngx_int_t +static ngx_stream_upstream_rr_peers_t * ngx_stream_upstream_zone_copy_peers(ngx_slab_pool_t *shpool, ngx_stream_upstream_srv_conf_t *uscf) { @@ -165,7 +186,7 @@ peers = ngx_slab_alloc(shpool, sizeof(ngx_stream_upstream_rr_peers_t)); if (peers == NULL) { - return NGX_ERROR; + return NULL; } ngx_memcpy(peers, uscf->peer.data, sizeof(ngx_stream_upstream_rr_peers_t)); @@ -177,7 +198,7 @@ peer = ngx_slab_calloc_locked(shpool, sizeof(ngx_stream_upstream_rr_peer_t)); if (peer == NULL) { - return NGX_ERROR; + return NULL; } ngx_memcpy(peer, *peerp, sizeof(ngx_stream_upstream_rr_peer_t)); @@ -191,7 +212,7 @@ backup = ngx_slab_alloc(shpool, sizeof(ngx_stream_upstream_rr_peers_t)); if (backup == NULL) { - return NGX_ERROR; + return NULL; } ngx_memcpy(backup, peers->next, sizeof(ngx_stream_upstream_rr_peers_t)); @@ -203,7 +224,7 @@ peer = ngx_slab_calloc_locked(shpool, sizeof(ngx_stream_upstream_rr_peer_t)); if (peer == NULL) { - return NGX_ERROR; + return NULL; } ngx_memcpy(peer, *peerp, sizeof(ngx_stream_upstream_rr_peer_t)); @@ -217,5 +238,5 @@ uscf->peer.data = peers; - return NGX_OK; + return peers; } | ||
Deleted | openssl-1.0.2a.tar.gz ^ | |
Added | openssl-1.0.2d.tar.gz ^ |