[-]
[+]
|
Changed |
nginx.spec
|
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/CHANGES
^
|
@@ -1,4 +1,51 @@
+Changes with nginx 1.9.13 29 Mar 2016
+
+ *) Change: non-idempotent requests (POST, LOCK, PATCH) are no longer
+ passed to the next server by default if a request has been sent to a
+ backend; the "non_idempotent" parameter of the "proxy_next_upstream"
+ directive explicitly allows retrying such requests.
+
+ *) Feature: the ngx_http_perl_module can be built dynamically.
+
+ *) Feature: UDP support in the stream module.
+
+ *) Feature: the "aio_write" directive.
+
+ *) Feature: now cache manager monitors number of elements in caches and
+ tries to avoid cache keys zone overflows.
+
+ *) Bugfix: "task already active" and "second aio post" alerts might
+ appear in logs when using the "sendfile" and "aio" directives with
+ subrequests.
+
+ *) Bugfix: "zero size buf in output" alerts might appear in logs if
+ caching was used and a client closed a connection prematurely.
+
+ *) Bugfix: connections with clients might be closed needlessly if
+ caching was used.
+ Thanks to Justin Li.
+
+ *) Bugfix: nginx might hog CPU if the "sendfile" directive was used on
+ Linux or Solaris and a file being sent was changed during sending.
+
+ *) Bugfix: connections might hang when using the "sendfile" and "aio
+ threads" directives.
+
+ *) Bugfix: in the "proxy_pass", "fastcgi_pass", "scgi_pass", and
+ "uwsgi_pass" directives when using variables.
+ Thanks to Piotr Sikora.
+
+ *) Bugfix: in the ngx_http_sub_filter_module.
+
+ *) Bugfix: if an error occurred in a cached backend connection, the
+ request was passed to the next server regardless of the
+ proxy_next_upstream directive.
+
+ *) Bugfix: "CreateFile() failed" errors when creating temporary files on
+ Windows.
+
+
Changes with nginx 1.9.12 24 Feb 2016
*) Feature: Huffman encoding of response headers in HTTP/2.
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/CHANGES.ru
^
|
@@ -1,4 +1,54 @@
+Изменения в nginx 1.9.13 29.03.2016
+
+ *) Изменение: неидемпотентные запросы (POST, LOCK, PATCH) теперь по
+ умолчанию не передаются на другой сервер, если запрос уже был
+ отправлен на бэкенд; параметр non_idempotent директивы
+ proxy_next_upstream явно разрешает повторять такие запросы.
+
+ *) Добавление: модуль ngx_http_perl_module теперь можно собрать
+ динамически.
+
+ *) Добавление: поддержка UDP в модуле stream.
+
+ *) Добавление: директива aio_write.
+
+ *) Добавление: теперь cache manager следит за количеством элементов в
+ кэше и старается не допускать переполнений зоны разделяемой памяти.
+
+ *) Исправление: при использовании директив sendfile и aio с подзапросами
+ в логах могли появляться сообщения "task already active" и "second
+ aio post".
+
+ *) Исправление: при использовании кэширования в логах могли появляться
+ сообщения "zero size buf in output", если клиент закрывал соединение
+ преждевременно.
+
+ *) Исправление: при использовании кэширования соединения с клиентами
+ могли закрываться без необходимости.
+ Спасибо Justin Li.
+
+ *) Исправление: nginx мог нагружать процессор при использовании
+ директивы sendfile на Linux и Solaris, если отправляемый файл был
+ изменён в процессе отправки.
+
+ *) Исправление: при использовании директив sendfile и "aio threads"
+ соединения могли зависать.
+
+ *) Исправление: в директивах proxy_pass, fastcgi_pass, scgi_pass и
+ uwsgi_pass при использовании переменных.
+ Спасибо Piotr Sikora.
+
+ *) Исправление: в модуле ngx_http_sub_filter_module.
+
+ *) Исправление: если в закэшированном соединении к бэкенду происходила
+ ошибка, запрос передавался на другой сервер без учёта директивы
+ proxy_next_upstream.
+
+ *) Исправление: ошибки "CreateFile() failed" при создании временных
+ файлов на Windows.
+
+
Изменения в nginx 1.9.12 24.02.2016
*) Добавление: кодирование Хаффмана заголовков ответов в HTTP/2.
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/auto/init
^
|
@@ -5,7 +5,6 @@
NGX_MAKEFILE=$NGX_OBJS/Makefile
NGX_MODULES_C=$NGX_OBJS/ngx_modules.c
-NGX_MODULES=
NGX_AUTO_HEADERS_H=$NGX_OBJS/ngx_auto_headers.h
NGX_AUTO_CONFIG_H=$NGX_OBJS/ngx_auto_config.h
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/auto/install
^
|
@@ -3,7 +3,7 @@
# Copyright (C) Nginx, Inc.
-if [ $USE_PERL = YES ]; then
+if [ $USE_PERL != NO ]; then
cat << END >> $NGX_MAKEFILE
@@ -107,54 +107,54 @@
install: build $NGX_INSTALL_PERL_MODULES
test -d '\$(DESTDIR)$NGX_PREFIX' || mkdir -p '\$(DESTDIR)$NGX_PREFIX'
- test -d '\$(DESTDIR)`dirname "$NGX_SBIN_PATH"`' \
+ test -d '\$(DESTDIR)`dirname "$NGX_SBIN_PATH"`' \\
|| mkdir -p '\$(DESTDIR)`dirname "$NGX_SBIN_PATH"`'
- test ! -f '\$(DESTDIR)$NGX_SBIN_PATH' \
- || mv '\$(DESTDIR)$NGX_SBIN_PATH' \
+ test ! -f '\$(DESTDIR)$NGX_SBIN_PATH' \\
+ || mv '\$(DESTDIR)$NGX_SBIN_PATH' \\
'\$(DESTDIR)$NGX_SBIN_PATH.old'
cp $NGX_OBJS/nginx '\$(DESTDIR)$NGX_SBIN_PATH'
- test -d '\$(DESTDIR)$NGX_CONF_PREFIX' \
+ test -d '\$(DESTDIR)$NGX_CONF_PREFIX' \\
|| mkdir -p '\$(DESTDIR)$NGX_CONF_PREFIX'
cp conf/koi-win '\$(DESTDIR)$NGX_CONF_PREFIX'
cp conf/koi-utf '\$(DESTDIR)$NGX_CONF_PREFIX'
cp conf/win-utf '\$(DESTDIR)$NGX_CONF_PREFIX'
- test -f '\$(DESTDIR)$NGX_CONF_PREFIX/mime.types' \
+ test -f '\$(DESTDIR)$NGX_CONF_PREFIX/mime.types' \\
|| cp conf/mime.types '\$(DESTDIR)$NGX_CONF_PREFIX'
cp conf/mime.types '\$(DESTDIR)$NGX_CONF_PREFIX/mime.types.default'
- test -f '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi_params' \
+ test -f '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi_params' \\
|| cp conf/fastcgi_params '\$(DESTDIR)$NGX_CONF_PREFIX'
- cp conf/fastcgi_params \
+ cp conf/fastcgi_params \\
'\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi_params.default'
- test -f '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi.conf' \
+ test -f '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi.conf' \\
|| cp conf/fastcgi.conf '\$(DESTDIR)$NGX_CONF_PREFIX'
cp conf/fastcgi.conf '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi.conf.default'
- test -f '\$(DESTDIR)$NGX_CONF_PREFIX/uwsgi_params' \
+ test -f '\$(DESTDIR)$NGX_CONF_PREFIX/uwsgi_params' \\
|| cp conf/uwsgi_params '\$(DESTDIR)$NGX_CONF_PREFIX'
- cp conf/uwsgi_params \
+ cp conf/uwsgi_params \\
'\$(DESTDIR)$NGX_CONF_PREFIX/uwsgi_params.default'
- test -f '\$(DESTDIR)$NGX_CONF_PREFIX/scgi_params' \
+ test -f '\$(DESTDIR)$NGX_CONF_PREFIX/scgi_params' \\
|| cp conf/scgi_params '\$(DESTDIR)$NGX_CONF_PREFIX'
- cp conf/scgi_params \
+ cp conf/scgi_params \\
'\$(DESTDIR)$NGX_CONF_PREFIX/scgi_params.default'
- test -f '\$(DESTDIR)$NGX_CONF_PATH' \
+ test -f '\$(DESTDIR)$NGX_CONF_PATH' \\
|| cp conf/nginx.conf '\$(DESTDIR)$NGX_CONF_PATH'
cp conf/nginx.conf '\$(DESTDIR)$NGX_CONF_PREFIX/nginx.conf.default'
- test -d '\$(DESTDIR)`dirname "$NGX_PID_PATH"`' \
+ test -d '\$(DESTDIR)`dirname "$NGX_PID_PATH"`' \\
|| mkdir -p '\$(DESTDIR)`dirname "$NGX_PID_PATH"`'
- test -d '\$(DESTDIR)`dirname "$NGX_HTTP_LOG_PATH"`' || \
- mkdir -p '\$(DESTDIR)`dirname "$NGX_HTTP_LOG_PATH"`'
+ test -d '\$(DESTDIR)`dirname "$NGX_HTTP_LOG_PATH"`' \\
+ || mkdir -p '\$(DESTDIR)`dirname "$NGX_HTTP_LOG_PATH"`'
- test -d '\$(DESTDIR)$NGX_PREFIX/html' \
+ test -d '\$(DESTDIR)$NGX_PREFIX/html' \\
|| cp -R $NGX_HTML '\$(DESTDIR)$NGX_PREFIX'
END
@@ -162,24 +162,38 @@
if test -n "$NGX_ERROR_LOG_PATH"; then
cat << END >> $NGX_MAKEFILE
- test -d '\$(DESTDIR)`dirname "$NGX_ERROR_LOG_PATH"`' || \
- mkdir -p '\$(DESTDIR)`dirname "$NGX_ERROR_LOG_PATH"`'
+ test -d '\$(DESTDIR)`dirname "$NGX_ERROR_LOG_PATH"`' \\
+ || mkdir -p '\$(DESTDIR)`dirname "$NGX_ERROR_LOG_PATH"`'
END
fi
-if test -n "$NGX_MODULES"; then
+if test -n "$DYNAMIC_MODULES"; then
cat << END >> $NGX_MAKEFILE
- test -d '\$(DESTDIR)$NGX_MODULES_PATH' \
+ test -d '\$(DESTDIR)$NGX_MODULES_PATH' \\
|| mkdir -p '\$(DESTDIR)$NGX_MODULES_PATH'
- cp $NGX_MODULES '\$(DESTDIR)$NGX_MODULES_PATH'
END
fi
+for ngx_module in $DYNAMIC_MODULES
+do
+ ngx_module=$ngx_module$ngx_modext
+
+ cat << END >> $NGX_MAKEFILE
+
+ test ! -f '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module' \\
+ || mv '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module' \\
+ '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module.old'
+ cp $NGX_OBJS/$ngx_module '\$(DESTDIR)$NGX_MODULES_PATH/$ngx_module'
+END
+
+done
+
+
# create Makefile
cat << END >> Makefile
@@ -190,6 +204,9 @@
install:
\$(MAKE) -f $NGX_MAKEFILE install
+modules:
+ \$(MAKE) -f $NGX_MAKEFILE modules
+
upgrade:
$NGX_SBIN_PATH -t
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/auto/lib/conf
^
|
@@ -66,7 +66,7 @@
. auto/lib/libgd/conf
fi
-if [ $USE_PERL = YES ]; then
+if [ $USE_PERL != NO ]; then
. auto/lib/perl/conf
fi
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/auto/lib/make
^
|
@@ -27,6 +27,6 @@
. auto/lib/libatomic/make
fi
-if [ $USE_PERL = YES ]; then
+if [ $USE_PERL != NO ]; then
. auto/lib/perl/make
fi
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/auto/lib/perl/conf
^
|
@@ -60,8 +60,11 @@
| sed -e 's/-arch i386//' -e 's/-arch x86_64//'`
fi
- CORE_LINK="$CORE_LINK $ngx_perl_ldopts"
- LINK_DEPS="$LINK_DEPS $NGX_OBJS/$ngx_perl_module"
+ if [ $USE_PERL = YES ]; then
+ CORE_LINK="$CORE_LINK $ngx_perl_ldopts"
+ fi
+
+ NGX_LIB_PERL="$ngx_perl_ldopts"
if test -n "$NGX_PERL_MODULES"; then
have=NGX_PERL_MODULES value="(u_char *) \"$NGX_PERL_MODULES\""
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/auto/lib/perl/make
^
|
@@ -8,7 +8,10 @@
cat << END >> $NGX_MAKEFILE
-$NGX_OBJS/src/http/modules/perl/blib/arch/auto/nginx/nginx.$ngx_perl_dlext: \\
+$NGX_OBJS/src/http/modules/perl/ngx_http_perl_module.o: \\
+ $NGX_OBJS/$ngx_perl_module
+
+$NGX_OBJS/$ngx_perl_module: \\
\$(CORE_DEPS) \$(HTTP_DEPS) \\
src/http/modules/perl/ngx_http_perl_module.h \\
$NGX_OBJS/src/http/modules/perl/Makefile
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/auto/make
^
|
@@ -225,12 +225,12 @@
build: binary modules manpage
-binary: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext}
+binary: $NGX_OBJS${ngx_dirsep}nginx$ngx_binext
-$NGX_OBJS${ngx_dirsep}nginx${ngx_binext}: $ngx_deps$ngx_spacer
- \$(LINK) ${ngx_long_start}${ngx_binout}$NGX_OBJS${ngx_dirsep}nginx$ngx_long_cont$ngx_objs$ngx_libs$ngx_link$ngx_main_link
+$NGX_OBJS${ngx_dirsep}nginx$ngx_binext: $ngx_deps$ngx_spacer
+ \$(LINK) $ngx_long_start$ngx_binout$NGX_OBJS${ngx_dirsep}nginx$ngx_long_cont$ngx_objs$ngx_libs$ngx_link$ngx_main_link
$ngx_rcc
-${ngx_long_end}
+$ngx_long_end
modules:
END
@@ -281,7 +281,7 @@
ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
else
ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS) \$(HTTP_INCS)"
- ngx_perl_cc="\$(CC) $ngx_compile_opt \$(NGX_PERL_CFLAGS) "
+ ngx_perl_cc="\$(CC) $ngx_compile_opt \$(NGX_PERL_CFLAGS)"
ngx_perl_cc="$ngx_perl_cc \$(CORE_INCS) \$(HTTP_INCS)"
fi
@@ -437,9 +437,9 @@
# the addons config.make
-if test -n "$NGX_ADDONS"; then
+if test -n "$NGX_ADDONS$DYNAMIC_ADDONS"; then
- for ngx_addon_dir in $NGX_ADDONS
+ for ngx_addon_dir in $NGX_ADDONS $DYNAMIC_ADDONS
do
if test -f $ngx_addon_dir/config.make; then
. $ngx_addon_dir/config.make
@@ -494,6 +494,8 @@
ngx_cc="\$(CC) $ngx_compile_opt $ngx_pic_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
else
ngx_cc="\$(CC) $ngx_compile_opt $ngx_pic_opt \$(CFLAGS) \$(ALL_INCS)"
+ ngx_perl_cc="\$(CC) $ngx_compile_opt $ngx_pic_opt \$(NGX_PERL_CFLAGS)"
+ ngx_perl_cc="$ngx_perl_cc \$(ALL_INCS)"
fi
ngx_obj_deps="\$(CORE_DEPS)"
@@ -605,9 +607,7 @@
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \
-e "s/\//$ngx_regex_dirsep/g"`
- ngx_obj=$NGX_OBJS${ngx_dirsep}${ngx_module}${ngx_modext}
-
- NGX_MODULES="$NGX_MODULES $ngx_obj"
+ ngx_obj=$NGX_OBJS$ngx_dirsep$ngx_module$ngx_modext
if [ "$NGX_PLATFORM" = win32 ]; then
ngx_module_libs="$CORE_LIBS $ngx_module_libs"
@@ -639,15 +639,15 @@
END
- for ngx_src in $ngx_module_srcs
+ for ngx_source in $ngx_module_srcs
do
- case "$ngx_src" in
+ case "$ngx_source" in
src/*)
- ngx_obj=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"`
+ ngx_obj=`echo $ngx_source | sed -e "s/\//$ngx_regex_dirsep/g"`
;;
*)
- ngx_obj="addon/`basename \`dirname $ngx_src\``"
- ngx_obj=`echo $ngx_obj/\`basename $ngx_src\` \
+ ngx_obj="addon/`basename \`dirname $ngx_source\``"
+ ngx_obj=`echo $ngx_obj/\`basename $ngx_source\` \
| sed -e "s/\//$ngx_regex_dirsep/g"`
;;
esac
@@ -658,14 +658,25 @@
-e "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g" \
-e "s#^\(.*\.\)S\\$#$ngx_objs_dir\1$ngx_objext#g"`
- ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"`
+ ngx_src=`echo $ngx_source | sed -e "s/\//$ngx_regex_dirsep/g"`
- cat << END >> $NGX_MAKEFILE
+ if [ $ngx_source = src/http/modules/perl/ngx_http_perl_module.c ]; then
+
+ cat << END >> $NGX_MAKEFILE
+
+$ngx_obj: $ngx_obj_deps$ngx_cont$ngx_src
+ $ngx_perl_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
+
+END
+ else
+
+ cat << END >> $NGX_MAKEFILE
$ngx_obj: $ngx_obj_deps$ngx_cont$ngx_src
$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
END
+ fi
done
done
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/auto/module
^
|
@@ -40,7 +40,7 @@
do
case $lib in
- LIBXSLT | LIBGD | GEOIP)
+ LIBXSLT | LIBGD | GEOIP | PERL)
libs="$libs \$NGX_LIB_$lib"
if eval [ "\$USE_${lib}" = NO ] ; then
@@ -48,7 +48,7 @@
fi
;;
- PCRE | OPENSSL | MD5 | SHA1 | ZLIB | PERL)
+ PCRE | OPENSSL | MD5 | SHA1 | ZLIB)
eval USE_${lib}=YES
;;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/auto/modules
^
|
@@ -727,14 +727,12 @@
. auto/module
fi
-if [ $HTTP_PERL = YES ]; then
- USE_PERL=YES
-
+if [ $HTTP_PERL != NO ]; then
ngx_module_name=ngx_http_perl_module
ngx_module_incs=src/http/modules/perl
ngx_module_deps=src/http/modules/perl/ngx_http_perl_module.h
ngx_module_srcs=src/http/modules/perl/ngx_http_perl_module.c
- ngx_module_libs=
+ ngx_module_libs=PERL
ngx_module_link=$HTTP_PERL
. auto/module
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/auto/options
^
|
@@ -271,6 +271,7 @@
--without-http_upstream_zone_module) HTTP_UPSTREAM_ZONE=NO ;;
--with-http_perl_module) HTTP_PERL=YES ;;
+ --with-http_perl_module=dynamic) HTTP_PERL=DYNAMIC ;;
--with-perl_modules_path=*) NGX_PERL_MODULES="$value" ;;
--with-perl=*) NGX_PERL="$value" ;;
@@ -452,6 +453,7 @@
disable ngx_http_upstream_zone_module
--with-http_perl_module enable ngx_http_perl_module
+ --with-http_perl_module=dynamic enable dynamic ngx_http_perl_module
--with-perl_modules_path=PATH set Perl modules path
--with-perl=PATH set perl binary pathname
@@ -477,8 +479,8 @@
--without-mail_imap_module disable ngx_mail_imap_module
--without-mail_smtp_module disable ngx_mail_smtp_module
- --with-stream enable TCP proxy module
- --with-stream=dynamic enable dynamic TCP proxy module
+ --with-stream enable TCP/UDP proxy module
+ --with-stream=dynamic enable dynamic TCP/UDP 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
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/auto/sources
^
|
@@ -165,6 +165,7 @@
src/os/unix/ngx_udp_recv.c \
src/os/unix/ngx_send.c \
src/os/unix/ngx_writev_chain.c \
+ src/os/unix/ngx_udp_send.c \
src/os/unix/ngx_channel.c \
src/os/unix/ngx_shmem.c \
src/os/unix/ngx_process.c \
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/auto/unix
^
|
@@ -329,6 +329,45 @@
. auto/feature
+# BSD way to get IPv4 datagram destination address
+
+ngx_feature="IP_RECVDSTADDR"
+ngx_feature_name="NGX_HAVE_IP_RECVDSTADDR"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/socket.h>
+ #include <netinet/in.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_RECVDSTADDR, NULL, 0)"
+. auto/feature
+
+
+# Linux way to get IPv4 datagram destination address
+
+ngx_feature="IP_PKTINFO"
+ngx_feature_name="NGX_HAVE_IP_PKTINFO"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/socket.h>
+ #include <netinet/in.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_PKTINFO, NULL, 0)"
+. auto/feature
+
+
+# RFC 3542 way to get IPv6 datagram destination address
+
+ngx_feature="IPV6_RECVPKTINFO"
+ngx_feature_name="NGX_HAVE_IPV6_RECVPKTINFO"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/socket.h>
+ #include <netinet/in.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="setsockopt(0, IPPROTO_IPV6, IPV6_RECVPKTINFO, NULL, 0)"
+. auto/feature
+
+
ngx_feature="TCP_DEFER_ACCEPT"
ngx_feature_name="NGX_HAVE_DEFERRED_ACCEPT"
ngx_feature_run=no
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/core/nginx.c
^
|
@@ -10,7 +10,7 @@
#include <nginx.h>
-static void ngx_show_version_info();
+static void ngx_show_version_info(void);
static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle);
static ngx_int_t ngx_get_options(int argc, char *const *argv);
static ngx_int_t ngx_process_options(ngx_cycle_t *cycle);
@@ -372,7 +372,7 @@
static void
-ngx_show_version_info()
+ngx_show_version_info(void)
{
ngx_write_stderr("nginx version: " NGINX_VER_BUILD NGX_LINEFEED);
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/core/nginx.h
^
|
@@ -9,8 +9,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 1009012
-#define NGINX_VERSION "1.9.12"
+#define nginx_version 1009013
+#define NGINX_VERSION "1.9.13"
#define NGINX_VER "nginx/" NGINX_VERSION
#ifdef NGX_BUILD
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/core/ngx_connection.c
^
|
@@ -210,6 +210,18 @@
olen = sizeof(int);
+ if (getsockopt(ls[i].fd, SOL_SOCKET, SO_TYPE, (void *) &ls[i].type,
+ &olen)
+ == -1)
+ {
+ ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
+ "getsockopt(SO_TYPE) %V failed", &ls[i].addr_text);
+ ls[i].ignore = 1;
+ continue;
+ }
+
+ olen = sizeof(int);
+
if (getsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF, (void *) &ls[i].rcvbuf,
&olen)
== -1)
@@ -274,6 +286,10 @@
#endif
+ if (ls[i].type != SOCK_STREAM) {
+ continue;
+ }
+
#if (NGX_HAVE_TCP_FASTOPEN)
olen = sizeof(int);
@@ -566,6 +582,11 @@
}
#endif
+ if (ls[i].type != SOCK_STREAM) {
+ ls[i].fd = s;
+ continue;
+ }
+
if (listen(s, ls[i].backlog) == -1) {
err = ngx_socket_errno;
@@ -865,6 +886,67 @@
#endif
#endif /* NGX_HAVE_DEFERRED_ACCEPT */
+
+#if (NGX_HAVE_IP_RECVDSTADDR)
+
+ if (ls[i].wildcard
+ && ls[i].type == SOCK_DGRAM
+ && ls[i].sockaddr->sa_family == AF_INET)
+ {
+ value = 1;
+
+ if (setsockopt(ls[i].fd, IPPROTO_IP, IP_RECVDSTADDR,
+ (const void *) &value, sizeof(int))
+ == -1)
+ {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
+ "setsockopt(IP_RECVDSTADDR) "
+ "for %V failed, ignored",
+ &ls[i].addr_text);
+ }
+ }
+
+#elif (NGX_HAVE_IP_PKTINFO)
+
+ if (ls[i].wildcard
+ && ls[i].type == SOCK_DGRAM
+ && ls[i].sockaddr->sa_family == AF_INET)
+ {
+ value = 1;
+
+ if (setsockopt(ls[i].fd, IPPROTO_IP, IP_PKTINFO,
+ (const void *) &value, sizeof(int))
+ == -1)
+ {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
+ "setsockopt(IP_PKTINFO) "
+ "for %V failed, ignored",
+ &ls[i].addr_text);
+ }
+ }
+
+#endif
+
+#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
+
+ if (ls[i].wildcard
+ && ls[i].type == SOCK_DGRAM
+ && ls[i].sockaddr->sa_family == AF_INET6)
+ {
+ value = 1;
+
+ if (setsockopt(ls[i].fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
+ (const void *) &value, sizeof(int))
+ == -1)
+ {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
+ "setsockopt(IPV6_RECVPKTINFO) "
+ "for %V failed, ignored",
+ &ls[i].addr_text);
+ }
+ }
+
+#endif
}
return;
@@ -978,7 +1060,7 @@
ngx_cycle->free_connections = c->data;
ngx_cycle->free_connection_n--;
- if (ngx_cycle->files) {
+ if (ngx_cycle->files && ngx_cycle->files[s] == NULL) {
ngx_cycle->files[s] = c;
}
@@ -1019,7 +1101,7 @@
ngx_cycle->free_connections = c;
ngx_cycle->free_connection_n++;
- if (ngx_cycle->files) {
+ if (ngx_cycle->files && ngx_cycle->files[c->fd] == c) {
ngx_cycle->files[c->fd] = NULL;
}
}
@@ -1045,16 +1127,18 @@
ngx_del_timer(c->write);
}
- if (ngx_del_conn) {
- ngx_del_conn(c, NGX_CLOSE_EVENT);
+ if (!c->shared) {
+ if (ngx_del_conn) {
+ ngx_del_conn(c, NGX_CLOSE_EVENT);
- } else {
- if (c->read->active || c->read->disabled) {
- ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
- }
+ } else {
+ if (c->read->active || c->read->disabled) {
+ ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
+ }
- if (c->write->active || c->write->disabled) {
- ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT);
+ if (c->write->active || c->write->disabled) {
+ ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT);
+ }
}
}
@@ -1078,6 +1162,10 @@
fd = c->fd;
c->fd = (ngx_socket_t) -1;
+ if (c->shared) {
+ return;
+ }
+
if (ngx_close_socket(fd) == -1) {
err = ngx_socket_errno;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/core/ngx_connection.h
^
|
@@ -64,6 +64,7 @@
unsigned nonblocking:1;
unsigned shared:1; /* shared between threads or processes */
unsigned addr_ntop:1;
+ unsigned wildcard:1;
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
unsigned ipv6only:1;
@@ -141,6 +142,8 @@
ngx_pool_t *pool;
+ int type;
+
struct sockaddr *sockaddr;
socklen_t socklen;
ngx_str_t addr_text;
@@ -174,6 +177,7 @@
unsigned idle:1;
unsigned reusable:1;
unsigned close:1;
+ unsigned shared:1;
unsigned sendfile:1;
unsigned sndlowat:1;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/core/ngx_cycle.c
^
|
@@ -512,6 +512,10 @@
continue;
}
+ if (ls[i].type != nls[n].type) {
+ continue;
+ }
+
if (ngx_cmp_sockaddr(nls[n].sockaddr, nls[n].socklen,
ls[i].sockaddr, ls[i].socklen, 1)
== NGX_OK)
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/core/ngx_file.c
^
|
@@ -124,6 +124,15 @@
}
}
+#if (NGX_THREADS && NGX_HAVE_PWRITEV)
+
+ if (tf->thread_write) {
+ return ngx_thread_write_chain_to_file(&tf->file, chain, tf->offset,
+ tf->pool);
+ }
+
+#endif
+
return ngx_write_chain_to_file(&tf->file, chain, tf->offset, tf->pool);
}
@@ -187,7 +196,7 @@
err = ngx_errno;
- if (err == NGX_EEXIST) {
+ if (err == NGX_EEXIST_FILE) {
n = (uint32_t) ngx_next_temp_number(1);
continue;
}
@@ -683,7 +692,7 @@
#if (NGX_WIN32)
- if (err == NGX_EEXIST) {
+ if (err == NGX_EEXIST || err == NGX_EEXIST_FILE) {
err = ngx_win32_rename_file(src, to, ext->log);
if (err == 0) {
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/core/ngx_file.h
^
|
@@ -27,6 +27,7 @@
ngx_int_t (*thread_handler)(ngx_thread_task_t *task,
ngx_file_t *file);
void *thread_ctx;
+ ngx_thread_task_t *thread_task;
#endif
#if (NGX_HAVE_FILE_AIO)
@@ -77,6 +78,7 @@
unsigned log_level:8;
unsigned persistent:1;
unsigned clean:1;
+ unsigned thread_write:1;
} ngx_temp_file_t;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/core/ngx_inet.c
^
|
@@ -529,14 +529,16 @@
ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u)
{
u_char *p;
+ size_t len;
p = u->url.data;
+ len = u->url.len;
- if (ngx_strncasecmp(p, (u_char *) "unix:", 5) == 0) {
+ if (len >= 5 && ngx_strncasecmp(p, (u_char *) "unix:", 5) == 0) {
return ngx_parse_unix_domain_url(pool, u);
}
- if (p[0] == '[') {
+ if (len && p[0] == '[') {
return ngx_parse_inet6_url(pool, u);
}
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/core/ngx_module.c
^
|
@@ -23,11 +23,10 @@
ngx_int_t
-ngx_preinit_modules()
+ngx_preinit_modules(void)
{
ngx_uint_t i;
- ngx_max_module = 0;
for (i = 0; ngx_modules[i]; i++) {
ngx_modules[i]->index = i;
ngx_modules[i]->name = ngx_module_names[i];
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/core/ngx_module.h
^
|
@@ -288,7 +288,7 @@
} ngx_core_module_t;
-ngx_int_t ngx_preinit_modules();
+ngx_int_t ngx_preinit_modules(void);
ngx_int_t ngx_cycle_modules(ngx_cycle_t *cycle);
ngx_int_t ngx_init_modules(ngx_cycle_t *cycle);
ngx_int_t ngx_count_modules(ngx_cycle_t *cycle, ngx_uint_t type);
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/core/ngx_output_chain.c
^
|
@@ -577,11 +577,15 @@
} else
#endif
#if (NGX_THREADS)
- if (src->file->thread_handler) {
- n = ngx_thread_read(&ctx->thread_task, src->file, dst->pos,
- (size_t) size, src->file_pos, ctx->pool);
+ if (ctx->thread_handler) {
+ src->file->thread_task = ctx->thread_task;
+ src->file->thread_handler = ctx->thread_handler;
+ src->file->thread_ctx = ctx->filter_ctx;
+
+ n = ngx_thread_read(src->file, dst->pos, (size_t) size,
+ src->file_pos, ctx->pool);
if (n == NGX_AGAIN) {
- ctx->aio = 1;
+ ctx->thread_task = src->file->thread_task;
return NGX_AGAIN;
}
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/core/ngx_palloc.c
^
|
@@ -9,6 +9,8 @@
#include <ngx_core.h>
+static ngx_inline void *ngx_palloc_small(ngx_pool_t *pool, size_t size,
+ ngx_uint_t align);
static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);
@@ -56,15 +58,6 @@
}
}
- for (l = pool->large; l; l = l->next) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
-
- if (l->alloc) {
- ngx_free(l->alloc);
- }
- }
-
#if (NGX_DEBUG)
/*
@@ -72,6 +65,10 @@
* so we cannot use this log while free()ing the pool
*/
+ for (l = pool->large; l; l = l->next) {
+ ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
+ }
+
for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
"free: %p, unused: %uz", p, p->d.end - p->d.last);
@@ -83,6 +80,12 @@
#endif
+ for (l = pool->large; l; l = l->next) {
+ if (l->alloc) {
+ ngx_free(l->alloc);
+ }
+ }
+
for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
ngx_free(p);
@@ -119,60 +122,55 @@
void *
ngx_palloc(ngx_pool_t *pool, size_t size)
{
- u_char *m;
- ngx_pool_t *p;
-
+#if !(NGX_DEBUG_PALLOC)
if (size <= pool->max) {
+ return ngx_palloc_small(pool, size, 1);
+ }
+#endif
- p = pool->current;
-
- do {
- m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);
-
- if ((size_t) (p->d.end - m) >= size) {
- p->d.last = m + size;
-
- return m;
- }
-
- p = p->d.next;
+ return ngx_palloc_large(pool, size);
+}
- } while (p);
- return ngx_palloc_block(pool, size);
+void *
+ngx_pnalloc(ngx_pool_t *pool, size_t size)
+{
+#if !(NGX_DEBUG_PALLOC)
+ if (size <= pool->max) {
+ return ngx_palloc_small(pool, size, 0);
}
+#endif
return ngx_palloc_large(pool, size);
}
-void *
-ngx_pnalloc(ngx_pool_t *pool, size_t size)
+static ngx_inline void *
+ngx_palloc_small(ngx_pool_t *pool, size_t size, ngx_uint_t align)
{
u_char *m;
ngx_pool_t *p;
- if (size <= pool->max) {
-
- p = pool->current;
+ p = pool->current;
- do {
- m = p->d.last;
+ do {
+ m = p->d.last;
- if ((size_t) (p->d.end - m) >= size) {
- p->d.last = m + size;
+ if (align) {
+ m = ngx_align_ptr(m, NGX_ALIGNMENT);
+ }
- return m;
- }
+ if ((size_t) (p->d.end - m) >= size) {
+ p->d.last = m + size;
- p = p->d.next;
+ return m;
+ }
- } while (p);
+ p = p->d.next;
- return ngx_palloc_block(pool, size);
- }
+ } while (p);
- return ngx_palloc_large(pool, size);
+ return ngx_palloc_block(pool, size);
}
@@ -237,7 +235,7 @@
}
}
- large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
+ large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1);
if (large == NULL) {
ngx_free(p);
return NULL;
@@ -262,7 +260,7 @@
return NULL;
}
- large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
+ large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1);
if (large == NULL) {
ngx_free(p);
return NULL;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/core/ngx_resolver.c
^
|
@@ -74,8 +74,10 @@
ngx_resolver_connection_t *rec, u_char *query, u_short qlen);
static ngx_int_t ngx_resolver_create_name_query(ngx_resolver_t *r,
ngx_resolver_node_t *rn, ngx_str_t *name);
+static ngx_int_t ngx_resolver_create_srv_query(ngx_resolver_t *r,
+ ngx_resolver_node_t *rn, ngx_str_t *name);
static ngx_int_t ngx_resolver_create_addr_query(ngx_resolver_t *r,
- ngx_resolver_node_t *rn, ngx_addr_t *addr);
+ ngx_resolver_node_t *rn, ngx_resolver_addr_t *addr);
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);
@@ -88,10 +90,15 @@
static void ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t n,
ngx_uint_t ident, ngx_uint_t code, ngx_uint_t qtype,
ngx_uint_t nan, ngx_uint_t trunc, ngx_uint_t ans);
+static void ngx_resolver_process_srv(ngx_resolver_t *r, u_char *buf, size_t n,
+ ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan,
+ ngx_uint_t trunc, ngx_uint_t ans);
static void ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan);
static ngx_resolver_node_t *ngx_resolver_lookup_name(ngx_resolver_t *r,
ngx_str_t *name, uint32_t hash);
+static ngx_resolver_node_t *ngx_resolver_lookup_srv(ngx_resolver_t *r,
+ ngx_str_t *name, uint32_t hash);
static ngx_resolver_node_t *ngx_resolver_lookup_addr(ngx_resolver_t *r,
in_addr_t addr);
static void ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t *temp,
@@ -105,9 +112,14 @@
static void ngx_resolver_free(ngx_resolver_t *r, void *p);
static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p);
static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size);
-static ngx_addr_t *ngx_resolver_export(ngx_resolver_t *r,
+static ngx_resolver_addr_t *ngx_resolver_export(ngx_resolver_t *r,
ngx_resolver_node_t *rn, ngx_uint_t rotate);
+static void ngx_resolver_report_srv(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx);
static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len);
+static void ngx_resolver_resolve_srv_names(ngx_resolver_ctx_t *ctx,
+ ngx_resolver_node_t *rn);
+static void ngx_resolver_srv_names_handler(ngx_resolver_ctx_t *ctx);
+static ngx_int_t ngx_resolver_cmp_srvs(const void *one, const void *two);
#if (NGX_HAVE_INET6)
static void ngx_resolver_rbtree_insert_addr6_value(ngx_rbtree_node_t *temp,
@@ -149,13 +161,18 @@
ngx_rbtree_init(&r->name_rbtree, &r->name_sentinel,
ngx_resolver_rbtree_insert_value);
+ ngx_rbtree_init(&r->srv_rbtree, &r->srv_sentinel,
+ ngx_resolver_rbtree_insert_value);
+
ngx_rbtree_init(&r->addr_rbtree, &r->addr_sentinel,
ngx_rbtree_insert_value);
ngx_queue_init(&r->name_resend_queue);
+ ngx_queue_init(&r->srv_resend_queue);
ngx_queue_init(&r->addr_resend_queue);
ngx_queue_init(&r->name_expire_queue);
+ ngx_queue_init(&r->srv_expire_queue);
ngx_queue_init(&r->addr_expire_queue);
#if (NGX_HAVE_INET6)
@@ -274,6 +291,8 @@
ngx_resolver_cleanup_tree(r, &r->name_rbtree);
+ ngx_resolver_cleanup_tree(r, &r->srv_rbtree);
+
ngx_resolver_cleanup_tree(r, &r->addr_rbtree);
#if (NGX_HAVE_INET6)
@@ -383,7 +402,9 @@
ngx_int_t
ngx_resolve_name(ngx_resolver_ctx_t *ctx)
{
+ size_t slen;
ngx_int_t rc;
+ ngx_str_t name;
ngx_resolver_t *r;
r = ctx->resolver;
@@ -400,9 +421,41 @@
return NGX_OK;
}
- /* lock name mutex */
+ if (ctx->service.len) {
+ slen = ctx->service.len;
+
+ if (ngx_strlchr(ctx->service.data,
+ ctx->service.data + ctx->service.len, '.')
+ == NULL)
+ {
+ slen += sizeof("_._tcp") - 1;
+ }
+
+ name.len = slen + 1 + ctx->name.len;
+
+ name.data = ngx_resolver_alloc(r, name.len);
+ if (name.data == NULL) {
+ return NGX_ERROR;
+ }
+
+ if (slen == ctx->service.len) {
+ ngx_sprintf(name.data, "%V.%V", &ctx->service, &ctx->name);
+
+ } else {
+ ngx_sprintf(name.data, "_%V._tcp.%V", &ctx->service, &ctx->name);
+ }
+
+ /* lock name mutex */
+
+ rc = ngx_resolve_name_locked(r, ctx, &name);
+
+ ngx_resolver_free(r, name.data);
+
+ } else {
+ /* lock name mutex */
- rc = ngx_resolve_name_locked(r, ctx, &ctx->name);
+ rc = ngx_resolve_name_locked(r, ctx, &ctx->name);
+ }
if (rc == NGX_OK) {
return NGX_OK;
@@ -429,6 +482,7 @@
void
ngx_resolve_name_done(ngx_resolver_ctx_t *ctx)
{
+ ngx_uint_t i;
ngx_resolver_t *r;
ngx_resolver_ctx_t *w, **p;
ngx_resolver_node_t *rn;
@@ -448,6 +502,23 @@
/* lock name mutex */
+ if (ctx->nsrvs) {
+ for (i = 0; i < ctx->nsrvs; i++) {
+ if (ctx->srvs[i].ctx) {
+ ngx_resolve_name_done(ctx->srvs[i].ctx);
+ }
+
+ if (ctx->srvs[i].addrs) {
+ ngx_resolver_free(r, ctx->srvs[i].addrs->sockaddr);
+ ngx_resolver_free(r, ctx->srvs[i].addrs);
+ }
+
+ ngx_resolver_free(r, ctx->srvs[i].name.data);
+ }
+
+ ngx_resolver_free(r, ctx->srvs);
+ }
+
if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
rn = ctx->node;
@@ -466,15 +537,20 @@
p = &w->next;
w = w->next;
}
- }
- ngx_log_error(NGX_LOG_ALERT, r->log, 0,
- "could not cancel %V resolving", &ctx->name);
+ ngx_log_error(NGX_LOG_ALERT, r->log, 0,
+ "could not cancel %V resolving", &ctx->name);
+ }
}
done:
- ngx_resolver_expire(r, &r->name_rbtree, &r->name_expire_queue);
+ if (ctx->service.len) {
+ ngx_resolver_expire(r, &r->srv_rbtree, &r->srv_expire_queue);
+
+ } else {
+ ngx_resolver_expire(r, &r->name_rbtree, &r->name_expire_queue);
+ }
/* unlock name mutex */
@@ -501,16 +577,31 @@
uint32_t hash;
ngx_int_t rc;
ngx_str_t cname;
- ngx_uint_t naddrs;
- ngx_addr_t *addrs;
+ ngx_uint_t i, naddrs;
+ ngx_queue_t *resend_queue, *expire_queue;
+ ngx_rbtree_t *tree;
ngx_resolver_ctx_t *next, *last;
+ ngx_resolver_addr_t *addrs;
ngx_resolver_node_t *rn;
ngx_strlow(name->data, name->data, name->len);
hash = ngx_crc32_short(name->data, name->len);
- rn = ngx_resolver_lookup_name(r, name, hash);
+ if (ctx->service.len) {
+ rn = ngx_resolver_lookup_srv(r, name, hash);
+
+ tree = &r->srv_rbtree;
+ resend_queue = &r->srv_resend_queue;
+ expire_queue = &r->srv_expire_queue;
+
+ } else {
+ rn = ngx_resolver_lookup_name(r, name, hash);
+
+ tree = &r->name_rbtree;
+ resend_queue = &r->name_resend_queue;
+ expire_queue = &r->name_expire_queue;
+ }
if (rn) {
@@ -525,7 +616,7 @@
rn->expire = ngx_time() + r->expire;
- ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
+ ngx_queue_insert_head(expire_queue, &rn->queue);
naddrs = (rn->naddrs == (u_short) -1) ? 0 : rn->naddrs;
#if (NGX_HAVE_INET6)
@@ -551,6 +642,7 @@
do {
ctx->state = NGX_OK;
+ ctx->valid = rn->valid;
ctx->naddrs = naddrs;
if (addrs == NULL) {
@@ -580,6 +672,23 @@
return NGX_OK;
}
+ if (rn->nsrvs) {
+ last->next = rn->waiting;
+ rn->waiting = NULL;
+
+ /* unlock name mutex */
+
+ do {
+ next = ctx->next;
+
+ ngx_resolver_resolve_srv_names(ctx, rn);
+
+ ctx = next;
+ } while (ctx);
+
+ return NGX_OK;
+ }
+
/* NGX_RESOLVE_CNAME */
if (ctx->recursion++ < NGX_RESOLVER_MAX_RECURSION) {
@@ -597,6 +706,7 @@
do {
ctx->state = NGX_RESOLVE_NXDOMAIN;
+ ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
next = ctx->next;
ctx->handler(ctx);
@@ -609,7 +719,7 @@
if (rn->waiting) {
- if (ctx->event == NULL) {
+ if (ctx->event == NULL && ctx->timeout) {
ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
if (ctx->event == NULL) {
return NGX_ERROR;
@@ -661,6 +771,16 @@
}
#endif
+ if (rn->nsrvs) {
+ for (i = 0; i < rn->nsrvs; i++) {
+ if (rn->u.srvs[i].name.data) {
+ ngx_resolver_free_locked(r, rn->u.srvs[i].name.data);
+ }
+ }
+
+ ngx_resolver_free_locked(r, rn->u.srvs);
+ }
+
/* unlock alloc mutex */
} else {
@@ -683,17 +803,22 @@
rn->query6 = NULL;
#endif
- ngx_rbtree_insert(&r->name_rbtree, &rn->node);
+ ngx_rbtree_insert(tree, &rn->node);
}
- rc = ngx_resolver_create_name_query(r, rn, name);
+ if (ctx->service.len) {
+ rc = ngx_resolver_create_srv_query(r, rn, name);
+
+ } else {
+ rc = ngx_resolver_create_name_query(r, rn, name);
+ }
if (rc == NGX_ERROR) {
goto failed;
}
if (rc == NGX_DECLINED) {
- ngx_rbtree_delete(&r->name_rbtree, &rn->node);
+ ngx_rbtree_delete(tree, &rn->node);
ngx_resolver_free(r, rn->query);
ngx_resolver_free(r, rn->name);
@@ -722,12 +847,13 @@
rn->naddrs6 = r->ipv6 ? (u_short) -1 : 0;
rn->tcp6 = 0;
#endif
+ rn->nsrvs = 0;
if (ngx_resolver_send_query(r, rn) != NGX_OK) {
goto failed;
}
- if (ctx->event == NULL) {
+ if (ctx->event == NULL && ctx->timeout) {
ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
if (ctx->event == NULL) {
goto failed;
@@ -741,13 +867,13 @@
ngx_add_timer(ctx->event, ctx->timeout);
}
- if (ngx_queue_empty(&r->name_resend_queue)) {
+ if (ngx_queue_empty(resend_queue)) {
ngx_add_timer(r->event, (ngx_msec_t) (r->resend_timeout * 1000));
}
rn->expire = ngx_time() + r->resend_timeout;
- ngx_queue_insert_head(&r->name_resend_queue, &rn->queue);
+ ngx_queue_insert_head(resend_queue, &rn->queue);
rn->code = 0;
rn->cnlen = 0;
@@ -766,7 +892,7 @@
failed:
- ngx_rbtree_delete(&r->name_rbtree, &rn->node);
+ ngx_rbtree_delete(tree, &rn->node);
if (rn->query) {
ngx_resolver_free(r, rn->query);
@@ -859,6 +985,7 @@
/* unlock addr mutex */
ctx->state = NGX_OK;
+ ctx->valid = rn->valid;
ctx->handler(ctx);
@@ -869,17 +996,19 @@
if (rn->waiting) {
- ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
- if (ctx->event == NULL) {
- return NGX_ERROR;
- }
+ if (ctx->event == NULL && ctx->timeout) {
+ ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
+ if (ctx->event == NULL) {
+ return NGX_ERROR;
+ }
- ctx->event->handler = ngx_resolver_timeout_handler;
- ctx->event->data = ctx;
- ctx->event->log = r->log;
- ctx->ident = -1;
+ ctx->event->handler = ngx_resolver_timeout_handler;
+ ctx->event->data = ctx;
+ ctx->event->log = r->log;
+ ctx->ident = -1;
- ngx_add_timer(ctx->event, ctx->timeout);
+ ngx_add_timer(ctx->event, ctx->timeout);
+ }
ctx->next = rn->waiting;
rn->waiting = ctx;
@@ -941,22 +1070,25 @@
rn->naddrs6 = (u_short) -1;
rn->tcp6 = 0;
#endif
+ rn->nsrvs = 0;
if (ngx_resolver_send_query(r, rn) != NGX_OK) {
goto failed;
}
- ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
- if (ctx->event == NULL) {
- goto failed;
- }
+ if (ctx->event == NULL && ctx->timeout) {
+ ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
+ if (ctx->event == NULL) {
+ goto failed;
+ }
- ctx->event->handler = ngx_resolver_timeout_handler;
- ctx->event->data = ctx;
- ctx->event->log = r->log;
- ctx->ident = -1;
+ ctx->event->handler = ngx_resolver_timeout_handler;
+ ctx->event->data = ctx;
+ ctx->event->log = r->log;
+ ctx->ident = -1;
- ngx_add_timer(ctx->event, ctx->timeout);
+ ngx_add_timer(ctx->event, ctx->timeout);
+ }
if (ngx_queue_empty(resend_queue)) {
ngx_add_timer(r->event, (ngx_msec_t) (r->resend_timeout * 1000));
@@ -1294,7 +1426,7 @@
static void
ngx_resolver_resend_handler(ngx_event_t *ev)
{
- time_t timer, atimer, ntimer;
+ time_t timer, atimer, stimer, ntimer;
#if (NGX_HAVE_INET6)
time_t a6timer;
#endif
@@ -1309,6 +1441,8 @@
ntimer = ngx_resolver_resend(r, &r->name_rbtree, &r->name_resend_queue);
+ stimer = ngx_resolver_resend(r, &r->srv_rbtree, &r->srv_resend_queue);
+
/* unlock name mutex */
/* lock addr mutex */
@@ -1336,6 +1470,13 @@
timer = ngx_min(timer, atimer);
}
+ if (timer == 0) {
+ timer = stimer;
+
+ } else if (stimer) {
+ timer = ngx_min(timer, stimer);
+ }
+
#if (NGX_HAVE_INET6)
if (timer == 0) {
@@ -1696,6 +1837,13 @@
break;
+ case NGX_RESOLVE_SRV:
+
+ ngx_resolver_process_srv(r, buf, n, ident, code, nan, trunc,
+ i + sizeof(ngx_resolver_qs_t));
+
+ break;
+
case NGX_RESOLVE_PTR:
ngx_resolver_process_ptr(r, buf, n, ident, code, nan);
@@ -1749,7 +1897,6 @@
uint32_t hash;
in_addr_t *addr;
ngx_str_t name;
- ngx_addr_t *addrs;
ngx_uint_t type, class, qident, naddrs, a, i, j, start;
#if (NGX_HAVE_INET6)
struct in6_addr *addr6;
@@ -1757,6 +1904,7 @@
ngx_resolver_an_t *an;
ngx_resolver_ctx_t *ctx, *next;
ngx_resolver_node_t *rn;
+ ngx_resolver_addr_t *addrs;
ngx_resolver_connection_t *rec;
if (ngx_resolver_copy(r, &name, buf,
@@ -1948,6 +2096,7 @@
while (next) {
ctx = next;
ctx->state = code;
+ ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
next = ctx->next;
ctx->handler(ctx);
@@ -2262,6 +2411,7 @@
while (next) {
ctx = next;
ctx->state = NGX_OK;
+ ctx->valid = rn->valid;
ctx->naddrs = naddrs;
if (addrs == NULL) {
@@ -2391,26 +2541,22 @@
static void
-ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
- ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan)
+ngx_resolver_process_srv(ngx_resolver_t *r, u_char *buf, size_t n,
+ ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan,
+ ngx_uint_t trunc, ngx_uint_t ans)
{
- char *err;
- size_t len;
- in_addr_t addr;
- int32_t ttl;
- ngx_int_t octet;
- ngx_str_t name;
- ngx_uint_t mask, type, class, qident, a, i, start;
- ngx_queue_t *expire_queue;
- ngx_rbtree_t *tree;
- ngx_resolver_an_t *an;
- ngx_resolver_ctx_t *ctx, *next;
- ngx_resolver_node_t *rn;
-#if (NGX_HAVE_INET6)
- uint32_t hash;
- ngx_int_t digit;
- struct in6_addr addr6;
-#endif
+ char *err;
+ u_char *cname;
+ size_t len;
+ int32_t ttl;
+ uint32_t hash;
+ ngx_str_t name;
+ ngx_uint_t type, qident, class, start, nsrvs, a, i, j;
+ ngx_resolver_an_t *an;
+ ngx_resolver_ctx_t *ctx, *next;
+ ngx_resolver_srv_t *srvs;
+ ngx_resolver_node_t *rn;
+ ngx_resolver_connection_t *rec;
if (ngx_resolver_copy(r, &name, buf,
buf + sizeof(ngx_resolver_hdr_t), buf + n)
@@ -2421,109 +2567,62 @@
ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver qs:%V", &name);
- /* AF_INET */
-
- addr = 0;
- i = sizeof(ngx_resolver_hdr_t);
-
- for (mask = 0; mask < 32; mask += 8) {
- len = buf[i++];
+ hash = ngx_crc32_short(name.data, name.len);
- octet = ngx_atoi(&buf[i], len);
- if (octet == NGX_ERROR || octet > 255) {
- goto invalid_in_addr_arpa;
- }
+ rn = ngx_resolver_lookup_srv(r, &name, hash);
- addr += octet << mask;
- i += len;
+ if (rn == NULL || rn->query == NULL) {
+ ngx_log_error(r->log_level, r->log, 0,
+ "unexpected response for %V", &name);
+ ngx_resolver_free(r, name.data);
+ goto failed;
}
- if (ngx_strcasecmp(&buf[i], (u_char *) "\7in-addr\4arpa") == 0) {
- i += sizeof("\7in-addr\4arpa");
-
- /* lock addr mutex */
-
- rn = ngx_resolver_lookup_addr(r, addr);
-
- tree = &r->addr_rbtree;
- expire_queue = &r->addr_expire_queue;
-
- goto valid;
+ if (trunc && rn->tcp) {
+ ngx_resolver_free(r, name.data);
+ goto failed;
}
-invalid_in_addr_arpa:
-
-#if (NGX_HAVE_INET6)
-
- i = sizeof(ngx_resolver_hdr_t);
+ qident = (rn->query[0] << 8) + rn->query[1];
- for (octet = 15; octet >= 0; octet--) {
- if (buf[i++] != '\1') {
- goto invalid_ip6_arpa;
- }
+ if (ident != qident) {
+ ngx_log_error(r->log_level, r->log, 0,
+ "wrong ident %ui response for %V, expect %ui",
+ ident, &name, qident);
+ ngx_resolver_free(r, name.data);
+ goto failed;
+ }
- digit = ngx_hextoi(&buf[i++], 1);
- if (digit == NGX_ERROR) {
- goto invalid_ip6_arpa;
- }
+ ngx_resolver_free(r, name.data);
- addr6.s6_addr[octet] = (u_char) digit;
+ if (trunc) {
- if (buf[i++] != '\1') {
- goto invalid_ip6_arpa;
- }
+ ngx_queue_remove(&rn->queue);
- digit = ngx_hextoi(&buf[i++], 1);
- if (digit == NGX_ERROR) {
- goto invalid_ip6_arpa;
+ if (rn->waiting == NULL) {
+ ngx_rbtree_delete(&r->srv_rbtree, &rn->node);
+ ngx_resolver_free_node(r, rn);
+ return;
}
- addr6.s6_addr[octet] += (u_char) (digit * 16);
- }
-
- if (ngx_strcasecmp(&buf[i], (u_char *) "\3ip6\4arpa") == 0) {
- i += sizeof("\3ip6\4arpa");
-
- /* lock addr mutex */
-
- hash = ngx_crc32_short(addr6.s6_addr, 16);
- rn = ngx_resolver_lookup_addr6(r, &addr6, hash);
-
- tree = &r->addr6_rbtree;
- expire_queue = &r->addr6_expire_queue;
+ rec = r->connections.elts;
+ rec = &rec[rn->last_connection];
- goto valid;
- }
+ rn->tcp = 1;
-invalid_ip6_arpa:
-#endif
+ (void) ngx_resolver_send_tcp_query(r, rec, rn->query, rn->qlen);
- ngx_log_error(r->log_level, r->log, 0,
- "invalid in-addr.arpa or ip6.arpa name in DNS response");
- ngx_resolver_free(r, name.data);
- return;
+ rn->expire = ngx_time() + r->resend_timeout;
-valid:
+ ngx_queue_insert_head(&r->srv_resend_queue, &rn->queue);
- if (rn == NULL || rn->query == NULL) {
- ngx_log_error(r->log_level, r->log, 0,
- "unexpected response for %V", &name);
- ngx_resolver_free(r, name.data);
- goto failed;
+ return;
}
- qident = (rn->query[0] << 8) + rn->query[1];
-
- if (ident != qident) {
- ngx_log_error(r->log_level, r->log, 0,
- "wrong ident %ui response for %V, expect %ui",
- ident, &name, qident);
- ngx_resolver_free(r, name.data);
- goto failed;
+ if (code == 0 && rn->code) {
+ code = rn->code;
}
- ngx_resolver_free(r, name.data);
-
if (code == 0 && nan == 0) {
code = NGX_RESOLVE_NXDOMAIN;
}
@@ -2534,13 +2633,12 @@
ngx_queue_remove(&rn->queue);
- ngx_rbtree_delete(tree, &rn->node);
-
- /* unlock addr mutex */
+ ngx_rbtree_delete(&r->srv_rbtree, &rn->node);
while (next) {
ctx = next;
ctx->state = code;
+ ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
next = ctx->next;
ctx->handler(ctx);
@@ -2551,7 +2649,9 @@
return;
}
- i += sizeof(ngx_resolver_qs_t);
+ i = ans;
+ nsrvs = 0;
+ cname = NULL;
for (a = 0; a < nan; a++) {
@@ -2577,7 +2677,7 @@
test_length:
if (i - start < 2) {
- err = "invalid name in DNS response";
+ err = "invalid name DNS response";
goto invalid;
}
@@ -2605,8 +2705,589 @@
ttl = 0;
}
- ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolver qt:%ui cl:%ui len:%uz",
+ rn->ttl = ngx_min(rn->ttl, (uint32_t) ttl);
+
+ i += sizeof(ngx_resolver_an_t);
+
+ switch (type) {
+
+ case NGX_RESOLVE_SRV:
+
+ if (i + 6 > n) {
+ goto short_response;
+ }
+
+ if (ngx_resolver_copy(r, NULL, buf, &buf[i + 6], buf + n)
+ != NGX_OK)
+ {
+ goto failed;
+ }
+
+ nsrvs++;
+
+ break;
+
+ case NGX_RESOLVE_CNAME:
+
+ cname = &buf[i];
+
+ break;
+
+ case NGX_RESOLVE_DNAME:
+
+ break;
+
+ default:
+
+ ngx_log_error(r->log_level, r->log, 0,
+ "unexpected RR type %ui", type);
+ }
+
+ i += len;
+ }
+
+ ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
+ "resolver nsrvs:%ui cname:%p ttl:%uD",
+ nsrvs, cname, rn->ttl);
+
+ if (nsrvs) {
+
+ srvs = ngx_resolver_calloc(r, nsrvs * sizeof(ngx_resolver_srv_t));
+ if (srvs == NULL) {
+ goto failed;
+ }
+
+ rn->u.srvs = srvs;
+ rn->nsrvs = (u_short) nsrvs;
+
+ j = 0;
+ i = ans;
+
+ for (a = 0; a < nan; a++) {
+
+ for ( ;; ) {
+
+ if (buf[i] & 0xc0) {
+ i += 2;
+ break;
+ }
+
+ if (buf[i] == 0) {
+ i++;
+ break;
+ }
+
+ i += 1 + buf[i];
+ }
+
+ an = (ngx_resolver_an_t *) &buf[i];
+
+ type = (an->type_hi << 8) + an->type_lo;
+ len = (an->len_hi << 8) + an->len_lo;
+
+ i += sizeof(ngx_resolver_an_t);
+
+ if (type == NGX_RESOLVE_SRV) {
+
+ srvs[j].priority = (buf[i] << 8) + buf[i + 1];
+ srvs[j].weight = (buf[i + 2] << 8) + buf[i + 3];
+
+ if (srvs[j].weight == 0) {
+ srvs[j].weight = 1;
+ }
+
+ srvs[j].port = (buf[i + 4] << 8) + buf[i + 5];
+
+ if (ngx_resolver_copy(r, &srvs[j].name, buf, &buf[i + 6],
+ buf + n)
+ != NGX_OK)
+ {
+ goto failed;
+ }
+
+ j++;
+ }
+
+ i += len;
+ }
+
+ ngx_sort(srvs, nsrvs, sizeof(ngx_resolver_srv_t),
+ ngx_resolver_cmp_srvs);
+
+ ngx_resolver_free(r, rn->query);
+ rn->query = NULL;
+
+ ngx_queue_remove(&rn->queue);
+
+ rn->valid = ngx_time() + (r->valid ? r->valid : (time_t) rn->ttl);
+ rn->expire = ngx_time() + r->expire;
+
+ ngx_queue_insert_head(&r->srv_expire_queue, &rn->queue);
+
+ next = rn->waiting;
+ rn->waiting = NULL;
+
+ while (next) {
+ ctx = next;
+ next = ctx->next;
+
+ ngx_resolver_resolve_srv_names(ctx, rn);
+ }
+
+ return;
+ }
+
+ rn->nsrvs = 0;
+
+ if (cname) {
+
+ /* CNAME only */
+
+ if (ngx_resolver_copy(r, &name, buf, cname, buf + n) != NGX_OK) {
+ goto failed;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0,
+ "resolver cname:\"%V\"", &name);
+
+ ngx_queue_remove(&rn->queue);
+
+ rn->cnlen = (u_short) name.len;
+ rn->u.cname = name.data;
+
+ rn->valid = ngx_time() + (r->valid ? r->valid : (time_t) rn->ttl);
+ rn->expire = ngx_time() + r->expire;
+
+ ngx_queue_insert_head(&r->srv_expire_queue, &rn->queue);
+
+ ngx_resolver_free(r, rn->query);
+ rn->query = NULL;
+#if (NGX_HAVE_INET6)
+ rn->query6 = NULL;
+#endif
+
+ ctx = rn->waiting;
+ rn->waiting = NULL;
+
+ if (ctx) {
+
+ if (ctx->recursion++ >= NGX_RESOLVER_MAX_RECURSION) {
+
+ /* unlock name mutex */
+
+ do {
+ ctx->state = NGX_RESOLVE_NXDOMAIN;
+ next = ctx->next;
+
+ ctx->handler(ctx);
+
+ ctx = next;
+ } while (ctx);
+
+ return;
+ }
+
+ for (next = ctx; next; next = next->next) {
+ next->node = NULL;
+ }
+
+ (void) ngx_resolve_name_locked(r, ctx, &name);
+ }
+
+ /* unlock name mutex */
+
+ return;
+ }
+
+ ngx_log_error(r->log_level, r->log, 0, "no SRV type in DNS response");
+
+ return;
+
+short_response:
+
+ err = "short DNS response";
+
+invalid:
+
+ /* unlock name mutex */
+
+ ngx_log_error(r->log_level, r->log, 0, err);
+
+ return;
+
+failed:
+
+ /* unlock name mutex */
+
+ return;
+}
+
+
+static void
+ngx_resolver_resolve_srv_names(ngx_resolver_ctx_t *ctx, ngx_resolver_node_t *rn)
+{
+ ngx_uint_t i;
+ ngx_resolver_t *r;
+ ngx_resolver_ctx_t *cctx;
+ ngx_resolver_srv_name_t *srvs;
+
+ r = ctx->resolver;
+
+ ctx->node = NULL;
+ ctx->state = NGX_OK;
+ ctx->valid = rn->valid;
+ ctx->count = rn->nsrvs;
+
+ srvs = ngx_resolver_calloc(r, rn->nsrvs * sizeof(ngx_resolver_srv_name_t));
+ if (srvs == NULL) {
+ goto failed;
+ }
+
+ ctx->srvs = srvs;
+ ctx->nsrvs = rn->nsrvs;
+
+ for (i = 0; i < rn->nsrvs; i++) {
+ srvs[i].name.data = ngx_resolver_alloc(r, rn->u.srvs[i].name.len);
+ if (srvs[i].name.data == NULL) {
+ goto failed;
+ }
+
+ srvs[i].name.len = rn->u.srvs[i].name.len;
+ ngx_memcpy(srvs[i].name.data, rn->u.srvs[i].name.data,
+ srvs[i].name.len);
+
+ cctx = ngx_resolve_start(r, NULL);
+ if (cctx == NULL) {
+ goto failed;
+ }
+
+ cctx->name = srvs[i].name;
+ cctx->handler = ngx_resolver_srv_names_handler;
+ cctx->data = ctx;
+ cctx->srvs = &srvs[i];
+ cctx->timeout = 0;
+
+ srvs[i].priority = rn->u.srvs[i].priority;
+ srvs[i].weight = rn->u.srvs[i].weight;
+ srvs[i].port = rn->u.srvs[i].port;
+ srvs[i].ctx = cctx;
+
+ if (ngx_resolve_name(cctx) == NGX_ERROR) {
+ srvs[i].ctx = NULL;
+ goto failed;
+ }
+ }
+
+ return;
+
+failed:
+
+ ctx->state = NGX_ERROR;
+ ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
+
+ ctx->handler(ctx);
+}
+
+
+static void
+ngx_resolver_srv_names_handler(ngx_resolver_ctx_t *cctx)
+{
+ ngx_uint_t i;
+ u_char (*sockaddr)[NGX_SOCKADDRLEN];
+ ngx_addr_t *addrs;
+ ngx_resolver_t *r;
+ struct sockaddr_in *sin;
+ ngx_resolver_ctx_t *ctx;
+ ngx_resolver_srv_name_t *srv;
+#if (NGX_HAVE_INET6)
+ struct sockaddr_in6 *sin6;
+#endif
+
+ r = cctx->resolver;
+ ctx = cctx->data;
+ srv = cctx->srvs;
+
+ ctx->count--;
+
+ srv->ctx = NULL;
+
+ if (cctx->naddrs) {
+
+ ctx->valid = ngx_min(ctx->valid, cctx->valid);
+
+ addrs = ngx_resolver_calloc(r, cctx->naddrs * sizeof(ngx_addr_t));
+ if (addrs == NULL) {
+ ngx_resolve_name_done(cctx);
+
+ ctx->state = NGX_ERROR;
+ ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
+
+ ctx->handler(ctx);
+ return;
+ }
+
+ sockaddr = ngx_resolver_alloc(r, cctx->naddrs * NGX_SOCKADDRLEN);
+ if (sockaddr == NULL) {
+ ngx_resolver_free(r, addrs);
+ ngx_resolve_name_done(cctx);
+
+ ctx->state = NGX_ERROR;
+ ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
+
+ ctx->handler(ctx);
+ return;
+ }
+
+ for (i = 0; i < cctx->naddrs; i++) {
+ addrs[i].sockaddr = (struct sockaddr *) sockaddr[i];
+ addrs[i].socklen = cctx->addrs[i].socklen;
+
+ ngx_memcpy(sockaddr[i], cctx->addrs[i].sockaddr,
+ addrs[i].socklen);
+
+ switch (addrs[i].sockaddr->sa_family) {
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *) addrs[i].sockaddr;
+ sin6->sin6_port = htons(srv->port);
+ break;
+#endif
+ default: /* AF_INET */
+ sin = (struct sockaddr_in *) addrs[i].sockaddr;
+ sin->sin_port = htons(srv->port);
+ }
+ }
+
+ srv->addrs = addrs;
+ srv->naddrs = cctx->naddrs;
+ }
+
+ ngx_resolve_name_done(cctx);
+
+ if (ctx->count == 0) {
+ ngx_resolver_report_srv(r, ctx);
+ }
+}
+
+
+static void
+ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
+ ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan)
+{
+ char *err;
+ size_t len;
+ in_addr_t addr;
+ int32_t ttl;
+ ngx_int_t octet;
+ ngx_str_t name;
+ ngx_uint_t mask, type, class, qident, a, i, start;
+ ngx_queue_t *expire_queue;
+ ngx_rbtree_t *tree;
+ ngx_resolver_an_t *an;
+ ngx_resolver_ctx_t *ctx, *next;
+ ngx_resolver_node_t *rn;
+#if (NGX_HAVE_INET6)
+ uint32_t hash;
+ ngx_int_t digit;
+ struct in6_addr addr6;
+#endif
+
+ if (ngx_resolver_copy(r, &name, buf,
+ buf + sizeof(ngx_resolver_hdr_t), buf + n)
+ != NGX_OK)
+ {
+ return;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver qs:%V", &name);
+
+ /* AF_INET */
+
+ addr = 0;
+ i = sizeof(ngx_resolver_hdr_t);
+
+ for (mask = 0; mask < 32; mask += 8) {
+ len = buf[i++];
+
+ octet = ngx_atoi(&buf[i], len);
+ if (octet == NGX_ERROR || octet > 255) {
+ goto invalid_in_addr_arpa;
+ }
+
+ addr += octet << mask;
+ i += len;
+ }
+
+ if (ngx_strcasecmp(&buf[i], (u_char *) "\7in-addr\4arpa") == 0) {
+ i += sizeof("\7in-addr\4arpa");
+
+ /* lock addr mutex */
+
+ rn = ngx_resolver_lookup_addr(r, addr);
+
+ tree = &r->addr_rbtree;
+ expire_queue = &r->addr_expire_queue;
+
+ goto valid;
+ }
+
+invalid_in_addr_arpa:
+
+#if (NGX_HAVE_INET6)
+
+ i = sizeof(ngx_resolver_hdr_t);
+
+ for (octet = 15; octet >= 0; octet--) {
+ if (buf[i++] != '\1') {
+ goto invalid_ip6_arpa;
+ }
+
+ digit = ngx_hextoi(&buf[i++], 1);
+ if (digit == NGX_ERROR) {
+ goto invalid_ip6_arpa;
+ }
+
+ addr6.s6_addr[octet] = (u_char) digit;
+
+ if (buf[i++] != '\1') {
+ goto invalid_ip6_arpa;
+ }
+
+ digit = ngx_hextoi(&buf[i++], 1);
+ if (digit == NGX_ERROR) {
+ goto invalid_ip6_arpa;
+ }
+
+ addr6.s6_addr[octet] += (u_char) (digit * 16);
+ }
+
+ if (ngx_strcasecmp(&buf[i], (u_char *) "\3ip6\4arpa") == 0) {
+ i += sizeof("\3ip6\4arpa");
+
+ /* lock addr mutex */
+
+ hash = ngx_crc32_short(addr6.s6_addr, 16);
+ rn = ngx_resolver_lookup_addr6(r, &addr6, hash);
+
+ tree = &r->addr6_rbtree;
+ expire_queue = &r->addr6_expire_queue;
+
+ goto valid;
+ }
+
+invalid_ip6_arpa:
+#endif
+
+ ngx_log_error(r->log_level, r->log, 0,
+ "invalid in-addr.arpa or ip6.arpa name in DNS response");
+ ngx_resolver_free(r, name.data);
+ return;
+
+valid:
+
+ if (rn == NULL || rn->query == NULL) {
+ ngx_log_error(r->log_level, r->log, 0,
+ "unexpected response for %V", &name);
+ ngx_resolver_free(r, name.data);
+ goto failed;
+ }
+
+ qident = (rn->query[0] << 8) + rn->query[1];
+
+ if (ident != qident) {
+ ngx_log_error(r->log_level, r->log, 0,
+ "wrong ident %ui response for %V, expect %ui",
+ ident, &name, qident);
+ ngx_resolver_free(r, name.data);
+ goto failed;
+ }
+
+ ngx_resolver_free(r, name.data);
+
+ if (code == 0 && nan == 0) {
+ code = NGX_RESOLVE_NXDOMAIN;
+ }
+
+ if (code) {
+ next = rn->waiting;
+ rn->waiting = NULL;
+
+ ngx_queue_remove(&rn->queue);
+
+ ngx_rbtree_delete(tree, &rn->node);
+
+ /* unlock addr mutex */
+
+ while (next) {
+ ctx = next;
+ ctx->state = code;
+ ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
+ next = ctx->next;
+
+ ctx->handler(ctx);
+ }
+
+ ngx_resolver_free_node(r, rn);
+
+ return;
+ }
+
+ i += sizeof(ngx_resolver_qs_t);
+
+ for (a = 0; a < nan; a++) {
+
+ start = i;
+
+ while (i < n) {
+
+ if (buf[i] & 0xc0) {
+ i += 2;
+ goto found;
+ }
+
+ if (buf[i] == 0) {
+ i++;
+ goto test_length;
+ }
+
+ i += 1 + buf[i];
+ }
+
+ goto short_response;
+
+ test_length:
+
+ if (i - start < 2) {
+ err = "invalid name in DNS response";
+ goto invalid;
+ }
+
+ found:
+
+ if (i + sizeof(ngx_resolver_an_t) >= n) {
+ goto short_response;
+ }
+
+ an = (ngx_resolver_an_t *) &buf[i];
+
+ type = (an->type_hi << 8) + an->type_lo;
+ class = (an->class_hi << 8) + an->class_lo;
+ len = (an->len_hi << 8) + an->len_lo;
+ ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16)
+ + (an->ttl[2] << 8) + (an->ttl[3]);
+
+ if (class != 1) {
+ ngx_log_error(r->log_level, r->log, 0,
+ "unexpected RR class %ui", class);
+ goto failed;
+ }
+
+ if (ttl < 0) {
+ ttl = 0;
+ }
+
+ ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
+ "resolver qt:%ui cl:%ui len:%uz",
type, class, len);
i += sizeof(ngx_resolver_an_t);
@@ -2675,6 +3356,7 @@
while (next) {
ctx = next;
ctx->state = NGX_OK;
+ ctx->valid = rn->valid;
ctx->name = name;
next = ctx->next;
@@ -2747,6 +3429,47 @@
static ngx_resolver_node_t *
+ngx_resolver_lookup_srv(ngx_resolver_t *r, ngx_str_t *name, uint32_t hash)
+{
+ ngx_int_t rc;
+ ngx_rbtree_node_t *node, *sentinel;
+ ngx_resolver_node_t *rn;
+
+ node = r->srv_rbtree.root;
+ sentinel = r->srv_rbtree.sentinel;
+
+ while (node != sentinel) {
+
+ if (hash < node->key) {
+ node = node->left;
+ continue;
+ }
+
+ if (hash > node->key) {
+ node = node->right;
+ continue;
+ }
+
+ /* hash == node->key */
+
+ rn = ngx_resolver_node(node);
+
+ rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen);
+
+ if (rc == 0) {
+ return rn;
+ }
+
+ node = (rc < 0) ? node->left : node->right;
+ }
+
+ /* not found */
+
+ return NULL;
+}
+
+
+static ngx_resolver_node_t *
ngx_resolver_lookup_addr(ngx_resolver_t *r, in_addr_t addr)
{
ngx_rbtree_node_t *node, *sentinel;
@@ -3034,8 +3757,96 @@
static ngx_int_t
+ngx_resolver_create_srv_query(ngx_resolver_t *r, ngx_resolver_node_t *rn,
+ ngx_str_t *name)
+{
+ u_char *p, *s;
+ size_t len, nlen;
+ ngx_uint_t ident;
+ ngx_resolver_qs_t *qs;
+ ngx_resolver_hdr_t *query;
+
+ nlen = name->len ? (1 + name->len + 1) : 1;
+
+ len = sizeof(ngx_resolver_hdr_t) + nlen + sizeof(ngx_resolver_qs_t);
+
+ p = ngx_resolver_alloc(r, len);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ rn->qlen = (u_short) len;
+ rn->query = p;
+
+ query = (ngx_resolver_hdr_t *) p;
+
+ ident = ngx_random();
+
+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
+ "resolve: \"%V\" SRV %i", name, ident & 0xffff);
+
+ query->ident_hi = (u_char) ((ident >> 8) & 0xff);
+ query->ident_lo = (u_char) (ident & 0xff);
+
+ /* recursion query */
+ query->flags_hi = 1; query->flags_lo = 0;
+
+ /* one question */
+ query->nqs_hi = 0; query->nqs_lo = 1;
+ query->nan_hi = 0; query->nan_lo = 0;
+ query->nns_hi = 0; query->nns_lo = 0;
+ query->nar_hi = 0; query->nar_lo = 0;
+
+ p += sizeof(ngx_resolver_hdr_t) + nlen;
+
+ qs = (ngx_resolver_qs_t *) p;
+
+ /* query type */
+ qs->type_hi = 0; qs->type_lo = NGX_RESOLVE_SRV;
+
+ /* IN query class */
+ qs->class_hi = 0; qs->class_lo = 1;
+
+ /* converts "www.example.com" to "\3www\7example\3com\0" */
+
+ len = 0;
+ p--;
+ *p-- = '\0';
+
+ if (name->len == 0) {
+ return NGX_DECLINED;
+ }
+
+ for (s = name->data + name->len - 1; s >= name->data; s--) {
+ if (*s != '.') {
+ *p = *s;
+ len++;
+
+ } else {
+ if (len == 0 || len > 255) {
+ return NGX_DECLINED;
+ }
+
+ *p = (u_char) len;
+ len = 0;
+ }
+
+ p--;
+ }
+
+ if (len == 0 || len > 255) {
+ return NGX_DECLINED;
+ }
+
+ *p = (u_char) len;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
ngx_resolver_create_addr_query(ngx_resolver_t *r, ngx_resolver_node_t *rn,
- ngx_addr_t *addr)
+ ngx_resolver_addr_t *addr)
{
u_char *p, *d;
size_t len;
@@ -3239,6 +4050,8 @@
static void
ngx_resolver_free_node(ngx_resolver_t *r, ngx_resolver_node_t *rn)
{
+ ngx_uint_t i;
+
/* lock alloc mutex */
if (rn->query) {
@@ -3263,6 +4076,16 @@
}
#endif
+ if (rn->nsrvs) {
+ for (i = 0; i < rn->nsrvs; i++) {
+ if (rn->u.srvs[i].name.data) {
+ ngx_resolver_free_locked(r, rn->u.srvs[i].name.data);
+ }
+ }
+
+ ngx_resolver_free_locked(r, rn->u.srvs);
+ }
+
ngx_resolver_free_locked(r, rn);
/* unlock alloc mutex */
@@ -3334,15 +4157,15 @@
}
-static ngx_addr_t *
+static ngx_resolver_addr_t *
ngx_resolver_export(ngx_resolver_t *r, ngx_resolver_node_t *rn,
ngx_uint_t rotate)
{
- ngx_addr_t *dst;
ngx_uint_t d, i, j, n;
u_char (*sockaddr)[NGX_SOCKADDRLEN];
in_addr_t *addr;
struct sockaddr_in *sin;
+ ngx_resolver_addr_t *dst;
#if (NGX_HAVE_INET6)
struct in6_addr *addr6;
struct sockaddr_in6 *sin6;
@@ -3353,7 +4176,7 @@
n += rn->naddrs6;
#endif
- dst = ngx_resolver_calloc(r, n * sizeof(ngx_addr_t));
+ dst = ngx_resolver_calloc(r, n * sizeof(ngx_resolver_addr_t));
if (dst == NULL) {
return NULL;
}
@@ -3417,6 +4240,99 @@
}
+static void
+ngx_resolver_report_srv(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
+{
+ ngx_uint_t naddrs, nsrvs, nw, i, j, k, l, m, n, w;
+ ngx_resolver_addr_t *addrs;
+ ngx_resolver_srv_name_t *srvs;
+
+ naddrs = 0;
+
+ for (i = 0; i < ctx->nsrvs; i++) {
+ naddrs += ctx->srvs[i].naddrs;
+ }
+
+ if (naddrs == 0) {
+ ctx->state = NGX_RESOLVE_NXDOMAIN;
+ ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
+
+ ctx->handler(ctx);
+ return;
+ }
+
+ addrs = ngx_resolver_calloc(r, naddrs * sizeof(ngx_resolver_addr_t));
+ if (addrs == NULL) {
+ ctx->state = NGX_ERROR;
+ ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
+
+ ctx->handler(ctx);
+ return;
+ }
+
+ srvs = ctx->srvs;
+ nsrvs = ctx->nsrvs;
+
+ i = 0;
+ n = 0;
+
+ do {
+ nw = 0;
+
+ for (j = i; j < nsrvs; j++) {
+ if (srvs[j].priority != srvs[i].priority) {
+ break;
+ }
+
+ nw += srvs[j].naddrs * srvs[j].weight;
+ }
+
+ if (nw == 0) {
+ goto next_srv;
+ }
+
+ w = ngx_random() % nw;
+
+ for (k = i; k < j; k++) {
+ if (w < srvs[k].naddrs * srvs[k].weight) {
+ break;
+ }
+
+ w -= srvs[k].naddrs * srvs[k].weight;
+ }
+
+ for (l = i; l < j; l++) {
+
+ for (m = 0; m < srvs[k].naddrs; m++) {
+ addrs[n].socklen = srvs[k].addrs[m].socklen;
+ addrs[n].sockaddr = srvs[k].addrs[m].sockaddr;
+ addrs[n].name = srvs[k].name;
+ addrs[n].priority = srvs[k].priority;
+ addrs[n].weight = srvs[k].weight;
+ n++;
+ }
+
+ if (++k == j) {
+ k = i;
+ }
+ }
+
+next_srv:
+
+ i = j;
+
+ } while (i < ctx->nsrvs);
+
+ ctx->state = NGX_OK;
+ ctx->addrs = addrs;
+ ctx->naddrs = naddrs;
+
+ ctx->handler(ctx);
+
+ ngx_resolver_free(r, addrs);
+}
+
+
char *
ngx_resolver_strerror(ngx_int_t err)
{
@@ -3728,3 +4644,19 @@
return NGX_ERROR;
}
+
+
+static ngx_int_t
+ngx_resolver_cmp_srvs(const void *one, const void *two)
+{
+ ngx_int_t p1, p2;
+ ngx_resolver_srv_t *first, *second;
+
+ first = (ngx_resolver_srv_t *) one;
+ second = (ngx_resolver_srv_t *) two;
+
+ p1 = first->priority;
+ p2 = second->priority;
+
+ return p1 - p2;
+}
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/core/ngx_resolver.h
^
|
@@ -21,6 +21,7 @@
#if (NGX_HAVE_INET6)
#define NGX_RESOLVE_AAAA 28
#endif
+#define NGX_RESOLVE_SRV 33
#define NGX_RESOLVE_DNAME 39
#define NGX_RESOLVE_FORMERR 1
@@ -58,6 +59,36 @@
typedef struct {
+ struct sockaddr *sockaddr;
+ socklen_t socklen;
+ ngx_str_t name;
+ u_short priority;
+ u_short weight;
+} ngx_resolver_addr_t;
+
+
+typedef struct {
+ ngx_str_t name;
+ u_short priority;
+ u_short weight;
+ u_short port;
+} ngx_resolver_srv_t;
+
+
+typedef struct {
+ ngx_str_t name;
+ u_short priority;
+ u_short weight;
+ u_short port;
+
+ ngx_resolver_ctx_t *ctx;
+
+ ngx_uint_t naddrs;
+ ngx_addr_t *addrs;
+} ngx_resolver_srv_name_t;
+
+
+typedef struct {
ngx_rbtree_node_t node;
ngx_queue_t queue;
@@ -81,10 +112,12 @@
in_addr_t addr;
in_addr_t *addrs;
u_char *cname;
+ ngx_resolver_srv_t *srvs;
} u;
u_char code;
u_short naddrs;
+ u_short nsrvs;
u_short cnlen;
#if (NGX_HAVE_INET6)
@@ -127,13 +160,18 @@
ngx_rbtree_t name_rbtree;
ngx_rbtree_node_t name_sentinel;
+ ngx_rbtree_t srv_rbtree;
+ ngx_rbtree_node_t srv_sentinel;
+
ngx_rbtree_t addr_rbtree;
ngx_rbtree_node_t addr_sentinel;
ngx_queue_t name_resend_queue;
+ ngx_queue_t srv_resend_queue;
ngx_queue_t addr_resend_queue;
ngx_queue_t name_expire_queue;
+ ngx_queue_t srv_expire_queue;
ngx_queue_t addr_expire_queue;
#if (NGX_HAVE_INET6)
@@ -163,12 +201,18 @@
ngx_int_t state;
ngx_str_t name;
+ ngx_str_t service;
+ time_t valid;
ngx_uint_t naddrs;
- ngx_addr_t *addrs;
- ngx_addr_t addr;
+ ngx_resolver_addr_t *addrs;
+ ngx_resolver_addr_t addr;
struct sockaddr_in sin;
+ ngx_uint_t count;
+ ngx_uint_t nsrvs;
+ ngx_resolver_srv_name_t *srvs;
+
ngx_resolver_handler_pt handler;
void *data;
ngx_msec_t timeout;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/event/modules/ngx_devpoll_module.c
^
|
@@ -14,7 +14,9 @@
/* Solaris declarations */
+#ifndef POLLREMOVE
#define POLLREMOVE 0x0800
+#endif
#define DP_POLL 0xD001
#define DP_ISPOLLED 0xD002
@@ -436,7 +438,7 @@
default:
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "unexpected event %04Xd for closed and removed socket %d, ",
+ "unexpected event %04Xd for closed and removed socket %d, "
"ioctl(DP_ISPOLLED) returned rc:%d, fd:%d, event %04Xd",
revents, fd, rc, pfd.fd, pfd.revents);
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/event/modules/ngx_epoll_module.c
^
|
@@ -840,6 +840,9 @@
}
wev->ready = 1;
+#if (NGX_THREADS)
+ wev->complete = 1;
+#endif
if (flags & NGX_POST_EVENTS) {
ngx_post_event(wev, &ngx_posted_events);
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/event/modules/ngx_eventport_module.c
^
|
@@ -49,7 +49,7 @@
void *portnfy_user; /* user defined */
} port_notify_t;
-#if (__FreeBSD_version < 700005)
+#if (__FreeBSD__) && (__FreeBSD_version < 700005)
typedef struct itimerspec { /* definition per POSIX.4 */
struct timespec it_interval;/* timer period */
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/event/ngx_event.c
^
|
@@ -746,6 +746,7 @@
return NGX_ERROR;
}
+ c->type = ls[i].type;
c->log = &ls[i].log;
c->listening = &ls[i];
@@ -818,7 +819,8 @@
#else
- rev->handler = ngx_event_accept;
+ rev->handler = (c->type == SOCK_STREAM) ? ngx_event_accept
+ : ngx_event_recvmsg;
if (ngx_use_accept_mutex
#if (NGX_HAVE_REUSEPORT)
@@ -1206,7 +1208,7 @@
#endif
-#if (NGX_HAVE_DEVPOLL)
+#if (NGX_HAVE_DEVPOLL) && !(NGX_TEST_BUILD_DEVPOLL)
module = &ngx_devpoll_module;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/event/ngx_event.h
^
|
@@ -343,7 +343,8 @@
#define NGX_DISABLE_EVENT EV_DISABLE
-#elif (NGX_HAVE_DEVPOLL || NGX_HAVE_EVENTPORT)
+#elif (NGX_HAVE_DEVPOLL && !(NGX_TEST_BUILD_DEVPOLL)) \
+ || (NGX_HAVE_EVENTPORT && !(NGX_TEST_BUILD_EVENTPORT))
#define NGX_READ_EVENT POLLIN
#define NGX_WRITE_EVENT POLLOUT
@@ -352,7 +353,7 @@
#define NGX_ONESHOT_EVENT 1
-#elif (NGX_HAVE_EPOLL)
+#elif (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
#define NGX_READ_EVENT (EPOLLIN|EPOLLRDHUP)
#define NGX_WRITE_EVENT EPOLLOUT
@@ -418,6 +419,7 @@
#define ngx_udp_recv ngx_io.udp_recv
#define ngx_send ngx_io.send
#define ngx_send_chain ngx_io.send_chain
+#define ngx_udp_send ngx_io.udp_send
#define NGX_EVENT_MODULE 0x544E5645 /* "EVNT" */
@@ -491,6 +493,9 @@
void ngx_event_accept(ngx_event_t *ev);
+#if !(NGX_WIN32)
+void ngx_event_recvmsg(ngx_event_t *ev);
+#endif
ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle);
u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len);
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/event/ngx_event_accept.c
^
|
@@ -13,6 +13,10 @@
static ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle);
static ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle, ngx_uint_t all);
static void ngx_close_accepted_connection(ngx_connection_t *c);
+#if (NGX_DEBUG)
+static void ngx_debug_accepted_connection(ngx_event_conf_t *ecf,
+ ngx_connection_t *c);
+#endif
void
@@ -149,6 +153,8 @@
return;
}
+ c->type = SOCK_STREAM;
+
#if (NGX_STAT_STUB)
(void) ngx_atomic_fetch_add(ngx_stat_active, 1);
#endif
@@ -276,79 +282,345 @@
#if (NGX_DEBUG)
{
+ ngx_str_t addr;
+ u_char text[NGX_SOCKADDR_STRLEN];
- ngx_str_t addr;
- struct sockaddr_in *sin;
- ngx_cidr_t *cidr;
- ngx_uint_t i;
- u_char text[NGX_SOCKADDR_STRLEN];
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
- ngx_uint_t n;
+ ngx_debug_accepted_connection(ecf, c);
+
+ if (log->log_level & NGX_LOG_DEBUG_EVENT) {
+ addr.data = text;
+ addr.len = ngx_sock_ntop(c->sockaddr, c->socklen, text,
+ NGX_SOCKADDR_STRLEN, 1);
+
+ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0,
+ "*%uA accept: %V fd:%d", c->number, &addr, s);
+ }
+
+ }
#endif
- cidr = ecf->debug_connection.elts;
- for (i = 0; i < ecf->debug_connection.nelts; i++) {
- if (cidr[i].family != (ngx_uint_t) c->sockaddr->sa_family) {
- goto next;
+ if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) {
+ if (ngx_add_conn(c) == NGX_ERROR) {
+ ngx_close_accepted_connection(c);
+ return;
}
+ }
- switch (cidr[i].family) {
+ log->data = NULL;
+ log->handler = NULL;
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) c->sockaddr;
- for (n = 0; n < 16; n++) {
- if ((sin6->sin6_addr.s6_addr[n]
- & cidr[i].u.in6.mask.s6_addr[n])
- != cidr[i].u.in6.addr.s6_addr[n])
- {
- goto next;
- }
- }
- break;
+ ls->handler(c);
+
+ if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
+ ev->available--;
+ }
+
+ } while (ev->available);
+}
+
+
+#if !(NGX_WIN32)
+
+void
+ngx_event_recvmsg(ngx_event_t *ev)
+{
+ ssize_t n;
+ ngx_log_t *log;
+ ngx_err_t err;
+ ngx_event_t *rev, *wev;
+ struct iovec iov[1];
+ struct msghdr msg;
+ ngx_listening_t *ls;
+ ngx_event_conf_t *ecf;
+ ngx_connection_t *c, *lc;
+ u_char sa[NGX_SOCKADDRLEN];
+ static u_char buffer[65535];
+
+#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
+
+#if (NGX_HAVE_IP_RECVDSTADDR)
+ u_char msg_control[CMSG_SPACE(sizeof(struct in_addr))];
+#elif (NGX_HAVE_IP_PKTINFO)
+ u_char msg_control[CMSG_SPACE(sizeof(struct in_pktinfo))];
#endif
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- break;
+#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
+ u_char msg_control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
#endif
- default: /* AF_INET */
- sin = (struct sockaddr_in *) c->sockaddr;
- if ((sin->sin_addr.s_addr & cidr[i].u.in.mask)
- != cidr[i].u.in.addr)
- {
- goto next;
- }
- break;
+#endif
+
+ if (ev->timedout) {
+ if (ngx_enable_accept_events((ngx_cycle_t *) ngx_cycle) != NGX_OK) {
+ return;
+ }
+
+ ev->timedout = 0;
+ }
+
+ ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module);
+
+ if (!(ngx_event_flags & NGX_USE_KQUEUE_EVENT)) {
+ ev->available = ecf->multi_accept;
+ }
+
+ lc = ev->data;
+ ls = lc->listening;
+ ev->ready = 0;
+
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
+ "recvmsg on %V, ready: %d", &ls->addr_text, ev->available);
+
+ do {
+ ngx_memzero(&msg, sizeof(struct msghdr));
+
+ iov[0].iov_base = (void *) buffer;
+ iov[0].iov_len = sizeof(buffer);
+
+ msg.msg_name = &sa;
+ msg.msg_namelen = sizeof(sa);
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+
+#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
+
+ if (ls->wildcard) {
+
+#if (NGX_HAVE_IP_RECVDSTADDR || NGX_HAVE_IP_PKTINFO)
+ if (ls->sockaddr->sa_family == AF_INET) {
+ msg.msg_control = &msg_control;
+ msg.msg_controllen = sizeof(msg_control);
}
+#endif
- log->log_level = NGX_LOG_DEBUG_CONNECTION|NGX_LOG_DEBUG_ALL;
- break;
+#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
+ if (ls->sockaddr->sa_family == AF_INET6) {
+ msg.msg_control = &msg_control6;
+ msg.msg_controllen = sizeof(msg_control6);
+ }
+#endif
+ }
- next:
+#endif
+
+ n = recvmsg(lc->fd, &msg, 0);
+
+ if (n == -1) {
+ err = ngx_socket_errno;
+
+ if (err == NGX_EAGAIN) {
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, err,
+ "recvmsg() not ready");
+ return;
+ }
+
+ ngx_log_error(NGX_LOG_ALERT, ev->log, err, "recvmsg() failed");
+
+ return;
+ }
+
+#if (NGX_STAT_STUB)
+ (void) ngx_atomic_fetch_add(ngx_stat_accepted, 1);
+#endif
+
+#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
+ if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) {
+ ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
+ "recvmsg() truncated data");
continue;
}
+#endif
- if (log->log_level & NGX_LOG_DEBUG_EVENT) {
- addr.data = text;
- addr.len = ngx_sock_ntop(c->sockaddr, c->socklen, text,
- NGX_SOCKADDR_STRLEN, 1);
+ ngx_accept_disabled = ngx_cycle->connection_n / 8
+ - ngx_cycle->free_connection_n;
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0,
- "*%uA accept: %V fd:%d", c->number, &addr, s);
+ c = ngx_get_connection(lc->fd, ev->log);
+ if (c == NULL) {
+ return;
}
+ c->shared = 1;
+ c->type = SOCK_DGRAM;
+ c->socklen = msg.msg_namelen;
+
+#if (NGX_STAT_STUB)
+ (void) ngx_atomic_fetch_add(ngx_stat_active, 1);
+#endif
+
+ c->pool = ngx_create_pool(ls->pool_size, ev->log);
+ if (c->pool == NULL) {
+ ngx_close_accepted_connection(c);
+ return;
+ }
+
+ c->sockaddr = ngx_palloc(c->pool, c->socklen);
+ if (c->sockaddr == NULL) {
+ ngx_close_accepted_connection(c);
+ return;
+ }
+
+ ngx_memcpy(c->sockaddr, msg.msg_name, c->socklen);
+
+ log = ngx_palloc(c->pool, sizeof(ngx_log_t));
+ if (log == NULL) {
+ ngx_close_accepted_connection(c);
+ return;
}
+
+ *log = ls->log;
+
+ c->send = ngx_udp_send;
+
+ c->log = log;
+ c->pool->log = log;
+
+ c->listening = ls;
+ c->local_sockaddr = ls->sockaddr;
+ c->local_socklen = ls->socklen;
+
+#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
+
+ if (ls->wildcard) {
+ struct cmsghdr *cmsg;
+ struct sockaddr *sockaddr;
+
+ sockaddr = ngx_palloc(c->pool, c->local_socklen);
+ if (sockaddr == NULL) {
+ ngx_close_accepted_connection(c);
+ return;
+ }
+
+ ngx_memcpy(sockaddr, c->local_sockaddr, c->local_socklen);
+ c->local_sockaddr = sockaddr;
+
+ for (cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg))
+ {
+
+#if (NGX_HAVE_IP_RECVDSTADDR)
+
+ if (cmsg->cmsg_level == IPPROTO_IP
+ && cmsg->cmsg_type == IP_RECVDSTADDR
+ && sockaddr->sa_family == AF_INET)
+ {
+ struct in_addr *addr;
+ struct sockaddr_in *sin;
+
+ addr = (struct in_addr *) CMSG_DATA(cmsg);
+ sin = (struct sockaddr_in *) sockaddr;
+ sin->sin_addr = *addr;
+
+ break;
+ }
+
+#elif (NGX_HAVE_IP_PKTINFO)
+
+ if (cmsg->cmsg_level == IPPROTO_IP
+ && cmsg->cmsg_type == IP_PKTINFO
+ && sockaddr->sa_family == AF_INET)
+ {
+ struct in_pktinfo *pkt;
+ struct sockaddr_in *sin;
+
+ pkt = (struct in_pktinfo *) CMSG_DATA(cmsg);
+ sin = (struct sockaddr_in *) sockaddr;
+ sin->sin_addr = pkt->ipi_addr;
+
+ break;
+ }
+
#endif
- if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) {
- if (ngx_add_conn(c) == NGX_ERROR) {
+#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
+
+ if (cmsg->cmsg_level == IPPROTO_IPV6
+ && cmsg->cmsg_type == IPV6_PKTINFO
+ && sockaddr->sa_family == AF_INET6)
+ {
+ struct in6_pktinfo *pkt6;
+ struct sockaddr_in6 *sin6;
+
+ pkt6 = (struct in6_pktinfo *) CMSG_DATA(cmsg);
+ sin6 = (struct sockaddr_in6 *) sockaddr;
+ sin6->sin6_addr = pkt6->ipi6_addr;
+
+ break;
+ }
+
+#endif
+
+ }
+ }
+
+#endif
+
+ c->buffer = ngx_create_temp_buf(c->pool, n);
+ if (c->buffer == NULL) {
+ ngx_close_accepted_connection(c);
+ return;
+ }
+
+ c->buffer->last = ngx_cpymem(c->buffer->last, buffer, n);
+
+ rev = c->read;
+ wev = c->write;
+
+ wev->ready = 1;
+
+ rev->log = log;
+ wev->log = log;
+
+ /*
+ * TODO: MT: - ngx_atomic_fetch_add()
+ * or protection by critical section or light mutex
+ *
+ * TODO: MP: - allocated in a shared memory
+ * - ngx_atomic_fetch_add()
+ * or protection by critical section or light mutex
+ */
+
+ c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
+
+#if (NGX_STAT_STUB)
+ (void) ngx_atomic_fetch_add(ngx_stat_handled, 1);
+#endif
+
+ if (ls->addr_ntop) {
+ c->addr_text.data = ngx_pnalloc(c->pool, ls->addr_text_max_len);
+ if (c->addr_text.data == NULL) {
ngx_close_accepted_connection(c);
return;
}
+
+ c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->socklen,
+ c->addr_text.data,
+ ls->addr_text_max_len, 0);
+ if (c->addr_text.len == 0) {
+ ngx_close_accepted_connection(c);
+ return;
+ }
+ }
+
+#if (NGX_DEBUG)
+ {
+ ngx_str_t addr;
+ u_char text[NGX_SOCKADDR_STRLEN];
+
+ ngx_debug_accepted_connection(ecf, c);
+
+ if (log->log_level & NGX_LOG_DEBUG_EVENT) {
+ addr.data = text;
+ addr.len = ngx_sock_ntop(c->sockaddr, c->socklen, text,
+ NGX_SOCKADDR_STRLEN, 1);
+
+ ngx_log_debug4(NGX_LOG_DEBUG_EVENT, log, 0,
+ "*%uA recvmsg: %V fd:%d n:%z",
+ c->number, &addr, c->fd, n);
+ }
+
}
+#endif
log->data = NULL;
log->handler = NULL;
@@ -356,12 +628,14 @@
ls->handler(c);
if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
- ev->available--;
+ ev->available -= n;
}
} while (ev->available);
}
+#endif
+
ngx_int_t
ngx_trylock_accept_mutex(ngx_cycle_t *cycle)
@@ -476,7 +750,7 @@
fd = c->fd;
c->fd = (ngx_socket_t) -1;
- if (ngx_close_socket(fd) == -1) {
+ if (!c->shared && ngx_close_socket(fd) == -1) {
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno,
ngx_close_socket_n " failed");
}
@@ -497,3 +771,64 @@
return ngx_snprintf(buf, len, " while accepting new connection on %V",
log->data);
}
+
+
+#if (NGX_DEBUG)
+
+static void
+ngx_debug_accepted_connection(ngx_event_conf_t *ecf, ngx_connection_t *c)
+{
+ struct sockaddr_in *sin;
+ ngx_cidr_t *cidr;
+ ngx_uint_t i;
+#if (NGX_HAVE_INET6)
+ struct sockaddr_in6 *sin6;
+ ngx_uint_t n;
+#endif
+
+ cidr = ecf->debug_connection.elts;
+ for (i = 0; i < ecf->debug_connection.nelts; i++) {
+ if (cidr[i].family != (ngx_uint_t) c->sockaddr->sa_family) {
+ goto next;
+ }
+
+ switch (cidr[i].family) {
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *) c->sockaddr;
+ for (n = 0; n < 16; n++) {
+ if ((sin6->sin6_addr.s6_addr[n]
+ & cidr[i].u.in6.mask.s6_addr[n])
+ != cidr[i].u.in6.addr.s6_addr[n])
+ {
+ goto next;
+ }
+ }
+ break;
+#endif
+
+#if (NGX_HAVE_UNIX_DOMAIN)
+ case AF_UNIX:
+ break;
+#endif
+
+ default: /* AF_INET */
+ sin = (struct sockaddr_in *) c->sockaddr;
+ if ((sin->sin_addr.s_addr & cidr[i].u.in.mask)
+ != cidr[i].u.in.addr)
+ {
+ goto next;
+ }
+ break;
+ }
+
+ c->log->log_level = NGX_LOG_DEBUG_CONNECTION|NGX_LOG_DEBUG_ALL;
+ break;
+
+ next:
+ continue;
+ }
+}
+
+#endif
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/event/ngx_event_connect.c
^
|
@@ -14,7 +14,7 @@
ngx_int_t
ngx_event_connect_peer(ngx_peer_connection_t *pc)
{
- int rc;
+ int rc, type;
ngx_int_t event;
ngx_err_t err;
ngx_uint_t level;
@@ -27,9 +27,12 @@
return rc;
}
- s = ngx_socket(pc->sockaddr->sa_family, SOCK_STREAM, 0);
+ type = (pc->type ? pc->type : SOCK_STREAM);
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0, "socket %d", s);
+ s = ngx_socket(pc->sockaddr->sa_family, type, 0);
+
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pc->log, 0, "%s socket %d",
+ (type == SOCK_STREAM) ? "stream" : "dgram", s);
if (s == (ngx_socket_t) -1) {
ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
@@ -49,6 +52,8 @@
return NGX_ERROR;
}
+ c->type = type;
+
if (pc->rcvbuf) {
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
(const void *) &pc->rcvbuf, sizeof(int)) == -1)
@@ -75,25 +80,31 @@
}
}
- c->recv = ngx_recv;
- c->send = ngx_send;
- c->recv_chain = ngx_recv_chain;
- c->send_chain = ngx_send_chain;
-
- c->sendfile = 1;
-
- c->log_error = pc->log_error;
-
- if (pc->sockaddr->sa_family == AF_UNIX) {
- c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
- c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
+ if (type == SOCK_STREAM) {
+ c->recv = ngx_recv;
+ c->send = ngx_send;
+ c->recv_chain = ngx_recv_chain;
+ c->send_chain = ngx_send_chain;
+
+ c->sendfile = 1;
+
+ if (pc->sockaddr->sa_family == AF_UNIX) {
+ c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
+ c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
#if (NGX_SOLARIS)
- /* Solaris's sendfilev() supports AF_NCA, AF_INET, and AF_INET6 */
- c->sendfile = 0;
+ /* Solaris's sendfilev() supports AF_NCA, AF_INET, and AF_INET6 */
+ c->sendfile = 0;
#endif
+ }
+
+ } else { /* type == SOCK_DGRAM */
+ c->recv = ngx_udp_recv;
+ c->send = ngx_send;
}
+ c->log_error = pc->log_error;
+
rev = c->read;
wev = c->write;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/event/ngx_event_connect.h
^
|
@@ -55,6 +55,7 @@
ngx_addr_t *local;
+ int type;
int rcvbuf;
ngx_log_t *log;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/event/ngx_event_pipe.c
^
|
@@ -112,6 +112,14 @@
return NGX_OK;
}
+#if (NGX_THREADS)
+ if (p->aio) {
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
+ "pipe read upstream: aio");
+ return NGX_AGAIN;
+ }
+#endif
+
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
"pipe read upstream: %d", p->upstream->read->ready);
@@ -258,19 +266,6 @@
break;
}
- if (rc == NGX_AGAIN) {
- if (ngx_event_flags & NGX_USE_LEVEL_EVENT
- && p->upstream->read->active
- && p->upstream->read->ready)
- {
- if (ngx_del_event(p->upstream->read, NGX_READ_EVENT, 0)
- == NGX_ERROR)
- {
- return NGX_ABORT;
- }
- }
- }
-
if (rc != NGX_OK) {
return rc;
}
@@ -475,8 +470,10 @@
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
"pipe write chain");
- if (ngx_event_pipe_write_chain_to_temp_file(p) == NGX_ABORT) {
- return NGX_ABORT;
+ rc = ngx_event_pipe_write_chain_to_temp_file(p);
+
+ if (rc != NGX_OK) {
+ return rc;
}
}
@@ -499,6 +496,18 @@
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
"pipe write downstream: %d", downstream->write->ready);
+#if (NGX_THREADS)
+
+ if (p->writing) {
+ rc = ngx_event_pipe_write_chain_to_temp_file(p);
+
+ if (rc == NGX_ABORT) {
+ return NGX_ABORT;
+ }
+ }
+
+#endif
+
flushed = 0;
for ( ;; ) {
@@ -532,6 +541,10 @@
p->out = NULL;
}
+ if (p->writing) {
+ break;
+ }
+
if (p->in) {
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
"pipe write downstream flush in");
@@ -608,7 +621,7 @@
p->out = p->out->next;
- } else if (!p->cacheable && p->in) {
+ } else if (!p->cacheable && !p->writing && p->in) {
cl = p->in;
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0,
@@ -710,12 +723,38 @@
ssize_t size, bsize, n;
ngx_buf_t *b;
ngx_uint_t prev_last_shadow;
- ngx_chain_t *cl, *tl, *next, *out, **ll, **last_out, **last_free, fl;
+ ngx_chain_t *cl, *tl, *next, *out, **ll, **last_out, **last_free;
+
+#if (NGX_THREADS)
+
+ if (p->writing) {
+
+ if (p->aio) {
+ return NGX_AGAIN;
+ }
+
+ out = p->writing;
+ p->writing = NULL;
+
+ n = ngx_write_chain_to_temp_file(p->temp_file, NULL);
+
+ if (n == NGX_ERROR) {
+ return NGX_ABORT;
+ }
+
+ goto done;
+ }
+
+#endif
if (p->buf_to_file) {
- fl.buf = p->buf_to_file;
- fl.next = p->in;
- out = &fl;
+ out = ngx_alloc_chain_link(p->pool);
+ if (out == NULL) {
+ return NGX_ABORT;
+ }
+
+ out->buf = p->buf_to_file;
+ out->next = p->in;
} else {
out = p->in;
@@ -775,12 +814,31 @@
p->last_in = &p->in;
}
+#if (NGX_THREADS)
+ p->temp_file->thread_write = p->thread_handler ? 1 : 0;
+ p->temp_file->file.thread_task = p->thread_task;
+ p->temp_file->file.thread_handler = p->thread_handler;
+ p->temp_file->file.thread_ctx = p->thread_ctx;
+#endif
+
n = ngx_write_chain_to_temp_file(p->temp_file, out);
if (n == NGX_ERROR) {
return NGX_ABORT;
}
+#if (NGX_THREADS)
+
+ if (n == NGX_AGAIN) {
+ p->writing = out;
+ p->thread_task = p->temp_file->file.thread_task;
+ return NGX_AGAIN;
+ }
+
+done:
+
+#endif
+
if (p->buf_to_file) {
p->temp_file->offset = p->buf_to_file->last - p->buf_to_file->pos;
n -= p->buf_to_file->last - p->buf_to_file->pos;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/event/ngx_event_pipe.h
^
|
@@ -30,6 +30,8 @@
ngx_chain_t *in;
ngx_chain_t **last_in;
+ ngx_chain_t *writing;
+
ngx_chain_t *out;
ngx_chain_t *free;
ngx_chain_t *busy;
@@ -45,6 +47,13 @@
ngx_event_pipe_output_filter_pt output_filter;
void *output_ctx;
+#if (NGX_THREADS)
+ ngx_int_t (*thread_handler)(ngx_thread_task_t *task,
+ ngx_file_t *file);
+ void *thread_ctx;
+ ngx_thread_task_t *thread_task;
+#endif
+
unsigned read:1;
unsigned cacheable:1;
unsigned single_buf:1;
@@ -56,6 +65,7 @@
unsigned downstream_done:1;
unsigned downstream_error:1;
unsigned cyclic_temp_file:1;
+ unsigned aio:1;
ngx_int_t allocated;
ngx_bufs_t bufs;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/http/modules/ngx_http_fastcgi_module.c
^
|
@@ -206,6 +206,7 @@
{ ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
{ ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
{ ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
+ { ngx_string("non_idempotent"), NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT },
{ ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
{ ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
{ ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/http/modules/ngx_http_proxy_module.c
^
|
@@ -213,6 +213,7 @@
{ ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
{ ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
{ ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
+ { ngx_string("non_idempotent"), NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT },
{ ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
{ ngx_string("http_502"), NGX_HTTP_UPSTREAM_FT_HTTP_502 },
{ ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/http/modules/ngx_http_scgi_module.c
^
|
@@ -77,6 +77,7 @@
{ ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
{ ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
{ ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
+ { ngx_string("non_idempotent"), NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT },
{ ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
{ ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
{ ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/http/modules/ngx_http_sub_filter_module.c
^
|
@@ -229,7 +229,7 @@
return ngx_http_next_header_filter(r);
}
- ctx->matches = ngx_pnalloc(r->pool, sizeof(ngx_array_t));
+ ctx->matches = ngx_palloc(r->pool, sizeof(ngx_array_t));
if (ctx->matches == NULL) {
return NGX_ERROR;
}
@@ -237,7 +237,7 @@
ctx->matches->elts = matches;
ctx->matches->nelts = j;
- ctx->tables = ngx_pnalloc(r->pool, sizeof(ngx_http_sub_tables_t));
+ ctx->tables = ngx_palloc(r->pool, sizeof(ngx_http_sub_tables_t));
if (ctx->tables == NULL) {
return NGX_ERROR;
}
@@ -859,7 +859,7 @@
pairs = conf->pairs->elts;
n = conf->pairs->nelts;
- matches = ngx_pnalloc(cf->pool, sizeof(ngx_http_sub_match_t) * n);
+ matches = ngx_palloc(cf->pool, sizeof(ngx_http_sub_match_t) * n);
if (matches == NULL) {
return NGX_CONF_ERROR;
}
@@ -869,7 +869,7 @@
matches[i].value = &pairs[i].value;
}
- conf->matches = ngx_pnalloc(cf->pool, sizeof(ngx_array_t));
+ conf->matches = ngx_palloc(cf->pool, sizeof(ngx_array_t));
if (conf->matches == NULL) {
return NGX_CONF_ERROR;
}
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/http/modules/ngx_http_uwsgi_module.c
^
|
@@ -109,6 +109,7 @@
{ ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
{ ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
{ ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
+ { ngx_string("non_idempotent"), NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT },
{ ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
{ ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
{ ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/http/ngx_http_cache.h
^
|
@@ -138,6 +138,8 @@
ngx_atomic_t cold;
ngx_atomic_t loading;
off_t size;
+ ngx_uint_t count;
+ ngx_uint_t watermark;
} ngx_http_file_cache_sh_t;
@@ -153,6 +155,8 @@
time_t inactive;
+ time_t fail_time;
+
ngx_uint_t files;
ngx_uint_t loader_files;
ngx_msec_t last;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/http/ngx_http_copy_filter_module.c
^
|
@@ -204,10 +204,11 @@
static ssize_t
ngx_http_copy_aio_sendfile_preload(ngx_buf_t *file)
{
- ssize_t n;
- static u_char buf[1];
- ngx_event_aio_t *aio;
- ngx_http_request_t *r;
+ ssize_t n;
+ static u_char buf[1];
+ ngx_event_aio_t *aio;
+ ngx_http_request_t *r;
+ ngx_output_chain_ctx_t *ctx;
n = ngx_file_aio_read(file->file, buf, 1, file->file_pos, NULL);
@@ -218,6 +219,9 @@
r = aio->data;
r->main->blocked++;
r->aio = 1;
+
+ ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module);
+ ctx->aio = 1;
}
return n;
@@ -252,6 +256,7 @@
ngx_str_t name;
ngx_thread_pool_t *tp;
ngx_http_request_t *r;
+ ngx_output_chain_ctx_t *ctx;
ngx_http_core_loc_conf_t *clcf;
r = file->thread_ctx;
@@ -285,6 +290,9 @@
r->main->blocked++;
r->aio = 1;
+ ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module);
+ ctx->aio = 1;
+
return NGX_OK;
}
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/http/ngx_http_core_module.c
^
|
@@ -400,6 +400,13 @@
0,
NULL },
+ { ngx_string("aio_write"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, aio_write),
+ NULL },
+
{ ngx_string("read_ahead"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_size_slot,
@@ -3606,6 +3613,7 @@
clcf->sendfile = NGX_CONF_UNSET;
clcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE;
clcf->aio = NGX_CONF_UNSET;
+ clcf->aio_write = NGX_CONF_UNSET;
#if (NGX_THREADS)
clcf->thread_pool = NGX_CONF_UNSET_PTR;
clcf->thread_pool_value = NGX_CONF_UNSET_PTR;
@@ -3827,6 +3835,7 @@
prev->sendfile_max_chunk, 0);
#if (NGX_HAVE_FILE_AIO || NGX_THREADS)
ngx_conf_merge_value(conf->aio, prev->aio, NGX_HTTP_AIO_OFF);
+ ngx_conf_merge_value(conf->aio_write, prev->aio_write, 0);
#endif
#if (NGX_THREADS)
ngx_conf_merge_ptr_value(conf->thread_pool, prev->thread_pool, NULL);
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/http/ngx_http_core_module.h
^
|
@@ -404,6 +404,7 @@
ngx_flag_t internal; /* internal */
ngx_flag_t sendfile; /* sendfile */
ngx_flag_t aio; /* aio */
+ ngx_flag_t aio_write; /* aio_write */
ngx_flag_t tcp_nopush; /* tcp_nopush */
ngx_flag_t tcp_nodelay; /* tcp_nodelay */
ngx_flag_t reset_timedout_connection; /* reset_timedout_connection */
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/http/ngx_http_file_cache.c
^
|
@@ -62,6 +62,7 @@
ngx_http_cache_t *c);
static ngx_int_t ngx_http_file_cache_delete_file(ngx_tree_ctx_t *ctx,
ngx_str_t *path);
+static void ngx_http_file_cache_set_watermark(ngx_http_file_cache_t *cache);
ngx_str_t ngx_http_cache_status[] = {
@@ -147,6 +148,8 @@
cache->sh->cold = 1;
cache->sh->loading = 0;
cache->sh->size = 0;
+ cache->sh->count = 0;
+ cache->sh->watermark = (ngx_uint_t) -1;
cache->bsize = ngx_fs_bsize(cache->path->name.data);
@@ -691,12 +694,13 @@
#if (NGX_THREADS)
if (clcf->aio == NGX_HTTP_AIO_THREADS) {
+ c->file.thread_task = c->thread_task;
c->file.thread_handler = ngx_http_cache_thread_handler;
c->file.thread_ctx = r;
- n = ngx_thread_read(&c->thread_task, &c->file, c->buf->pos,
- c->body_start, 0, r->pool);
+ n = ngx_thread_read(&c->file, c->buf->pos, c->body_start, 0, r->pool);
+ c->thread_task = c->file.thread_task;
c->reading = (n == NGX_AGAIN);
return n;
@@ -860,6 +864,8 @@
fcn = ngx_slab_calloc_locked(cache->shpool,
sizeof(ngx_http_file_cache_node_t));
if (fcn == NULL) {
+ ngx_http_file_cache_set_watermark(cache);
+
ngx_shmtx_unlock(&cache->shpool->mutex);
(void) ngx_http_file_cache_forced_expire(cache);
@@ -876,6 +882,8 @@
}
}
+ cache->sh->count++;
+
ngx_memcpy((u_char *) &fcn->node.key, c->key, sizeof(ngx_rbtree_key_t));
ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)],
@@ -1630,6 +1638,7 @@
ngx_queue_remove(&fcn->queue);
ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
ngx_slab_free_locked(cache->shpool, fcn);
+ cache->sh->count--;
c->node = NULL;
}
@@ -1882,6 +1891,7 @@
ngx_queue_remove(q);
ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
ngx_slab_free_locked(cache->shpool, fcn);
+ cache->sh->count--;
}
}
@@ -1891,8 +1901,9 @@
{
ngx_http_file_cache_t *cache = data;
- off_t size;
- time_t next, wait;
+ off_t size;
+ time_t next, wait;
+ ngx_uint_t count, watermark;
next = ngx_http_file_cache_expire(cache);
@@ -1903,13 +1914,16 @@
ngx_shmtx_lock(&cache->shpool->mutex);
size = cache->sh->size;
+ count = cache->sh->count;
+ watermark = cache->sh->watermark;
ngx_shmtx_unlock(&cache->shpool->mutex);
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
- "http file cache size: %O", size);
+ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
+ "http file cache size: %O c:%ui w:%i",
+ size, count, (ngx_int_t) watermark);
- if (size < cache->max_size) {
+ if (size < cache->max_size && count < watermark) {
return next;
}
@@ -2093,10 +2107,20 @@
fcn = ngx_slab_calloc_locked(cache->shpool,
sizeof(ngx_http_file_cache_node_t));
if (fcn == NULL) {
+ ngx_http_file_cache_set_watermark(cache);
+
+ if (cache->fail_time != ngx_time()) {
+ cache->fail_time = ngx_time();
+ ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
+ "could not allocate node%s", cache->shpool->log_ctx);
+ }
+
ngx_shmtx_unlock(&cache->shpool->mutex);
return NGX_ERROR;
}
+ cache->sh->count++;
+
ngx_memcpy((u_char *) &fcn->node.key, c->key, sizeof(ngx_rbtree_key_t));
ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)],
@@ -2139,6 +2163,16 @@
}
+static void
+ngx_http_file_cache_set_watermark(ngx_http_file_cache_t *cache)
+{
+ cache->sh->watermark = cache->sh->count - cache->sh->count / 8;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
+ "http file cache watermark: %ui", cache->sh->watermark);
+}
+
+
time_t
ngx_http_file_cache_valid(ngx_array_t *cache_valid, ngx_uint_t status)
{
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/http/ngx_http_request_body.c
^
|
@@ -34,7 +34,7 @@
ssize_t size;
ngx_int_t rc;
ngx_buf_t *b;
- ngx_chain_t out, *cl;
+ ngx_chain_t out;
ngx_http_request_body_t *rb;
ngx_http_core_loc_conf_t *clcf;
@@ -59,10 +59,6 @@
goto done;
}
- if (r->request_body_no_buffering) {
- r->request_body_in_file_only = 0;
- }
-
rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
if (rb == NULL) {
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -148,37 +144,8 @@
if (rb->rest == 0) {
/* the whole request body was pre-read */
-
- if (r->request_body_in_file_only) {
- if (ngx_http_write_request_body(r) != NGX_OK) {
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- goto done;
- }
-
- if (rb->temp_file->file.offset != 0) {
-
- cl = ngx_chain_get_free_buf(r->pool, &rb->free);
- if (cl == NULL) {
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- goto done;
- }
-
- b = cl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- b->in_file = 1;
- b->file_last = rb->temp_file->file.offset;
- b->file = &rb->temp_file->file;
-
- rb->bufs = cl;
- }
- }
-
r->request_body_no_buffering = 0;
-
post_handler(r);
-
return NGX_OK;
}
@@ -289,8 +256,7 @@
size_t size;
ssize_t n;
ngx_int_t rc;
- ngx_buf_t *b;
- ngx_chain_t *cl, out;
+ ngx_chain_t out;
ngx_connection_t *c;
ngx_http_request_body_t *rb;
ngx_http_core_loc_conf_t *clcf;
@@ -439,33 +405,6 @@
ngx_del_timer(c->read);
}
- if (rb->temp_file || r->request_body_in_file_only) {
-
- /* save the last part */
-
- if (ngx_http_write_request_body(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (rb->temp_file->file.offset != 0) {
-
- cl = ngx_chain_get_free_buf(r->pool, &rb->free);
- if (cl == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- b = cl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- b->in_file = 1;
- b->file_last = rb->temp_file->file.offset;
- b->file = &rb->temp_file->file;
-
- rb->bufs = cl;
- }
- }
-
if (!r->request_body_no_buffering) {
r->read_event_handler = ngx_http_block_reading;
rb->post_handler(r);
@@ -1127,9 +1066,8 @@
ngx_int_t
ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
-#if (NGX_DEBUG)
+ ngx_buf_t *b;
ngx_chain_t *cl;
-#endif
ngx_http_request_body_t *rb;
rb = r->request_body;
@@ -1166,13 +1104,46 @@
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- if (rb->rest > 0
- && rb->buf && rb->buf->last == rb->buf->end
- && !r->request_body_no_buffering)
- {
+ if (r->request_body_no_buffering) {
+ return NGX_OK;
+ }
+
+ if (rb->rest > 0) {
+
+ if (rb->buf && rb->buf->last == rb->buf->end
+ && ngx_http_write_request_body(r) != NGX_OK)
+ {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ return NGX_OK;
+ }
+
+ /* rb->rest == 0 */
+
+ if (rb->temp_file || r->request_body_in_file_only) {
+
if (ngx_http_write_request_body(r) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
+
+ if (rb->temp_file->file.offset != 0) {
+
+ cl = ngx_chain_get_free_buf(r->pool, &rb->free);
+ if (cl == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ b = cl->buf;
+
+ ngx_memzero(b, sizeof(ngx_buf_t));
+
+ b->in_file = 1;
+ b->file_last = rb->temp_file->file.offset;
+ b->file = &rb->temp_file->file;
+
+ rb->bufs = cl;
+ }
}
return NGX_OK;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/http/ngx_http_upstream.c
^
|
@@ -76,6 +76,13 @@
static ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data);
static ngx_int_t ngx_http_upstream_non_buffered_filter(void *data,
ssize_t bytes);
+#if (NGX_THREADS)
+static ngx_int_t ngx_http_upstream_thread_handler(ngx_thread_task_t *task,
+ ngx_file_t *file);
+static void ngx_http_upstream_thread_event_handler(ngx_event_t *ev);
+#endif
+static ngx_int_t ngx_http_upstream_output_filter(void *data,
+ ngx_chain_t *chain);
static void ngx_http_upstream_process_downstream(ngx_http_request_t *r);
static void ngx_http_upstream_process_upstream(ngx_http_request_t *r,
ngx_http_upstream_t *u);
@@ -416,10 +423,10 @@
ngx_conf_bitmask_t ngx_http_upstream_cache_method_mask[] = {
- { ngx_string("GET"), NGX_HTTP_GET},
- { ngx_string("HEAD"), NGX_HTTP_HEAD },
- { ngx_string("POST"), NGX_HTTP_POST },
- { ngx_null_string, 0 }
+ { ngx_string("GET"), NGX_HTTP_GET },
+ { ngx_string("HEAD"), NGX_HTTP_HEAD },
+ { ngx_string("POST"), NGX_HTTP_POST },
+ { ngx_null_string, 0 }
};
@@ -2861,11 +2868,16 @@
ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
}
+ if (r->header_only && !u->cacheable && !u->store) {
+ ngx_http_upstream_finalize_request(r, u, 0);
+ return;
+ }
+
#endif
p = u->pipe;
- p->output_filter = (ngx_event_pipe_output_filter_pt) ngx_http_output_filter;
+ p->output_filter = ngx_http_upstream_output_filter;
p->output_ctx = r;
p->tag = u->output.tag;
p->bufs = u->conf->bufs;
@@ -2908,6 +2920,13 @@
p->max_temp_file_size = u->conf->max_temp_file_size;
p->temp_file_write_size = u->conf->temp_file_write_size;
+#if (NGX_THREADS)
+ if (clcf->aio == NGX_HTTP_AIO_THREADS && clcf->aio_write) {
+ p->thread_handler = ngx_http_upstream_thread_handler;
+ p->thread_ctx = r;
+ }
+#endif
+
p->preread_bufs = ngx_alloc_chain_link(r->pool);
if (p->preread_bufs == NULL) {
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
@@ -3482,6 +3501,97 @@
}
+#if (NGX_THREADS)
+
+static ngx_int_t
+ngx_http_upstream_thread_handler(ngx_thread_task_t *task, ngx_file_t *file)
+{
+ ngx_str_t name;
+ ngx_event_pipe_t *p;
+ ngx_thread_pool_t *tp;
+ ngx_http_request_t *r;
+ ngx_http_core_loc_conf_t *clcf;
+
+ r = file->thread_ctx;
+ p = r->upstream->pipe;
+
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+ tp = clcf->thread_pool;
+
+ if (tp == NULL) {
+ if (ngx_http_complex_value(r, clcf->thread_pool_value, &name)
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ tp = ngx_thread_pool_get((ngx_cycle_t *) ngx_cycle, &name);
+
+ if (tp == NULL) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "thread pool \"%V\" not found", &name);
+ return NGX_ERROR;
+ }
+ }
+
+ task->event.data = r;
+ task->event.handler = ngx_http_upstream_thread_event_handler;
+
+ if (ngx_thread_task_post(tp, task) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ r->main->blocked++;
+ r->aio = 1;
+ p->aio = 1;
+
+ return NGX_OK;
+}
+
+
+static void
+ngx_http_upstream_thread_event_handler(ngx_event_t *ev)
+{
+ ngx_connection_t *c;
+ ngx_http_request_t *r;
+
+ r = ev->data;
+ c = r->connection;
+
+ ngx_http_set_log_request(c->log, r);
+
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
+ "http upstream thread: \"%V?%V\"", &r->uri, &r->args);
+
+ r->main->blocked--;
+ r->aio = 0;
+
+ r->write_event_handler(r);
+
+ ngx_http_run_posted_requests(c);
+}
+
+#endif
+
+
+static ngx_int_t
+ngx_http_upstream_output_filter(void *data, ngx_chain_t *chain)
+{
+ ngx_int_t rc;
+ ngx_event_pipe_t *p;
+ ngx_http_request_t *r;
+
+ r = data;
+ p = r->upstream->pipe;
+
+ rc = ngx_http_output_filter(r, chain);
+
+ p->aio = r->aio;
+
+ return rc;
+}
+
+
static void
ngx_http_upstream_process_downstream(ngx_http_request_t *r)
{
@@ -3500,6 +3610,10 @@
c->log->action = "sending to client";
+#if (NGX_THREADS)
+ p->aio = r->aio;
+#endif
+
if (wev->timedout) {
if (wev->delayed) {
@@ -3629,6 +3743,12 @@
p = u->pipe;
+#if (NGX_THREADS)
+ if (p->writing) {
+ return;
+ }
+#endif
+
if (u->peer.connection) {
if (u->store) {
@@ -3827,42 +3947,36 @@
"upstream timed out");
}
- if (u->peer.cached && ft_type == NGX_HTTP_UPSTREAM_FT_ERROR
- && (!u->request_sent || !r->request_body_no_buffering))
- {
- status = 0;
-
+ if (u->peer.cached && ft_type == NGX_HTTP_UPSTREAM_FT_ERROR) {
/* TODO: inform balancer instead */
-
u->peer.tries++;
+ }
- } else {
- switch (ft_type) {
+ switch (ft_type) {
- case NGX_HTTP_UPSTREAM_FT_TIMEOUT:
- status = NGX_HTTP_GATEWAY_TIME_OUT;
- break;
+ case NGX_HTTP_UPSTREAM_FT_TIMEOUT:
+ status = NGX_HTTP_GATEWAY_TIME_OUT;
+ break;
- case NGX_HTTP_UPSTREAM_FT_HTTP_500:
- status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- break;
+ case NGX_HTTP_UPSTREAM_FT_HTTP_500:
+ status = NGX_HTTP_INTERNAL_SERVER_ERROR;
+ break;
- case NGX_HTTP_UPSTREAM_FT_HTTP_403:
- status = NGX_HTTP_FORBIDDEN;
- break;
+ case NGX_HTTP_UPSTREAM_FT_HTTP_403:
+ status = NGX_HTTP_FORBIDDEN;
+ break;
- case NGX_HTTP_UPSTREAM_FT_HTTP_404:
- status = NGX_HTTP_NOT_FOUND;
- break;
+ case NGX_HTTP_UPSTREAM_FT_HTTP_404:
+ status = NGX_HTTP_NOT_FOUND;
+ break;
- /*
- * NGX_HTTP_UPSTREAM_FT_BUSY_LOCK and NGX_HTTP_UPSTREAM_FT_MAX_WAITING
- * never reach here
- */
+ /*
+ * NGX_HTTP_UPSTREAM_FT_BUSY_LOCK and NGX_HTTP_UPSTREAM_FT_MAX_WAITING
+ * never reach here
+ */
- default:
- status = NGX_HTTP_BAD_GATEWAY;
- }
+ default:
+ status = NGX_HTTP_BAD_GATEWAY;
}
if (r->connection->error) {
@@ -3871,37 +3985,42 @@
return;
}
- if (status) {
- u->state->status = status;
- timeout = u->conf->next_upstream_timeout;
-
- if (u->peer.tries == 0
- || !(u->conf->next_upstream & ft_type)
- || (u->request_sent && r->request_body_no_buffering)
- || (timeout && ngx_current_msec - u->peer.start_time >= timeout))
- {
-#if (NGX_HTTP_CACHE)
+ u->state->status = status;
- if (u->cache_status == NGX_HTTP_CACHE_EXPIRED
- && (u->conf->cache_use_stale & ft_type))
- {
- ngx_int_t rc;
+ timeout = u->conf->next_upstream_timeout;
- rc = u->reinit_request(r);
+ if (u->request_sent
+ && (r->method & (NGX_HTTP_POST|NGX_HTTP_LOCK|NGX_HTTP_PATCH)))
+ {
+ ft_type |= NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT;
+ }
- if (rc == NGX_OK) {
- u->cache_status = NGX_HTTP_CACHE_STALE;
- rc = ngx_http_upstream_cache_send(r, u);
- }
+ if (u->peer.tries == 0
+ || ((u->conf->next_upstream & ft_type) != ft_type)
+ || (u->request_sent && r->request_body_no_buffering)
+ || (timeout && ngx_current_msec - u->peer.start_time >= timeout))
+ {
+#if (NGX_HTTP_CACHE)
- ngx_http_upstream_finalize_request(r, u, rc);
- return;
+ if (u->cache_status == NGX_HTTP_CACHE_EXPIRED
+ && (u->conf->cache_use_stale & ft_type))
+ {
+ ngx_int_t rc;
+
+ rc = u->reinit_request(r);
+
+ if (rc == NGX_OK) {
+ u->cache_status = NGX_HTTP_CACHE_STALE;
+ rc = ngx_http_upstream_cache_send(r, u);
}
-#endif
- ngx_http_upstream_finalize_request(r, u, status);
+ ngx_http_upstream_finalize_request(r, u, rc);
return;
}
+#endif
+
+ ngx_http_upstream_finalize_request(r, u, status);
+ return;
}
if (u->peer.connection) {
@@ -4068,7 +4187,8 @@
if (!u->header_sent
|| rc == NGX_HTTP_REQUEST_TIME_OUT
- || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST)
+ || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST
+ || (u->pipe && u->pipe->downstream_error))
{
ngx_http_finalize_request(r, rc);
return;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/http/ngx_http_upstream.h
^
|
@@ -29,6 +29,7 @@
#define NGX_HTTP_UPSTREAM_FT_UPDATING 0x00000400
#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK 0x00000800
#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING 0x00001000
+#define NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT 0x00002000
#define NGX_HTTP_UPSTREAM_FT_NOLIVE 0x40000000
#define NGX_HTTP_UPSTREAM_FT_OFF 0x80000000
@@ -281,7 +282,7 @@
ngx_uint_t no_port; /* unsigned no_port:1 */
ngx_uint_t naddrs;
- ngx_addr_t *addrs;
+ ngx_resolver_addr_t *addrs;
struct sockaddr *sockaddr;
socklen_t socklen;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/http/v2/ngx_http_v2.c
^
|
@@ -2503,8 +2503,8 @@
ngx_http_v2_srv_conf_t *h2scf;
ngx_http_v2_out_frame_t *frame;
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
- "http2 send SETTINGS frame");
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+ "http2 send SETTINGS frame ack:%ui", ack);
frame = ngx_palloc(h2c->pool, sizeof(ngx_http_v2_out_frame_t));
if (frame == NULL) {
@@ -2595,6 +2595,10 @@
ngx_buf_t *buf;
ngx_http_v2_out_frame_t *frame;
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+ "http2 send WINDOW_UPDATE frame sid:%ui, window:%uz",
+ sid, window);
+
frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_WINDOW_UPDATE_SIZE,
NGX_HTTP_V2_WINDOW_UPDATE_FRAME,
NGX_HTTP_V2_NO_FLAG, sid);
@@ -2619,6 +2623,10 @@
ngx_buf_t *buf;
ngx_http_v2_out_frame_t *frame;
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+ "http2 send RST_STREAM frame sid:%ui, status:%uz",
+ sid, status);
+
frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_RST_STREAM_SIZE,
NGX_HTTP_V2_RST_STREAM_FRAME,
NGX_HTTP_V2_NO_FLAG, sid);
@@ -2642,6 +2650,9 @@
ngx_buf_t *buf;
ngx_http_v2_out_frame_t *frame;
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+ "http2 send GOAWAY frame, status:%uz", status);
+
frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_GOAWAY_SIZE,
NGX_HTTP_V2_GOAWAY_FRAME,
NGX_HTTP_V2_NO_FLAG, 0);
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/os/unix/ngx_darwin_init.c
^
|
@@ -23,6 +23,7 @@
ngx_readv_chain,
ngx_udp_unix_recv,
ngx_unix_send,
+ ngx_udp_unix_send,
#if (NGX_HAVE_SENDFILE)
ngx_darwin_sendfile_chain,
NGX_IO_SENDFILE
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/os/unix/ngx_errno.h
^
|
@@ -25,6 +25,7 @@
#define NGX_EACCES EACCES
#define NGX_EBUSY EBUSY
#define NGX_EEXIST EEXIST
+#define NGX_EEXIST_FILE EEXIST
#define NGX_EXDEV EXDEV
#define NGX_ENOTDIR ENOTDIR
#define NGX_EISDIR EISDIR
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/os/unix/ngx_files.c
^
|
@@ -12,9 +12,11 @@
#if (NGX_THREADS)
#include <ngx_thread_pool.h>
static void ngx_thread_read_handler(void *data, ngx_log_t *log);
+static void ngx_thread_write_chain_to_file_handler(void *data, ngx_log_t *log);
#endif
-static ssize_t ngx_writev_file(ngx_file_t *file, ngx_array_t *vec, size_t size,
+static ngx_chain_t *ngx_chain_to_iovec(ngx_iovec_t *vec, ngx_chain_t *cl);
+static ssize_t ngx_writev_file(ngx_file_t *file, ngx_iovec_t *vec,
off_t offset);
@@ -76,38 +78,39 @@
#if (NGX_THREADS)
typedef struct {
- ngx_fd_t fd;
- u_char *buf;
- size_t size;
- off_t offset;
-
- size_t read;
- ngx_err_t err;
-} ngx_thread_read_ctx_t;
+ ngx_fd_t fd;
+ ngx_uint_t write; /* unsigned write:1; */
+
+ u_char *buf;
+ size_t size;
+ ngx_chain_t *chain;
+ off_t offset;
+
+ size_t nbytes;
+ ngx_err_t err;
+} ngx_thread_file_ctx_t;
ssize_t
-ngx_thread_read(ngx_thread_task_t **taskp, ngx_file_t *file, u_char *buf,
- size_t size, off_t offset, ngx_pool_t *pool)
+ngx_thread_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset,
+ ngx_pool_t *pool)
{
ngx_thread_task_t *task;
- ngx_thread_read_ctx_t *ctx;
+ ngx_thread_file_ctx_t *ctx;
ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
"thread read: %d, %p, %uz, %O",
file->fd, buf, size, offset);
- task = *taskp;
+ task = file->thread_task;
if (task == NULL) {
- task = ngx_thread_task_alloc(pool, sizeof(ngx_thread_read_ctx_t));
+ task = ngx_thread_task_alloc(pool, sizeof(ngx_thread_file_ctx_t));
if (task == NULL) {
return NGX_ERROR;
}
- task->handler = ngx_thread_read_handler;
-
- *taskp = task;
+ file->thread_task = task;
}
ctx = task->ctx;
@@ -115,15 +118,25 @@
if (task->event.complete) {
task->event.complete = 0;
+ if (ctx->write) {
+ ngx_log_error(NGX_LOG_ALERT, file->log, 0,
+ "invalid thread call, read instead of write");
+ return NGX_ERROR;
+ }
+
if (ctx->err) {
ngx_log_error(NGX_LOG_CRIT, file->log, ctx->err,
"pread() \"%s\" failed", file->name.data);
return NGX_ERROR;
}
- return ctx->read;
+ return ctx->nbytes;
}
+ task->handler = ngx_thread_read_handler;
+
+ ctx->write = 0;
+
ctx->fd = file->fd;
ctx->buf = buf;
ctx->size = size;
@@ -142,7 +155,7 @@
static void
ngx_thread_read_handler(void *data, ngx_log_t *log)
{
- ngx_thread_read_ctx_t *ctx = data;
+ ngx_thread_file_ctx_t *ctx = data;
ssize_t n;
@@ -154,7 +167,7 @@
ctx->err = ngx_errno;
} else {
- ctx->read = n;
+ ctx->nbytes = n;
ctx->err = 0;
}
@@ -276,17 +289,13 @@
}
-#define NGX_IOVS 8
-
ssize_t
ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
ngx_pool_t *pool)
{
- u_char *prev;
- size_t size;
ssize_t total, n;
- ngx_array_t vec;
- struct iovec *iov, iovs[NGX_IOVS];
+ ngx_iovec_t vec;
+ struct iovec iovs[NGX_IOVS_PREALLOCATE];
/* use pwrite() if there is the only buf in a chain */
@@ -298,46 +307,18 @@
total = 0;
- vec.elts = iovs;
- vec.size = sizeof(struct iovec);
- vec.nalloc = NGX_IOVS;
- vec.pool = pool;
+ vec.iovs = iovs;
+ vec.nalloc = NGX_IOVS_PREALLOCATE;
do {
- prev = NULL;
- iov = NULL;
- size = 0;
-
- vec.nelts = 0;
-
/* create the iovec and coalesce the neighbouring bufs */
-
- while (cl && vec.nelts < IOV_MAX) {
- if (prev == cl->buf->pos) {
- iov->iov_len += cl->buf->last - cl->buf->pos;
-
- } else {
- iov = ngx_array_push(&vec);
- if (iov == NULL) {
- return NGX_ERROR;
- }
-
- iov->iov_base = (void *) cl->buf->pos;
- iov->iov_len = cl->buf->last - cl->buf->pos;
- }
-
- size += cl->buf->last - cl->buf->pos;
- prev = cl->buf->last;
- cl = cl->next;
- }
+ cl = ngx_chain_to_iovec(&vec, cl);
/* use pwrite() if there is the only iovec buffer */
- if (vec.nelts == 1) {
- iov = vec.elts;
-
- n = ngx_write_file(file, (u_char *) iov[0].iov_base,
- iov[0].iov_len, offset);
+ if (vec.count == 1) {
+ n = ngx_write_file(file, (u_char *) iovs[0].iov_base,
+ iovs[0].iov_len, offset);
if (n == NGX_ERROR) {
return n;
@@ -346,7 +327,7 @@
return total + n;
}
- n = ngx_writev_file(file, &vec, size, offset);
+ n = ngx_writev_file(file, &vec, offset);
if (n == NGX_ERROR) {
return n;
@@ -361,20 +342,61 @@
}
+static ngx_chain_t *
+ngx_chain_to_iovec(ngx_iovec_t *vec, ngx_chain_t *cl)
+{
+ size_t total, size;
+ u_char *prev;
+ ngx_uint_t n;
+ struct iovec *iov;
+
+ iov = NULL;
+ prev = NULL;
+ total = 0;
+ n = 0;
+
+ for ( /* void */ ; cl; cl = cl->next) {
+ size = cl->buf->last - cl->buf->pos;
+
+ if (prev == cl->buf->pos) {
+ iov->iov_len += size;
+
+ } else {
+ if (n == vec->nalloc) {
+ break;
+ }
+
+ iov = &vec->iovs[n++];
+
+ iov->iov_base = (void *) cl->buf->pos;
+ iov->iov_len = size;
+ }
+
+ prev = cl->buf->pos + size;
+ total += size;
+ }
+
+ vec->count = n;
+ vec->size = total;
+
+ return cl;
+}
+
+
static ssize_t
-ngx_writev_file(ngx_file_t *file, ngx_array_t *vec, size_t size, off_t offset)
+ngx_writev_file(ngx_file_t *file, ngx_iovec_t *vec, off_t offset)
{
ssize_t n;
ngx_err_t err;
ngx_log_debug3(NGX_LOG_DEBUG_CORE, file->log, 0,
- "writev: %d, %uz, %O", file->fd, size, offset);
+ "writev: %d, %uz, %O", file->fd, vec->size, offset);
#if (NGX_HAVE_PWRITEV)
eintr:
- n = pwritev(file->fd, vec->elts, vec->nelts, offset);
+ n = pwritev(file->fd, vec->iovs, vec->count, offset);
if (n == -1) {
err = ngx_errno;
@@ -390,10 +412,10 @@
return NGX_ERROR;
}
- if ((size_t) n != size) {
+ if ((size_t) n != vec->size) {
ngx_log_error(NGX_LOG_CRIT, file->log, 0,
"pwritev() \"%s\" has written only %z of %uz",
- file->name.data, n, size);
+ file->name.data, n, vec->size);
return NGX_ERROR;
}
@@ -411,7 +433,7 @@
eintr:
- n = writev(file->fd, vec->elts, vec->nelts);
+ n = writev(file->fd, vec->iovs, vec->count);
if (n == -1) {
err = ngx_errno;
@@ -427,10 +449,10 @@
return NGX_ERROR;
}
- if ((size_t) n != size) {
+ if ((size_t) n != vec->size) {
ngx_log_error(NGX_LOG_CRIT, file->log, 0,
"writev() \"%s\" has written only %z of %uz",
- file->name.data, n, size);
+ file->name.data, n, vec->size);
return NGX_ERROR;
}
@@ -444,6 +466,132 @@
}
+#if (NGX_THREADS)
+
+ssize_t
+ngx_thread_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
+ ngx_pool_t *pool)
+{
+ ngx_thread_task_t *task;
+ ngx_thread_file_ctx_t *ctx;
+
+ ngx_log_debug3(NGX_LOG_DEBUG_CORE, file->log, 0,
+ "thread write chain: %d, %p, %O",
+ file->fd, cl, offset);
+
+ task = file->thread_task;
+
+ if (task == NULL) {
+ task = ngx_thread_task_alloc(pool,
+ sizeof(ngx_thread_file_ctx_t));
+ if (task == NULL) {
+ return NGX_ERROR;
+ }
+
+ file->thread_task = task;
+ }
+
+ ctx = task->ctx;
+
+ if (task->event.complete) {
+ task->event.complete = 0;
+
+ if (!ctx->write) {
+ ngx_log_error(NGX_LOG_ALERT, file->log, 0,
+ "invalid thread call, write instead of read");
+ return NGX_ERROR;
+ }
+
+ if (ctx->err || ctx->nbytes == 0) {
+ ngx_log_error(NGX_LOG_CRIT, file->log, ctx->err,
+ "pwritev() \"%s\" failed", file->name.data);
+ return NGX_ERROR;
+ }
+
+ file->offset += ctx->nbytes;
+ return ctx->nbytes;
+ }
+
+ task->handler = ngx_thread_write_chain_to_file_handler;
+
+ ctx->write = 1;
+
+ ctx->fd = file->fd;
+ ctx->chain = cl;
+ ctx->offset = offset;
+
+ if (file->thread_handler(task, file) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ return NGX_AGAIN;
+}
+
+
+static void
+ngx_thread_write_chain_to_file_handler(void *data, ngx_log_t *log)
+{
+ ngx_thread_file_ctx_t *ctx = data;
+
+#if (NGX_HAVE_PWRITEV)
+
+ off_t offset;
+ ssize_t n;
+ ngx_err_t err;
+ ngx_chain_t *cl;
+ ngx_iovec_t vec;
+ struct iovec iovs[NGX_IOVS_PREALLOCATE];
+
+ vec.iovs = iovs;
+ vec.nalloc = NGX_IOVS_PREALLOCATE;
+
+ cl = ctx->chain;
+ offset = ctx->offset;
+
+ ctx->nbytes = 0;
+ ctx->err = 0;
+
+ do {
+ /* create the iovec and coalesce the neighbouring bufs */
+ cl = ngx_chain_to_iovec(&vec, cl);
+
+eintr:
+
+ n = pwritev(ctx->fd, iovs, vec.count, offset);
+
+ if (n == -1) {
+ err = ngx_errno;
+
+ if (err == NGX_EINTR) {
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, err,
+ "pwritev() was interrupted");
+ goto eintr;
+ }
+
+ ctx->err = err;
+ return;
+ }
+
+ if ((size_t) n != vec.size) {
+ ctx->nbytes = 0;
+ return;
+ }
+
+ ctx->nbytes += n;
+ offset += n;
+ } while (cl);
+
+#else
+
+ ctx->err = NGX_ENOSYS;
+ return;
+
+#endif
+}
+
+#endif /* NGX_THREADS */
+
+
ngx_int_t
ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s)
{
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/os/unix/ngx_files.h
^
|
@@ -385,8 +385,10 @@
#endif
#if (NGX_THREADS)
-ssize_t ngx_thread_read(ngx_thread_task_t **taskp, ngx_file_t *file,
- u_char *buf, size_t size, off_t offset, ngx_pool_t *pool);
+ssize_t ngx_thread_read(ngx_file_t *file, u_char *buf, size_t size,
+ off_t offset, ngx_pool_t *pool);
+ssize_t ngx_thread_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl,
+ off_t offset, ngx_pool_t *pool);
#endif
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/os/unix/ngx_freebsd_init.c
^
|
@@ -32,6 +32,7 @@
ngx_readv_chain,
ngx_udp_unix_recv,
ngx_unix_send,
+ ngx_udp_unix_send,
#if (NGX_HAVE_SENDFILE)
ngx_freebsd_sendfile_chain,
NGX_IO_SENDFILE
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/os/unix/ngx_freebsd_sendfile_chain.c
^
|
@@ -247,6 +247,19 @@
#if (NGX_HAVE_AIO_SENDFILE)
if (ebusy) {
+ if (aio->event.active) {
+ /*
+ * tolerate duplicate calls; they can happen due to subrequests
+ * or multiple calls of the next body filter from a filter
+ */
+
+ if (sent) {
+ c->busy_count = 0;
+ }
+
+ return in;
+ }
+
if (sent == 0) {
c->busy_count++;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/os/unix/ngx_linux_init.c
^
|
@@ -18,6 +18,7 @@
ngx_readv_chain,
ngx_udp_unix_recv,
ngx_unix_send,
+ ngx_udp_unix_send,
#if (NGX_HAVE_SENDFILE)
ngx_linux_sendfile_chain,
NGX_IO_SENDFILE
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/os/unix/ngx_linux_sendfile_chain.c
^
|
@@ -292,6 +292,19 @@
}
}
+ if (n == 0) {
+ /*
+ * if sendfile returns zero, then someone has truncated the file,
+ * so the offset became beyond the end of the file
+ */
+
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+ "sendfile() reported that \"%s\" was truncated at %O",
+ file->file->name.data, file->file_pos);
+
+ return NGX_ERROR;
+ }
+
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "sendfile: %z of %uz @%O",
n, size, file->file_pos);
@@ -315,7 +328,6 @@
ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size,
size_t *sent)
{
- ngx_uint_t flags;
ngx_event_t *wev;
ngx_thread_task_t *task;
ngx_linux_sendfile_ctx_t *ctx;
@@ -343,29 +355,60 @@
if (task->event.complete) {
task->event.complete = 0;
- if (ctx->err && ctx->err != NGX_EAGAIN) {
+ if (ctx->err == NGX_EAGAIN) {
+ *sent = 0;
+
+ if (wev->complete) {
+ return NGX_DONE;
+ }
+
+ return NGX_AGAIN;
+ }
+
+ if (ctx->err) {
wev->error = 1;
ngx_connection_error(c, ctx->err, "sendfile() failed");
return NGX_ERROR;
}
+ if (ctx->sent == 0) {
+ /*
+ * if sendfile returns zero, then someone has truncated the file,
+ * so the offset became beyond the end of the file
+ */
+
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+ "sendfile() reported that \"%s\" was truncated at %O",
+ file->file->name.data, file->file_pos);
+
+ return NGX_ERROR;
+ }
+
*sent = ctx->sent;
- return (ctx->sent == ctx->size) ? NGX_DONE : NGX_AGAIN;
+ if (ctx->sent == ctx->size || wev->complete) {
+ return NGX_DONE;
+ }
+
+ return NGX_AGAIN;
+ }
+
+ if (task->event.active && ctx->file == file) {
+ /*
+ * tolerate duplicate calls; they can happen due to subrequests
+ * or multiple calls of the next body filter from a filter
+ */
+
+ *sent = 0;
+
+ return NGX_OK;
}
ctx->file = file;
ctx->socket = c->fd;
ctx->size = size;
- if (wev->active) {
- flags = (ngx_event_flags & NGX_USE_CLEAR_EVENT) ? NGX_CLEAR_EVENT
- : NGX_LEVEL_EVENT;
-
- if (ngx_del_event(wev, NGX_WRITE_EVENT, flags) == NGX_ERROR) {
- return NGX_ERROR;
- }
- }
+ wev->complete = 0;
if (file->file->thread_handler(task, file->file) != NGX_OK) {
return NGX_ERROR;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/os/unix/ngx_os.h
^
|
@@ -28,6 +28,7 @@
ngx_recv_chain_pt recv_chain;
ngx_recv_pt udp_recv;
ngx_send_pt send;
+ ngx_send_pt udp_send;
ngx_send_chain_pt send_chain;
ngx_uint_t flags;
} ngx_os_io_t;
@@ -47,6 +48,7 @@
ssize_t ngx_unix_send(ngx_connection_t *c, u_char *buf, size_t size);
ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in,
off_t limit);
+ssize_t ngx_udp_unix_send(ngx_connection_t *c, u_char *buf, size_t size);
#if (IOV_MAX > 64)
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/os/unix/ngx_posix_config.h
^
|
@@ -128,7 +128,7 @@
#endif
-#if (NGX_HAVE_DEVPOLL)
+#if (NGX_HAVE_DEVPOLL) && !(NGX_TEST_BUILD_DEVPOLL)
#include <sys/ioctl.h>
#include <sys/devpoll.h>
#endif
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/os/unix/ngx_posix_init.c
^
|
@@ -24,6 +24,7 @@
ngx_readv_chain,
ngx_udp_unix_recv,
ngx_unix_send,
+ ngx_udp_unix_send,
ngx_writev_chain,
0
};
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/os/unix/ngx_solaris_init.c
^
|
@@ -19,6 +19,7 @@
ngx_readv_chain,
ngx_udp_unix_recv,
ngx_unix_send,
+ ngx_udp_unix_send,
#if (NGX_HAVE_SENDFILE)
ngx_solaris_sendfilev_chain,
NGX_IO_SENDFILE
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/os/unix/ngx_solaris_sendfilev_chain.c
^
|
@@ -48,6 +48,7 @@
ssize_t n;
ngx_int_t eintr;
ngx_err_t err;
+ ngx_buf_t *file;
ngx_uint_t nsfv;
sendfilevec_t *sfv, sfvs[NGX_SENDFILEVECS];
ngx_event_t *wev;
@@ -77,6 +78,7 @@
fd = SFV_FD_SELF;
prev = NULL;
fprev = 0;
+ file = NULL;
sfv = NULL;
eintr = 0;
sent = 0;
@@ -153,6 +155,7 @@
sfv->sfv_len = (size_t) size;
}
+ file = cl->buf;
fprev = cl->buf->file_pos + size;
send += size;
}
@@ -179,6 +182,26 @@
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
"sendfilev() sent only %uz bytes", sent);
+
+ } else if (n == 0 && sent == 0) {
+
+ /*
+ * sendfilev() is documented to return -1 with errno
+ * set to EINVAL if svf_len is greater than the file size,
+ * but at least Solaris 11 returns 0 instead
+ */
+
+ if (file) {
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+ "sendfilev() reported that \"%s\" was truncated at %O",
+ file->file->name.data, file->file_pos);
+
+ } else {
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+ "sendfilev() returned 0 with memory buffers");
+ }
+
+ return NGX_CHAIN_ERROR;
}
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
[-]
[+]
|
Added |
nginx-1.9.13.tar.gz/src/os/unix/ngx_udp_send.c
^
|
@@ -0,0 +1,56 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+
+
+ssize_t
+ngx_udp_unix_send(ngx_connection_t *c, u_char *buf, size_t size)
+{
+ ssize_t n;
+ ngx_err_t err;
+ ngx_event_t *wev;
+
+ wev = c->write;
+
+ for ( ;; ) {
+ n = sendto(c->fd, buf, size, 0, c->sockaddr, c->socklen);
+
+ ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "sendto: fd:%d %z of %uz to \"%V\"",
+ c->fd, n, size, &c->addr_text);
+
+ if (n >= 0) {
+ if ((size_t) n != size) {
+ wev->error = 1;
+ (void) ngx_connection_error(c, 0, "sendto() incomplete");
+ return NGX_ERROR;
+ }
+
+ c->sent += n;
+
+ return n;
+ }
+
+ err = ngx_socket_errno;
+
+ if (err == NGX_EAGAIN) {
+ wev->ready = 0;
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, NGX_EAGAIN,
+ "sendto() not ready");
+ return NGX_AGAIN;
+ }
+
+ if (err != NGX_EINTR) {
+ wev->error = 1;
+ (void) ngx_connection_error(c, err, "sendto() failed");
+ return NGX_ERROR;
+ }
+ }
+}
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/stream/ngx_stream.c
^
|
@@ -275,8 +275,11 @@
port = ports->elts;
for (i = 0; i < ports->nelts; i++) {
- if (p == port[i].port && sa->sa_family == port[i].family) {
+ if (p == port[i].port
+ && listen->type == port[i].type
+ && sa->sa_family == port[i].family)
+ {
/* a port is already in the port list */
port = &port[i];
@@ -292,6 +295,7 @@
}
port->family = sa->sa_family;
+ port->type = listen->type;
port->port = p;
if (ngx_array_init(&port->addrs, cf->temp_pool, 2,
@@ -364,6 +368,7 @@
ls->addr_ntop = 1;
ls->handler = ngx_stream_init_connection;
ls->pool_size = 256;
+ ls->type = addr[i].opt.type;
cscf = addr->opt.ctx->srv_conf[ngx_stream_core_module.ctx_index];
@@ -373,6 +378,8 @@
ls->backlog = addr[i].opt.backlog;
+ ls->wildcard = addr[i].opt.wildcard;
+
ls->keepalive = addr[i].opt.so_keepalive;
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
ls->keepidle = addr[i].opt.tcp_keepidle;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/stream/ngx_stream.h
^
|
@@ -66,6 +66,7 @@
int tcp_keepcnt;
#endif
int backlog;
+ int type;
} ngx_stream_listen_t;
@@ -102,6 +103,7 @@
typedef struct {
int family;
+ int type;
in_port_t port;
ngx_array_t addrs; /* array of ngx_stream_conf_addr_t */
} ngx_stream_conf_port_t;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/stream/ngx_stream_core_module.c
^
|
@@ -252,7 +252,7 @@
in_port_t port;
ngx_str_t *value;
ngx_url_t u;
- ngx_uint_t i;
+ ngx_uint_t i, backlog;
struct sockaddr *sa;
struct sockaddr_in *sin;
ngx_stream_listen_t *ls;
@@ -343,6 +343,7 @@
ls->socklen = u.socklen;
ls->backlog = NGX_LISTEN_BACKLOG;
+ ls->type = SOCK_STREAM;
ls->wildcard = u.wildcard;
ls->ctx = cf->ctx;
@@ -350,8 +351,17 @@
ls->ipv6only = 1;
#endif
+ backlog = 0;
+
for (i = 2; i < cf->args->nelts; i++) {
+#if !(NGX_WIN32)
+ if (ngx_strcmp(value[i].data, "udp") == 0) {
+ ls->type = SOCK_DGRAM;
+ continue;
+ }
+#endif
+
if (ngx_strcmp(value[i].data, "bind") == 0) {
ls->bind = 1;
continue;
@@ -367,6 +377,8 @@
return NGX_CONF_ERROR;
}
+ backlog = 1;
+
continue;
}
@@ -530,5 +542,21 @@
return NGX_CONF_ERROR;
}
+ if (ls->type == SOCK_DGRAM) {
+ if (backlog) {
+ return "\"backlog\" parameter is incompatible with \"udp\"";
+ }
+
+#if (NGX_STREAM_SSL)
+ if (ls->ssl) {
+ return "\"ssl\" parameter is incompatible with \"udp\"";
+ }
+#endif
+
+ if (ls->so_keepalive) {
+ return "\"so_keepalive\" parameter is incompatible with \"udp\"";
+ }
+ }
+
return NGX_CONF_OK;
}
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/stream/ngx_stream_handler.c
^
|
@@ -52,7 +52,7 @@
* is the "*:port" wildcard so getsockname() is needed to determine
* the server address.
*
- * AcceptEx() already gave this address.
+ * AcceptEx() and recvmsg() already gave this address.
*/
if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
@@ -137,8 +137,9 @@
len = ngx_sock_ntop(c->sockaddr, c->socklen, text, NGX_SOCKADDR_STRLEN, 1);
- ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%uA client %*s connected to %V",
- c->number, len, text, &addr_conf->addr_text);
+ ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%uA %sclient %*s connected to %V",
+ c->number, c->type == SOCK_DGRAM ? "udp " : "",
+ len, text, &addr_conf->addr_text);
c->log->connection = c->number;
c->log->handler = ngx_stream_log_error;
@@ -166,7 +167,10 @@
}
}
- if (cscf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
+ if (c->type == SOCK_STREAM
+ && cscf->tcp_nodelay
+ && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
+ {
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, "tcp_nodelay");
tcp_nodelay = 1;
@@ -325,7 +329,8 @@
s = log->data;
- p = ngx_snprintf(buf, len, ", client: %V, server: %V",
+ p = ngx_snprintf(buf, len, ", %sclient: %V, server: %V",
+ s->connection->type == SOCK_DGRAM ? "udp " : "",
&s->connection->addr_text,
&s->connection->listening->addr_text);
len -= p - buf;
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/stream/ngx_stream_proxy_module.c
^
|
@@ -17,6 +17,7 @@
size_t buffer_size;
size_t upload_rate;
size_t download_rate;
+ ngx_uint_t responses;
ngx_uint_t next_upstream_tries;
ngx_flag_t next_upstream;
ngx_flag_t proxy_protocol;
@@ -54,7 +55,7 @@
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,
+static void ngx_stream_proxy_process(ngx_stream_session_t *s,
ngx_uint_t from_upstream, ngx_uint_t do_write);
static void ngx_stream_proxy_next_upstream(ngx_stream_session_t *s);
static void ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_int_t rc);
@@ -167,6 +168,13 @@
offsetof(ngx_stream_proxy_srv_conf_t, download_rate),
NULL },
+ { ngx_string("proxy_responses"),
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ NGX_STREAM_SRV_CONF_OFFSET,
+ offsetof(ngx_stream_proxy_srv_conf_t, responses),
+ NULL },
+
{ ngx_string("proxy_next_upstream"),
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
@@ -351,6 +359,7 @@
u->peer.log_error = NGX_ERROR_ERR;
u->peer.local = pscf->local;
+ u->peer.type = c->type;
uscf = pscf->upstream;
@@ -370,6 +379,14 @@
u->proxy_protocol = pscf->proxy_protocol;
u->start_sec = ngx_time();
+ c->write->handler = ngx_stream_proxy_downstream_handler;
+ c->read->handler = ngx_stream_proxy_downstream_handler;
+
+ if (c->type == SOCK_DGRAM) {
+ ngx_stream_proxy_connect(s);
+ return;
+ }
+
p = ngx_pnalloc(c->pool, pscf->buffer_size);
if (p == NULL) {
ngx_stream_proxy_finalize(s, NGX_ERROR);
@@ -381,9 +398,6 @@
u->downstream_buf.pos = p;
u->downstream_buf.last = p;
- 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
@@ -406,8 +420,8 @@
u->proxy_protocol = 0;
}
- if (ngx_stream_proxy_process(s, 0, 0) != NGX_OK) {
- return;
+ if (c->read->ready) {
+ ngx_post_event(c->read, &ngx_posted_events);
}
ngx_stream_proxy_connect(s);
@@ -488,7 +502,10 @@
cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
- if (cscf->tcp_nodelay && pc->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
+ if (pc->type == SOCK_STREAM
+ && cscf->tcp_nodelay
+ && pc->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
+ {
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0, "tcp_nodelay");
tcp_nodelay = 1;
@@ -516,7 +533,7 @@
pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
#if (NGX_STREAM_SSL)
- if (pscf->ssl && pc->ssl == NULL) {
+ if (pc->type == SOCK_STREAM && pscf->ssl && pc->ssl == NULL) {
ngx_stream_proxy_ssl_init_connection(s);
return;
}
@@ -535,7 +552,9 @@
handler = c->log->handler;
c->log->handler = NULL;
- ngx_log_error(NGX_LOG_INFO, c->log, 0, "proxy %V connected to %V",
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "%sproxy %V connected to %V",
+ pc->type == SOCK_DGRAM ? "udp " : "",
&str, u->peer.name);
c->log->handler = handler;
@@ -544,24 +563,36 @@
c->log->action = "proxying connection";
- p = ngx_pnalloc(c->pool, pscf->buffer_size);
- if (p == NULL) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
- return;
+ if (u->upstream_buf.start == NULL) {
+ p = ngx_pnalloc(c->pool, pscf->buffer_size);
+ if (p == NULL) {
+ ngx_stream_proxy_finalize(s, NGX_ERROR);
+ return;
+ }
+
+ u->upstream_buf.start = p;
+ u->upstream_buf.end = p + pscf->buffer_size;
+ u->upstream_buf.pos = p;
+ u->upstream_buf.last = p;
}
- u->upstream_buf.start = p;
- u->upstream_buf.end = p + pscf->buffer_size;
- u->upstream_buf.pos = p;
- u->upstream_buf.last = p;
+ if (c->type == SOCK_DGRAM) {
+ s->received = c->buffer->last - c->buffer->pos;
+ u->downstream_buf = *c->buffer;
+
+ if (pscf->responses == 0) {
+ pc->read->ready = 0;
+ pc->read->eof = 1;
+ }
+ }
u->connected = 1;
pc->read->handler = ngx_stream_proxy_upstream_handler;
pc->write->handler = ngx_stream_proxy_upstream_handler;
- if (ngx_stream_proxy_process(s, 1, 0) != NGX_OK) {
- return;
+ if (pc->read->ready || pc->read->eof) {
+ ngx_post_event(pc->read, &ngx_posted_events);
}
ngx_stream_proxy_process(s, 0, 1);
@@ -894,11 +925,15 @@
s = c->data;
u = s->upstream;
+ c = s->connection;
+ pc = u->peer.connection;
+
+ pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
+
if (ev->timedout) {
+ ev->timedout = 0;
if (ev->delayed) {
-
- ev->timedout = 0;
ev->delayed = 0;
if (!ev->ready) {
@@ -907,20 +942,35 @@
return;
}
- if (u->connected) {
- pc = u->peer.connection;
-
- 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);
- }
+ if (u->connected && !c->read->delayed && !pc->read->delayed) {
+ ngx_add_timer(c->write, pscf->timeout);
}
return;
}
} else {
+ if (s->connection->type == SOCK_DGRAM) {
+ if (pscf->responses == NGX_MAX_INT32_VALUE) {
+
+ /*
+ * successfully terminate timed out UDP session
+ * with unspecified number of responses
+ */
+
+ pc->read->ready = 0;
+ pc->read->eof = 1;
+
+ ngx_stream_proxy_process(s, 1, 0);
+ return;
+ }
+
+ if (u->received == 0) {
+ ngx_stream_proxy_next_upstream(s);
+ return;
+ }
+ }
+
ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out");
ngx_stream_proxy_finalize(s, NGX_DECLINED);
return;
@@ -1019,7 +1069,7 @@
}
-static ngx_int_t
+static void
ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream,
ngx_uint_t do_write)
{
@@ -1039,6 +1089,21 @@
c = s->connection;
pc = u->connected ? u->peer.connection : NULL;
+ if (c->type == SOCK_DGRAM && (ngx_terminate || ngx_exiting)) {
+
+ /* socket is already closed on worker shutdown */
+
+ handler = c->log->handler;
+ c->log->handler = NULL;
+
+ ngx_log_error(NGX_LOG_INFO, c->log, 0, "disconnected on shutdown");
+
+ c->log->handler = handler;
+
+ ngx_stream_proxy_finalize(s, NGX_OK);
+ return;
+ }
+
pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
if (from_upstream) {
@@ -1066,9 +1131,19 @@
n = dst->send(dst, b->pos, size);
+ if (n == NGX_AGAIN && dst->shared) {
+ /* cannot wait on a shared socket */
+ n = NGX_ERROR;
+ }
+
if (n == NGX_ERROR) {
+ if (c->type == SOCK_DGRAM && !from_upstream) {
+ ngx_stream_proxy_next_upstream(s);
+ return;
+ }
+
ngx_stream_proxy_finalize(s, NGX_DECLINED);
- return NGX_ERROR;
+ return;
}
if (n > 0) {
@@ -1118,6 +1193,12 @@
}
}
+ if (c->type == SOCK_DGRAM && ++u->responses == pscf->responses)
+ {
+ src->read->ready = 0;
+ src->read->eof = 1;
+ }
+
*received += n;
b->last += n;
do_write = 1;
@@ -1126,6 +1207,11 @@
}
if (n == NGX_ERROR) {
+ if (c->type == SOCK_DGRAM && u->received == 0) {
+ ngx_stream_proxy_next_upstream(s);
+ return;
+ }
+
src->read->eof = 1;
}
}
@@ -1138,29 +1224,30 @@
c->log->handler = NULL;
ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "%s disconnected"
+ "%s%s disconnected"
", bytes from/to client:%O/%O"
", bytes from/to upstream:%O/%O",
+ src->type == SOCK_DGRAM ? "udp " : "",
from_upstream ? "upstream" : "client",
s->received, c->sent, u->received, pc ? pc->sent : 0);
c->log->handler = handler;
ngx_stream_proxy_finalize(s, NGX_OK);
- return NGX_DONE;
+ return;
}
flags = src->read->eof ? NGX_CLOSE_EVENT : 0;
- if (ngx_handle_read_event(src->read, flags) != NGX_OK) {
+ if (!src->shared && ngx_handle_read_event(src->read, flags) != NGX_OK) {
ngx_stream_proxy_finalize(s, NGX_ERROR);
- return NGX_ERROR;
+ return;
}
if (dst) {
- if (ngx_handle_write_event(dst->write, 0) != NGX_OK) {
+ if (!dst->shared && ngx_handle_write_event(dst->write, 0) != NGX_OK) {
ngx_stream_proxy_finalize(s, NGX_ERROR);
- return NGX_ERROR;
+ return;
}
if (!c->read->delayed && !pc->read->delayed) {
@@ -1170,8 +1257,6 @@
ngx_del_timer(c->write);
}
}
-
- return NGX_OK;
}
@@ -1333,6 +1418,7 @@
conf->buffer_size = NGX_CONF_UNSET_SIZE;
conf->upload_rate = NGX_CONF_UNSET_SIZE;
conf->download_rate = NGX_CONF_UNSET_SIZE;
+ conf->responses = NGX_CONF_UNSET_UINT;
conf->next_upstream_tries = NGX_CONF_UNSET_UINT;
conf->next_upstream = NGX_CONF_UNSET;
conf->proxy_protocol = NGX_CONF_UNSET;
@@ -1375,6 +1461,9 @@
ngx_conf_merge_size_value(conf->download_rate,
prev->download_rate, 0);
+ ngx_conf_merge_uint_value(conf->responses,
+ prev->responses, NGX_MAX_INT32_VALUE);
+
ngx_conf_merge_uint_value(conf->next_upstream_tries,
prev->next_upstream_tries, 0);
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/stream/ngx_stream_upstream.c
^
|
@@ -388,7 +388,7 @@
uscf->port = u->port;
uscf->no_port = u->no_port;
- if (u->naddrs == 1) {
+ if (u->naddrs == 1 && (u->port || u->family == AF_UNIX)) {
uscf->servers = ngx_array_create(cf->pool, 1,
sizeof(ngx_stream_upstream_server_t));
if (uscf->servers == NULL) {
|
[-]
[+]
|
Changed |
nginx-1.9.13.tar.gz/src/stream/ngx_stream_upstream.h
^
|
@@ -84,6 +84,7 @@
ngx_buf_t upstream_buf;
off_t received;
time_t start_sec;
+ ngx_uint_t responses;
#if (NGX_STREAM_SSL)
ngx_str_t ssl_name;
#endif
|