[-]
[+]
|
Changed |
nginx-1.11.changes
|
|
[-]
[+]
|
Changed |
nginx-1.11.spec
^
|
|
[-]
[+]
|
Deleted |
nginx-1.11.0.tar.bz2/auto/lib/md5
^
|
-(directory)
|
[-]
[+]
|
Deleted |
nginx-1.11.0.tar.bz2/auto/lib/md5/conf
^
|
@@ -1,103 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-if [ $MD5 != NONE ]; then
-
- if grep MD5_Init $MD5/md5.h 2>&1 >/dev/null; then
- # OpenSSL md5
- OPENSSL_MD5=YES
- have=NGX_HAVE_OPENSSL_MD5 . auto/have
- have=NGX_OPENSSL_MD5 . auto/have
- else
- # rsaref md5
- OPENSSL_MD5=NO
- fi
-
- have=NGX_HAVE_MD5 . auto/have
- CORE_INCS="$CORE_INCS $MD5"
-
- case "$NGX_CC_NAME" in
-
- msvc | owc | bcc)
- LINK_DEPS="$LINK_DEPS $MD5/md5.lib"
- CORE_LIBS="$CORE_LIBS $MD5/md5.lib"
- ;;
-
- icc)
- LINK_DEPS="$LINK_DEPS $MD5/libmd5.a"
-
- # to allow -ipo optimization we link with the *.o but not library
- CORE_LIBS="$CORE_LIBS $MD5/md5_dgst.o"
-
- if [ $MD5_ASM = YES ]; then
- CORE_LIBS="$CORE_LIBS $MD5/asm/mx86-elf.o"
- fi
- ;;
-
- *)
- LINK_DEPS="$LINK_DEPS $MD5/libmd5.a"
- CORE_LIBS="$CORE_LIBS $MD5/libmd5.a"
- #CORE_LIBS="$CORE_LIBS -L $MD5 -lmd5"
- ;;
-
- esac
-
-else
-
- if [ "$NGX_PLATFORM" != win32 ]; then
-
- MD5=NO
-
- # FreeBSD, Solaris 10
-
- ngx_feature="md5 in system md library"
- ngx_feature_name=NGX_HAVE_MD5
- ngx_feature_run=no
- ngx_feature_incs="#include <md5.h>"
- ngx_feature_path=
- ngx_feature_libs="-lmd"
- ngx_feature_test="MD5_CTX md5; MD5Init(&md5)"
- . auto/feature
-
- ngx_md5_lib="system md"
-
- if [ $ngx_found = no ]; then
-
- # Solaris 8/9
-
- ngx_feature="md5 in system md5 library"
- ngx_feature_libs="-lmd5"
- . auto/feature
-
- ngx_md5_lib="system md5"
- fi
-
- if [ $ngx_found = no ]; then
-
- # OpenSSL crypto library
-
- ngx_feature="md5 in system OpenSSL crypto library"
- ngx_feature_name="NGX_OPENSSL_MD5"
- ngx_feature_incs="#include <openssl/md5.h>"
- ngx_feature_libs="-lcrypto"
- ngx_feature_test="MD5_CTX md5; MD5_Init(&md5)"
- . auto/feature
-
- ngx_md5_lib="system crypto"
-
- if [ $ngx_found = yes ]; then
- have=NGX_HAVE_OPENSSL_MD5_H . auto/have
- have=NGX_HAVE_MD5 . auto/have
- fi
- fi
-
- if [ $ngx_found = yes ]; then
- CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
- MD5=YES
- MD5_LIB=$ngx_md5_lib
- fi
- fi
-
-fi
|
[-]
[+]
|
Deleted |
nginx-1.11.0.tar.bz2/auto/lib/md5/make
^
|
@@ -1,96 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-case "$NGX_CC_NAME" in
-
- msvc)
- ngx_makefile=makefile.msvc
- ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC MD5_ASM=$MD5_ASM"
- ngx_md5="MD5=\"$MD5\""
- ;;
-
- owc)
- ngx_makefile=makefile.owc
- ngx_opt="CPU_OPT=\"$CPU_OPT\""
- ngx_md5=`echo MD5=\"$MD5\" | sed -e "s/\//$ngx_regex_dirsep/g"`
- ;;
-
- bcc)
- ngx_makefile=makefile.bcc
- ngx_opt="-DCPU_OPT=\"$CPU_OPT\" -DMD5_ASM=$MD5_ASM"
- ngx_md5=`echo \-DMD5=\"$MD5\" | sed -e "s/\//$ngx_regex_dirsep/g"`
- ;;
-
-esac
-
-
-done=NO
-
-
-case "$NGX_PLATFORM" in
-
- win32)
- cat << END >> $NGX_MAKEFILE
-
-`echo "$MD5/md5.lib: $NGX_MAKEFILE" | sed -e "s/\//$ngx_regex_dirsep/g"`
- \$(MAKE) -f auto/lib/md5/$ngx_makefile $ngx_opt $ngx_md5
-
-END
-
- done=YES
- ;;
-
- SunOS:*:i86pc)
- if [ $MD5_ASM = YES ]; then
-
- cat << END >> $NGX_MAKEFILE
-
-$MD5/libmd5.a: $NGX_MAKEFILE
- cd $MD5 \\
- && \$(MAKE) CFLAGS="$MD5_OPT -DSOL -DMD5_ASM -DL_ENDIAN" \\
- CC="\$(CC)" CPP="\$(CPP)" \\
- MD5_ASM_OBJ=asm/mx86-sol.o clean libmd5.a
-
-END
-
- done=YES
- fi
- ;;
-
- # FreeBSD: i386
- # Linux: i686
-
- *:i386 | *:i686)
- if [ $MD5_ASM = YES ]; then
-
- cat << END >> $NGX_MAKEFILE
-
-$MD5/libmd5.a: $NGX_MAKEFILE
- cd $MD5 \\
- && \$(MAKE) CFLAGS="$MD5_OPT -DELF -DMD5_ASM -DL_ENDIAN" \\
- CC="\$(CC)" CPP="\$(CPP)" \\
- MD5_ASM_OBJ=asm/mx86-elf.o clean libmd5.a
-
-END
-
- done=YES
- fi
- ;;
-
-esac
-
-
-if [ $done = NO ]; then
-
- cat << END >> $NGX_MAKEFILE
-
-$MD5/libmd5.a: $NGX_MAKEFILE
- cd $MD5 \\
- && \$(MAKE) CFLAGS="$MD5_OPT" \\
- CC="\$(CC)" MD5_ASM_OBJ= clean libmd5.a
-
-END
-
-fi
|
[-]
[+]
|
Deleted |
nginx-1.11.0.tar.bz2/auto/lib/md5/makefile.bcc
^
|
@@ -1,22 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -q -O2 -tWM $(CPU_OPT) -DL_ENDIAN
-
-!if "$(MD5_ASM)" == "YES"
-
-md5.lib:
- cd $(MD5)
- bcc32 -c $(CFLAGS) -DMD5_ASM md5_dgst.c
- tlib md5.lib +md5_dgst.obj +"asm\m-win32.obj"
-
-!else
-
-md5.lib:
- cd $(MD5)
- bcc32 -c $(CFLAGS) md5_dgst.c
- tlib md5.lib +md5_dgst.obj
-
-!endif
|
[-]
[+]
|
Deleted |
nginx-1.11.0.tar.bz2/auto/lib/md5/makefile.msvc
^
|
@@ -1,22 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -nologo -O2 -Ob1 -Oi -Gs $(LIBC) $(CPU_OPT) -D L_ENDIAN
-
-!IF "$(MD5_ASM)" == "YES"
-
-md5.lib:
- cd $(MD5)
- cl -c $(CFLAGS) -D MD5_ASM md5_dgst.c
- link -lib -out:md5.lib md5_dgst.obj asm/m-win32.obj
-
-!ELSE
-
-md5.lib:
- cd $(MD5)
- cl -c $(CFLAGS) md5_dgst.c
- link -lib -out:md5.lib md5_dgst.obj
-
-!ENDIF
|
[-]
[+]
|
Deleted |
nginx-1.11.0.tar.bz2/auto/lib/md5/makefile.owc
^
|
@@ -1,11 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -zq -bt=nt -bm -ot -op -oi -oe -s $(CPU_OPT)
-
-md5.lib:
- cd $(MD5)
- wcl386 -c $(CFLAGS) -dL_ENDIAN md5_dgst.c
- wlib -n md5.lib md5_dgst.obj
|
[-]
[+]
|
Deleted |
nginx-1.11.0.tar.bz2/auto/lib/sha1
^
|
-(directory)
|
[-]
[+]
|
Deleted |
nginx-1.11.0.tar.bz2/auto/lib/sha1/conf
^
|
@@ -1,79 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-if [ $SHA1 != NONE ]; then
-
- have=NGX_HAVE_SHA1 . auto/have
- CORE_INCS="$CORE_INCS $SHA1"
-
- case "$NGX_CC_NAME" in
-
- msvc | owc | bcc)
- LINK_DEPS="$LINK_DEPS $SHA1/sha1.lib"
- CORE_LIBS="$CORE_LIBS $SHA1/sha1.lib"
- ;;
-
- icc)
- LINK_DEPS="$LINK_DEPS $SHA1/libsha.a"
-
- # to allow -ipo optimization we link with the *.o but not library
- CORE_LIBS="$CORE_LIBS $SHA1/sha1_dgst.o"
-
- if [ $SHA1_ASM = YES ]; then
- CORE_LIBS="$CORE_LIBS $SHA1/asm/sx86-elf.o"
- fi
- ;;
-
- *)
- LINK_DEPS="$LINK_DEPS $SHA1/libsha.a"
- CORE_LIBS="$CORE_LIBS $SHA1/libsha.a"
- #CORE_LIBS="$CORE_LIBS -L $SHA1 -lsha"
- ;;
-
- esac
-
-else
-
- if [ "$NGX_PLATFORM" != win32 ]; then
-
- SHA1=NO
-
- # FreeBSD
-
- ngx_feature="sha1 in system md library"
- ngx_feature_name=NGX_HAVE_SHA1
- ngx_feature_run=no
- ngx_feature_incs="#include <sha.h>"
- ngx_feature_path=
- ngx_feature_libs="-lmd"
- ngx_feature_test="SHA_CTX sha1; SHA1_Init(&sha1)"
- . auto/feature
-
- ngx_sha1_lib="system md"
-
- if [ $ngx_found = no ]; then
-
- # OpenSSL crypto library
-
- ngx_feature="sha1 in system OpenSSL crypto library"
- ngx_feature_incs="#include <openssl/sha.h>"
- ngx_feature_libs="-lcrypto"
- . auto/feature
-
- ngx_sha1_lib="system crypto"
-
- if [ $ngx_found = yes ]; then
- have=NGX_HAVE_OPENSSL_SHA1_H . auto/have
- fi
- fi
-
- if [ $ngx_found = yes ]; then
- CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
- SHA1=YES
- SHA1_LIB=$ngx_sha1_lib
- fi
- fi
-
-fi
|
[-]
[+]
|
Deleted |
nginx-1.11.0.tar.bz2/auto/lib/sha1/make
^
|
@@ -1,96 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-case "$NGX_CC_NAME" in
-
- msvc)
- ngx_makefile=makefile.msvc
- ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC SHA1_ASM=$SHA1_ASM"
- ngx_sha1="SHA1=\"$SHA1\""
- ;;
-
- owc)
- ngx_makefile=makefile.owc
- ngx_opt="CPU_OPT=\"$CPU_OPT\""
- ngx_sha1=`echo SHA1=\"$SHA1\" | sed -e "s/\//$ngx_regex_dirsep/g"`
- ;;
-
- bcc)
- ngx_makefile=makefile.bcc
- ngx_opt="-DCPU_OPT=\"$CPU_OPT\" -DSHA1_ASM=$SHA1_ASM"
- ngx_sha1=`echo \-DSHA1=\"$SHA1\" | sed -e "s/\//$ngx_regex_dirsep/g"`
- ;;
-
-esac
-
-
-done=NO
-
-
-case "$NGX_PLATFORM" in
-
- win32)
- cat << END >> $NGX_MAKEFILE
-
-`echo "$SHA1/sha1.lib: $NGX_MAKEFILE" | sed -e "s/\//$ngx_regex_dirsep/g"`
- \$(MAKE) -f auto/lib/sha1/$ngx_makefile $ngx_opt $ngx_sha1
-
-END
-
- done=YES
- ;;
-
- SunOS:*:i86pc)
- if [ $SHA1_ASM = YES ]; then
-
- cat << END >> $NGX_MAKEFILE
-
-$SHA1/libsha.a: $NGX_MAKEFILE
- cd $SHA1 \\
- && \$(MAKE) CFLAGS="$SHA1_OPT -DSOL -DSHA1_ASM -DL_ENDIAN" \\
- CC="\$(CC)" CPP="\$(CPP)" \\
- SHA_ASM_OBJ=asm/sx86-sol.o clean libsha.a
-
-END
-
- done=YES
- fi
- ;;
-
- # FreeBSD: i386
- # Linux: i686
-
- *:i386 | *:i686)
- if [ $SHA1_ASM = YES ]; then
-
- cat << END >> $NGX_MAKEFILE
-
-$SHA1/libsha.a: $NGX_MAKEFILE
- cd $SHA1 \\
- && \$(MAKE) CFLAGS="$SHA1_OPT -DELF -DSHA1_ASM -DL_ENDIAN" \\
- CC="\$(CC)" CPP="\$(CPP)" \\
- SHA_ASM_OBJ=asm/sx86-elf.o clean libsha.a
-
-END
-
- done=YES
- fi
- ;;
-
-esac
-
-
-if [ $done = NO ]; then
-
- cat << END >> $NGX_MAKEFILE
-
-$SHA1/libsha.a: $NGX_MAKEFILE
- cd $SHA1 \\
- && \$(MAKE) CFLAGS="$SHA1_OPT" \\
- CC="\$(CC)" SHA_ASM_OBJ= clean libsha.a
-
-END
-
-fi
|
[-]
[+]
|
Deleted |
nginx-1.11.0.tar.bz2/auto/lib/sha1/makefile.bcc
^
|
@@ -1,22 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -q -O2 -tWM $(CPU_OPT) -DL_ENDIAN
-
-!if "$(SHA1_ASM)" == "YES"
-
-sha1.lib:
- cd $(SHA1)
- bcc32 -c $(CFLAGS) -DSHA1_ASM sha1dgst.c
- tlib sha1.lib +sha1dgst.obj +"asm\s-win32.obj"
-
-!else
-
-sha1.lib:
- cd $(SHA1)
- bcc32 -c $(CFLAGS) sha1dgst.c
- tlib sha1.lib +sha1dgst.obj
-
-!endif
|
[-]
[+]
|
Deleted |
nginx-1.11.0.tar.bz2/auto/lib/sha1/makefile.msvc
^
|
@@ -1,22 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -nologo -O2 -Ob1 -Oi -Gs $(LIBC) $(CPU_OPT) -D L_ENDIAN
-
-!IF "$(SHA1_ASM)" == "YES"
-
-sha1.lib:
- cd $(SHA1)
- cl -c $(CFLAGS) -D SHA1_ASM sha1dgst.c
- link -lib -out:sha1.lib sha1dgst.obj asm/s-win32.obj
-
-!ELSE
-
-sha1.lib:
- cd $(SHA1)
- cl -c $(CFLAGS) sha1dgst.c
- link -lib -out:sha1.lib sha1dgst.obj
-
-!ENDIF
|
[-]
[+]
|
Deleted |
nginx-1.11.0.tar.bz2/auto/lib/sha1/makefile.owc
^
|
@@ -1,11 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -zq -bt=nt -bm -ot -op -oi -oe -s $(CPU_OPT)
-
-sha1.lib:
- cd $(SHA1)
- wcl386 -c $(CFLAGS) -dL_ENDIAN sha1dgst.c
- wlib -n sha1.lib sha1dgst.obj
|
[-]
[+]
|
Deleted |
nginx-1.11.0.tar.bz2/auto/lib/test
^
|
@@ -1,40 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-echo $ngx_n "checking for $ngx_lib ...$ngx_c"
-
-cat << END >> $NGX_AUTOCONF_ERR
-
-----------------------------------------
-checking for $ngx_lib
-
-END
-
-ngx_found=no
-
-cat << END > $NGX_AUTOTEST.c
-
-$ngx_lib_incs
-
-int main() {
- $ngx_lib_test;
- return 0;
-}
-
-
-eval "$CC $cc_test_flags $ngx_lib_cflags \
- -o $NGX_AUTOTEST $NGX_AUTOTEST.c $ngx_libs \
- >> $NGX_ERR 2>&1"
-
-if [ -x $NGX_AUTOTEST ]; then
- echo " found"
-
- ngx_found=yes
-
-else
- echo " not found"
-fi
-
-rm -rf $NGX_AUTOTEST*
|
|
Deleted |
nginx-1.11.1.tar.bz2
^
|
|
Deleted |
nginx-1.11.3.tar.bz2
^
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/CHANGES
^
|
@@ -1,4 +1,93 @@
+Changes with nginx 1.11.4 13 Sep 2016
+
+ *) Feature: the $upstream_bytes_received variable.
+
+ *) Feature: the $bytes_received, $session_time, $protocol, $status,
+ $upstream_addr, $upstream_bytes_sent, $upstream_bytes_received,
+ $upstream_connect_time, $upstream_first_byte_time, and
+ $upstream_session_time variables in the stream module.
+
+ *) Feature: the ngx_stream_log_module.
+
+ *) Feature: the "proxy_protocol" parameter of the "listen" directive,
+ the $proxy_protocol_addr and $proxy_protocol_port variables in the
+ stream module.
+
+ *) Feature: the ngx_stream_realip_module.
+
+ *) Bugfix: nginx could not be built with the stream module and the
+ ngx_http_ssl_module, but without ngx_stream_ssl_module; the bug had
+ appeared in 1.11.3.
+
+ *) Feature: the IP_BIND_ADDRESS_NO_PORT socket option was not used; the
+ bug had appeared in 1.11.2.
+
+ *) Bugfix: in the "ranges" parameter of the "geo" directive.
+
+ *) Bugfix: an incorrect response might be returned when using the "aio
+ threads" and "sendfile" directives; the bug had appeared in 1.9.13.
+
+
+Changes with nginx 1.11.3 26 Jul 2016
+
+ *) Change: now the "accept_mutex" directive is turned off by default.
+
+ *) Feature: now nginx uses EPOLLEXCLUSIVE on Linux.
+
+ *) Feature: the ngx_stream_geo_module.
+
+ *) Feature: the ngx_stream_geoip_module.
+
+ *) Feature: the ngx_stream_split_clients_module.
+
+ *) Feature: variables support in the "proxy_pass" and "proxy_ssl_name"
+ directives in the stream module.
+
+ *) Bugfix: socket leak when using HTTP/2.
+
+ *) Bugfix: in configure tests.
+ Thanks to Piotr Sikora.
+
+
+Changes with nginx 1.11.2 05 Jul 2016
+
+ *) Change: now nginx always uses internal MD5 and SHA1 implementations;
+ the --with-md5 and --with-sha1 configure options were canceled.
+
+ *) Feature: variables support in the stream module.
+
+ *) Feature: the ngx_stream_map_module.
+
+ *) Feature: the ngx_stream_return_module.
+
+ *) Feature: a port can be specified in the "proxy_bind", "fastcgi_bind",
+ "memcached_bind", "scgi_bind", and "uwsgi_bind" directives.
+
+ *) Feature: now nginx uses the IP_BIND_ADDRESS_NO_PORT socket option
+ when available.
+
+ *) Bugfix: a segmentation fault might occur in a worker process when
+ using HTTP/2 and the "proxy_request_buffering" directive.
+
+ *) Bugfix: the "Content-Length" request header line was always added to
+ requests passed to backends, including requests without body, when
+ using HTTP/2.
+
+ *) Bugfix: "http request count is zero" alerts might appear in logs when
+ using HTTP/2.
+
+ *) Bugfix: unnecessary buffering might occur when using the "sub_filter"
+ directive; the issue had appeared in 1.9.4.
+
+
+Changes with nginx 1.11.1 31 May 2016
+
+ *) Security: a segmentation fault might occur in a worker process while
+ writing a specially crafted request body to a temporary file
+ (CVE-2016-4450); the bug had appeared in 1.3.9.
+
+
Changes with nginx 1.11.0 24 May 2016
*) Feature: the "transparent" parameter of the "proxy_bind",
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/CHANGES.ru
^
|
@@ -1,4 +1,94 @@
+Изменения в nginx 1.11.4 13.09.2016
+
+ *) Добавление: переменная $upstream_bytes_received.
+
+ *) Добавление: переменные $bytes_received, $session_time, $protocol,
+ $status, $upstream_addr, $upstream_bytes_sent,
+ $upstream_bytes_received, $upstream_connect_time,
+ $upstream_first_byte_time и $upstream_session_time в модуле stream.
+
+ *) Добавление: модуль ngx_stream_log_module.
+
+ *) Добавление: параметр proxy_protocol в директиве listen, переменные
+ $proxy_protocol_addr и $proxy_protocol_port в модуле stream.
+
+ *) Добавление: модуль ngx_stream_realip_module.
+
+ *) Исправление: nginx не собирался с модулем stream и модулем
+ ngx_http_ssl_module, но без модуля ngx_stream_ssl_module; ошибка
+ появилась в 1.11.3.
+
+ *) Добавление: опция сокета IP_BIND_ADDRESS_NO_PORT не использовалась;
+ ошибка появилась в 1.11.2.
+
+ *) Исправление: в параметре ranges директивы geo.
+
+ *) Исправление: при использовании директив "aio threads" и sendfile мог
+ возвращаться некорректный ответ; ошибка появилась в 1.9.13.
+
+
+Изменения в nginx 1.11.3 26.07.2016
+
+ *) Изменение: теперь accept_mutex по умолчанию выключен.
+
+ *) Добавление: теперь nginx использует EPOLLEXCLUSIVE на Linux.
+
+ *) Добавление: модуль ngx_stream_geo_module.
+
+ *) Добавление: модуль ngx_stream_geoip_module.
+
+ *) Добавление: модуль ngx_stream_split_clients_module.
+
+ *) Добавление: директивы proxy_pass и proxy_ssl_name в модуле stream
+ поддерживают переменные.
+
+ *) Исправление: утечки сокетов при использовании HTTP/2.
+
+ *) Исправление: в configure.
+ Спасибо Piotr Sikora.
+
+
+Изменения в nginx 1.11.2 05.07.2016
+
+ *) Изменение: теперь nginx всегда использует внутренние реализации MD5 и
+ SHA1; параметры configure --with-md5 и --with-sha1 упразднены.
+
+ *) Добавление: поддержка переменных в модуле stream.
+
+ *) Добавление: модуль ngx_stream_map_module.
+
+ *) Добавление: модуль ngx_stream_return_module.
+
+ *) Добавление: в директивах proxy_bind, fastcgi_bind, memcached_bind,
+ scgi_bind и uwsgi_bind теперь можно указывать порт.
+
+ *) Добавление: теперь nginx использует опцию сокета
+ IP_BIND_ADDRESS_NO_PORT, если она доступна.
+
+ *) Исправление: при использовании HTTP/2 и директивы
+ proxy_request_buffering в рабочем процессе мог произойти segmentation
+ fault.
+
+ *) Исправление: при использовании HTTP/2 к запросам, передаваемым на
+ бэкенд, всегда добавлялась строка заголовка "Content-Length", даже
+ если у запроса не было тела.
+
+ *) Исправление: при использовании HTTP/2 в логах могли появляться
+ сообщения "http request count is zero".
+
+ *) Исправление: при использовании директивы sub_filter могло
+ буферизироваться больше данных, чем это необходимо; проблема
+ появилась в 1.9.4.
+
+
+Изменения в nginx 1.11.1 31.05.2016
+
+ *) Безопасность: при записи тела специально созданного запроса во
+ временный файл в рабочем процессе мог происходить segmentation fault
+ (CVE-2016-4450); ошибка появилась в 1.3.9.
+
+
Изменения в nginx 1.11.0 24.05.2016
*) Добавление: параметр transparent директив proxy_bind, fastcgi_bind,
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/cc/acc
^
|
@@ -12,4 +12,3 @@
PCRE_OPT="$PCRE_OPT -Ae"
ZLIB_OPT="$ZLIB_OPT -Ae"
-MD5_OPT="$MD5_OPT -Ae"
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/cc/clang
^
|
@@ -66,12 +66,6 @@
PCRE_OPT="$PCRE_OPT -pipe"
fi
-if [ ".$MD5_OPT" = "." ]; then
- MD5_OPT="-O2 -pipe $CPU_OPT"
-else
- MD5_OPT="$MD5_OPT -pipe"
-fi
-
if [ ".$ZLIB_OPT" = "." ]; then
ZLIB_OPT="-O2 -pipe $CPU_OPT"
else
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/cc/conf
^
|
@@ -231,7 +231,7 @@
ngx_feature_incs=
ngx_feature_path=
ngx_feature_libs=
- ngx_feature_test="__builtin_bswap64(0)"
+ ngx_feature_test="if (__builtin_bswap64(0)) return 1"
. auto/feature
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/cc/gcc
^
|
@@ -128,12 +128,6 @@
PCRE_OPT="$PCRE_OPT $PIPE"
fi
-if [ ".$MD5_OPT" = "." ]; then
- MD5_OPT="-O2 -fomit-frame-pointer $PIPE $CPU_OPT"
-else
- MD5_OPT="$MD5_OPT $PIPE"
-fi
-
if [ ".$ZLIB_OPT" = "." ]; then
ZLIB_OPT="-O2 -fomit-frame-pointer $PIPE $CPU_OPT"
else
@@ -151,9 +145,13 @@
#CFLAGS="$CFLAGS -Winline"
#CFLAGS="$CFLAGS -Wmissing-prototypes"
-
case "$NGX_GCC_VER" in
- [3-5].*)
+ 2.*)
+ # we have a lot of the unused function arguments
+ CFLAGS="$CFLAGS -Wno-unused"
+ ;;
+
+ *)
# we have a lot of the unused function arguments
CFLAGS="$CFLAGS -Wno-unused-parameter"
# 4.2.1 shows the warning in wrong places
@@ -164,11 +162,6 @@
CFLAGS="$CFLAGS -Wno-deprecated-declarations"
fi
;;
-
- *)
- # we have a lot of the unused function arguments
- CFLAGS="$CFLAGS -Wno-unused"
- ;;
esac
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/cc/icc
^
|
@@ -43,10 +43,6 @@
PCRE_OPT="-O $CPU_OPT"
fi
-if [ ".$MD5_OPT" = "." ]; then
- MD5_OPT="-O $CPU_OPT"
-fi
-
if [ ".$ZLIB_OPT" = "." ]; then
ZLIB_OPT="-O $CPU_OPT"
fi
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/cc/sunc
^
|
@@ -20,7 +20,10 @@
cat << END > $NGX_AUTOTEST.c
-int main() { printf("%d", __SUNPRO_C); }
+int main(void) {
+ printf("%d", __SUNPRO_C);
+ return 0;
+}
END
@@ -145,10 +148,6 @@
PCRE_OPT="$ngx_fast $IPO $CPU_OPT"
fi
-if [ ".$MD5_OPT" = "." ]; then
- MD5_OPT="$ngx_fast $IPO $CPU_OPT"
-fi
-
if [ ".$ZLIB_OPT" = "." ]; then
ZLIB_OPT="$ngx_fast $IPO $CPU_OPT"
fi
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/endianness
^
|
@@ -15,7 +15,7 @@
cat << END > $NGX_AUTOTEST.c
-int main() {
+int main(void) {
int i = 0x11223344;
char *p;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/feature
^
|
@@ -31,7 +31,7 @@
$NGX_INCLUDE_UNISTD_H
$ngx_feature_incs
-int main() {
+int main(void) {
$ngx_feature_test;
return 0;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/include
^
|
@@ -20,7 +20,7 @@
$NGX_INCLUDE_SYS_PARAM_H
#include <$ngx_include>
-int main() {
+int main(void) {
return 0;
}
@@ -45,9 +45,6 @@
eval "NGX_INCLUDE_$ngx_name='#include <$ngx_include>'"
- #STUB
- eval "NGX_$ngx_name='#include <$ngx_include>'"
-
else
echo " not found"
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/lib/conf
^
|
@@ -25,35 +25,6 @@
. auto/lib/openssl/conf
fi
-if [ $USE_MD5 = YES ]; then
-
- if [ $USE_OPENSSL = YES ]; then
- have=NGX_HAVE_OPENSSL_MD5_H . auto/have
- have=NGX_OPENSSL_MD5 . auto/have
- have=NGX_HAVE_MD5 . auto/have
- MD5=YES
- MD5_LIB=OpenSSL
-
- else
- . auto/lib/md5/conf
- fi
-
-fi
-
-if [ $USE_SHA1 = YES ]; then
-
- if [ $USE_OPENSSL = YES ]; then
- have=NGX_HAVE_OPENSSL_SHA1_H . auto/have
- have=NGX_HAVE_SHA1 . auto/have
- SHA1=YES
- SHA1_LIB=OpenSSL
-
- else
- . auto/lib/sha1/conf
- fi
-
-fi
-
if [ $USE_ZLIB = YES ]; then
. auto/lib/zlib/conf
fi
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/lib/make
^
|
@@ -7,14 +7,6 @@
. auto/lib/pcre/make
fi
-if [ $MD5 != NONE -a $MD5 != NO -a $MD5 != YES ]; then
- . auto/lib/md5/make
-fi
-
-if [ $SHA1 != NONE -a $SHA1 != NO -a $SHA1 != YES ]; then
- . auto/lib/sha1/make
-fi
-
if [ $OPENSSL != NONE -a $OPENSSL != NO -a $OPENSSL != YES ]; then
. auto/lib/openssl/make
fi
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/module
^
|
@@ -48,10 +48,14 @@
fi
;;
- PCRE | OPENSSL | MD5 | SHA1 | ZLIB)
+ PCRE | OPENSSL | ZLIB)
eval USE_${lib}=YES
;;
+ MD5 | SHA1)
+ # obsolete
+ ;;
+
*)
libs="$libs $lib"
;;
@@ -79,10 +83,14 @@
do
case $lib in
- PCRE | OPENSSL | MD5 | SHA1 | ZLIB | LIBXSLT | LIBGD | PERL | GEOIP)
+ PCRE | OPENSSL | ZLIB | LIBXSLT | LIBGD | PERL | GEOIP)
eval USE_${lib}=YES
;;
+ MD5 | SHA1)
+ # obsolete
+ ;;
+
*)
CORE_LIBS="$CORE_LIBS $lib"
;;
@@ -109,10 +117,14 @@
do
case $lib in
- PCRE | OPENSSL | MD5 | SHA1 | ZLIB | LIBXSLT | LIBGD | PERL | GEOIP)
+ PCRE | OPENSSL | ZLIB | LIBXSLT | LIBGD | PERL | GEOIP)
eval USE_${lib}=YES
;;
+ MD5 | SHA1)
+ # obsolete
+ ;;
+
*)
CORE_LIBS="$CORE_LIBS $lib"
;;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/modules
^
|
@@ -43,6 +43,7 @@
if [ $NGX_TEST_BUILD_EPOLL = YES ]; then
have=NGX_HAVE_EPOLL . auto/have
have=NGX_HAVE_EPOLLRDHUP . auto/have
+ have=NGX_HAVE_EPOLLEXCLUSIVE . auto/have
have=NGX_HAVE_EVENTFD . auto/have
have=NGX_TEST_BUILD_EPOLL . auto/have
EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE"
@@ -101,7 +102,6 @@
if [ $HTTP_CACHE = YES ]; then
- USE_MD5=YES
have=NGX_HTTP_CACHE . auto/have
HTTP_SRCS="$HTTP_SRCS $HTTP_FILE_CACHE_SRCS"
fi
@@ -522,8 +522,6 @@
fi
if [ $HTTP_AUTH_BASIC = YES ]; then
- USE_MD5=YES
- USE_SHA1=YES
have=NGX_CRYPT . auto/have
ngx_module_name=ngx_http_auth_basic_module
@@ -682,7 +680,6 @@
if [ $HTTP_PROXY = YES ]; then
have=NGX_HTTP_X_FORWARDED_FOR . auto/have
- #USE_MD5=YES
ngx_module_name=ngx_http_proxy_module
ngx_module_incs=
@@ -772,8 +769,6 @@
fi
if [ $HTTP_SECURE_LINK = YES ]; then
- USE_MD5=YES
-
ngx_module_name=ngx_http_secure_link_module
ngx_module_incs=
ngx_module_deps=
@@ -971,22 +966,26 @@
STREAM_INCS=
ngx_module_type=STREAM
- ngx_module_libs=
- ngx_module_link=YES
ngx_module_order=
ngx_module_name="ngx_stream_module \
ngx_stream_core_module \
+ ngx_stream_log_module \
ngx_stream_proxy_module \
ngx_stream_upstream_module"
ngx_module_incs="src/stream"
ngx_module_deps="src/stream/ngx_stream.h \
+ src/stream/ngx_stream_variables.h \
+ src/stream/ngx_stream_script.h \
src/stream/ngx_stream_upstream.h \
src/stream/ngx_stream_upstream_round_robin.h"
ngx_module_srcs="src/stream/ngx_stream.c \
+ src/stream/ngx_stream_variables.c \
+ src/stream/ngx_stream_script.c \
src/stream/ngx_stream_handler.c \
src/stream/ngx_stream_core_module.c \
+ src/stream/ngx_stream_log_module.c \
src/stream/ngx_stream_proxy_module.c \
src/stream/ngx_stream_upstream.c \
src/stream/ngx_stream_upstream_round_robin.c"
@@ -1002,6 +1001,18 @@
ngx_module_name=ngx_stream_ssl_module
ngx_module_deps=src/stream/ngx_stream_ssl_module.h
ngx_module_srcs=src/stream/ngx_stream_ssl_module.c
+ ngx_module_libs=
+ ngx_module_link=$STREAM_SSL
+
+ . auto/module
+ fi
+
+ if [ $STREAM_REALIP = YES ]; then
+ ngx_module_name=ngx_stream_realip_module
+ ngx_module_deps=
+ ngx_module_srcs=src/stream/ngx_stream_realip_module.c
+ ngx_module_libs=
+ ngx_module_link=$STREAM_REALIP
. auto/module
fi
@@ -1010,6 +1021,8 @@
ngx_module_name=ngx_stream_limit_conn_module
ngx_module_deps=
ngx_module_srcs=src/stream/ngx_stream_limit_conn_module.c
+ ngx_module_libs=
+ ngx_module_link=$STREAM_LIMIT_CONN
. auto/module
fi
@@ -1018,6 +1031,58 @@
ngx_module_name=ngx_stream_access_module
ngx_module_deps=
ngx_module_srcs=src/stream/ngx_stream_access_module.c
+ ngx_module_libs=
+ ngx_module_link=$STREAM_ACCESS
+
+ . auto/module
+ fi
+
+ if [ $STREAM_GEO = YES ]; then
+ ngx_module_name=ngx_stream_geo_module
+ ngx_module_deps=
+ ngx_module_srcs=src/stream/ngx_stream_geo_module.c
+ ngx_module_libs=
+ ngx_module_link=$STREAM_GEO
+
+ . auto/module
+ fi
+
+ if [ $STREAM_GEOIP != NO ]; then
+ ngx_module_name=ngx_stream_geoip_module
+ ngx_module_deps=
+ ngx_module_srcs=src/stream/ngx_stream_geoip_module.c
+ ngx_module_libs=GEOIP
+ ngx_module_link=$STREAM_GEOIP
+
+ . auto/module
+ fi
+
+ if [ $STREAM_MAP = YES ]; then
+ ngx_module_name=ngx_stream_map_module
+ ngx_module_deps=
+ ngx_module_srcs=src/stream/ngx_stream_map_module.c
+ ngx_module_libs=
+ ngx_module_link=$STREAM_MAP
+
+ . auto/module
+ fi
+
+ if [ $STREAM_SPLIT_CLIENTS = YES ]; then
+ ngx_module_name=ngx_stream_split_clients_module
+ ngx_module_deps=
+ ngx_module_srcs=src/stream/ngx_stream_split_clients_module.c
+ ngx_module_libs=
+ ngx_module_link=$STREAM_SPLIT_CLIENTS
+
+ . auto/module
+ fi
+
+ if [ $STREAM_RETURN = YES ]; then
+ ngx_module_name=ngx_stream_return_module
+ ngx_module_deps=
+ ngx_module_srcs=src/stream/ngx_stream_return_module.c
+ ngx_module_libs=
+ ngx_module_link=$STREAM_RETURN
. auto/module
fi
@@ -1026,6 +1091,8 @@
ngx_module_name=ngx_stream_upstream_hash_module
ngx_module_deps=
ngx_module_srcs=src/stream/ngx_stream_upstream_hash_module.c
+ ngx_module_libs=
+ ngx_module_link=$STREAM_UPSTREAM_HASH
. auto/module
fi
@@ -1034,6 +1101,8 @@
ngx_module_name=ngx_stream_upstream_least_conn_module
ngx_module_deps=
ngx_module_srcs=src/stream/ngx_stream_upstream_least_conn_module.c
+ ngx_module_libs=
+ ngx_module_link=$STREAM_UPSTREAM_LEAST_CONN
. auto/module
fi
@@ -1044,6 +1113,8 @@
ngx_module_name=ngx_stream_upstream_zone_module
ngx_module_deps=
ngx_module_srcs=src/stream/ngx_stream_upstream_zone_module.c
+ ngx_module_libs=
+ ngx_module_link=$STREAM_UPSTREAM_ZONE
. auto/module
fi
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/options
^
|
@@ -115,8 +115,14 @@
STREAM=NO
STREAM_SSL=NO
+STREAM_REALIP=NO
STREAM_LIMIT_CONN=YES
STREAM_ACCESS=YES
+STREAM_GEO=YES
+STREAM_GEOIP=NO
+STREAM_MAP=YES
+STREAM_SPLIT_CLIENTS=YES
+STREAM_RETURN=YES
STREAM_UPSTREAM_HASH=YES
STREAM_UPSTREAM_LEAST_CONN=YES
STREAM_UPSTREAM_ZONE=YES
@@ -136,16 +142,6 @@
USE_OPENSSL=NO
OPENSSL=NONE
-USE_MD5=NO
-MD5=NONE
-MD5_OPT=
-MD5_ASM=NO
-
-USE_SHA1=NO
-SHA1=NONE
-SHA1_OPT=
-SHA1_ASM=NO
-
USE_ZLIB=NO
ZLIB=NONE
ZLIB_OPT=
@@ -301,9 +297,18 @@
--with-stream) STREAM=YES ;;
--with-stream=dynamic) STREAM=DYNAMIC ;;
--with-stream_ssl_module) STREAM_SSL=YES ;;
+ --with-stream_realip_module) STREAM_REALIP=YES ;;
+ --with-stream_geoip_module) STREAM_GEOIP=YES ;;
+ --with-stream_geoip_module=dynamic)
+ STREAM_GEOIP=DYNAMIC ;;
--without-stream_limit_conn_module)
STREAM_LIMIT_CONN=NO ;;
--without-stream_access_module) STREAM_ACCESS=NO ;;
+ --without-stream_geo_module) STREAM_GEO=NO ;;
+ --without-stream_map_module) STREAM_MAP=NO ;;
+ --without-stream_split_clients_module)
+ STREAM_SPLIT_CLIENTS=NO ;;
+ --without-stream_return_module) STREAM_RETURN=NO ;;
--without-stream_upstream_hash_module)
STREAM_UPSTREAM_HASH=NO ;;
--without-stream_upstream_least_conn_module)
@@ -333,13 +338,31 @@
--with-openssl=*) OPENSSL="$value" ;;
--with-openssl-opt=*) OPENSSL_OPT="$value" ;;
- --with-md5=*) MD5="$value" ;;
- --with-md5-opt=*) MD5_OPT="$value" ;;
- --with-md5-asm) MD5_ASM=YES ;;
-
- --with-sha1=*) SHA1="$value" ;;
- --with-sha1-opt=*) SHA1_OPT="$value" ;;
- --with-sha1-asm) SHA1_ASM=YES ;;
+ --with-md5=*)
+ NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG
+$0: warning: the \"--with-md5\" option is deprecated"
+ ;;
+ --with-md5-opt=*)
+ NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG
+$0: warning: the \"--with-md5-opt\" option is deprecated"
+ ;;
+ --with-md5-asm)
+ NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG
+$0: warning: the \"--with-md5-asm\" option is deprecated"
+ ;;
+
+ --with-sha1=*)
+ NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG
+$0: warning: the \"--with-sha1\" option is deprecated"
+ ;;
+ --with-sha1-opt=*)
+ NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG
+$0: warning: the \"--with-sha1-opt\" option is deprecated"
+ ;;
+ --with-sha1-asm)
+ NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG
+$0: warning: the \"--with-sha1-asm\" option is deprecated"
+ ;;
--with-zlib=*) ZLIB="$value" ;;
--with-zlib-opt=*) ZLIB_OPT="$value" ;;
@@ -482,8 +505,16 @@
--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
+ --with-stream_realip_module enable ngx_stream_realip_module
+ --with-stream_geoip_module enable ngx_stream_geoip_module
+ --with-stream_geoip_module=dynamic enable dynamic ngx_stream_geoip_module
--without-stream_limit_conn_module disable ngx_stream_limit_conn_module
--without-stream_access_module disable ngx_stream_access_module
+ --without-stream_geo_module disable ngx_stream_geo_module
+ --without-stream_map_module disable ngx_stream_map_module
+ --without-stream_split_clients_module
+ disable ngx_stream_split_clients_module
+ --without-stream_return_module disable ngx_stream_return_module
--without-stream_upstream_hash_module
disable ngx_stream_upstream_hash_module
--without-stream_upstream_least_conn_module
@@ -511,14 +542,6 @@
--with-pcre-opt=OPTIONS set additional build options for PCRE
--with-pcre-jit build PCRE with JIT compilation support
- --with-md5=DIR set path to md5 library sources
- --with-md5-opt=OPTIONS set additional build options for md5
- --with-md5-asm use md5 assembler sources
-
- --with-sha1=DIR set path to sha1 library sources
- --with-sha1-opt=OPTIONS set additional build options for sha1
- --with-sha1-asm use sha1 assembler sources
-
--with-zlib=DIR set path to zlib library sources
--with-zlib-opt=OPTIONS set additional build options for zlib
--with-zlib-asm=CPU use zlib assembler sources optimized
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/os/darwin
^
|
@@ -113,6 +113,6 @@
ngx_feature_incs="#include <libkern/OSAtomic.h>"
ngx_feature_path=
ngx_feature_libs=
-ngx_feature_test="int32_t lock, n;
- n = OSAtomicCompareAndSwap32Barrier(0, 1, &lock)"
+ngx_feature_test="int32_t lock = 0;
+ if (!OSAtomicCompareAndSwap32Barrier(0, 1, &lock)) return 1"
. auto/feature
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/os/linux
^
|
@@ -44,6 +44,7 @@
struct epoll_event ee;
ee.events = EPOLLIN|EPOLLOUT|EPOLLET;
ee.data.ptr = NULL;
+ (void) ee;
efd = epoll_create(100);
if (efd == -1) return 1;"
. auto/feature
@@ -69,6 +70,22 @@
ee.data.ptr = NULL;
epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ee)"
. auto/feature
+
+
+ # EPOLLEXCLUSIVE appeared in Linux 4.5, glibc 2.24
+
+ ngx_feature="EPOLLEXCLUSIVE"
+ ngx_feature_name="NGX_HAVE_EPOLLEXCLUSIVE"
+ ngx_feature_run=no
+ ngx_feature_incs="#include <sys/epoll.h>"
+ ngx_feature_path=
+ ngx_feature_libs=
+ ngx_feature_test="int efd = 0, fd = 0;
+ struct epoll_event ee;
+ ee.events = EPOLLIN|EPOLLEXCLUSIVE;
+ ee.data.ptr = NULL;
+ epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ee)"
+ . auto/feature
fi
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/os/solaris
^
|
@@ -52,7 +52,7 @@
ngx_feature_incs="#include <port.h>"
ngx_feature_path=
ngx_feature_libs=
-ngx_feature_test="int n = port_create()"
+ngx_feature_test="(void) port_create()"
. auto/feature
if [ $ngx_found = yes ]; then
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/sources
^
|
@@ -61,6 +61,7 @@
src/core/ngx_crc32.c \
src/core/ngx_murmurhash.c \
src/core/ngx_md5.c \
+ src/core/ngx_sha1.c \
src/core/ngx_rbtree.c \
src/core/ngx_radix_tree.c \
src/core/ngx_slab.c \
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/summary
^
|
@@ -28,20 +28,6 @@
*) echo " + using OpenSSL library: $OPENSSL" ;;
esac
-case $MD5 in
- YES) echo " + md5: using $MD5_LIB library" ;;
- NONE) echo " + md5 library is not used" ;;
- NO) echo " + using builtin md5 code" ;;
- *) echo " + using md5 library: $MD5" ;;
-esac
-
-case $SHA1 in
- YES) echo " + sha1: using $SHA1_LIB library" ;;
- NONE) echo " + sha1 library is not used" ;;
- NO) echo " + sha1 library is not found" ;;
- *) echo " + using sha1 library: $SHA1" ;;
-esac
-
case $ZLIB in
YES) echo " + using system zlib library" ;;
NONE) echo " + zlib library is not used" ;;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/types/sizeof
^
|
@@ -25,7 +25,7 @@
$NGX_INCLUDE_INTTYPES_H
$NGX_INCLUDE_AUTO_CONFIG_H
-int main() {
+int main(void) {
printf("%d", (int) sizeof($ngx_type));
return 0;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/types/typedef
^
|
@@ -27,7 +27,7 @@
#include <netinet/in.h>
$NGX_INCLUDE_INTTYPES_H
-int main() {
+int main(void) {
$ngx_try i = 0;
return (int) i;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/types/uintptr_t
^
|
@@ -17,9 +17,9 @@
cat << END > $NGX_AUTOTEST.c
#include <sys/types.h>
-$NGX_INTTYPES_H
+$NGX_INCLUDE_INTTYPES_H
-int main() {
+int main(void) {
uintptr_t i = 0;
return (int) i;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/auto/unix
^
|
@@ -75,7 +75,7 @@
ngx_feature_incs="#include <sys/event.h>"
ngx_feature_path=
ngx_feature_libs=
- ngx_feature_test="int kq; kq = kqueue()"
+ ngx_feature_test="(void) kqueue()"
. auto/feature
if [ $ngx_found = yes ]; then
@@ -92,7 +92,8 @@
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="struct kevent kev;
- kev.fflags = NOTE_LOWAT;"
+ kev.fflags = NOTE_LOWAT;
+ (void) kev"
. auto/feature
@@ -260,11 +261,11 @@
ngx_feature_incs="#include <dlfcn.h>"
ngx_feature_path=
ngx_feature_libs=
-ngx_feature_test="dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); dlsym(NULL, NULL)"
+ngx_feature_test="dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); dlsym(NULL, \"\")"
. auto/feature
-if [ $ngx_found != yes ]; then
+if [ $ngx_found = no ]; then
ngx_feature="dlopen() in libdl"
ngx_feature_libs="-ldl"
@@ -287,7 +288,7 @@
. auto/feature
-if [ $ngx_found != yes ]; then
+if [ $ngx_found = no ]; then
ngx_feature="sched_yield() in librt"
ngx_feature_libs="-lrt"
@@ -341,6 +342,19 @@
. auto/feature
+# Linux IP_BIND_ADDRESS_NO_PORT
+
+ngx_feature="IP_BIND_ADDRESS_NO_PORT"
+ngx_feature_name="NGX_HAVE_IP_BIND_ADDRESS_NO_PORT"
+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_BIND_ADDRESS_NO_PORT, NULL, 0)"
+. auto/feature
+
+
# Linux transparent proxying
ngx_feature="IP_TRANSPARENT"
@@ -479,9 +493,9 @@
ngx_feature_incs="#include <aio.h>"
ngx_feature_path=
ngx_feature_libs=
- ngx_feature_test="int n; struct aiocb iocb;
+ ngx_feature_test="struct aiocb iocb;
iocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
- n = aio_read(&iocb)"
+ (void) aio_read(&iocb)"
. auto/feature
if [ $ngx_found = yes ]; then
@@ -501,6 +515,7 @@
iocb.aio_lio_opcode = IOCB_CMD_PREAD;
iocb.aio_flags = IOCB_FLAG_RESFD;
iocb.aio_resfd = -1;
+ (void) iocb;
(void) eventfd(0, 0)"
. auto/feature
@@ -516,11 +531,12 @@
ngx_feature="Linux AIO support (SYS_eventfd)"
ngx_feature_incs="#include <linux/aio_abi.h>
#include <sys/syscall.h>"
- ngx_feature_test="int n = SYS_eventfd;
- struct iocb iocb;
+ ngx_feature_test="struct iocb iocb;
iocb.aio_lio_opcode = IOCB_CMD_PREAD;
iocb.aio_flags = IOCB_FLAG_RESFD;
- iocb.aio_resfd = -1;"
+ iocb.aio_resfd = -1;
+ (void) iocb;
+ (void) SYS_eventfd"
. auto/feature
if [ $ngx_found = yes ]; then
@@ -558,7 +574,7 @@
ngx_feature="eventfd() (SYS_eventfd)"
ngx_feature_incs="#include <sys/syscall.h>"
- ngx_feature_test="int n = SYS_eventfd"
+ ngx_feature_test="(void) SYS_eventfd"
. auto/feature
fi
fi
@@ -631,7 +647,8 @@
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="struct sockaddr_in6 sin6;
- sin6.sin6_family = AF_INET6;"
+ sin6.sin6_family = AF_INET6;
+ (void) sin6"
. auto/feature
fi
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/contrib/unicode2nginx/unicode-to-nginx.pl
^
|
@@ -10,7 +10,7 @@
# Needs perl 5.6 or later.
-# Written by Maxim Dounin, mdounin@rambler-co.ru
+# Written by Maxim Dounin, mdounin@mdounin.ru
###############################################################################
@@ -33,7 +33,10 @@
# Produce UTF-8 sequence from character code;
- my $un_utf8 = join('', map { sprintf("%02X", $_) } unpack("C*", pack("U", hex($un_code))));
+ my $un_utf8 = join('',
+ map { sprintf("%02X", $_) }
+ unpack("U0C*", pack("U", hex($un_code)))
+ );
print " $cs_code $un_utf8 ; $un_name\n";
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/core/nginx.h
^
|
@@ -9,8 +9,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 1011000
-#define NGINX_VERSION "1.11.0"
+#define nginx_version 1011004
+#define NGINX_VERSION "1.11.4"
#define NGINX_VER "nginx/" NGINX_VERSION
#ifdef NGX_BUILD
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/core/ngx_connection.h
^
|
@@ -186,10 +186,6 @@
unsigned need_last_buf:1;
-#if (NGX_HAVE_IOCP)
- unsigned accept_context_updated:1;
-#endif
-
#if (NGX_HAVE_AIO_SENDFILE)
unsigned busy_count:2;
#endif
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/core/ngx_crypt.c
^
|
@@ -8,9 +8,7 @@
#include <ngx_core.h>
#include <ngx_crypt.h>
#include <ngx_md5.h>
-#if (NGX_HAVE_SHA1)
#include <ngx_sha1.h>
-#endif
#if (NGX_CRYPT)
@@ -19,16 +17,11 @@
u_char **encrypted);
static ngx_int_t ngx_crypt_plain(ngx_pool_t *pool, u_char *key, u_char *salt,
u_char **encrypted);
-
-#if (NGX_HAVE_SHA1)
-
static ngx_int_t ngx_crypt_ssha(ngx_pool_t *pool, u_char *key, u_char *salt,
u_char **encrypted);
static ngx_int_t ngx_crypt_sha(ngx_pool_t *pool, u_char *key, u_char *salt,
u_char **encrypted);
-#endif
-
static u_char *ngx_crypt_to64(u_char *p, uint32_t v, size_t n);
@@ -42,13 +35,11 @@
} else if (ngx_strncmp(salt, "{PLAIN}", sizeof("{PLAIN}") - 1) == 0) {
return ngx_crypt_plain(pool, key, salt, encrypted);
-#if (NGX_HAVE_SHA1)
} else if (ngx_strncmp(salt, "{SSHA}", sizeof("{SSHA}") - 1) == 0) {
return ngx_crypt_ssha(pool, key, salt, encrypted);
} else if (ngx_strncmp(salt, "{SHA}", sizeof("{SHA}") - 1) == 0) {
return ngx_crypt_sha(pool, key, salt, encrypted);
-#endif
}
/* fallback to libc crypt() */
@@ -193,8 +184,6 @@
}
-#if (NGX_HAVE_SHA1)
-
static ngx_int_t
ngx_crypt_ssha(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
{
@@ -278,6 +267,4 @@
return NGX_OK;
}
-#endif /* NGX_HAVE_SHA1 */
-
#endif /* NGX_CRYPT */
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/core/ngx_file.c
^
|
@@ -225,7 +225,7 @@
file[path->name.len + path->len] = '/';
- for (n = 0; n < 3; n++) {
+ for (n = 0; n < NGX_MAX_PATH_LEVEL; n++) {
level = path->level[n];
if (level == 0) {
@@ -249,7 +249,7 @@
pos = path->name.len;
- for (i = 0; i < 3; i++) {
+ for (i = 0; i < NGX_MAX_PATH_LEVEL; i++) {
if (path->level[i] == 0) {
break;
}
@@ -399,6 +399,8 @@
ngx_conf_merge_path_value(ngx_conf_t *cf, ngx_path_t **path, ngx_path_t *prev,
ngx_path_init_t *init)
{
+ ngx_uint_t i;
+
if (*path) {
return NGX_CONF_OK;
}
@@ -419,13 +421,10 @@
return NGX_CONF_ERROR;
}
- (*path)->level[0] = init->level[0];
- (*path)->level[1] = init->level[1];
- (*path)->level[2] = init->level[2];
-
- (*path)->len = init->level[0] + (init->level[0] ? 1 : 0)
- + init->level[1] + (init->level[1] ? 1 : 0)
- + init->level[2] + (init->level[2] ? 1 : 0);
+ for (i = 0; i < NGX_MAX_PATH_LEVEL; i++) {
+ (*path)->level[i] = init->level[i];
+ (*path)->len += init->level[i] + (init->level[i] ? 1 : 0);
+ }
if (ngx_add_path(cf, path) != NGX_OK) {
return NGX_CONF_ERROR;
@@ -518,7 +517,7 @@
return NGX_ERROR;
}
- for (n = 0; n < 3; n++) {
+ for (n = 0; n < NGX_MAX_PATH_LEVEL; n++) {
if (p[i]->level[n] != path->level[n]) {
if (path->conf_file == NULL) {
if (p[i]->conf_file == NULL) {
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/core/ngx_file.h
^
|
@@ -49,7 +49,7 @@
typedef struct {
ngx_str_t name;
size_t len;
- size_t level[3];
+ size_t level[NGX_MAX_PATH_LEVEL];
ngx_path_manager_pt manager;
ngx_path_loader_pt loader;
@@ -62,7 +62,7 @@
typedef struct {
ngx_str_t name;
- size_t level[3];
+ size_t level[NGX_MAX_PATH_LEVEL];
} ngx_path_init_t;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/core/ngx_inet.c
^
|
@@ -466,6 +466,93 @@
ngx_int_t
+ngx_cidr_match(struct sockaddr *sa, ngx_array_t *cidrs)
+{
+#if (NGX_HAVE_INET6)
+ u_char *p;
+#endif
+ in_addr_t inaddr;
+ ngx_cidr_t *cidr;
+ ngx_uint_t family, i;
+#if (NGX_HAVE_INET6)
+ ngx_uint_t n;
+ struct in6_addr *inaddr6;
+#endif
+
+#if (NGX_SUPPRESS_WARN)
+ inaddr = 0;
+#if (NGX_HAVE_INET6)
+ inaddr6 = NULL;
+#endif
+#endif
+
+ family = sa->sa_family;
+
+ if (family == AF_INET) {
+ inaddr = ((struct sockaddr_in *) sa)->sin_addr.s_addr;
+ }
+
+#if (NGX_HAVE_INET6)
+ else if (family == AF_INET6) {
+ inaddr6 = &((struct sockaddr_in6 *) sa)->sin6_addr;
+
+ if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
+ family = AF_INET;
+
+ p = inaddr6->s6_addr;
+
+ inaddr = p[12] << 24;
+ inaddr += p[13] << 16;
+ inaddr += p[14] << 8;
+ inaddr += p[15];
+
+ inaddr = htonl(inaddr);
+ }
+ }
+#endif
+
+ for (cidr = cidrs->elts, i = 0; i < cidrs->nelts; i++) {
+ if (cidr[i].family != family) {
+ goto next;
+ }
+
+ switch (family) {
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ for (n = 0; n < 16; n++) {
+ if ((inaddr6->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 */
+ if ((inaddr & cidr[i].u.in.mask) != cidr[i].u.in.addr) {
+ goto next;
+ }
+ break;
+ }
+
+ return NGX_OK;
+
+ next:
+ continue;
+ }
+
+ return NGX_DECLINED;
+}
+
+
+ngx_int_t
ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, size_t len)
{
in_addr_t inaddr;
@@ -529,13 +616,9 @@
ngx_parse_addr_port(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text,
size_t len)
{
- u_char *p, *last;
- size_t plen;
- ngx_int_t rc, port;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
+ u_char *p, *last;
+ size_t plen;
+ ngx_int_t rc, port;
rc = ngx_parse_addr(pool, addr, text, len);
@@ -585,20 +668,7 @@
return rc;
}
- switch (addr->sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) addr->sockaddr;
- sin6->sin6_port = htons((in_port_t) port);
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) addr->sockaddr;
- sin->sin_port = htons((in_port_t) port);
- break;
- }
+ ngx_inet_set_port(addr->sockaddr, (in_port_t) port);
return NGX_OK;
}
@@ -1356,3 +1426,61 @@
return NGX_OK;
}
+
+
+in_port_t
+ngx_inet_get_port(struct sockaddr *sa)
+{
+ struct sockaddr_in *sin;
+#if (NGX_HAVE_INET6)
+ struct sockaddr_in6 *sin6;
+#endif
+
+ switch (sa->sa_family) {
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *) sa;
+ return ntohs(sin6->sin6_port);
+#endif
+
+#if (NGX_HAVE_UNIX_DOMAIN)
+ case AF_UNIX:
+ return 0;
+#endif
+
+ default: /* AF_INET */
+ sin = (struct sockaddr_in *) sa;
+ return ntohs(sin->sin_port);
+ }
+}
+
+
+void
+ngx_inet_set_port(struct sockaddr *sa, in_port_t port)
+{
+ struct sockaddr_in *sin;
+#if (NGX_HAVE_INET6)
+ struct sockaddr_in6 *sin6;
+#endif
+
+ switch (sa->sa_family) {
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *) sa;
+ sin6->sin6_port = htons(port);
+ break;
+#endif
+
+#if (NGX_HAVE_UNIX_DOMAIN)
+ case AF_UNIX:
+ break;
+#endif
+
+ default: /* AF_INET */
+ sin = (struct sockaddr_in *) sa;
+ sin->sin_port = htons(port);
+ break;
+ }
+}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/core/ngx_inet.h
^
|
@@ -113,6 +113,7 @@
size_t len, ngx_uint_t port);
size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);
ngx_int_t ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr);
+ngx_int_t ngx_cidr_match(struct sockaddr *sa, ngx_array_t *cidrs);
ngx_int_t ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text,
size_t len);
ngx_int_t ngx_parse_addr_port(ngx_pool_t *pool, ngx_addr_t *addr,
@@ -121,6 +122,8 @@
ngx_int_t ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u);
ngx_int_t ngx_cmp_sockaddr(struct sockaddr *sa1, socklen_t slen1,
struct sockaddr *sa2, socklen_t slen2, ngx_uint_t cmp_port);
+in_port_t ngx_inet_get_port(struct sockaddr *sa);
+void ngx_inet_set_port(struct sockaddr *sa, in_port_t port);
#endif /* _NGX_INET_H_INCLUDED_ */
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/core/ngx_md5.c
^
|
@@ -3,8 +3,6 @@
* An internal implementation, based on Alexander Peslyak's
* public domain implementation:
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
- * It is not expected to be optimal and is used only
- * if no MD5 implementation was found in system.
*/
@@ -13,8 +11,6 @@
#include <ngx_md5.h>
-#if !(NGX_HAVE_MD5)
-
static const u_char *ngx_md5_body(ngx_md5_t *ctx, const u_char *data,
size_t size);
@@ -285,5 +281,3 @@
return p;
}
-
-#endif
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/core/ngx_md5.h
^
|
@@ -13,36 +13,6 @@
#include <ngx_core.h>
-#if (NGX_HAVE_MD5)
-
-#if (NGX_HAVE_OPENSSL_MD5_H)
-#include <openssl/md5.h>
-#else
-#include <md5.h>
-#endif
-
-
-typedef MD5_CTX ngx_md5_t;
-
-
-#if (NGX_OPENSSL_MD5)
-
-#define ngx_md5_init MD5_Init
-#define ngx_md5_update MD5_Update
-#define ngx_md5_final MD5_Final
-
-#else
-
-#define ngx_md5_init MD5Init
-#define ngx_md5_update MD5Update
-#define ngx_md5_final MD5Final
-
-#endif
-
-
-#else /* !NGX_HAVE_MD5 */
-
-
typedef struct {
uint64_t bytes;
uint32_t a, b, c, d;
@@ -55,6 +25,4 @@
void ngx_md5_final(u_char result[16], ngx_md5_t *ctx);
-#endif
-
#endif /* _NGX_MD5_H_INCLUDED_ */
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/core/ngx_module.h
^
|
@@ -119,17 +119,8 @@
#define NGX_MODULE_SIGNATURE_16 "0"
#endif
-#if (NGX_HAVE_MD5)
-#define NGX_MODULE_SIGNATURE_17 "1"
-#else
#define NGX_MODULE_SIGNATURE_17 "0"
-#endif
-
-#if (NGX_HAVE_SHA1)
-#define NGX_MODULE_SIGNATURE_18 "1"
-#else
#define NGX_MODULE_SIGNATURE_18 "0"
-#endif
#if (NGX_HAVE_OPENAT)
#define NGX_MODULE_SIGNATURE_19 "1"
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/core/ngx_proxy_protocol.c
^
|
@@ -141,19 +141,11 @@
case AF_INET:
buf = ngx_cpymem(buf, "PROXY TCP4 ", sizeof("PROXY TCP4 ") - 1);
-
- port = ntohs(((struct sockaddr_in *) c->sockaddr)->sin_port);
- lport = ntohs(((struct sockaddr_in *) c->local_sockaddr)->sin_port);
-
break;
#if (NGX_HAVE_INET6)
case AF_INET6:
buf = ngx_cpymem(buf, "PROXY TCP6 ", sizeof("PROXY TCP6 ") - 1);
-
- port = ntohs(((struct sockaddr_in6 *) c->sockaddr)->sin6_port);
- lport = ntohs(((struct sockaddr_in6 *) c->local_sockaddr)->sin6_port);
-
break;
#endif
@@ -169,5 +161,8 @@
buf += ngx_sock_ntop(c->local_sockaddr, c->local_socklen, buf, last - buf,
0);
+ port = ngx_inet_get_port(c->sockaddr);
+ lport = ngx_inet_get_port(c->local_sockaddr);
+
return ngx_slprintf(buf, last, " %ui %ui" CRLF, port, lport);
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/core/ngx_resolver.c
^
|
@@ -2996,12 +2996,8 @@
ngx_addr_t *addrs;
ngx_resolver_t *r;
ngx_sockaddr_t *sockaddr;
- 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;
@@ -3045,17 +3041,7 @@
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);
- }
+ ngx_inet_set_port(addrs[i].sockaddr, srv->port);
}
srv->addrs = addrs;
|
[-]
[+]
|
Added |
nginx-1.11.4.tar.bz2/src/core/ngx_sha1.c
^
|
@@ -0,0 +1,294 @@
+
+/*
+ * Copyright (C) Maxim Dounin
+ * Copyright (C) Nginx, Inc.
+ *
+ * An internal SHA1 implementation.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_sha1.h>
+
+
+static const u_char *ngx_sha1_body(ngx_sha1_t *ctx, const u_char *data,
+ size_t size);
+
+
+void
+ngx_sha1_init(ngx_sha1_t *ctx)
+{
+ ctx->a = 0x67452301;
+ ctx->b = 0xefcdab89;
+ ctx->c = 0x98badcfe;
+ ctx->d = 0x10325476;
+ ctx->e = 0xc3d2e1f0;
+
+ ctx->bytes = 0;
+}
+
+
+void
+ngx_sha1_update(ngx_sha1_t *ctx, const void *data, size_t size)
+{
+ size_t used, free;
+
+ used = (size_t) (ctx->bytes & 0x3f);
+ ctx->bytes += size;
+
+ if (used) {
+ free = 64 - used;
+
+ if (size < free) {
+ ngx_memcpy(&ctx->buffer[used], data, size);
+ return;
+ }
+
+ ngx_memcpy(&ctx->buffer[used], data, free);
+ data = (u_char *) data + free;
+ size -= free;
+ (void) ngx_sha1_body(ctx, ctx->buffer, 64);
+ }
+
+ if (size >= 64) {
+ data = ngx_sha1_body(ctx, data, size & ~(size_t) 0x3f);
+ size &= 0x3f;
+ }
+
+ ngx_memcpy(ctx->buffer, data, size);
+}
+
+
+void
+ngx_sha1_final(u_char result[20], ngx_sha1_t *ctx)
+{
+ size_t used, free;
+
+ used = (size_t) (ctx->bytes & 0x3f);
+
+ ctx->buffer[used++] = 0x80;
+
+ free = 64 - used;
+
+ if (free < 8) {
+ ngx_memzero(&ctx->buffer[used], free);
+ (void) ngx_sha1_body(ctx, ctx->buffer, 64);
+ used = 0;
+ free = 64;
+ }
+
+ ngx_memzero(&ctx->buffer[used], free - 8);
+
+ ctx->bytes <<= 3;
+ ctx->buffer[56] = (u_char) (ctx->bytes >> 56);
+ ctx->buffer[57] = (u_char) (ctx->bytes >> 48);
+ ctx->buffer[58] = (u_char) (ctx->bytes >> 40);
+ ctx->buffer[59] = (u_char) (ctx->bytes >> 32);
+ ctx->buffer[60] = (u_char) (ctx->bytes >> 24);
+ ctx->buffer[61] = (u_char) (ctx->bytes >> 16);
+ ctx->buffer[62] = (u_char) (ctx->bytes >> 8);
+ ctx->buffer[63] = (u_char) ctx->bytes;
+
+ (void) ngx_sha1_body(ctx, ctx->buffer, 64);
+
+ result[0] = (u_char) (ctx->a >> 24);
+ result[1] = (u_char) (ctx->a >> 16);
+ result[2] = (u_char) (ctx->a >> 8);
+ result[3] = (u_char) ctx->a;
+ result[4] = (u_char) (ctx->b >> 24);
+ result[5] = (u_char) (ctx->b >> 16);
+ result[6] = (u_char) (ctx->b >> 8);
+ result[7] = (u_char) ctx->b;
+ result[8] = (u_char) (ctx->c >> 24);
+ result[9] = (u_char) (ctx->c >> 16);
+ result[10] = (u_char) (ctx->c >> 8);
+ result[11] = (u_char) ctx->c;
+ result[12] = (u_char) (ctx->d >> 24);
+ result[13] = (u_char) (ctx->d >> 16);
+ result[14] = (u_char) (ctx->d >> 8);
+ result[15] = (u_char) ctx->d;
+ result[16] = (u_char) (ctx->e >> 24);
+ result[17] = (u_char) (ctx->e >> 16);
+ result[18] = (u_char) (ctx->e >> 8);
+ result[19] = (u_char) ctx->e;
+
+ ngx_memzero(ctx, sizeof(*ctx));
+}
+
+
+/*
+ * Helper functions.
+ */
+
+#define ROTATE(bits, word) (((word) << (bits)) | ((word) >> (32 - (bits))))
+
+#define F1(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
+#define F2(b, c, d) ((b) ^ (c) ^ (d))
+#define F3(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
+
+#define STEP(f, a, b, c, d, e, w, t) \
+ temp = ROTATE(5, (a)) + f((b), (c), (d)) + (e) + (w) + (t); \
+ (e) = (d); \
+ (d) = (c); \
+ (c) = ROTATE(30, (b)); \
+ (b) = (a); \
+ (a) = temp;
+
+
+/*
+ * GET() reads 4 input bytes in big-endian byte order and returns
+ * them as uint32_t.
+ */
+
+#define GET(n) \
+ ((uint32_t) p[n * 4 + 3] | \
+ ((uint32_t) p[n * 4 + 2] << 8) | \
+ ((uint32_t) p[n * 4 + 1] << 16) | \
+ ((uint32_t) p[n * 4] << 24))
+
+
+/*
+ * This processes one or more 64-byte data blocks, but does not update
+ * the bit counters. There are no alignment requirements.
+ */
+
+static const u_char *
+ngx_sha1_body(ngx_sha1_t *ctx, const u_char *data, size_t size)
+{
+ uint32_t a, b, c, d, e, temp;
+ uint32_t saved_a, saved_b, saved_c, saved_d, saved_e;
+ uint32_t words[80];
+ ngx_uint_t i;
+ const u_char *p;
+
+ p = data;
+
+ a = ctx->a;
+ b = ctx->b;
+ c = ctx->c;
+ d = ctx->d;
+ e = ctx->e;
+
+ do {
+ saved_a = a;
+ saved_b = b;
+ saved_c = c;
+ saved_d = d;
+ saved_e = e;
+
+ /* Load data block into the words array */
+
+ for (i = 0; i < 16; i++) {
+ words[i] = GET(i);
+ }
+
+ for (i = 16; i < 80; i++) {
+ words[i] = ROTATE(1, words[i - 3] ^ words[i - 8] ^ words[i - 14]
+ ^ words[i - 16]);
+ }
+
+ /* Transformations */
+
+ STEP(F1, a, b, c, d, e, words[0], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[1], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[2], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[3], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[4], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[5], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[6], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[7], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[8], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[9], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[10], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[11], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[12], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[13], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[14], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[15], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[16], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[17], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[18], 0x5a827999);
+ STEP(F1, a, b, c, d, e, words[19], 0x5a827999);
+
+ STEP(F2, a, b, c, d, e, words[20], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[21], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[22], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[23], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[24], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[25], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[26], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[27], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[28], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[29], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[30], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[31], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[32], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[33], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[34], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[35], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[36], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[37], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[38], 0x6ed9eba1);
+ STEP(F2, a, b, c, d, e, words[39], 0x6ed9eba1);
+
+ STEP(F3, a, b, c, d, e, words[40], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[41], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[42], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[43], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[44], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[45], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[46], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[47], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[48], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[49], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[50], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[51], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[52], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[53], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[54], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[55], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[56], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[57], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[58], 0x8f1bbcdc);
+ STEP(F3, a, b, c, d, e, words[59], 0x8f1bbcdc);
+
+ STEP(F2, a, b, c, d, e, words[60], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[61], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[62], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[63], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[64], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[65], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[66], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[67], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[68], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[69], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[70], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[71], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[72], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[73], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[74], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[75], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[76], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[77], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[78], 0xca62c1d6);
+ STEP(F2, a, b, c, d, e, words[79], 0xca62c1d6);
+
+ a += saved_a;
+ b += saved_b;
+ c += saved_c;
+ d += saved_d;
+ e += saved_e;
+
+ p += 64;
+
+ } while (size -= 64);
+
+ ctx->a = a;
+ ctx->b = b;
+ ctx->c = c;
+ ctx->d = d;
+ ctx->e = e;
+
+ return p;
+}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/core/ngx_sha1.h
^
|
@@ -13,19 +13,16 @@
#include <ngx_core.h>
-#if (NGX_HAVE_OPENSSL_SHA1_H)
-#include <openssl/sha.h>
-#else
-#include <sha.h>
-#endif
+typedef struct {
+ uint64_t bytes;
+ uint32_t a, b, c, d, e, f;
+ u_char buffer[64];
+} ngx_sha1_t;
-typedef SHA_CTX ngx_sha1_t;
-
-
-#define ngx_sha1_init SHA1_Init
-#define ngx_sha1_update SHA1_Update
-#define ngx_sha1_final SHA1_Final
+void ngx_sha1_init(ngx_sha1_t *ctx);
+void ngx_sha1_update(ngx_sha1_t *ctx, const void *data, size_t size);
+void ngx_sha1_final(u_char result[20], ngx_sha1_t *ctx);
#endif /* _NGX_SHA1_H_INCLUDED_ */
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/core/ngx_string.c
^
|
@@ -1563,7 +1563,7 @@
n = 0;
while (size) {
- if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
+ if (escape[*src >> 5] & (1U << (*src & 0x1f))) {
n++;
}
src++;
@@ -1574,7 +1574,7 @@
}
while (size) {
- if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
+ if (escape[*src >> 5] & (1U << (*src & 0x1f))) {
*dst++ = '%';
*dst++ = hex[*src >> 4];
*dst++ = hex[*src & 0xf];
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/core/ngx_thread_pool.c
^
|
@@ -137,6 +137,13 @@
return NGX_ERROR;
}
+ err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ if (err) {
+ ngx_log_error(NGX_LOG_ALERT, log, err,
+ "pthread_attr_setdetachstate() failed");
+ return NGX_ERROR;
+ }
+
#if 0
err = pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN);
if (err) {
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/event/modules/ngx_epoll_module.c
^
|
@@ -17,18 +17,19 @@
#define EPOLLIN 0x001
#define EPOLLPRI 0x002
#define EPOLLOUT 0x004
+#define EPOLLERR 0x008
+#define EPOLLHUP 0x010
#define EPOLLRDNORM 0x040
#define EPOLLRDBAND 0x080
#define EPOLLWRNORM 0x100
#define EPOLLWRBAND 0x200
#define EPOLLMSG 0x400
-#define EPOLLERR 0x008
-#define EPOLLHUP 0x010
#define EPOLLRDHUP 0x2000
-#define EPOLLET 0x80000000
+#define EPOLLEXCLUSIVE 0x10000000
#define EPOLLONESHOT 0x40000000
+#define EPOLLET 0x80000000
#define EPOLL_CTL_ADD 1
#define EPOLL_CTL_DEL 2
@@ -610,6 +611,12 @@
op = EPOLL_CTL_ADD;
}
+#if (NGX_HAVE_EPOLLEXCLUSIVE && NGX_HAVE_EPOLLRDHUP)
+ if (flags & NGX_EXCLUSIVE_EVENT) {
+ events &= ~EPOLLRDHUP;
+ }
+#endif
+
ee.events = events | (uint32_t) flags;
ee.data.ptr = (void *) ((uintptr_t) c | ev->instance);
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/event/ngx_event.c
^
|
@@ -822,15 +822,38 @@
rev->handler = (c->type == SOCK_STREAM) ? ngx_event_accept
: ngx_event_recvmsg;
- if (ngx_use_accept_mutex
#if (NGX_HAVE_REUSEPORT)
- && !ls[i].reuseport
+
+ if (ls[i].reuseport) {
+ if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ continue;
+ }
+
#endif
- )
+
+ if (ngx_use_accept_mutex) {
+ continue;
+ }
+
+#if (NGX_HAVE_EPOLLEXCLUSIVE)
+
+ if ((ngx_event_flags & NGX_USE_EPOLL_EVENT)
+ && ccf->worker_processes > 1)
{
+ if (ngx_add_event(rev, NGX_READ_EVENT, NGX_EXCLUSIVE_EVENT)
+ == NGX_ERROR)
+ {
+ return NGX_ERROR;
+ }
+
continue;
}
+#endif
+
if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
return NGX_ERROR;
}
@@ -1261,7 +1284,7 @@
ngx_conf_init_ptr_value(ecf->name, event_module->name->data);
ngx_conf_init_value(ecf->multi_accept, 0);
- ngx_conf_init_value(ecf->accept_mutex, 1);
+ ngx_conf_init_value(ecf->accept_mutex, 0);
ngx_conf_init_msec_value(ecf->accept_mutex_delay, 500);
return NGX_CONF_OK;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/event/ngx_event.h
^
|
@@ -76,11 +76,6 @@
unsigned cancelable:1;
-#if (NGX_WIN32)
- /* setsockopt(SO_UPDATE_ACCEPT_CONTEXT) was successful */
- unsigned accept_context_updated:1;
-#endif
-
#if (NGX_HAVE_KQUEUE)
unsigned kq_vnode:1;
@@ -372,6 +367,9 @@
#define NGX_ONESHOT_EVENT EPOLLONESHOT
#endif
+#if (NGX_HAVE_EPOLLEXCLUSIVE)
+#define NGX_EXCLUSIVE_EVENT EPOLLEXCLUSIVE
+#endif
#elif (NGX_HAVE_POLL)
@@ -400,6 +398,11 @@
#endif
+#if (NGX_TEST_BUILD_EPOLL)
+#define NGX_EXCLUSIVE_EVENT 0
+#endif
+
+
#ifndef NGX_CLEAR_EVENT
#define NGX_CLEAR_EVENT 0 /* dummy declaration */
#endif
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/event/ngx_event_connect.c
^
|
@@ -21,6 +21,9 @@
ngx_event_connect_peer(ngx_peer_connection_t *pc)
{
int rc, type;
+#if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT || NGX_LINUX)
+ in_port_t port;
+#endif
ngx_int_t event;
ngx_err_t err;
ngx_uint_t level;
@@ -87,6 +90,53 @@
}
#endif
+#if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT || NGX_LINUX)
+ port = ngx_inet_get_port(pc->local->sockaddr);
+#endif
+
+#if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT)
+
+ if (pc->sockaddr->sa_family != AF_UNIX && port == 0) {
+ static int bind_address_no_port = 1;
+
+ if (bind_address_no_port) {
+ if (setsockopt(s, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT,
+ (const void *) &bind_address_no_port,
+ sizeof(int)) == -1)
+ {
+ err = ngx_socket_errno;
+
+ if (err != NGX_EOPNOTSUPP && err != NGX_ENOPROTOOPT) {
+ ngx_log_error(NGX_LOG_ALERT, pc->log, err,
+ "setsockopt(IP_BIND_ADDRESS_NO_PORT) "
+ "failed, ignored");
+
+ } else {
+ bind_address_no_port = 0;
+ }
+ }
+ }
+ }
+
+#endif
+
+#if (NGX_LINUX)
+
+ if (pc->type == SOCK_DGRAM && port != 0) {
+ int reuse_addr = 1;
+
+ if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+ (const void *) &reuse_addr, sizeof(int))
+ == -1)
+ {
+ ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
+ "setsockopt(SO_REUSEADDR) failed");
+ goto failed;
+ }
+ }
+
+#endif
+
if (bind(s, pc->local->sockaddr, pc->local->socklen) == -1) {
ngx_log_error(NGX_LOG_CRIT, pc->log, ngx_socket_errno,
"bind(%V) failed", &pc->local->name);
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/event/ngx_event_openssl.c
^
|
@@ -118,9 +118,7 @@
#else
-#ifndef OPENSSL_IS_BORINGSSL
OPENSSL_config(NULL);
-#endif
SSL_library_init();
SSL_load_error_strings();
@@ -592,6 +590,30 @@
ngx_int_t
+ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers,
+ ngx_uint_t prefer_server_ciphers)
+{
+ if (SSL_CTX_set_cipher_list(ssl->ctx, (char *) ciphers->data) == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "SSL_CTX_set_cipher_list(\"%V\") failed",
+ ciphers);
+ return NGX_ERROR;
+ }
+
+ if (prefer_server_ciphers) {
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
+ }
+
+#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER)
+ /* a temporary 512-bit RSA key is required for export versions of MSIE */
+ SSL_CTX_set_tmp_rsa_callback(ssl->ctx, ngx_ssl_rsa512_key_callback);
+#endif
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
ngx_int_t depth)
{
@@ -1999,7 +2021,9 @@
|| n == SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST /* 151 */
|| n == SSL_R_EXCESSIVE_MESSAGE_SIZE /* 152 */
|| n == SSL_R_LENGTH_MISMATCH /* 159 */
+#ifdef SSL_R_NO_CIPHERS_PASSED
|| n == SSL_R_NO_CIPHERS_PASSED /* 182 */
+#endif
|| n == SSL_R_NO_CIPHERS_SPECIFIED /* 183 */
|| n == SSL_R_NO_COMPRESSION_SPECIFIED /* 187 */
|| n == SSL_R_NO_SHARED_CIPHER /* 193 */
@@ -2917,13 +2941,6 @@
}
-#ifdef OPENSSL_NO_SHA256
-#define ngx_ssl_session_ticket_md EVP_sha1
-#else
-#define ngx_ssl_session_ticket_md EVP_sha256
-#endif
-
-
static int
ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx,
@@ -2934,6 +2951,8 @@
ngx_array_t *keys;
ngx_connection_t *c;
ngx_ssl_session_ticket_key_t *key;
+ const EVP_MD *digest;
+ const EVP_CIPHER *cipher;
#if (NGX_DEBUG)
u_char buf[32];
#endif
@@ -2941,6 +2960,13 @@
c = ngx_ssl_get_connection(ssl_conn);
ssl_ctx = c->ssl->session_ctx;
+ cipher = EVP_aes_128_cbc();
+#ifdef OPENSSL_NO_SHA256
+ digest = EVP_sha1();
+#else
+ digest = EVP_sha256();
+#endif
+
keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_ticket_keys_index);
if (keys == NULL) {
return -1;
@@ -2956,13 +2982,29 @@
ngx_hex_dump(buf, key[0].name, 16) - buf, buf,
SSL_session_reused(ssl_conn) ? "reused" : "new");
- RAND_bytes(iv, 16);
- EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, key[0].aes_key, iv);
- HMAC_Init_ex(hctx, key[0].hmac_key, 16,
- ngx_ssl_session_ticket_md(), NULL);
+ if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) != 1) {
+ ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "RAND_bytes() failed");
+ return -1;
+ }
+
+ if (EVP_EncryptInit_ex(ectx, cipher, NULL, key[0].aes_key, iv) != 1) {
+ ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
+ "EVP_EncryptInit_ex() failed");
+ return -1;
+ }
+
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+ if (HMAC_Init_ex(hctx, key[0].hmac_key, 16, digest, NULL) != 1) {
+ ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed");
+ return -1;
+ }
+#else
+ HMAC_Init_ex(hctx, key[0].hmac_key, 16, digest, NULL);
+#endif
+
ngx_memcpy(name, key[0].name, 16);
- return 0;
+ return 1;
} else {
/* decrypt session ticket */
@@ -2986,9 +3028,20 @@
ngx_hex_dump(buf, key[i].name, 16) - buf, buf,
(i == 0) ? " (default)" : "");
- HMAC_Init_ex(hctx, key[i].hmac_key, 16,
- ngx_ssl_session_ticket_md(), NULL);
- EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, key[i].aes_key, iv);
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+ if (HMAC_Init_ex(hctx, key[i].hmac_key, 16, digest, NULL) != 1) {
+ ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed");
+ return -1;
+ }
+#else
+ HMAC_Init_ex(hctx, key[i].hmac_key, 16, digest, NULL);
+#endif
+
+ if (EVP_DecryptInit_ex(ectx, cipher, NULL, key[i].aes_key, iv) != 1) {
+ ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
+ "EVP_DecryptInit_ex() failed");
+ return -1;
+ }
return (i == 0) ? 1 : 2 /* renew */;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/event/ngx_event_openssl.h
^
|
@@ -144,6 +144,8 @@
ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords);
ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords);
+ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers,
+ ngx_uint_t prefer_server_ciphers);
ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_str_t *cert, ngx_int_t depth);
ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/event/ngx_event_openssl_stapling.c
^
|
@@ -376,6 +376,7 @@
{
ngx_url_t u;
char *s;
+ ngx_str_t rsp;
STACK_OF(OPENSSL_STRING) *aia;
if (responder->len == 0) {
@@ -403,6 +404,8 @@
return NGX_DECLINED;
}
+ responder = &rsp;
+
responder->len = ngx_strlen(s);
responder->data = ngx_palloc(cf->pool, responder->len);
if (responder->data == NULL) {
@@ -920,7 +923,6 @@
u_char *p;
size_t len;
- in_port_t port;
socklen_t socklen;
ngx_uint_t i;
struct sockaddr *sockaddr;
@@ -962,8 +964,6 @@
goto failed;
}
- port = htons(ctx->port);
-
for (i = 0; i < resolve->naddrs; i++) {
socklen = resolve->addrs[i].socklen;
@@ -974,16 +974,7 @@
}
ngx_memcpy(sockaddr, resolve->addrs[i].sockaddr, socklen);
-
- switch (sockaddr->sa_family) {
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- ((struct sockaddr_in6 *) sockaddr)->sin6_port = port;
- break;
-#endif
- default: /* AF_INET */
- ((struct sockaddr_in *) sockaddr)->sin_port = port;
- }
+ ngx_inet_set_port(sockaddr, ctx->port);
ctx->addrs[i].sockaddr = sockaddr;
ctx->addrs[i].socklen = socklen;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/event/ngx_event_pipe.c
^
|
@@ -300,7 +300,7 @@
if (n == NGX_ERROR) {
p->upstream_error = 1;
- return NGX_ERROR;
+ break;
}
if (n == NGX_AGAIN) {
@@ -815,10 +815,12 @@
}
#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;
+ if (p->thread_handler) {
+ p->temp_file->thread_write = 1;
+ 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);
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/modules/ngx_http_geo_module.c
^
|
@@ -469,7 +469,12 @@
for (i = 0; i < 0x10000; i++) {
a = (ngx_array_t *) ctx.high.low[i];
- if (a == NULL || a->nelts == 0) {
+ if (a == NULL) {
+ continue;
+ }
+
+ if (a->nelts == 0) {
+ ctx.high.low[i] = NULL;
continue;
}
@@ -814,7 +819,7 @@
range = a->elts;
ngx_memmove(&range[i + 2], &range[i + 1],
- (a->nelts - 2 - i) * sizeof(ngx_http_geo_range_t));
+ (a->nelts - 2 - i) * sizeof(ngx_http_geo_range_t));
range[i + 1].start = (u_short) s;
range[i + 1].end = (u_short) e;
@@ -853,7 +858,7 @@
range = a->elts;
ngx_memmove(&range[i + 3], &range[i + 1],
- (a->nelts - 3 - i) * sizeof(ngx_http_geo_range_t));
+ (a->nelts - 3 - i) * sizeof(ngx_http_geo_range_t));
range[i + 2].start = (u_short) (e + 1);
range[i + 2].end = range[i].end;
@@ -881,7 +886,7 @@
range = a->elts;
ngx_memmove(&range[i + 1], &range[i],
- (a->nelts - 1 - i) * sizeof(ngx_http_geo_range_t));
+ (a->nelts - 1 - i) * sizeof(ngx_http_geo_range_t));
range[i + 1].start = (u_short) (e + 1);
@@ -905,7 +910,7 @@
range = a->elts;
ngx_memmove(&range[i + 2], &range[i + 1],
- (a->nelts - 2 - i) * sizeof(ngx_http_geo_range_t));
+ (a->nelts - 2 - i) * sizeof(ngx_http_geo_range_t));
range[i + 1].start = (u_short) s;
range[i + 1].end = (u_short) e;
@@ -935,13 +940,20 @@
return NGX_CONF_ERROR;
}
- range->start = (u_short) s;
- range->end = (u_short) e;
- range->value = ctx->value;
+ range = a->elts;
+
+ ngx_memmove(&range[1], &range[0],
+ (a->nelts - 1) * sizeof(ngx_http_geo_range_t));
+
+ range[0].start = (u_short) s;
+ range[0].end = (u_short) e;
+ range[0].value = ctx->value;
next:
- continue;
+ if (h == 0xffff) {
+ break;
+ }
}
return NGX_CONF_OK;
@@ -959,7 +971,7 @@
warn = 0;
- for (n = start; n <= end; n += 0x10000) {
+ for (n = start; n <= end; n = (n + 0x10000) & 0xffff0000) {
h = n >> 16;
@@ -978,9 +990,9 @@
a = (ngx_array_t *) ctx->high.low[h];
- if (a == NULL) {
+ if (a == NULL || a->nelts == 0) {
warn = 1;
- continue;
+ goto next;
}
range = a->elts;
@@ -990,20 +1002,22 @@
&& e == (ngx_uint_t) range[i].end)
{
ngx_memmove(&range[i], &range[i + 1],
- (a->nelts - 1 - i) * sizeof(ngx_http_geo_range_t));
+ (a->nelts - 1 - i) * sizeof(ngx_http_geo_range_t));
a->nelts--;
break;
}
- if (s != (ngx_uint_t) range[i].start
- && e != (ngx_uint_t) range[i].end)
- {
- continue;
+ if (i == a->nelts - 1) {
+ warn = 1;
}
+ }
- warn = 1;
+ next:
+
+ if (h == 0xffff) {
+ break;
}
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/modules/ngx_http_limit_req_module.c
^
|
@@ -362,15 +362,13 @@
{
size_t size;
ngx_int_t rc, excess;
- ngx_time_t *tp;
ngx_msec_t now;
ngx_msec_int_t ms;
ngx_rbtree_node_t *node, *sentinel;
ngx_http_limit_req_ctx_t *ctx;
ngx_http_limit_req_node_t *lr;
- tp = ngx_timeofday();
- now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
+ now = ngx_current_msec;
ctx = limit->shm_zone->data;
@@ -483,7 +481,6 @@
ngx_uint_t *ep, ngx_http_limit_req_limit_t **limit)
{
ngx_int_t excess;
- ngx_time_t *tp;
ngx_msec_t now, delay, max_delay;
ngx_msec_int_t ms;
ngx_http_limit_req_ctx_t *ctx;
@@ -509,9 +506,7 @@
ngx_shmtx_lock(&ctx->shpool->mutex);
- tp = ngx_timeofday();
-
- now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
+ now = ngx_current_msec;
ms = (ngx_msec_int_t) (now - lr->last);
excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
@@ -549,16 +544,13 @@
ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, ngx_uint_t n)
{
ngx_int_t excess;
- ngx_time_t *tp;
ngx_msec_t now;
ngx_queue_t *q;
ngx_msec_int_t ms;
ngx_rbtree_node_t *node;
ngx_http_limit_req_node_t *lr;
- tp = ngx_timeofday();
-
- now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
+ now = ngx_current_msec;
/*
* n == 1 deletes one or two zero rate entries
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/modules/ngx_http_log_module.c
^
|
@@ -1000,7 +1000,7 @@
n = 0;
while (size) {
- if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
+ if (escape[*src >> 5] & (1U << (*src & 0x1f))) {
n++;
}
src++;
@@ -1011,7 +1011,7 @@
}
while (size) {
- if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
+ if (escape[*src >> 5] & (1U << (*src & 0x1f))) {
*dst++ = '\\';
*dst++ = 'x';
*dst++ = hex[*src >> 4];
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/modules/ngx_http_proxy_module.c
^
|
@@ -4323,13 +4323,9 @@
}
}
- if (SSL_CTX_set_cipher_list(plcf->upstream.ssl->ctx,
- (const char *) plcf->ssl_ciphers.data)
- == 0)
+ if (ngx_ssl_ciphers(cf, plcf->upstream.ssl, &plcf->ssl_ciphers, 0)
+ != NGX_OK)
{
- ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
- "SSL_CTX_set_cipher_list(\"%V\") failed",
- &plcf->ssl_ciphers);
return NGX_ERROR;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/modules/ngx_http_realip_module.c
^
|
@@ -138,10 +138,6 @@
ngx_list_part_t *part;
ngx_table_elt_t *header;
ngx_connection_t *c;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
ngx_http_realip_ctx_t *ctx;
ngx_http_realip_loc_conf_t *rlcf;
@@ -242,21 +238,7 @@
!= NGX_DECLINED)
{
if (rlcf->type == NGX_HTTP_REALIP_PROXY) {
-
- switch (addr.sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) addr.sockaddr;
- sin6->sin6_port = htons(c->proxy_protocol_port);
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) addr.sockaddr;
- sin->sin_port = htons(c->proxy_protocol_port);
- break;
- }
+ ngx_inet_set_port(addr.sockaddr, c->proxy_protocol_port);
}
return ngx_http_realip_set_addr(r, &addr);
@@ -282,7 +264,6 @@
}
ctx = cln->data;
- ngx_http_set_ctx(r, ctx, ngx_http_realip_module);
c = r->connection;
@@ -300,6 +281,7 @@
ngx_memcpy(p, text, len);
cln->handler = ngx_http_realip_cleanup;
+ ngx_http_set_ctx(r, ctx, ngx_http_realip_module);
ctx->connection = c;
ctx->sockaddr = c->sockaddr;
@@ -578,24 +560,7 @@
return NGX_ERROR;
}
- switch (sa->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- port = ntohs(((struct sockaddr_in6 *) sa)->sin6_port);
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- port = 0;
- break;
-#endif
-
- default: /* AF_INET */
- port = ntohs(((struct sockaddr_in *) sa)->sin_port);
- break;
- }
+ port = ngx_inet_get_port(sa);
if (port > 0 && port < 65536) {
v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/modules/ngx_http_ssi_filter_module.c
^
|
@@ -2722,8 +2722,8 @@
ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t gmt)
{
+ time_t now;
ngx_http_ssi_ctx_t *ctx;
- ngx_time_t *tp;
ngx_str_t *timefmt;
struct tm tm;
char buf[NGX_HTTP_SSI_DATE_LEN];
@@ -2732,7 +2732,7 @@
v->no_cacheable = 0;
v->not_found = 0;
- tp = ngx_timeofday();
+ now = ngx_time();
ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module);
@@ -2746,15 +2746,15 @@
return NGX_ERROR;
}
- v->len = ngx_sprintf(v->data, "%T", tp->sec) - v->data;
+ v->len = ngx_sprintf(v->data, "%T", now) - v->data;
return NGX_OK;
}
if (gmt) {
- ngx_libc_gmtime(tp->sec, &tm);
+ ngx_libc_gmtime(now, &tm);
} else {
- ngx_libc_localtime(tp->sec, &tm);
+ ngx_libc_localtime(now, &tm);
}
v->len = strftime(buf, NGX_HTTP_SSI_DATE_LEN,
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/modules/ngx_http_ssl_module.c
^
|
@@ -689,13 +689,10 @@
return NGX_CONF_ERROR;
}
- if (SSL_CTX_set_cipher_list(conf->ssl.ctx,
- (const char *) conf->ciphers.data)
- == 0)
+ if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers,
+ conf->prefer_server_ciphers)
+ != NGX_OK)
{
- ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
- "SSL_CTX_set_cipher_list(\"%V\") failed",
- &conf->ciphers);
return NGX_CONF_ERROR;
}
@@ -730,15 +727,6 @@
return NGX_CONF_ERROR;
}
- if (conf->prefer_server_ciphers) {
- SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
- }
-
-#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER)
- /* a temporary 512-bit RSA key is required for export versions of MSIE */
- SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback);
-#endif
-
if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
return NGX_CONF_ERROR;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/modules/ngx_http_sub_filter_module.c
^
|
@@ -83,7 +83,9 @@
static ngx_int_t ngx_http_sub_output(ngx_http_request_t *r,
ngx_http_sub_ctx_t *ctx);
static ngx_int_t ngx_http_sub_parse(ngx_http_request_t *r,
- ngx_http_sub_ctx_t *ctx);
+ ngx_http_sub_ctx_t *ctx, ngx_uint_t flush);
+static ngx_int_t ngx_http_sub_match(ngx_http_sub_ctx_t *ctx, ngx_int_t start,
+ ngx_str_t *m);
static char * ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
@@ -285,6 +287,7 @@
ngx_int_t rc;
ngx_buf_t *b;
ngx_str_t *sub;
+ ngx_uint_t flush, last;
ngx_chain_t *cl;
ngx_http_sub_ctx_t *ctx;
ngx_http_sub_match_t *match;
@@ -326,6 +329,9 @@
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http sub filter \"%V\"", &r->uri);
+ flush = 0;
+ last = 0;
+
while (ctx->in || ctx->buf) {
if (ctx->buf == NULL) {
@@ -334,11 +340,19 @@
ctx->pos = ctx->buf->pos;
}
+ if (ctx->buf->flush || ctx->buf->recycled) {
+ flush = 1;
+ }
+
+ if (ctx->in == NULL) {
+ last = flush;
+ }
+
b = NULL;
while (ctx->pos < ctx->buf->last) {
- rc = ngx_http_sub_parse(r, ctx);
+ rc = ngx_http_sub_parse(r, ctx, last);
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"parse: %i, looked: \"%V\" %p-%p",
@@ -590,9 +604,10 @@
static ngx_int_t
-ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
+ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx,
+ ngx_uint_t flush)
{
- u_char *p, *last, *pat, *pat_end, c;
+ u_char *p, c;
ngx_str_t *m;
ngx_int_t offset, start, next, end, len, rc;
ngx_uint_t shift, i, j;
@@ -602,6 +617,7 @@
slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module);
tables = ctx->tables;
+ match = ctx->matches->elts;
offset = ctx->offset;
end = ctx->buf->last - ctx->pos;
@@ -628,7 +644,6 @@
/* a potential match */
start = offset - (ngx_int_t) tables->min_match_len + 1;
- match = ctx->matches->elts;
i = ngx_max(tables->index[c], ctx->index);
j = tables->index[c + 1];
@@ -641,41 +656,15 @@
m = &match[i].match;
- pat = m->data;
- pat_end = m->data + m->len;
-
- if (start >= 0) {
- p = ctx->pos + start;
+ rc = ngx_http_sub_match(ctx, start, m);
- } else {
- last = ctx->looked.data + ctx->looked.len;
- p = last + start;
-
- while (p < last && pat < pat_end) {
- if (ngx_tolower(*p) != *pat) {
- goto next;
- }
-
- p++;
- pat++;
- }
-
- p = ctx->pos;
- }
-
- while (p < ctx->buf->last && pat < pat_end) {
- if (ngx_tolower(*p) != *pat) {
- goto next;
- }
-
- p++;
- pat++;
+ if (rc == NGX_DECLINED) {
+ goto next;
}
ctx->index = i;
- if (pat != pat_end) {
- /* partial match */
+ if (rc == NGX_AGAIN) {
goto again;
}
@@ -695,6 +684,26 @@
ctx->index = 0;
}
+ if (flush) {
+ for ( ;; ) {
+ start = offset - (ngx_int_t) tables->min_match_len + 1;
+
+ if (start >= end) {
+ break;
+ }
+
+ for (i = 0; i < ctx->matches->nelts; i++) {
+ m = &match[i].match;
+
+ if (ngx_http_sub_match(ctx, start, m) == NGX_AGAIN) {
+ goto again;
+ }
+ }
+
+ offset++;
+ }
+ }
+
again:
ctx->offset = offset;
@@ -731,6 +740,51 @@
}
+static ngx_int_t
+ngx_http_sub_match(ngx_http_sub_ctx_t *ctx, ngx_int_t start, ngx_str_t *m)
+{
+ u_char *p, *last, *pat, *pat_end;
+
+ pat = m->data;
+ pat_end = m->data + m->len;
+
+ if (start >= 0) {
+ p = ctx->pos + start;
+
+ } else {
+ last = ctx->looked.data + ctx->looked.len;
+ p = last + start;
+
+ while (p < last && pat < pat_end) {
+ if (ngx_tolower(*p) != *pat) {
+ return NGX_DECLINED;
+ }
+
+ p++;
+ pat++;
+ }
+
+ p = ctx->pos;
+ }
+
+ while (p < ctx->buf->last && pat < pat_end) {
+ if (ngx_tolower(*p) != *pat) {
+ return NGX_DECLINED;
+ }
+
+ p++;
+ pat++;
+ }
+
+ if (pat != pat_end) {
+ /* partial match */
+ return NGX_AGAIN;
+ }
+
+ return NGX_OK;
+}
+
+
static char *
ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/modules/ngx_http_userid_filter_module.c
^
|
@@ -836,7 +836,7 @@
ngx_gettimeofday(&tp);
/* use the most significant usec part that fits to 16 bits */
- start_value = ((tp.tv_usec / 20) << 16) | ngx_pid;
+ start_value = (((uint32_t) tp.tv_usec / 20) << 16) | ngx_pid;
return NGX_OK;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/modules/ngx_http_uwsgi_module.c
^
|
@@ -2325,13 +2325,9 @@
}
}
- if (SSL_CTX_set_cipher_list(uwcf->upstream.ssl->ctx,
- (const char *) uwcf->ssl_ciphers.data)
- == 0)
+ if (ngx_ssl_ciphers(cf, uwcf->upstream.ssl, &uwcf->ssl_ciphers, 0)
+ != NGX_OK)
{
- ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
- "SSL_CTX_set_cipher_list(\"%V\") failed",
- &uwcf->ssl_ciphers);
return NGX_ERROR;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/ngx_http.c
^
|
@@ -1144,12 +1144,8 @@
in_port_t p;
ngx_uint_t i;
struct sockaddr *sa;
- struct sockaddr_in *sin;
ngx_http_conf_port_t *port;
ngx_http_core_main_conf_t *cmcf;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
@@ -1162,27 +1158,7 @@
}
sa = &lsopt->sockaddr.sockaddr;
-
- switch (sa->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = &lsopt->sockaddr.sockaddr_in6;
- p = sin6->sin6_port;
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- p = 0;
- break;
-#endif
-
- default: /* AF_INET */
- sin = &lsopt->sockaddr.sockaddr_in;
- p = sin->sin_port;
- break;
- }
+ p = ngx_inet_get_port(sa);
port = cmcf->ports->elts;
for (i = 0; i < cmcf->ports->nelts; i++) {
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/ngx_http_core_module.c
^
|
@@ -2823,120 +2823,46 @@
ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr,
u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive)
{
- u_char *p;
- in_addr_t inaddr;
- ngx_int_t rc;
- ngx_addr_t paddr;
- ngx_cidr_t *cidr;
- ngx_uint_t family, i;
-#if (NGX_HAVE_INET6)
- ngx_uint_t n;
- struct in6_addr *inaddr6;
-#endif
-
-#if (NGX_SUPPRESS_WARN)
- inaddr = 0;
-#if (NGX_HAVE_INET6)
- inaddr6 = NULL;
-#endif
-#endif
+ u_char *p;
+ ngx_int_t rc;
+ ngx_addr_t paddr;
- family = addr->sockaddr->sa_family;
-
- if (family == AF_INET) {
- inaddr = ((struct sockaddr_in *) addr->sockaddr)->sin_addr.s_addr;
+ if (ngx_cidr_match(addr->sockaddr, proxies) != NGX_OK) {
+ return NGX_DECLINED;
}
-#if (NGX_HAVE_INET6)
- else if (family == AF_INET6) {
- inaddr6 = &((struct sockaddr_in6 *) addr->sockaddr)->sin6_addr;
-
- if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
- family = AF_INET;
-
- p = inaddr6->s6_addr;
-
- inaddr = p[12] << 24;
- inaddr += p[13] << 16;
- inaddr += p[14] << 8;
- inaddr += p[15];
-
- inaddr = htonl(inaddr);
+ for (p = xff + xfflen - 1; p > xff; p--, xfflen--) {
+ if (*p != ' ' && *p != ',') {
+ break;
}
}
-#endif
-
- for (cidr = proxies->elts, i = 0; i < proxies->nelts; i++) {
- if (cidr[i].family != family) {
- goto next;
- }
-
- switch (family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- for (n = 0; n < 16; n++) {
- if ((inaddr6->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:
+ for ( /* void */ ; p > xff; p--) {
+ if (*p == ' ' || *p == ',') {
+ p++;
break;
-#endif
-
- default: /* AF_INET */
- if ((inaddr & cidr[i].u.in.mask) != cidr[i].u.in.addr) {
- goto next;
- }
- break;
- }
-
- for (p = xff + xfflen - 1; p > xff; p--, xfflen--) {
- if (*p != ' ' && *p != ',') {
- break;
- }
- }
-
- for ( /* void */ ; p > xff; p--) {
- if (*p == ' ' || *p == ',') {
- p++;
- break;
- }
}
+ }
- if (ngx_parse_addr_port(r->pool, &paddr, p, xfflen - (p - xff))
- != NGX_OK)
- {
- return NGX_DECLINED;
- }
+ if (ngx_parse_addr_port(r->pool, &paddr, p, xfflen - (p - xff)) != NGX_OK) {
+ return NGX_DECLINED;
+ }
- *addr = paddr;
+ *addr = paddr;
- if (recursive && p > xff) {
- rc = ngx_http_get_forwarded_addr_internal(r, addr, xff, p - 1 - xff,
- proxies, 1);
-
- if (rc == NGX_DECLINED) {
- return NGX_DONE;
- }
+ if (recursive && p > xff) {
+ rc = ngx_http_get_forwarded_addr_internal(r, addr, xff, p - 1 - xff,
+ proxies, 1);
- /* rc == NGX_OK || rc == NGX_DONE */
- return rc;
+ if (rc == NGX_DECLINED) {
+ return NGX_DONE;
}
- return NGX_OK;
-
- next:
- continue;
+ /* rc == NGX_OK || rc == NGX_DONE */
+ return rc;
}
- return NGX_DECLINED;
+ return NGX_OK;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/ngx_http_file_cache.c
^
|
@@ -101,7 +101,7 @@
return NGX_ERROR;
}
- for (n = 0; n < 3; n++) {
+ for (n = 0; n < NGX_MAX_PATH_LEVEL; n++) {
if (cache->path->level[n] != ocache->path->level[n]) {
ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
"cache \"%V\" had previously different levels",
@@ -2257,7 +2257,7 @@
p = value[i].data + 7;
last = value[i].data + value[i].len;
- for (n = 0; n < 3 && p < last; n++) {
+ for (n = 0; n < NGX_MAX_PATH_LEVEL && p < last; n++) {
if (*p > '0' && *p < '3') {
@@ -2268,7 +2268,7 @@
break;
}
- if (*p++ == ':' && n < 2 && p != last) {
+ if (*p++ == ':' && n < NGX_MAX_PATH_LEVEL - 1 && p < last) {
continue;
}
@@ -2278,7 +2278,7 @@
goto invalid_levels;
}
- if (cache->path->len < 10 + 3) {
+ if (cache->path->len < 10 + NGX_MAX_PATH_LEVEL) {
continue;
}
@@ -2450,7 +2450,7 @@
ngx_memcpy(p, "/temp", sizeof("/temp"));
ngx_memcpy(&cache->temp_path->level, &cache->path->level,
- 3 * sizeof(size_t));
+ NGX_MAX_PATH_LEVEL * sizeof(size_t));
cache->temp_path->len = cache->path->len;
cache->temp_path->conf_file = cf->conf_file->file.name.data;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/ngx_http_parse.c
^
|
@@ -481,7 +481,7 @@
/* check "/.", "//", "%", and "\" (Win32) in URI */
case sw_after_slash_in_uri:
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ if (usual[ch >> 5] & (1U << (ch & 0x1f))) {
state = sw_check_uri;
break;
}
@@ -540,7 +540,7 @@
/* check "/", "%" and "\" (Win32) in URI */
case sw_check_uri:
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ if (usual[ch >> 5] & (1U << (ch & 0x1f))) {
break;
}
@@ -626,7 +626,7 @@
/* URI */
case sw_uri:
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ if (usual[ch >> 5] & (1U << (ch & 0x1f))) {
break;
}
@@ -1131,7 +1131,7 @@
/* check "/.", "//", "%", and "\" (Win32) in URI */
case sw_after_slash_in_uri:
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ if (usual[ch >> 5] & (1U << (ch & 0x1f))) {
state = sw_check_uri;
break;
}
@@ -1179,7 +1179,7 @@
/* check "/", "%" and "\" (Win32) in URI */
case sw_check_uri:
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ if (usual[ch >> 5] & (1U << (ch & 0x1f))) {
break;
}
@@ -1228,7 +1228,7 @@
/* URI */
case sw_uri:
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ if (usual[ch >> 5] & (1U << (ch & 0x1f))) {
break;
}
@@ -1289,7 +1289,7 @@
case sw_usual:
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ if (usual[ch >> 5] & (1U << (ch & 0x1f))) {
*u++ = ch;
ch = *p++;
break;
@@ -1358,7 +1358,7 @@
case sw_slash:
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ if (usual[ch >> 5] & (1U << (ch & 0x1f))) {
state = sw_usual;
*u++ = ch;
ch = *p++;
@@ -1401,7 +1401,7 @@
case sw_dot:
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ if (usual[ch >> 5] & (1U << (ch & 0x1f))) {
state = sw_usual;
*u++ = ch;
ch = *p++;
@@ -1442,7 +1442,7 @@
case sw_dot_dot:
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ if (usual[ch >> 5] & (1U << (ch & 0x1f))) {
state = sw_usual;
*u++ = ch;
ch = *p++;
@@ -1836,7 +1836,7 @@
continue;
}
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ if (usual[ch >> 5] & (1U << (ch & 0x1f))) {
continue;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/ngx_http_request.c
^
|
@@ -2068,7 +2068,7 @@
if (sscf->verify) {
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client attempted to request the server name "
- "different from that one was negotiated");
+ "different from the one that was negotiated");
ngx_http_finalize_request(r, NGX_HTTP_MISDIRECTED_REQUEST);
return NGX_ERROR;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/ngx_http_script.c
^
|
@@ -350,11 +350,9 @@
goto invalid_variable;
}
-#if (NGX_PCRE)
- {
- ngx_uint_t n;
-
if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') {
+#if (NGX_PCRE)
+ ngx_uint_t n;
n = sc->source->data[i] - '0';
@@ -371,9 +369,13 @@
i++;
continue;
- }
- }
+#else
+ ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0,
+ "using variable \"$%c\" requires "
+ "PCRE library", sc->source->data[i]);
+ return NGX_ERROR;
#endif
+ }
if (sc->source->data[i] == '{') {
bracket = 1;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/ngx_http_upstream.c
^
|
@@ -391,6 +391,10 @@
ngx_http_upstream_response_length_variable, 0,
NGX_HTTP_VAR_NOCACHEABLE, 0 },
+ { ngx_string("upstream_bytes_received"), NULL,
+ ngx_http_upstream_response_length_variable, 1,
+ NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
#if (NGX_HTTP_CACHE)
{ ngx_string("upstream_cache_status"), NULL,
@@ -2136,6 +2140,8 @@
return;
}
+ u->state->bytes_received += n;
+
u->buffer.last += n;
#if 0
@@ -2642,6 +2648,7 @@
return;
}
+ u->state->bytes_received += n;
u->state->response_length += n;
if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
@@ -3215,6 +3222,10 @@
do_write = 1;
b->last += n;
+ if (from_upstream) {
+ u->state->bytes_received += n;
+ }
+
continue;
}
@@ -3411,6 +3422,7 @@
}
if (n > 0) {
+ u->state->bytes_received += n;
u->state->response_length += n;
if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
@@ -4095,6 +4107,8 @@
u->state->response_time = ngx_current_msec - u->state->response_time;
if (u->pipe && u->pipe->read_length) {
+ u->state->bytes_received += u->pipe->read_length
+ - u->pipe->preread_size;
u->state->response_length = u->pipe->read_length;
}
}
@@ -5242,7 +5256,13 @@
state = r->upstream_states->elts;
for ( ;; ) {
- p = ngx_sprintf(p, "%O", state[i].response_length);
+
+ if (data == 1) {
+ p = ngx_sprintf(p, "%O", state[i].bytes_received);
+
+ } else {
+ p = ngx_sprintf(p, "%O", state[i].response_length);
+ }
if (++i == r->upstream_states->nelts) {
break;
@@ -5828,7 +5848,8 @@
return NGX_CONF_ERROR;
}
- rc = ngx_parse_addr(cf->pool, local->addr, value[1].data, value[1].len);
+ rc = ngx_parse_addr_port(cf->pool, local->addr, value[1].data,
+ value[1].len);
switch (rc) {
case NGX_OK:
@@ -5900,7 +5921,7 @@
return NGX_ERROR;
}
- rc = ngx_parse_addr(r->pool, addr, val.data, val.len);
+ rc = ngx_parse_addr_port(r->pool, addr, val.data, val.len);
if (rc == NGX_ERROR) {
return NGX_ERROR;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/ngx_http_upstream.h
^
|
@@ -63,6 +63,7 @@
ngx_msec_t connect_time;
ngx_msec_t header_time;
off_t response_length;
+ off_t bytes_received;
ngx_str_t *peer;
} ngx_http_upstream_state_t;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/ngx_http_upstream_round_robin.c
^
|
@@ -354,16 +354,7 @@
}
ngx_memcpy(sockaddr, ur->addrs[i].sockaddr, socklen);
-
- switch (sockaddr->sa_family) {
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- ((struct sockaddr_in6 *) sockaddr)->sin6_port = htons(ur->port);
- break;
-#endif
- default: /* AF_INET */
- ((struct sockaddr_in *) sockaddr)->sin_port = htons(ur->port);
- }
+ ngx_inet_set_port(sockaddr, ur->port);
p = ngx_pnalloc(r->pool, NGX_SOCKADDR_STRLEN);
if (p == NULL) {
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/ngx_http_variables.c
^
|
@@ -1201,11 +1201,7 @@
ngx_http_variable_remote_port(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
- ngx_uint_t port;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
+ ngx_uint_t port;
v->len = 0;
v->valid = 1;
@@ -1217,26 +1213,7 @@
return NGX_ERROR;
}
- switch (r->connection->sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
- port = ntohs(sin6->sin6_port);
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- port = 0;
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) r->connection->sockaddr;
- port = ntohs(sin->sin_port);
- break;
- }
+ port = ngx_inet_get_port(r->connection->sockaddr);
if (port > 0 && port < 65536) {
v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
@@ -1321,11 +1298,7 @@
ngx_http_variable_server_port(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
- ngx_uint_t port;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
+ ngx_uint_t port;
v->len = 0;
v->valid = 1;
@@ -1341,26 +1314,7 @@
return NGX_ERROR;
}
- switch (r->connection->local_sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) r->connection->local_sockaddr;
- port = ntohs(sin6->sin6_port);
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- port = 0;
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) r->connection->local_sockaddr;
- port = ntohs(sin->sin_port);
- break;
- }
+ port = ngx_inet_get_port(r->connection->local_sockaddr);
if (port > 0 && port < 65536) {
v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/v2/ngx_http_v2.c
^
|
@@ -410,6 +410,16 @@
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http2 write handler");
+ if (h2c->last_out == NULL && !c->buffered) {
+
+ if (wev->timer_set) {
+ ngx_del_timer(wev);
+ }
+
+ ngx_http_v2_handle_connection(h2c);
+ return;
+ }
+
h2c->blocked = 1;
rc = ngx_http_v2_send_output_queue(h2c);
@@ -468,7 +478,7 @@
wev = c->write;
if (!wev->ready) {
- return NGX_OK;
+ return NGX_AGAIN;
}
cl = NULL;
@@ -539,15 +549,6 @@
c->tcp_nodelay = NGX_TCP_NODELAY_SET;
}
- if (cl) {
- ngx_add_timer(wev, clcf->send_timeout);
-
- } else {
- if (wev->timer_set) {
- ngx_del_timer(wev);
- }
- }
-
for ( /* void */ ; out; out = fn) {
fn = out->next;
@@ -572,6 +573,15 @@
h2c->last_out = frame;
+ if (!wev->ready) {
+ ngx_add_timer(wev, clcf->send_timeout);
+ return NGX_AGAIN;
+ }
+
+ if (wev->timer_set) {
+ ngx_del_timer(wev);
+ }
+
return NGX_OK;
error:
@@ -589,7 +599,8 @@
static void
ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c)
{
- ngx_connection_t *c;
+ ngx_int_t rc;
+ ngx_connection_t *c;
ngx_http_v2_srv_conf_t *h2scf;
if (h2c->last_out || h2c->processing) {
@@ -604,7 +615,22 @@
}
if (c->buffered) {
- return;
+ h2c->blocked = 1;
+
+ rc = ngx_http_v2_send_output_queue(h2c);
+
+ h2c->blocked = 0;
+
+ if (rc == NGX_ERROR) {
+ ngx_http_close_connection(c);
+ return;
+ }
+
+ if (rc == NGX_AGAIN) {
+ return;
+ }
+
+ /* rc == NGX_OK */
}
h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
@@ -615,7 +641,7 @@
}
if (ngx_terminate || ngx_exiting) {
- ngx_http_close_connection(c);
+ ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
return;
}
@@ -3424,7 +3450,9 @@
return;
}
- r->headers_in.chunked = (r->headers_in.content_length_n == -1);
+ if (r->headers_in.content_length_n == -1 && !r->stream->in_closed) {
+ r->headers_in.chunked = 1;
+ }
ngx_http_process_request(r);
}
@@ -3544,7 +3572,7 @@
}
if (r->request_body_no_buffering) {
- size = len - h2scf->preread_size;
+ size = (size_t) len - h2scf->preread_size;
} else {
stream->no_flow_control = 1;
@@ -3638,7 +3666,7 @@
rb->buf = NULL;
}
- if (r->headers_in.content_length_n == -1) {
+ if (r->headers_in.chunked) {
r->headers_in.content_length_n = rb->received;
}
@@ -3890,6 +3918,10 @@
ngx_event_t *rev;
ngx_connection_t *fc;
+ if (stream->rst_sent) {
+ return NGX_OK;
+ }
+
if (ngx_http_v2_send_rst_stream(h2c, stream->node->id, status)
== NGX_ERROR)
{
@@ -3897,6 +3929,7 @@
}
stream->rst_sent = 1;
+ stream->skip_data = 1;
fc = stream->request->connection;
fc->error = 1;
@@ -3928,6 +3961,7 @@
if (stream->queued) {
fc->write->handler = ngx_http_v2_close_stream_handler;
+ fc->read->handler = ngx_http_empty_handler;
return;
}
@@ -4169,10 +4203,6 @@
c->error = 1;
- if (h2c->state.stream) {
- ngx_http_v2_close_stream(h2c->state.stream, NGX_HTTP_BAD_REQUEST);
- }
-
if (!h2c->processing) {
ngx_http_close_connection(c);
return;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/v2/ngx_http_v2.h
^
|
@@ -298,7 +298,7 @@
#define ngx_http_v2_parse_uint16(p) ((p)[0] << 8 | (p)[1])
#define ngx_http_v2_parse_uint32(p) \
- ((p)[0] << 24 | (p)[1] << 16 | (p)[2] << 8 | (p)[3])
+ ((uint32_t) (p)[0] << 24 | (p)[1] << 16 | (p)[2] << 8 | (p)[3])
#endif
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/http/v2/ngx_http_v2_filter_module.c
^
|
@@ -137,10 +137,6 @@
ngx_http_v2_out_frame_t *frame;
ngx_http_core_loc_conf_t *clcf;
ngx_http_core_srv_conf_t *cscf;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
u_char addr[NGX_SOCKADDR_STRLEN];
static const u_char nginx[5] = "\x84\xaa\x63\x55\xe7";
@@ -169,6 +165,12 @@
return NGX_OK;
}
+ fc = r->connection;
+
+ if (fc->error) {
+ return NGX_ERROR;
+ }
+
if (r->method == NGX_HTTP_HEAD) {
r->header_only = 1;
}
@@ -259,8 +261,6 @@
len += 1 + ngx_http_v2_literal_size("Wed, 31 Dec 1986 18:00:00 GMT");
}
- fc = r->connection;
-
if (r->headers_out.location && r->headers_out.location->value.len) {
if (r->headers_out.location->value.data[0] == '/') {
@@ -280,24 +280,7 @@
}
}
- switch (fc->local_sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) fc->local_sockaddr;
- port = ntohs(sin6->sin6_port);
- break;
-#endif
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- port = 0;
- break;
-#endif
- default: /* AF_INET */
- sin = (struct sockaddr_in *) fc->local_sockaddr;
- port = ntohs(sin->sin_port);
- break;
- }
+ port = ngx_inet_get_port(fc->local_sockaddr);
location.len = sizeof("https://") - 1 + host.len
+ r->headers_out.location->value.len;
@@ -995,12 +978,11 @@
ngx_http_v2_filter_get_data_frame(ngx_http_v2_stream_t *stream,
size_t len, ngx_chain_t *first, ngx_chain_t *last)
{
- u_char flags;
- ngx_buf_t *buf;
- ngx_chain_t *cl;
+ u_char flags;
+ ngx_buf_t *buf;
+ ngx_chain_t *cl;
ngx_http_v2_out_frame_t *frame;
-
frame = stream->free_frames;
if (frame) {
@@ -1028,7 +1010,7 @@
buf = cl->buf;
- if (!buf->start) {
+ if (buf->start == NULL) {
buf->start = ngx_palloc(stream->request->pool,
NGX_HTTP_V2_FRAME_HEADER_SIZE);
if (buf->start == NULL) {
@@ -1203,7 +1185,6 @@
ngx_http_v2_stream_t *stream;
stream = frame->stream;
-
cl = frame->first;
if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_v2_module) {
@@ -1313,18 +1294,20 @@
ngx_http_v2_handle_stream(ngx_http_v2_connection_t *h2c,
ngx_http_v2_stream_t *stream)
{
- ngx_event_t *wev;
+ ngx_connection_t *fc;
- if (stream->handled || stream->blocked || stream->exhausted) {
+ if (stream->handled || stream->blocked) {
return;
}
- wev = stream->request->connection->write;
+ fc = stream->request->connection;
- if (!wev->delayed) {
- stream->handled = 1;
- ngx_queue_insert_tail(&h2c->posted, &stream->queue);
+ if (!fc->error && (stream->exhausted || fc->write->delayed)) {
+ return;
}
+
+ stream->handled = 1;
+ ngx_queue_insert_tail(&h2c->posted, &stream->queue);
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/mail/ngx_mail.c
^
|
@@ -228,35 +228,11 @@
in_port_t p;
ngx_uint_t i;
struct sockaddr *sa;
- struct sockaddr_in *sin;
ngx_mail_conf_port_t *port;
ngx_mail_conf_addr_t *addr;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
sa = &listen->sockaddr.sockaddr;
-
- switch (sa->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = &listen->sockaddr.sockaddr_in6;
- p = sin6->sin6_port;
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- p = 0;
- break;
-#endif
-
- default: /* AF_INET */
- sin = &listen->sockaddr.sockaddr_in;
- p = sin->sin_port;
- break;
- }
+ p = ngx_inet_get_port(sa);
port = ports->elts;
for (i = 0; i < ports->nelts; i++) {
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/mail/ngx_mail.h
^
|
@@ -117,13 +117,15 @@
ngx_str_t server_name;
u_char *file_name;
- ngx_int_t line;
+ ngx_uint_t line;
ngx_resolver_t *resolver;
ngx_log_t *error_log;
/* server ctx */
ngx_mail_conf_ctx_t *ctx;
+
+ ngx_uint_t listen; /* unsigned listen:1; */
} ngx_mail_core_srv_conf_t;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/mail/ngx_mail_auth_http_module.c
^
|
@@ -462,15 +462,11 @@
ngx_mail_auth_http_process_headers(ngx_mail_session_t *s,
ngx_mail_auth_http_ctx_t *ctx)
{
- u_char *p;
- time_t timer;
- size_t len, size;
- ngx_int_t rc, port, n;
- ngx_addr_t *peer;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
+ u_char *p;
+ time_t timer;
+ size_t len, size;
+ ngx_int_t rc, port, n;
+ ngx_addr_t *peer;
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
"mail auth http process headers");
@@ -813,20 +809,7 @@
return;
}
- switch (peer->sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) peer->sockaddr;
- sin6->sin6_port = htons((in_port_t) port);
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) peer->sockaddr;
- sin->sin_port = htons((in_port_t) port);
- break;
- }
+ ngx_inet_set_port(peer->sockaddr, (in_port_t) port);
len = ctx->addr.len + 1 + ctx->port.len;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/mail/ngx_mail_core_module.c
^
|
@@ -279,6 +279,13 @@
*cf = pcf;
+ if (rv == NGX_CONF_OK && !cscf->listen) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "no \"listen\" is defined for server in %s:%ui",
+ cscf->file_name, cscf->line);
+ return NGX_CONF_ERROR;
+ }
+
return rv;
}
@@ -295,6 +302,8 @@
ngx_mail_module_t *module;
ngx_mail_core_main_conf_t *cmcf;
+ cscf->listen = 1;
+
value = cf->args->elts;
ngx_memzero(&u, sizeof(ngx_url_t));
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/mail/ngx_mail_ssl_module.c
^
|
@@ -422,24 +422,13 @@
}
}
- if (SSL_CTX_set_cipher_list(conf->ssl.ctx,
- (const char *) conf->ciphers.data)
- == 0)
+ if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers,
+ conf->prefer_server_ciphers)
+ != NGX_OK)
{
- ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
- "SSL_CTX_set_cipher_list(\"%V\") failed",
- &conf->ciphers);
return NGX_CONF_ERROR;
}
- if (conf->prefer_server_ciphers) {
- SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
- }
-
-#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER)
- SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback);
-#endif
-
if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
return NGX_CONF_ERROR;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/os/unix/ngx_files.c
^
|
@@ -356,6 +356,11 @@
n = 0;
for ( /* void */ ; cl; cl = cl->next) {
+
+ if (ngx_buf_special(cl->buf)) {
+ continue;
+ }
+
size = cl->buf->last - cl->buf->pos;
if (prev == cl->buf->pos) {
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/os/unix/ngx_posix_init.c
^
|
@@ -33,7 +33,8 @@
ngx_int_t
ngx_os_init(ngx_log_t *log)
{
- ngx_uint_t n;
+ ngx_time_t *tp;
+ ngx_uint_t n;
#if (NGX_HAVE_OS_SPECIFIC_INIT)
if (ngx_os_specific_init(log) != NGX_OK) {
@@ -76,7 +77,8 @@
ngx_inherited_nonblocking = 0;
#endif
- srandom(ngx_time());
+ tp = ngx_timeofday();
+ srandom(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec);
return NGX_OK;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/os/unix/ngx_process_cycle.c
^
|
@@ -785,6 +785,7 @@
{
sigset_t set;
ngx_int_t n;
+ ngx_time_t *tp;
ngx_uint_t i;
ngx_cpuset_t *cpu_affinity;
struct rlimit rlmt;
@@ -884,7 +885,8 @@
"sigprocmask() failed");
}
- srandom((ngx_pid << 16) ^ ngx_time());
+ tp = ngx_timeofday();
+ srandom(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec);
/*
* disable deleting previous events for the listening sockets because
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/os/unix/ngx_thread_mutex.c
^
|
@@ -49,7 +49,7 @@
* for each mutex from 10 to 100 based on spin count taken
* previously.
* FreeBSD: Deadlock detection. The default spin count is 2000.
- * It can be overriden using LIBPTHREAD_SPINLOOPS environment
+ * It can be overridden using LIBPTHREAD_SPINLOOPS environment
* variable or by pthread_mutex_setspinloops_np(). If a lock
* is still busy, sched_yield() can be called on both UP and
* SMP systems. The default yield loop count is zero, but
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream.c
^
|
@@ -143,11 +143,26 @@
}
- /* parse inside the stream{} block */
-
pcf = *cf;
cf->ctx = ctx;
+ for (m = 0; cf->cycle->modules[m]; m++) {
+ if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) {
+ continue;
+ }
+
+ module = cf->cycle->modules[m]->ctx;
+
+ if (module->preconfiguration) {
+ if (module->preconfiguration(cf) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+ }
+ }
+
+
+ /* parse inside the stream{} block */
+
cf->module_type = NGX_STREAM_MODULE;
cf->cmd_type = NGX_STREAM_MAIN_CONF;
rv = ngx_conf_parse(cf, NULL);
@@ -215,6 +230,10 @@
}
}
+ if (ngx_stream_variables_init_vars(cf) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
*cf = pcf;
@@ -243,35 +262,11 @@
in_port_t p;
ngx_uint_t i;
struct sockaddr *sa;
- struct sockaddr_in *sin;
ngx_stream_conf_port_t *port;
ngx_stream_conf_addr_t *addr;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
sa = &listen->sockaddr.sockaddr;
-
- switch (sa->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = &listen->sockaddr.sockaddr_in6;
- p = sin6->sin6_port;
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- p = 0;
- break;
-#endif
-
- default: /* AF_INET */
- sin = &listen->sockaddr.sockaddr_in;
- p = sin->sin_port;
- break;
- }
+ p = ngx_inet_get_port(sa);
port = ports->elts;
for (i = 0; i < ports->nelts; i++) {
@@ -460,6 +455,7 @@
#if (NGX_STREAM_SSL)
addrs[i].conf.ssl = addr[i].opt.ssl;
#endif
+ addrs[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
len = ngx_sock_ntop(&addr[i].opt.sockaddr.sockaddr, addr[i].opt.socklen,
buf, NGX_SOCKADDR_STRLEN, 1);
@@ -509,6 +505,7 @@
#if (NGX_STREAM_SSL)
addrs6[i].conf.ssl = addr[i].opt.ssl;
#endif
+ addrs6[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
len = ngx_sock_ntop(&addr[i].opt.sockaddr.sockaddr, addr[i].opt.socklen,
buf, NGX_SOCKADDR_STRLEN, 1);
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream.h
^
|
@@ -20,64 +20,76 @@
typedef struct ngx_stream_session_s ngx_stream_session_t;
+#include <ngx_stream_variables.h>
+#include <ngx_stream_script.h>
#include <ngx_stream_upstream.h>
#include <ngx_stream_upstream_round_robin.h>
+#define NGX_STREAM_OK 200
+#define NGX_STREAM_BAD_REQUEST 400
+#define NGX_STREAM_FORBIDDEN 403
+#define NGX_STREAM_INTERNAL_SERVER_ERROR 500
+#define NGX_STREAM_BAD_GATEWAY 502
+#define NGX_STREAM_SERVICE_UNAVAILABLE 503
+
+
typedef struct {
- void **main_conf;
- void **srv_conf;
+ void **main_conf;
+ void **srv_conf;
} ngx_stream_conf_ctx_t;
typedef struct {
- ngx_sockaddr_t sockaddr;
- socklen_t socklen;
+ ngx_sockaddr_t sockaddr;
+ socklen_t socklen;
/* server ctx */
- ngx_stream_conf_ctx_t *ctx;
+ ngx_stream_conf_ctx_t *ctx;
- unsigned bind:1;
- unsigned wildcard:1;
+ unsigned bind:1;
+ unsigned wildcard:1;
#if (NGX_STREAM_SSL)
- unsigned ssl:1;
+ unsigned ssl:1;
#endif
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
- unsigned ipv6only:1;
+ unsigned ipv6only:1;
#endif
#if (NGX_HAVE_REUSEPORT)
- unsigned reuseport:1;
+ unsigned reuseport:1;
#endif
- unsigned so_keepalive:2;
+ unsigned so_keepalive:2;
+ unsigned proxy_protocol:1;
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
- int tcp_keepidle;
- int tcp_keepintvl;
- int tcp_keepcnt;
+ int tcp_keepidle;
+ int tcp_keepintvl;
+ int tcp_keepcnt;
#endif
- int backlog;
- int type;
+ int backlog;
+ int type;
} ngx_stream_listen_t;
typedef struct {
- ngx_stream_conf_ctx_t *ctx;
- ngx_str_t addr_text;
+ ngx_stream_conf_ctx_t *ctx;
+ ngx_str_t addr_text;
#if (NGX_STREAM_SSL)
- ngx_uint_t ssl; /* unsigned ssl:1; */
+ unsigned ssl:1;
#endif
+ unsigned proxy_protocol:1;
} ngx_stream_addr_conf_t;
typedef struct {
- in_addr_t addr;
- ngx_stream_addr_conf_t conf;
+ in_addr_t addr;
+ ngx_stream_addr_conf_t conf;
} ngx_stream_in_addr_t;
#if (NGX_HAVE_INET6)
typedef struct {
- struct in6_addr addr6;
- ngx_stream_addr_conf_t conf;
+ struct in6_addr addr6;
+ ngx_stream_addr_conf_t conf;
} ngx_stream_in6_addr_t;
#endif
@@ -85,21 +97,21 @@
typedef struct {
/* ngx_stream_in_addr_t or ngx_stream_in6_addr_t */
- void *addrs;
- ngx_uint_t naddrs;
+ void *addrs;
+ ngx_uint_t naddrs;
} ngx_stream_port_t;
typedef struct {
- int family;
- int type;
- in_port_t port;
- ngx_array_t addrs; /* array of ngx_stream_conf_addr_t */
+ int family;
+ int type;
+ in_port_t port;
+ ngx_array_t addrs; /* array of ngx_stream_conf_addr_t */
} ngx_stream_conf_port_t;
typedef struct {
- ngx_stream_listen_t opt;
+ ngx_stream_listen_t opt;
} ngx_stream_conf_addr_t;
@@ -107,10 +119,23 @@
typedef struct {
- ngx_array_t servers; /* ngx_stream_core_srv_conf_t */
- ngx_array_t listen; /* ngx_stream_listen_t */
- ngx_stream_access_pt limit_conn_handler;
- ngx_stream_access_pt access_handler;
+ ngx_array_t servers; /* ngx_stream_core_srv_conf_t */
+ ngx_array_t listen; /* ngx_stream_listen_t */
+
+ ngx_stream_access_pt realip_handler;
+ ngx_stream_access_pt limit_conn_handler;
+ ngx_stream_access_pt access_handler;
+ ngx_stream_access_pt access_log_handler;
+
+ ngx_hash_t variables_hash;
+
+ ngx_array_t variables; /* ngx_stream_variable_t */
+ ngx_uint_t ncaptures;
+
+ ngx_uint_t variables_hash_max_size;
+ ngx_uint_t variables_hash_bucket_size;
+
+ ngx_hash_keys_arrays_t *variables_keys;
} ngx_stream_core_main_conf_t;
@@ -118,41 +143,70 @@
typedef struct {
- ngx_stream_handler_pt handler;
- ngx_stream_conf_ctx_t *ctx;
- u_char *file_name;
- ngx_int_t line;
- ngx_log_t *error_log;
- ngx_flag_t tcp_nodelay;
+ ngx_stream_handler_pt handler;
+
+ ngx_stream_conf_ctx_t *ctx;
+
+ u_char *file_name;
+ ngx_uint_t line;
+
+ ngx_flag_t tcp_nodelay;
+
+ ngx_log_t *error_log;
+
+ ngx_msec_t resolver_timeout;
+ ngx_resolver_t *resolver;
+
+ ngx_msec_t proxy_protocol_timeout;
+
+ ngx_uint_t listen; /* unsigned listen:1; */
} ngx_stream_core_srv_conf_t;
struct ngx_stream_session_s {
- uint32_t signature; /* "STRM" */
+ uint32_t signature; /* "STRM" */
+
+ ngx_connection_t *connection;
- ngx_connection_t *connection;
+ off_t received;
+ time_t start_sec;
+ ngx_msec_t start_msec;
- off_t received;
+ ngx_log_handler_pt log_handler;
- ngx_log_handler_pt log_handler;
+ void **ctx;
+ void **main_conf;
+ void **srv_conf;
- void **ctx;
- void **main_conf;
- void **srv_conf;
+ ngx_stream_upstream_t *upstream;
+ ngx_array_t *upstream_states;
+ /* of ngx_stream_upstream_state_t */
+ ngx_stream_variable_value_t *variables;
- ngx_stream_upstream_t *upstream;
+#if (NGX_PCRE)
+ ngx_uint_t ncaptures;
+ int *captures;
+ u_char *captures_data;
+#endif
+
+ ngx_uint_t status;
+
+#if (NGX_STREAM_SSL)
+ ngx_uint_t ssl; /* unsigned ssl:1; */
+#endif
};
typedef struct {
- ngx_int_t (*postconfiguration)(ngx_conf_t *cf);
+ ngx_int_t (*preconfiguration)(ngx_conf_t *cf);
+ ngx_int_t (*postconfiguration)(ngx_conf_t *cf);
- void *(*create_main_conf)(ngx_conf_t *cf);
- char *(*init_main_conf)(ngx_conf_t *cf, void *conf);
+ void *(*create_main_conf)(ngx_conf_t *cf);
+ char *(*init_main_conf)(ngx_conf_t *cf, void *conf);
- void *(*create_srv_conf)(ngx_conf_t *cf);
- char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev,
- void *conf);
+ void *(*create_srv_conf)(ngx_conf_t *cf);
+ char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev,
+ void *conf);
} ngx_stream_module_t;
@@ -190,7 +244,7 @@
void ngx_stream_init_connection(ngx_connection_t *c);
-void ngx_stream_close_connection(ngx_connection_t *c);
+void ngx_stream_finalize_session(ngx_stream_session_t *s, ngx_uint_t rc);
extern ngx_module_t ngx_stream_module;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_access_module.c
^
|
@@ -88,6 +88,7 @@
static ngx_stream_module_t ngx_stream_access_module_ctx = {
+ NULL, /* preconfiguration */
ngx_stream_access_init, /* postconfiguration */
NULL, /* create main configuration */
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_core_module.c
^
|
@@ -10,7 +10,9 @@
#include <ngx_stream.h>
+static ngx_int_t ngx_stream_core_preconfiguration(ngx_conf_t *cf);
static void *ngx_stream_core_create_main_conf(ngx_conf_t *cf);
+static char *ngx_stream_core_init_main_conf(ngx_conf_t *cf, void *conf);
static void *ngx_stream_core_create_srv_conf(ngx_conf_t *cf);
static char *ngx_stream_core_merge_srv_conf(ngx_conf_t *cf, void *parent,
void *child);
@@ -20,10 +22,26 @@
void *conf);
static char *ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
+static char *ngx_stream_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
static ngx_command_t ngx_stream_core_commands[] = {
+ { ngx_string("variables_hash_max_size"),
+ NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ NGX_STREAM_MAIN_CONF_OFFSET,
+ offsetof(ngx_stream_core_main_conf_t, variables_hash_max_size),
+ NULL },
+
+ { ngx_string("variables_hash_bucket_size"),
+ NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ NGX_STREAM_MAIN_CONF_OFFSET,
+ offsetof(ngx_stream_core_main_conf_t, variables_hash_bucket_size),
+ NULL },
+
{ ngx_string("server"),
NGX_STREAM_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
ngx_stream_core_server,
@@ -45,6 +63,27 @@
0,
NULL },
+ { ngx_string("resolver"),
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
+ ngx_stream_core_resolver,
+ NGX_STREAM_SRV_CONF_OFFSET,
+ 0,
+ NULL },
+
+ { ngx_string("resolver_timeout"),
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_msec_slot,
+ NGX_STREAM_SRV_CONF_OFFSET,
+ offsetof(ngx_stream_core_srv_conf_t, resolver_timeout),
+ NULL },
+
+ { ngx_string("proxy_protocol_timeout"),
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_msec_slot,
+ NGX_STREAM_SRV_CONF_OFFSET,
+ offsetof(ngx_stream_core_srv_conf_t, proxy_protocol_timeout),
+ NULL },
+
{ ngx_string("tcp_nodelay"),
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
@@ -57,10 +96,11 @@
static ngx_stream_module_t ngx_stream_core_module_ctx = {
+ ngx_stream_core_preconfiguration, /* preconfiguration */
NULL, /* postconfiguration */
ngx_stream_core_create_main_conf, /* create main configuration */
- NULL, /* init main configuration */
+ ngx_stream_core_init_main_conf, /* init main configuration */
ngx_stream_core_create_srv_conf, /* create server configuration */
ngx_stream_core_merge_srv_conf /* merge server configuration */
@@ -83,6 +123,13 @@
};
+static ngx_int_t
+ngx_stream_core_preconfiguration(ngx_conf_t *cf)
+{
+ return ngx_stream_variables_add_core_vars(cf);
+}
+
+
static void *
ngx_stream_core_create_main_conf(ngx_conf_t *cf)
{
@@ -106,10 +153,32 @@
return NULL;
}
+ cmcf->variables_hash_max_size = NGX_CONF_UNSET_UINT;
+ cmcf->variables_hash_bucket_size = NGX_CONF_UNSET_UINT;
+
return cmcf;
}
+static char *
+ngx_stream_core_init_main_conf(ngx_conf_t *cf, void *conf)
+{
+ ngx_stream_core_main_conf_t *cmcf = conf;
+
+ ngx_conf_init_uint_value(cmcf->variables_hash_max_size, 1024);
+ ngx_conf_init_uint_value(cmcf->variables_hash_bucket_size, 64);
+
+ cmcf->variables_hash_bucket_size =
+ ngx_align(cmcf->variables_hash_bucket_size, ngx_cacheline_size);
+
+ if (cmcf->ncaptures) {
+ cmcf->ncaptures = (cmcf->ncaptures + 1) * 3;
+ }
+
+ return NGX_CONF_OK;
+}
+
+
static void *
ngx_stream_core_create_srv_conf(ngx_conf_t *cf)
{
@@ -129,6 +198,8 @@
cscf->file_name = cf->conf_file->file.name.data;
cscf->line = cf->conf_file->line;
+ cscf->resolver_timeout = NGX_CONF_UNSET_MSEC;
+ cscf->proxy_protocol_timeout = NGX_CONF_UNSET_MSEC;
cscf->tcp_nodelay = NGX_CONF_UNSET;
return cscf;
@@ -141,6 +212,27 @@
ngx_stream_core_srv_conf_t *prev = parent;
ngx_stream_core_srv_conf_t *conf = child;
+ ngx_conf_merge_msec_value(conf->resolver_timeout,
+ prev->resolver_timeout, 30000);
+
+ if (conf->resolver == NULL) {
+
+ if (prev->resolver == NULL) {
+
+ /*
+ * create dummy resolver in stream {} context
+ * to inherit it in all servers
+ */
+
+ prev->resolver = ngx_resolver_create(cf, NULL, 0);
+ if (prev->resolver == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ conf->resolver = prev->resolver;
+ }
+
if (conf->handler == NULL) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"no handler for server in %s:%ui",
@@ -156,6 +248,9 @@
}
}
+ ngx_conf_merge_msec_value(conf->proxy_protocol_timeout,
+ prev->proxy_protocol_timeout, 30000);
+
ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1);
return NGX_CONF_OK;
@@ -241,6 +336,13 @@
*cf = pcf;
+ if (rv == NGX_CONF_OK && !cscf->listen) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "no \"listen\" is defined for server in %s:%ui",
+ cscf->file_name, cscf->line);
+ return NGX_CONF_ERROR;
+ }
+
return rv;
}
@@ -248,12 +350,16 @@
static char *
ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
+ ngx_stream_core_srv_conf_t *cscf = conf;
+
ngx_str_t *value;
ngx_url_t u;
ngx_uint_t i, backlog;
ngx_stream_listen_t *ls, *als;
ngx_stream_core_main_conf_t *cmcf;
+ cscf->listen = 1;
+
value = cf->args->elts;
ngx_memzero(&u, sizeof(ngx_url_t));
@@ -477,6 +583,11 @@
#endif
}
+ if (ngx_strcmp(value[i].data, "proxy_protocol") == 0) {
+ ls->proxy_protocol = 1;
+ continue;
+ }
+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"the invalid \"%V\" parameter", &value[i]);
return NGX_CONF_ERROR;
@@ -496,6 +607,10 @@
if (ls->so_keepalive) {
return "\"so_keepalive\" parameter is incompatible with \"udp\"";
}
+
+ if (ls->proxy_protocol) {
+ return "\"proxy_protocol\" parameter is incompatible with \"udp\"";
+ }
}
als = cmcf->listen.elts;
@@ -517,5 +632,27 @@
return NGX_CONF_ERROR;
}
+ return NGX_CONF_OK;
+}
+
+
+static char *
+ngx_stream_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_stream_core_srv_conf_t *cscf = conf;
+
+ ngx_str_t *value;
+
+ if (cscf->resolver) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ cscf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1);
+ if (cscf->resolver == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
return NGX_CONF_OK;
}
|
[-]
[+]
|
Added |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_geo_module.c
^
|
@@ -0,0 +1,1586 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_stream.h>
+
+
+typedef struct {
+ ngx_stream_variable_value_t *value;
+ u_short start;
+ u_short end;
+} ngx_stream_geo_range_t;
+
+
+typedef struct {
+ ngx_radix_tree_t *tree;
+#if (NGX_HAVE_INET6)
+ ngx_radix_tree_t *tree6;
+#endif
+} ngx_stream_geo_trees_t;
+
+
+typedef struct {
+ ngx_stream_geo_range_t **low;
+ ngx_stream_variable_value_t *default_value;
+} ngx_stream_geo_high_ranges_t;
+
+
+typedef struct {
+ ngx_str_node_t sn;
+ ngx_stream_variable_value_t *value;
+ size_t offset;
+} ngx_stream_geo_variable_value_node_t;
+
+
+typedef struct {
+ ngx_stream_variable_value_t *value;
+ ngx_str_t *net;
+ ngx_stream_geo_high_ranges_t high;
+ ngx_radix_tree_t *tree;
+#if (NGX_HAVE_INET6)
+ ngx_radix_tree_t *tree6;
+#endif
+ ngx_rbtree_t rbtree;
+ ngx_rbtree_node_t sentinel;
+ ngx_pool_t *pool;
+ ngx_pool_t *temp_pool;
+
+ size_t data_size;
+
+ ngx_str_t include_name;
+ ngx_uint_t includes;
+ ngx_uint_t entries;
+
+ unsigned ranges:1;
+ unsigned outside_entries:1;
+ unsigned allow_binary_include:1;
+ unsigned binary_include:1;
+} ngx_stream_geo_conf_ctx_t;
+
+
+typedef struct {
+ union {
+ ngx_stream_geo_trees_t trees;
+ ngx_stream_geo_high_ranges_t high;
+ } u;
+
+ ngx_int_t index;
+} ngx_stream_geo_ctx_t;
+
+
+static ngx_int_t ngx_stream_geo_addr(ngx_stream_session_t *s,
+ ngx_stream_geo_ctx_t *ctx, ngx_addr_t *addr);
+
+static char *ngx_stream_geo_block(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static char *ngx_stream_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf);
+static char *ngx_stream_geo_range(ngx_conf_t *cf,
+ ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *value);
+static char *ngx_stream_geo_add_range(ngx_conf_t *cf,
+ ngx_stream_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end);
+static ngx_uint_t ngx_stream_geo_delete_range(ngx_conf_t *cf,
+ ngx_stream_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end);
+static char *ngx_stream_geo_cidr(ngx_conf_t *cf,
+ ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *value);
+static char *ngx_stream_geo_cidr_add(ngx_conf_t *cf,
+ ngx_stream_geo_conf_ctx_t *ctx, ngx_cidr_t *cidr, ngx_str_t *value,
+ ngx_str_t *net);
+static ngx_stream_variable_value_t *ngx_stream_geo_value(ngx_conf_t *cf,
+ ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *value);
+static ngx_int_t ngx_stream_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net,
+ ngx_cidr_t *cidr);
+static char *ngx_stream_geo_include(ngx_conf_t *cf,
+ ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *name);
+static ngx_int_t ngx_stream_geo_include_binary_base(ngx_conf_t *cf,
+ ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *name);
+static void ngx_stream_geo_create_binary_base(ngx_stream_geo_conf_ctx_t *ctx);
+static u_char *ngx_stream_geo_copy_values(u_char *base, u_char *p,
+ ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
+
+
+static ngx_command_t ngx_stream_geo_commands[] = {
+
+ { ngx_string("geo"),
+ NGX_STREAM_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
+ ngx_stream_geo_block,
+ 0,
+ 0,
+ NULL },
+
+ ngx_null_command
+};
+
+
+static ngx_stream_module_t ngx_stream_geo_module_ctx = {
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
+
+ NULL, /* create main configuration */
+ NULL, /* init main configuration */
+
+ NULL, /* create server configuration */
+ NULL /* merge server configuration */
+};
+
+
+ngx_module_t ngx_stream_geo_module = {
+ NGX_MODULE_V1,
+ &ngx_stream_geo_module_ctx, /* module context */
+ ngx_stream_geo_commands, /* module directives */
+ NGX_STREAM_MODULE, /* module type */
+ NULL, /* init master */
+ NULL, /* init module */
+ NULL, /* init process */
+ NULL, /* init thread */
+ NULL, /* exit thread */
+ NULL, /* exit process */
+ NULL, /* exit master */
+ NGX_MODULE_V1_PADDING
+};
+
+
+typedef struct {
+ u_char GEORNG[6];
+ u_char version;
+ u_char ptr_size;
+ uint32_t endianness;
+ uint32_t crc32;
+} ngx_stream_geo_header_t;
+
+
+static ngx_stream_geo_header_t ngx_stream_geo_header = {
+ { 'G', 'E', 'O', 'R', 'N', 'G' }, 0, sizeof(void *), 0x12345678, 0
+};
+
+
+/* geo range is AF_INET only */
+
+static ngx_int_t
+ngx_stream_geo_cidr_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ ngx_stream_geo_ctx_t *ctx = (ngx_stream_geo_ctx_t *) data;
+
+ in_addr_t inaddr;
+ ngx_addr_t addr;
+ struct sockaddr_in *sin;
+ ngx_stream_variable_value_t *vv;
+#if (NGX_HAVE_INET6)
+ u_char *p;
+ struct in6_addr *inaddr6;
+#endif
+
+ if (ngx_stream_geo_addr(s, ctx, &addr) != NGX_OK) {
+ vv = (ngx_stream_variable_value_t *)
+ ngx_radix32tree_find(ctx->u.trees.tree, INADDR_NONE);
+ goto done;
+ }
+
+ switch (addr.sockaddr->sa_family) {
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
+ p = inaddr6->s6_addr;
+
+ if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
+ inaddr = p[12] << 24;
+ inaddr += p[13] << 16;
+ inaddr += p[14] << 8;
+ inaddr += p[15];
+
+ vv = (ngx_stream_variable_value_t *)
+ ngx_radix32tree_find(ctx->u.trees.tree, inaddr);
+
+ } else {
+ vv = (ngx_stream_variable_value_t *)
+ ngx_radix128tree_find(ctx->u.trees.tree6, p);
+ }
+
+ break;
+#endif
+
+ default: /* AF_INET */
+ sin = (struct sockaddr_in *) addr.sockaddr;
+ inaddr = ntohl(sin->sin_addr.s_addr);
+
+ vv = (ngx_stream_variable_value_t *)
+ ngx_radix32tree_find(ctx->u.trees.tree, inaddr);
+
+ break;
+ }
+
+done:
+
+ *v = *vv;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "stream geo: %v", v);
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_geo_range_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ ngx_stream_geo_ctx_t *ctx = (ngx_stream_geo_ctx_t *) data;
+
+ in_addr_t inaddr;
+ ngx_addr_t addr;
+ ngx_uint_t n;
+ struct sockaddr_in *sin;
+ ngx_stream_geo_range_t *range;
+#if (NGX_HAVE_INET6)
+ u_char *p;
+ struct in6_addr *inaddr6;
+#endif
+
+ *v = *ctx->u.high.default_value;
+
+ if (ngx_stream_geo_addr(s, ctx, &addr) == NGX_OK) {
+
+ switch (addr.sockaddr->sa_family) {
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
+
+ if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
+ p = inaddr6->s6_addr;
+
+ inaddr = p[12] << 24;
+ inaddr += p[13] << 16;
+ inaddr += p[14] << 8;
+ inaddr += p[15];
+
+ } else {
+ inaddr = INADDR_NONE;
+ }
+
+ break;
+#endif
+
+ default: /* AF_INET */
+ sin = (struct sockaddr_in *) addr.sockaddr;
+ inaddr = ntohl(sin->sin_addr.s_addr);
+ break;
+ }
+
+ } else {
+ inaddr = INADDR_NONE;
+ }
+
+ if (ctx->u.high.low) {
+ range = ctx->u.high.low[inaddr >> 16];
+
+ if (range) {
+ n = inaddr & 0xffff;
+ do {
+ if (n >= (ngx_uint_t) range->start
+ && n <= (ngx_uint_t) range->end)
+ {
+ *v = *range->value;
+ break;
+ }
+ } while ((++range)->value);
+ }
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "stream geo: %v", v);
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_geo_addr(ngx_stream_session_t *s, ngx_stream_geo_ctx_t *ctx,
+ ngx_addr_t *addr)
+{
+ ngx_stream_variable_value_t *v;
+
+ if (ctx->index == -1) {
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "stream geo started: %V", &s->connection->addr_text);
+
+ addr->sockaddr = s->connection->sockaddr;
+ addr->socklen = s->connection->socklen;
+ /* addr->name = s->connection->addr_text; */
+
+ return NGX_OK;
+ }
+
+ v = ngx_stream_get_flushed_variable(s, ctx->index);
+
+ if (v == NULL || v->not_found) {
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "stream geo not found");
+
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "stream geo started: %v", v);
+
+ if (ngx_parse_addr(s->connection->pool, addr, v->data, v->len) == NGX_OK) {
+ return NGX_OK;
+ }
+
+ return NGX_ERROR;
+}
+
+
+static char *
+ngx_stream_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ char *rv;
+ size_t len;
+ ngx_str_t *value, name;
+ ngx_uint_t i;
+ ngx_conf_t save;
+ ngx_pool_t *pool;
+ ngx_array_t *a;
+ ngx_stream_variable_t *var;
+ ngx_stream_geo_ctx_t *geo;
+ ngx_stream_geo_conf_ctx_t ctx;
+#if (NGX_HAVE_INET6)
+ static struct in6_addr zero;
+#endif
+
+ value = cf->args->elts;
+
+ geo = ngx_palloc(cf->pool, sizeof(ngx_stream_geo_ctx_t));
+ if (geo == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ name = value[1];
+
+ if (name.data[0] != '$') {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid variable name \"%V\"", &name);
+ return NGX_CONF_ERROR;
+ }
+
+ name.len--;
+ name.data++;
+
+ if (cf->args->nelts == 3) {
+
+ geo->index = ngx_stream_get_variable_index(cf, &name);
+ if (geo->index == NGX_ERROR) {
+ return NGX_CONF_ERROR;
+ }
+
+ name = value[2];
+
+ if (name.data[0] != '$') {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid variable name \"%V\"", &name);
+ return NGX_CONF_ERROR;
+ }
+
+ name.len--;
+ name.data++;
+
+ } else {
+ geo->index = -1;
+ }
+
+ var = ngx_stream_add_variable(cf, &name, NGX_STREAM_VAR_CHANGEABLE);
+ if (var == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log);
+ if (pool == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ngx_memzero(&ctx, sizeof(ngx_stream_geo_conf_ctx_t));
+
+ ctx.temp_pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log);
+ if (ctx.temp_pool == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ngx_rbtree_init(&ctx.rbtree, &ctx.sentinel, ngx_str_rbtree_insert_value);
+
+ ctx.pool = cf->pool;
+ ctx.data_size = sizeof(ngx_stream_geo_header_t)
+ + sizeof(ngx_stream_variable_value_t)
+ + 0x10000 * sizeof(ngx_stream_geo_range_t *);
+ ctx.allow_binary_include = 1;
+
+ save = *cf;
+ cf->pool = pool;
+ cf->ctx = &ctx;
+ cf->handler = ngx_stream_geo;
+ cf->handler_conf = conf;
+
+ rv = ngx_conf_parse(cf, NULL);
+
+ *cf = save;
+
+ if (ctx.ranges) {
+
+ if (ctx.high.low && !ctx.binary_include) {
+ for (i = 0; i < 0x10000; i++) {
+ a = (ngx_array_t *) ctx.high.low[i];
+
+ if (a == NULL) {
+ continue;
+ }
+
+ if (a->nelts == 0) {
+ ctx.high.low[i] = NULL;
+ continue;
+ }
+
+ len = a->nelts * sizeof(ngx_stream_geo_range_t);
+
+ ctx.high.low[i] = ngx_palloc(cf->pool, len + sizeof(void *));
+ if (ctx.high.low[i] == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ngx_memcpy(ctx.high.low[i], a->elts, len);
+ ctx.high.low[i][a->nelts].value = NULL;
+ ctx.data_size += len + sizeof(void *);
+ }
+
+ if (ctx.allow_binary_include
+ && !ctx.outside_entries
+ && ctx.entries > 100000
+ && ctx.includes == 1)
+ {
+ ngx_stream_geo_create_binary_base(&ctx);
+ }
+ }
+
+ if (ctx.high.default_value == NULL) {
+ ctx.high.default_value = &ngx_stream_variable_null_value;
+ }
+
+ geo->u.high = ctx.high;
+
+ var->get_handler = ngx_stream_geo_range_variable;
+ var->data = (uintptr_t) geo;
+
+ ngx_destroy_pool(ctx.temp_pool);
+ ngx_destroy_pool(pool);
+
+ } else {
+ if (ctx.tree == NULL) {
+ ctx.tree = ngx_radix_tree_create(cf->pool, -1);
+ if (ctx.tree == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ geo->u.trees.tree = ctx.tree;
+
+#if (NGX_HAVE_INET6)
+ if (ctx.tree6 == NULL) {
+ ctx.tree6 = ngx_radix_tree_create(cf->pool, -1);
+ if (ctx.tree6 == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ geo->u.trees.tree6 = ctx.tree6;
+#endif
+
+ var->get_handler = ngx_stream_geo_cidr_variable;
+ var->data = (uintptr_t) geo;
+
+ ngx_destroy_pool(ctx.temp_pool);
+ ngx_destroy_pool(pool);
+
+ if (ngx_radix32tree_insert(ctx.tree, 0, 0,
+ (uintptr_t) &ngx_stream_variable_null_value)
+ == NGX_ERROR)
+ {
+ return NGX_CONF_ERROR;
+ }
+
+ /* NGX_BUSY is okay (default was set explicitly) */
+
+#if (NGX_HAVE_INET6)
+ if (ngx_radix128tree_insert(ctx.tree6, zero.s6_addr, zero.s6_addr,
+ (uintptr_t) &ngx_stream_variable_null_value)
+ == NGX_ERROR)
+ {
+ return NGX_CONF_ERROR;
+ }
+#endif
+ }
+
+ return rv;
+}
+
+
+static char *
+ngx_stream_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
+{
+ char *rv;
+ ngx_str_t *value;
+ ngx_stream_geo_conf_ctx_t *ctx;
+
+ ctx = cf->ctx;
+
+ value = cf->args->elts;
+
+ if (cf->args->nelts == 1) {
+
+ if (ngx_strcmp(value[0].data, "ranges") == 0) {
+
+ if (ctx->tree
+#if (NGX_HAVE_INET6)
+ || ctx->tree6
+#endif
+ )
+ {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "the \"ranges\" directive must be "
+ "the first directive inside \"geo\" block");
+ goto failed;
+ }
+
+ ctx->ranges = 1;
+
+ rv = NGX_CONF_OK;
+
+ goto done;
+ }
+ }
+
+ if (cf->args->nelts != 2) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid number of the geo parameters");
+ goto failed;
+ }
+
+ if (ngx_strcmp(value[0].data, "include") == 0) {
+
+ rv = ngx_stream_geo_include(cf, ctx, &value[1]);
+
+ goto done;
+ }
+
+ if (ctx->ranges) {
+ rv = ngx_stream_geo_range(cf, ctx, value);
+
+ } else {
+ rv = ngx_stream_geo_cidr(cf, ctx, value);
+ }
+
+done:
+
+ ngx_reset_pool(cf->pool);
+
+ return rv;
+
+failed:
+
+ ngx_reset_pool(cf->pool);
+
+ return NGX_CONF_ERROR;
+}
+
+
+static char *
+ngx_stream_geo_range(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx,
+ ngx_str_t *value)
+{
+ u_char *p, *last;
+ in_addr_t start, end;
+ ngx_str_t *net;
+ ngx_uint_t del;
+
+ if (ngx_strcmp(value[0].data, "default") == 0) {
+
+ if (ctx->high.default_value) {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "duplicate default geo range value: \"%V\", old value: \"%v\"",
+ &value[1], ctx->high.default_value);
+ }
+
+ ctx->high.default_value = ngx_stream_geo_value(cf, ctx, &value[1]);
+ if (ctx->high.default_value == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+ }
+
+ if (ctx->binary_include) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "binary geo range base \"%s\" cannot be mixed with usual entries",
+ ctx->include_name.data);
+ return NGX_CONF_ERROR;
+ }
+
+ if (ctx->high.low == NULL) {
+ ctx->high.low = ngx_pcalloc(ctx->pool,
+ 0x10000 * sizeof(ngx_stream_geo_range_t *));
+ if (ctx->high.low == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ ctx->entries++;
+ ctx->outside_entries = 1;
+
+ if (ngx_strcmp(value[0].data, "delete") == 0) {
+ net = &value[1];
+ del = 1;
+
+ } else {
+ net = &value[0];
+ del = 0;
+ }
+
+ last = net->data + net->len;
+
+ p = ngx_strlchr(net->data, last, '-');
+
+ if (p == NULL) {
+ goto invalid;
+ }
+
+ start = ngx_inet_addr(net->data, p - net->data);
+
+ if (start == INADDR_NONE) {
+ goto invalid;
+ }
+
+ start = ntohl(start);
+
+ p++;
+
+ end = ngx_inet_addr(p, last - p);
+
+ if (end == INADDR_NONE) {
+ goto invalid;
+ }
+
+ end = ntohl(end);
+
+ if (start > end) {
+ goto invalid;
+ }
+
+ if (del) {
+ if (ngx_stream_geo_delete_range(cf, ctx, start, end)) {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "no address range \"%V\" to delete", net);
+ }
+
+ return NGX_CONF_OK;
+ }
+
+ ctx->value = ngx_stream_geo_value(cf, ctx, &value[1]);
+
+ if (ctx->value == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ctx->net = net;
+
+ return ngx_stream_geo_add_range(cf, ctx, start, end);
+
+invalid:
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid range \"%V\"", net);
+
+ return NGX_CONF_ERROR;
+}
+
+
+/* the add procedure is optimized to add a growing up sequence */
+
+static char *
+ngx_stream_geo_add_range(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx,
+ in_addr_t start, in_addr_t end)
+{
+ in_addr_t n;
+ ngx_uint_t h, i, s, e;
+ ngx_array_t *a;
+ ngx_stream_geo_range_t *range;
+
+ for (n = start; n <= end; n = (n + 0x10000) & 0xffff0000) {
+
+ h = n >> 16;
+
+ if (n == start) {
+ s = n & 0xffff;
+ } else {
+ s = 0;
+ }
+
+ if ((n | 0xffff) > end) {
+ e = end & 0xffff;
+
+ } else {
+ e = 0xffff;
+ }
+
+ a = (ngx_array_t *) ctx->high.low[h];
+
+ if (a == NULL) {
+ a = ngx_array_create(ctx->temp_pool, 64,
+ sizeof(ngx_stream_geo_range_t));
+ if (a == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ctx->high.low[h] = (ngx_stream_geo_range_t *) a;
+ }
+
+ i = a->nelts;
+ range = a->elts;
+
+ while (i) {
+
+ i--;
+
+ if (e < (ngx_uint_t) range[i].start) {
+ continue;
+ }
+
+ if (s > (ngx_uint_t) range[i].end) {
+
+ /* add after the range */
+
+ range = ngx_array_push(a);
+ if (range == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ range = a->elts;
+
+ ngx_memmove(&range[i + 2], &range[i + 1],
+ (a->nelts - 2 - i) * sizeof(ngx_stream_geo_range_t));
+
+ range[i + 1].start = (u_short) s;
+ range[i + 1].end = (u_short) e;
+ range[i + 1].value = ctx->value;
+
+ goto next;
+ }
+
+ if (s == (ngx_uint_t) range[i].start
+ && e == (ngx_uint_t) range[i].end)
+ {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "duplicate range \"%V\", value: \"%v\", old value: \"%v\"",
+ ctx->net, ctx->value, range[i].value);
+
+ range[i].value = ctx->value;
+
+ goto next;
+ }
+
+ if (s > (ngx_uint_t) range[i].start
+ && e < (ngx_uint_t) range[i].end)
+ {
+ /* split the range and insert the new one */
+
+ range = ngx_array_push(a);
+ if (range == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ range = ngx_array_push(a);
+ if (range == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ range = a->elts;
+
+ ngx_memmove(&range[i + 3], &range[i + 1],
+ (a->nelts - 3 - i) * sizeof(ngx_stream_geo_range_t));
+
+ range[i + 2].start = (u_short) (e + 1);
+ range[i + 2].end = range[i].end;
+ range[i + 2].value = range[i].value;
+
+ range[i + 1].start = (u_short) s;
+ range[i + 1].end = (u_short) e;
+ range[i + 1].value = ctx->value;
+
+ range[i].end = (u_short) (s - 1);
+
+ goto next;
+ }
+
+ if (s == (ngx_uint_t) range[i].start
+ && e < (ngx_uint_t) range[i].end)
+ {
+ /* shift the range start and insert the new range */
+
+ range = ngx_array_push(a);
+ if (range == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ range = a->elts;
+
+ ngx_memmove(&range[i + 1], &range[i],
+ (a->nelts - 1 - i) * sizeof(ngx_stream_geo_range_t));
+
+ range[i + 1].start = (u_short) (e + 1);
+
+ range[i].start = (u_short) s;
+ range[i].end = (u_short) e;
+ range[i].value = ctx->value;
+
+ goto next;
+ }
+
+ if (s > (ngx_uint_t) range[i].start
+ && e == (ngx_uint_t) range[i].end)
+ {
+ /* shift the range end and insert the new range */
+
+ range = ngx_array_push(a);
+ if (range == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ range = a->elts;
+
+ ngx_memmove(&range[i + 2], &range[i + 1],
+ (a->nelts - 2 - i) * sizeof(ngx_stream_geo_range_t));
+
+ range[i + 1].start = (u_short) s;
+ range[i + 1].end = (u_short) e;
+ range[i + 1].value = ctx->value;
+
+ range[i].end = (u_short) (s - 1);
+
+ goto next;
+ }
+
+ s = (ngx_uint_t) range[i].start;
+ e = (ngx_uint_t) range[i].end;
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "range \"%V\" overlaps \"%d.%d.%d.%d-%d.%d.%d.%d\"",
+ ctx->net,
+ h >> 8, h & 0xff, s >> 8, s & 0xff,
+ h >> 8, h & 0xff, e >> 8, e & 0xff);
+
+ return NGX_CONF_ERROR;
+ }
+
+ /* add the first range */
+
+ range = ngx_array_push(a);
+ if (range == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ range = a->elts;
+
+ ngx_memmove(&range[1], &range[0],
+ (a->nelts - 1) * sizeof(ngx_stream_geo_range_t));
+
+ range[0].start = (u_short) s;
+ range[0].end = (u_short) e;
+ range[0].value = ctx->value;
+
+ next:
+
+ if (h == 0xffff) {
+ break;
+ }
+ }
+
+ return NGX_CONF_OK;
+}
+
+
+static ngx_uint_t
+ngx_stream_geo_delete_range(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx,
+ in_addr_t start, in_addr_t end)
+{
+ in_addr_t n;
+ ngx_uint_t h, i, s, e, warn;
+ ngx_array_t *a;
+ ngx_stream_geo_range_t *range;
+
+ warn = 0;
+
+ for (n = start; n <= end; n = (n + 0x10000) & 0xffff0000) {
+
+ h = n >> 16;
+
+ if (n == start) {
+ s = n & 0xffff;
+ } else {
+ s = 0;
+ }
+
+ if ((n | 0xffff) > end) {
+ e = end & 0xffff;
+
+ } else {
+ e = 0xffff;
+ }
+
+ a = (ngx_array_t *) ctx->high.low[h];
+
+ if (a == NULL || a->nelts == 0) {
+ warn = 1;
+ goto next;
+ }
+
+ range = a->elts;
+ for (i = 0; i < a->nelts; i++) {
+
+ if (s == (ngx_uint_t) range[i].start
+ && e == (ngx_uint_t) range[i].end)
+ {
+ ngx_memmove(&range[i], &range[i + 1],
+ (a->nelts - 1 - i) * sizeof(ngx_stream_geo_range_t));
+
+ a->nelts--;
+
+ break;
+ }
+
+ if (i == a->nelts - 1) {
+ warn = 1;
+ }
+ }
+
+ next:
+
+ if (h == 0xffff) {
+ break;
+ }
+ }
+
+ return warn;
+}
+
+
+static char *
+ngx_stream_geo_cidr(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx,
+ ngx_str_t *value)
+{
+ char *rv;
+ ngx_int_t rc, del;
+ ngx_str_t *net;
+ ngx_cidr_t cidr;
+
+ if (ctx->tree == NULL) {
+ ctx->tree = ngx_radix_tree_create(ctx->pool, -1);
+ if (ctx->tree == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+#if (NGX_HAVE_INET6)
+ if (ctx->tree6 == NULL) {
+ ctx->tree6 = ngx_radix_tree_create(ctx->pool, -1);
+ if (ctx->tree6 == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+#endif
+
+ if (ngx_strcmp(value[0].data, "default") == 0) {
+ cidr.family = AF_INET;
+ cidr.u.in.addr = 0;
+ cidr.u.in.mask = 0;
+
+ rv = ngx_stream_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]);
+
+ if (rv != NGX_CONF_OK) {
+ return rv;
+ }
+
+#if (NGX_HAVE_INET6)
+ cidr.family = AF_INET6;
+ ngx_memzero(&cidr.u.in6, sizeof(ngx_in6_cidr_t));
+
+ rv = ngx_stream_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]);
+
+ if (rv != NGX_CONF_OK) {
+ return rv;
+ }
+#endif
+
+ return NGX_CONF_OK;
+ }
+
+ if (ngx_strcmp(value[0].data, "delete") == 0) {
+ net = &value[1];
+ del = 1;
+
+ } else {
+ net = &value[0];
+ del = 0;
+ }
+
+ if (ngx_stream_geo_cidr_value(cf, net, &cidr) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (cidr.family == AF_INET) {
+ cidr.u.in.addr = ntohl(cidr.u.in.addr);
+ cidr.u.in.mask = ntohl(cidr.u.in.mask);
+ }
+
+ if (del) {
+ switch (cidr.family) {
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ rc = ngx_radix128tree_delete(ctx->tree6,
+ cidr.u.in6.addr.s6_addr,
+ cidr.u.in6.mask.s6_addr);
+ break;
+#endif
+
+ default: /* AF_INET */
+ rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr,
+ cidr.u.in.mask);
+ break;
+ }
+
+ if (rc != NGX_OK) {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "no network \"%V\" to delete", net);
+ }
+
+ return NGX_CONF_OK;
+ }
+
+ return ngx_stream_geo_cidr_add(cf, ctx, &cidr, &value[1], net);
+}
+
+
+static char *
+ngx_stream_geo_cidr_add(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx,
+ ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net)
+{
+ ngx_int_t rc;
+ ngx_stream_variable_value_t *val, *old;
+
+ val = ngx_stream_geo_value(cf, ctx, value);
+
+ if (val == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ switch (cidr->family) {
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr,
+ cidr->u.in6.mask.s6_addr,
+ (uintptr_t) val);
+
+ if (rc == NGX_OK) {
+ return NGX_CONF_OK;
+ }
+
+ if (rc == NGX_ERROR) {
+ return NGX_CONF_ERROR;
+ }
+
+ /* rc == NGX_BUSY */
+
+ old = (ngx_stream_variable_value_t *)
+ ngx_radix128tree_find(ctx->tree6,
+ cidr->u.in6.addr.s6_addr);
+
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
+ net, val, old);
+
+ rc = ngx_radix128tree_delete(ctx->tree6,
+ cidr->u.in6.addr.s6_addr,
+ cidr->u.in6.mask.s6_addr);
+
+ if (rc == NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree");
+ return NGX_CONF_ERROR;
+ }
+
+ rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr,
+ cidr->u.in6.mask.s6_addr,
+ (uintptr_t) val);
+
+ break;
+#endif
+
+ default: /* AF_INET */
+ rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr,
+ cidr->u.in.mask, (uintptr_t) val);
+
+ if (rc == NGX_OK) {
+ return NGX_CONF_OK;
+ }
+
+ if (rc == NGX_ERROR) {
+ return NGX_CONF_ERROR;
+ }
+
+ /* rc == NGX_BUSY */
+
+ old = (ngx_stream_variable_value_t *)
+ ngx_radix32tree_find(ctx->tree, cidr->u.in.addr);
+
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
+ net, val, old);
+
+ rc = ngx_radix32tree_delete(ctx->tree,
+ cidr->u.in.addr, cidr->u.in.mask);
+
+ if (rc == NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree");
+ return NGX_CONF_ERROR;
+ }
+
+ rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr,
+ cidr->u.in.mask, (uintptr_t) val);
+
+ break;
+ }
+
+ if (rc == NGX_OK) {
+ return NGX_CONF_OK;
+ }
+
+ return NGX_CONF_ERROR;
+}
+
+
+static ngx_stream_variable_value_t *
+ngx_stream_geo_value(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx,
+ ngx_str_t *value)
+{
+ uint32_t hash;
+ ngx_stream_variable_value_t *val;
+ ngx_stream_geo_variable_value_node_t *gvvn;
+
+ hash = ngx_crc32_long(value->data, value->len);
+
+ gvvn = (ngx_stream_geo_variable_value_node_t *)
+ ngx_str_rbtree_lookup(&ctx->rbtree, value, hash);
+
+ if (gvvn) {
+ return gvvn->value;
+ }
+
+ val = ngx_palloc(ctx->pool, sizeof(ngx_stream_variable_value_t));
+ if (val == NULL) {
+ return NULL;
+ }
+
+ val->len = value->len;
+ val->data = ngx_pstrdup(ctx->pool, value);
+ if (val->data == NULL) {
+ return NULL;
+ }
+
+ val->valid = 1;
+ val->no_cacheable = 0;
+ val->not_found = 0;
+
+ gvvn = ngx_palloc(ctx->temp_pool,
+ sizeof(ngx_stream_geo_variable_value_node_t));
+ if (gvvn == NULL) {
+ return NULL;
+ }
+
+ gvvn->sn.node.key = hash;
+ gvvn->sn.str.len = val->len;
+ gvvn->sn.str.data = val->data;
+ gvvn->value = val;
+ gvvn->offset = 0;
+
+ ngx_rbtree_insert(&ctx->rbtree, &gvvn->sn.node);
+
+ ctx->data_size += ngx_align(sizeof(ngx_stream_variable_value_t)
+ + value->len, sizeof(void *));
+
+ return val;
+}
+
+
+static ngx_int_t
+ngx_stream_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr)
+{
+ ngx_int_t rc;
+
+ if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
+ cidr->family = AF_INET;
+ cidr->u.in.addr = 0xffffffff;
+ cidr->u.in.mask = 0xffffffff;
+
+ return NGX_OK;
+ }
+
+ rc = ngx_ptocidr(net, cidr);
+
+ if (rc == NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid network \"%V\"", net);
+ return NGX_ERROR;
+ }
+
+ if (rc == NGX_DONE) {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "low address bits of %V are meaningless", net);
+ }
+
+ return NGX_OK;
+}
+
+
+static char *
+ngx_stream_geo_include(ngx_conf_t *cf, ngx_stream_geo_conf_ctx_t *ctx,
+ ngx_str_t *name)
+{
+ char *rv;
+ ngx_str_t file;
+
+ file.len = name->len + 4;
+ file.data = ngx_pnalloc(ctx->temp_pool, name->len + 5);
+ if (file.data == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ngx_sprintf(file.data, "%V.bin%Z", name);
+
+ if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (ctx->ranges) {
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
+
+ switch (ngx_stream_geo_include_binary_base(cf, ctx, &file)) {
+ case NGX_OK:
+ return NGX_CONF_OK;
+ case NGX_ERROR:
+ return NGX_CONF_ERROR;
+ default:
+ break;
+ }
+ }
+
+ file.len -= 4;
+ file.data[file.len] = '\0';
+
+ ctx->include_name = file;
+
+ if (ctx->outside_entries) {
+ ctx->allow_binary_include = 0;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
+
+ rv = ngx_conf_parse(cf, &file);
+
+ ctx->includes++;
+ ctx->outside_entries = 0;
+
+ return rv;
+}
+
+
+static ngx_int_t
+ngx_stream_geo_include_binary_base(ngx_conf_t *cf,
+ ngx_stream_geo_conf_ctx_t *ctx, ngx_str_t *name)
+{
+ u_char *base, ch;
+ time_t mtime;
+ size_t size, len;
+ ssize_t n;
+ uint32_t crc32;
+ ngx_err_t err;
+ ngx_int_t rc;
+ ngx_uint_t i;
+ ngx_file_t file;
+ ngx_file_info_t fi;
+ ngx_stream_geo_range_t *range, **ranges;
+ ngx_stream_geo_header_t *header;
+ ngx_stream_variable_value_t *vv;
+
+ ngx_memzero(&file, sizeof(ngx_file_t));
+ file.name = *name;
+ file.log = cf->log;
+
+ file.fd = ngx_open_file(name->data, NGX_FILE_RDONLY, 0, 0);
+ if (file.fd == NGX_INVALID_FILE) {
+ err = ngx_errno;
+ if (err != NGX_ENOENT) {
+ ngx_conf_log_error(NGX_LOG_CRIT, cf, err,
+ ngx_open_file_n " \"%s\" failed", name->data);
+ }
+ return NGX_DECLINED;
+ }
+
+ if (ctx->outside_entries) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "binary geo range base \"%s\" cannot be mixed with usual entries",
+ name->data);
+ rc = NGX_ERROR;
+ goto done;
+ }
+
+ if (ctx->binary_include) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "second binary geo range base \"%s\" cannot be mixed with \"%s\"",
+ name->data, ctx->include_name.data);
+ rc = NGX_ERROR;
+ goto done;
+ }
+
+ if (ngx_fd_info(file.fd, &fi) == NGX_FILE_ERROR) {
+ ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
+ ngx_fd_info_n " \"%s\" failed", name->data);
+ goto failed;
+ }
+
+ size = (size_t) ngx_file_size(&fi);
+ mtime = ngx_file_mtime(&fi);
+
+ ch = name->data[name->len - 4];
+ name->data[name->len - 4] = '\0';
+
+ if (ngx_file_info(name->data, &fi) == NGX_FILE_ERROR) {
+ ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
+ ngx_file_info_n " \"%s\" failed", name->data);
+ goto failed;
+ }
+
+ name->data[name->len - 4] = ch;
+
+ if (mtime < ngx_file_mtime(&fi)) {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "stale binary geo range base \"%s\"", name->data);
+ goto failed;
+ }
+
+ base = ngx_palloc(ctx->pool, size);
+ if (base == NULL) {
+ goto failed;
+ }
+
+ n = ngx_read_file(&file, base, size, 0);
+
+ if (n == NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
+ ngx_read_file_n " \"%s\" failed", name->data);
+ goto failed;
+ }
+
+ if ((size_t) n != size) {
+ ngx_conf_log_error(NGX_LOG_CRIT, cf, 0,
+ ngx_read_file_n " \"%s\" returned only %z bytes instead of %z",
+ name->data, n, size);
+ goto failed;
+ }
+
+ header = (ngx_stream_geo_header_t *) base;
+
+ if (size < 16 || ngx_memcmp(&ngx_stream_geo_header, header, 12) != 0) {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "incompatible binary geo range base \"%s\"", name->data);
+ goto failed;
+ }
+
+ ngx_crc32_init(crc32);
+
+ vv = (ngx_stream_variable_value_t *)
+ (base + sizeof(ngx_stream_geo_header_t));
+
+ while (vv->data) {
+ len = ngx_align(sizeof(ngx_stream_variable_value_t) + vv->len,
+ sizeof(void *));
+ ngx_crc32_update(&crc32, (u_char *) vv, len);
+ vv->data += (size_t) base;
+ vv = (ngx_stream_variable_value_t *) ((u_char *) vv + len);
+ }
+ ngx_crc32_update(&crc32, (u_char *) vv,
+ sizeof(ngx_stream_variable_value_t));
+ vv++;
+
+ ranges = (ngx_stream_geo_range_t **) vv;
+
+ for (i = 0; i < 0x10000; i++) {
+ ngx_crc32_update(&crc32, (u_char *) &ranges[i], sizeof(void *));
+ if (ranges[i]) {
+ ranges[i] = (ngx_stream_geo_range_t *)
+ ((u_char *) ranges[i] + (size_t) base);
+ }
+ }
+
+ range = (ngx_stream_geo_range_t *) &ranges[0x10000];
+
+ while ((u_char *) range < base + size) {
+ while (range->value) {
+ ngx_crc32_update(&crc32, (u_char *) range,
+ sizeof(ngx_stream_geo_range_t));
+ range->value = (ngx_stream_variable_value_t *)
+ ((u_char *) range->value + (size_t) base);
+ range++;
+ }
+ ngx_crc32_update(&crc32, (u_char *) range, sizeof(void *));
+ range = (ngx_stream_geo_range_t *) ((u_char *) range + sizeof(void *));
+ }
+
+ ngx_crc32_final(crc32);
+
+ if (crc32 != header->crc32) {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "CRC32 mismatch in binary geo range base \"%s\"", name->data);
+ goto failed;
+ }
+
+ ngx_conf_log_error(NGX_LOG_NOTICE, cf, 0,
+ "using binary geo range base \"%s\"", name->data);
+
+ ctx->include_name = *name;
+ ctx->binary_include = 1;
+ ctx->high.low = ranges;
+ rc = NGX_OK;
+
+ goto done;
+
+failed:
+
+ rc = NGX_DECLINED;
+
+done:
+
+ if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+ ngx_close_file_n " \"%s\" failed", name->data);
+ }
+
+ return rc;
+}
+
+
+static void
+ngx_stream_geo_create_binary_base(ngx_stream_geo_conf_ctx_t *ctx)
+{
+ u_char *p;
+ uint32_t hash;
+ ngx_str_t s;
+ ngx_uint_t i;
+ ngx_file_mapping_t fm;
+ ngx_stream_geo_range_t *r, *range, **ranges;
+ ngx_stream_geo_header_t *header;
+ ngx_stream_geo_variable_value_node_t *gvvn;
+
+ fm.name = ngx_pnalloc(ctx->temp_pool, ctx->include_name.len + 5);
+ if (fm.name == NULL) {
+ return;
+ }
+
+ ngx_sprintf(fm.name, "%V.bin%Z", &ctx->include_name);
+
+ fm.size = ctx->data_size;
+ fm.log = ctx->pool->log;
+
+ ngx_log_error(NGX_LOG_NOTICE, fm.log, 0,
+ "creating binary geo range base \"%s\"", fm.name);
+
+ if (ngx_create_file_mapping(&fm) != NGX_OK) {
+ return;
+ }
+
+ p = ngx_cpymem(fm.addr, &ngx_stream_geo_header,
+ sizeof(ngx_stream_geo_header_t));
+
+ p = ngx_stream_geo_copy_values(fm.addr, p, ctx->rbtree.root,
+ ctx->rbtree.sentinel);
+
+ p += sizeof(ngx_stream_variable_value_t);
+
+ ranges = (ngx_stream_geo_range_t **) p;
+
+ p += 0x10000 * sizeof(ngx_stream_geo_range_t *);
+
+ for (i = 0; i < 0x10000; i++) {
+ r = ctx->high.low[i];
+ if (r == NULL) {
+ continue;
+ }
+
+ range = (ngx_stream_geo_range_t *) p;
+ ranges[i] = (ngx_stream_geo_range_t *) (p - (u_char *) fm.addr);
+
+ do {
+ s.len = r->value->len;
+ s.data = r->value->data;
+ hash = ngx_crc32_long(s.data, s.len);
+ gvvn = (ngx_stream_geo_variable_value_node_t *)
+ ngx_str_rbtree_lookup(&ctx->rbtree, &s, hash);
+
+ range->value = (ngx_stream_variable_value_t *) gvvn->offset;
+ range->start = r->start;
+ range->end = r->end;
+ range++;
+
+ } while ((++r)->value);
+
+ range->value = NULL;
+
+ p = (u_char *) range + sizeof(void *);
+ }
+
+ header = fm.addr;
+ header->crc32 = ngx_crc32_long((u_char *) fm.addr
+ + sizeof(ngx_stream_geo_header_t),
+ fm.size - sizeof(ngx_stream_geo_header_t));
+
+ ngx_close_file_mapping(&fm);
+}
+
+
+static u_char *
+ngx_stream_geo_copy_values(u_char *base, u_char *p, ngx_rbtree_node_t *node,
+ ngx_rbtree_node_t *sentinel)
+{
+ ngx_stream_variable_value_t *vv;
+ ngx_stream_geo_variable_value_node_t *gvvn;
+
+ if (node == sentinel) {
+ return p;
+ }
+
+ gvvn = (ngx_stream_geo_variable_value_node_t *) node;
+ gvvn->offset = p - base;
+
+ vv = (ngx_stream_variable_value_t *) p;
+ *vv = *gvvn->value;
+ p += sizeof(ngx_stream_variable_value_t);
+ vv->data = (u_char *) (p - base);
+
+ p = ngx_cpymem(p, gvvn->sn.str.data, gvvn->sn.str.len);
+
+ p = ngx_align_ptr(p, sizeof(void *));
+
+ p = ngx_stream_geo_copy_values(base, p, node->left, sentinel);
+
+ return ngx_stream_geo_copy_values(base, p, node->right, sentinel);
+}
|
[-]
[+]
|
Added |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_geoip_module.c
^
|
@@ -0,0 +1,814 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_stream.h>
+
+#include <GeoIP.h>
+#include <GeoIPCity.h>
+
+
+#define NGX_GEOIP_COUNTRY_CODE 0
+#define NGX_GEOIP_COUNTRY_CODE3 1
+#define NGX_GEOIP_COUNTRY_NAME 2
+
+
+typedef struct {
+ GeoIP *country;
+ GeoIP *org;
+ GeoIP *city;
+#if (NGX_HAVE_GEOIP_V6)
+ unsigned country_v6:1;
+ unsigned org_v6:1;
+ unsigned city_v6:1;
+#endif
+} ngx_stream_geoip_conf_t;
+
+
+typedef struct {
+ ngx_str_t *name;
+ uintptr_t data;
+} ngx_stream_geoip_var_t;
+
+
+typedef const char *(*ngx_stream_geoip_variable_handler_pt)(GeoIP *,
+ u_long addr);
+
+
+ngx_stream_geoip_variable_handler_pt ngx_stream_geoip_country_functions[] = {
+ GeoIP_country_code_by_ipnum,
+ GeoIP_country_code3_by_ipnum,
+ GeoIP_country_name_by_ipnum,
+};
+
+
+#if (NGX_HAVE_GEOIP_V6)
+
+typedef const char *(*ngx_stream_geoip_variable_handler_v6_pt)(GeoIP *,
+ geoipv6_t addr);
+
+
+ngx_stream_geoip_variable_handler_v6_pt
+ ngx_stream_geoip_country_v6_functions[] =
+{
+ GeoIP_country_code_by_ipnum_v6,
+ GeoIP_country_code3_by_ipnum_v6,
+ GeoIP_country_name_by_ipnum_v6,
+};
+
+#endif
+
+
+static ngx_int_t ngx_stream_geoip_country_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_geoip_org_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_geoip_city_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_geoip_region_name_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_geoip_city_float_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_geoip_city_int_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static GeoIPRecord *ngx_stream_geoip_get_city_record(ngx_stream_session_t *s);
+
+static ngx_int_t ngx_stream_geoip_add_variables(ngx_conf_t *cf);
+static void *ngx_stream_geoip_create_conf(ngx_conf_t *cf);
+static char *ngx_stream_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static char *ngx_stream_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static char *ngx_stream_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static void ngx_stream_geoip_cleanup(void *data);
+
+
+static ngx_command_t ngx_stream_geoip_commands[] = {
+
+ { ngx_string("geoip_country"),
+ NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE12,
+ ngx_stream_geoip_country,
+ NGX_STREAM_MAIN_CONF_OFFSET,
+ 0,
+ NULL },
+
+ { ngx_string("geoip_org"),
+ NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE12,
+ ngx_stream_geoip_org,
+ NGX_STREAM_MAIN_CONF_OFFSET,
+ 0,
+ NULL },
+
+ { ngx_string("geoip_city"),
+ NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE12,
+ ngx_stream_geoip_city,
+ NGX_STREAM_MAIN_CONF_OFFSET,
+ 0,
+ NULL },
+
+ ngx_null_command
+};
+
+
+static ngx_stream_module_t ngx_stream_geoip_module_ctx = {
+ ngx_stream_geoip_add_variables, /* preconfiguration */
+ NULL, /* postconfiguration */
+
+ ngx_stream_geoip_create_conf, /* create main configuration */
+ NULL, /* init main configuration */
+
+ NULL, /* create server configuration */
+ NULL /* merge server configuration */
+};
+
+
+ngx_module_t ngx_stream_geoip_module = {
+ NGX_MODULE_V1,
+ &ngx_stream_geoip_module_ctx, /* module context */
+ ngx_stream_geoip_commands, /* module directives */
+ NGX_STREAM_MODULE, /* module type */
+ NULL, /* init master */
+ NULL, /* init module */
+ NULL, /* init process */
+ NULL, /* init thread */
+ NULL, /* exit thread */
+ NULL, /* exit process */
+ NULL, /* exit master */
+ NGX_MODULE_V1_PADDING
+};
+
+
+static ngx_stream_variable_t ngx_stream_geoip_vars[] = {
+
+ { ngx_string("geoip_country_code"), NULL,
+ ngx_stream_geoip_country_variable,
+ NGX_GEOIP_COUNTRY_CODE, 0, 0 },
+
+ { ngx_string("geoip_country_code3"), NULL,
+ ngx_stream_geoip_country_variable,
+ NGX_GEOIP_COUNTRY_CODE3, 0, 0 },
+
+ { ngx_string("geoip_country_name"), NULL,
+ ngx_stream_geoip_country_variable,
+ NGX_GEOIP_COUNTRY_NAME, 0, 0 },
+
+ { ngx_string("geoip_org"), NULL,
+ ngx_stream_geoip_org_variable,
+ 0, 0, 0 },
+
+ { ngx_string("geoip_city_continent_code"), NULL,
+ ngx_stream_geoip_city_variable,
+ offsetof(GeoIPRecord, continent_code), 0, 0 },
+
+ { ngx_string("geoip_city_country_code"), NULL,
+ ngx_stream_geoip_city_variable,
+ offsetof(GeoIPRecord, country_code), 0, 0 },
+
+ { ngx_string("geoip_city_country_code3"), NULL,
+ ngx_stream_geoip_city_variable,
+ offsetof(GeoIPRecord, country_code3), 0, 0 },
+
+ { ngx_string("geoip_city_country_name"), NULL,
+ ngx_stream_geoip_city_variable,
+ offsetof(GeoIPRecord, country_name), 0, 0 },
+
+ { ngx_string("geoip_region"), NULL,
+ ngx_stream_geoip_city_variable,
+ offsetof(GeoIPRecord, region), 0, 0 },
+
+ { ngx_string("geoip_region_name"), NULL,
+ ngx_stream_geoip_region_name_variable,
+ 0, 0, 0 },
+
+ { ngx_string("geoip_city"), NULL,
+ ngx_stream_geoip_city_variable,
+ offsetof(GeoIPRecord, city), 0, 0 },
+
+ { ngx_string("geoip_postal_code"), NULL,
+ ngx_stream_geoip_city_variable,
+ offsetof(GeoIPRecord, postal_code), 0, 0 },
+
+ { ngx_string("geoip_latitude"), NULL,
+ ngx_stream_geoip_city_float_variable,
+ offsetof(GeoIPRecord, latitude), 0, 0 },
+
+ { ngx_string("geoip_longitude"), NULL,
+ ngx_stream_geoip_city_float_variable,
+ offsetof(GeoIPRecord, longitude), 0, 0 },
+
+ { ngx_string("geoip_dma_code"), NULL,
+ ngx_stream_geoip_city_int_variable,
+ offsetof(GeoIPRecord, dma_code), 0, 0 },
+
+ { ngx_string("geoip_area_code"), NULL,
+ ngx_stream_geoip_city_int_variable,
+ offsetof(GeoIPRecord, area_code), 0, 0 },
+
+ { ngx_null_string, NULL, NULL, 0, 0, 0 }
+};
+
+
+static u_long
+ngx_stream_geoip_addr(ngx_stream_session_t *s, ngx_stream_geoip_conf_t *gcf)
+{
+ ngx_addr_t addr;
+ struct sockaddr_in *sin;
+
+ addr.sockaddr = s->connection->sockaddr;
+ addr.socklen = s->connection->socklen;
+ /* addr.name = s->connection->addr_text; */
+
+#if (NGX_HAVE_INET6)
+
+ if (addr.sockaddr->sa_family == AF_INET6) {
+ u_char *p;
+ in_addr_t inaddr;
+ struct in6_addr *inaddr6;
+
+ inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
+
+ if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
+ p = inaddr6->s6_addr;
+
+ inaddr = p[12] << 24;
+ inaddr += p[13] << 16;
+ inaddr += p[14] << 8;
+ inaddr += p[15];
+
+ return inaddr;
+ }
+ }
+
+#endif
+
+ if (addr.sockaddr->sa_family != AF_INET) {
+ return INADDR_NONE;
+ }
+
+ sin = (struct sockaddr_in *) addr.sockaddr;
+ return ntohl(sin->sin_addr.s_addr);
+}
+
+
+#if (NGX_HAVE_GEOIP_V6)
+
+static geoipv6_t
+ngx_stream_geoip_addr_v6(ngx_stream_session_t *s, ngx_stream_geoip_conf_t *gcf)
+{
+ ngx_addr_t addr;
+ in_addr_t addr4;
+ struct in6_addr addr6;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+
+ addr.sockaddr = s->connection->sockaddr;
+ addr.socklen = s->connection->socklen;
+ /* addr.name = s->connection->addr_text; */
+
+ switch (addr.sockaddr->sa_family) {
+
+ case AF_INET:
+ /* Produce IPv4-mapped IPv6 address. */
+ sin = (struct sockaddr_in *) addr.sockaddr;
+ addr4 = ntohl(sin->sin_addr.s_addr);
+
+ ngx_memzero(&addr6, sizeof(struct in6_addr));
+ addr6.s6_addr[10] = 0xff;
+ addr6.s6_addr[11] = 0xff;
+ addr6.s6_addr[12] = addr4 >> 24;
+ addr6.s6_addr[13] = addr4 >> 16;
+ addr6.s6_addr[14] = addr4 >> 8;
+ addr6.s6_addr[15] = addr4;
+ return addr6;
+
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *) addr.sockaddr;
+ return sin6->sin6_addr;
+
+ default:
+ return in6addr_any;
+ }
+}
+
+#endif
+
+
+static ngx_int_t
+ngx_stream_geoip_country_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ ngx_stream_geoip_variable_handler_pt handler =
+ ngx_stream_geoip_country_functions[data];
+#if (NGX_HAVE_GEOIP_V6)
+ ngx_stream_geoip_variable_handler_v6_pt handler_v6 =
+ ngx_stream_geoip_country_v6_functions[data];
+#endif
+
+ const char *val;
+ ngx_stream_geoip_conf_t *gcf;
+
+ gcf = ngx_stream_get_module_main_conf(s, ngx_stream_geoip_module);
+
+ if (gcf->country == NULL) {
+ goto not_found;
+ }
+
+#if (NGX_HAVE_GEOIP_V6)
+ val = gcf->country_v6
+ ? handler_v6(gcf->country, ngx_stream_geoip_addr_v6(s, gcf))
+ : handler(gcf->country, ngx_stream_geoip_addr(s, gcf));
+#else
+ val = handler(gcf->country, ngx_stream_geoip_addr(s, gcf));
+#endif
+
+ if (val == NULL) {
+ goto not_found;
+ }
+
+ v->len = ngx_strlen(val);
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = (u_char *) val;
+
+ return NGX_OK;
+
+not_found:
+
+ v->not_found = 1;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_geoip_org_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ size_t len;
+ char *val;
+ ngx_stream_geoip_conf_t *gcf;
+
+ gcf = ngx_stream_get_module_main_conf(s, ngx_stream_geoip_module);
+
+ if (gcf->org == NULL) {
+ goto not_found;
+ }
+
+#if (NGX_HAVE_GEOIP_V6)
+ val = gcf->org_v6
+ ? GeoIP_name_by_ipnum_v6(gcf->org,
+ ngx_stream_geoip_addr_v6(s, gcf))
+ : GeoIP_name_by_ipnum(gcf->org,
+ ngx_stream_geoip_addr(s, gcf));
+#else
+ val = GeoIP_name_by_ipnum(gcf->org, ngx_stream_geoip_addr(s, gcf));
+#endif
+
+ if (val == NULL) {
+ goto not_found;
+ }
+
+ len = ngx_strlen(val);
+ v->data = ngx_pnalloc(s->connection->pool, len);
+ if (v->data == NULL) {
+ ngx_free(val);
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(v->data, val, len);
+
+ v->len = len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ ngx_free(val);
+
+ return NGX_OK;
+
+not_found:
+
+ v->not_found = 1;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_geoip_city_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ char *val;
+ size_t len;
+ GeoIPRecord *gr;
+
+ gr = ngx_stream_geoip_get_city_record(s);
+ if (gr == NULL) {
+ goto not_found;
+ }
+
+ val = *(char **) ((char *) gr + data);
+ if (val == NULL) {
+ goto no_value;
+ }
+
+ len = ngx_strlen(val);
+ v->data = ngx_pnalloc(s->connection->pool, len);
+ if (v->data == NULL) {
+ GeoIPRecord_delete(gr);
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(v->data, val, len);
+
+ v->len = len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ GeoIPRecord_delete(gr);
+
+ return NGX_OK;
+
+no_value:
+
+ GeoIPRecord_delete(gr);
+
+not_found:
+
+ v->not_found = 1;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_geoip_region_name_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ size_t len;
+ const char *val;
+ GeoIPRecord *gr;
+
+ gr = ngx_stream_geoip_get_city_record(s);
+ if (gr == NULL) {
+ goto not_found;
+ }
+
+ val = GeoIP_region_name_by_code(gr->country_code, gr->region);
+
+ GeoIPRecord_delete(gr);
+
+ if (val == NULL) {
+ goto not_found;
+ }
+
+ len = ngx_strlen(val);
+ v->data = ngx_pnalloc(s->connection->pool, len);
+ if (v->data == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(v->data, val, len);
+
+ v->len = len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ return NGX_OK;
+
+not_found:
+
+ v->not_found = 1;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_geoip_city_float_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ float val;
+ GeoIPRecord *gr;
+
+ gr = ngx_stream_geoip_get_city_record(s);
+ if (gr == NULL) {
+ v->not_found = 1;
+ return NGX_OK;
+ }
+
+ v->data = ngx_pnalloc(s->connection->pool, NGX_INT64_LEN + 5);
+ if (v->data == NULL) {
+ GeoIPRecord_delete(gr);
+ return NGX_ERROR;
+ }
+
+ val = *(float *) ((char *) gr + data);
+
+ v->len = ngx_sprintf(v->data, "%.4f", val) - v->data;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ GeoIPRecord_delete(gr);
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_geoip_city_int_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ int val;
+ GeoIPRecord *gr;
+
+ gr = ngx_stream_geoip_get_city_record(s);
+ if (gr == NULL) {
+ v->not_found = 1;
+ return NGX_OK;
+ }
+
+ v->data = ngx_pnalloc(s->connection->pool, NGX_INT64_LEN);
+ if (v->data == NULL) {
+ GeoIPRecord_delete(gr);
+ return NGX_ERROR;
+ }
+
+ val = *(int *) ((char *) gr + data);
+
+ v->len = ngx_sprintf(v->data, "%d", val) - v->data;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ GeoIPRecord_delete(gr);
+
+ return NGX_OK;
+}
+
+
+static GeoIPRecord *
+ngx_stream_geoip_get_city_record(ngx_stream_session_t *s)
+{
+ ngx_stream_geoip_conf_t *gcf;
+
+ gcf = ngx_stream_get_module_main_conf(s, ngx_stream_geoip_module);
+
+ if (gcf->city) {
+#if (NGX_HAVE_GEOIP_V6)
+ return gcf->city_v6
+ ? GeoIP_record_by_ipnum_v6(gcf->city,
+ ngx_stream_geoip_addr_v6(s, gcf))
+ : GeoIP_record_by_ipnum(gcf->city,
+ ngx_stream_geoip_addr(s, gcf));
+#else
+ return GeoIP_record_by_ipnum(gcf->city, ngx_stream_geoip_addr(s, gcf));
+#endif
+ }
+
+ return NULL;
+}
+
+
+static ngx_int_t
+ngx_stream_geoip_add_variables(ngx_conf_t *cf)
+{
+ ngx_stream_variable_t *var, *v;
+
+ for (v = ngx_stream_geoip_vars; v->name.len; v++) {
+ var = ngx_stream_add_variable(cf, &v->name, v->flags);
+ if (var == NULL) {
+ return NGX_ERROR;
+ }
+
+ var->get_handler = v->get_handler;
+ var->data = v->data;
+ }
+
+ return NGX_OK;
+}
+
+
+static void *
+ngx_stream_geoip_create_conf(ngx_conf_t *cf)
+{
+ ngx_pool_cleanup_t *cln;
+ ngx_stream_geoip_conf_t *conf;
+
+ conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_geoip_conf_t));
+ if (conf == NULL) {
+ return NULL;
+ }
+
+ cln = ngx_pool_cleanup_add(cf->pool, 0);
+ if (cln == NULL) {
+ return NULL;
+ }
+
+ cln->handler = ngx_stream_geoip_cleanup;
+ cln->data = conf;
+
+ return conf;
+}
+
+
+static char *
+ngx_stream_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_stream_geoip_conf_t *gcf = conf;
+
+ ngx_str_t *value;
+
+ if (gcf->country) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ gcf->country = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);
+
+ if (gcf->country == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "GeoIP_open(\"%V\") failed", &value[1]);
+
+ return NGX_CONF_ERROR;
+ }
+
+ if (cf->args->nelts == 3) {
+ if (ngx_strcmp(value[2].data, "utf8") == 0) {
+ GeoIP_set_charset(gcf->country, GEOIP_CHARSET_UTF8);
+
+ } else {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter \"%V\"", &value[2]);
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ switch (gcf->country->databaseType) {
+
+ case GEOIP_COUNTRY_EDITION:
+
+ return NGX_CONF_OK;
+
+#if (NGX_HAVE_GEOIP_V6)
+ case GEOIP_COUNTRY_EDITION_V6:
+
+ gcf->country_v6 = 1;
+ return NGX_CONF_OK;
+#endif
+
+ default:
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid GeoIP database \"%V\" type:%d",
+ &value[1], gcf->country->databaseType);
+ return NGX_CONF_ERROR;
+ }
+}
+
+
+static char *
+ngx_stream_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_stream_geoip_conf_t *gcf = conf;
+
+ ngx_str_t *value;
+
+ if (gcf->org) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ gcf->org = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);
+
+ if (gcf->org == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "GeoIP_open(\"%V\") failed", &value[1]);
+
+ return NGX_CONF_ERROR;
+ }
+
+ if (cf->args->nelts == 3) {
+ if (ngx_strcmp(value[2].data, "utf8") == 0) {
+ GeoIP_set_charset(gcf->org, GEOIP_CHARSET_UTF8);
+
+ } else {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter \"%V\"", &value[2]);
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ switch (gcf->org->databaseType) {
+
+ case GEOIP_ISP_EDITION:
+ case GEOIP_ORG_EDITION:
+ case GEOIP_DOMAIN_EDITION:
+ case GEOIP_ASNUM_EDITION:
+
+ return NGX_CONF_OK;
+
+#if (NGX_HAVE_GEOIP_V6)
+ case GEOIP_ISP_EDITION_V6:
+ case GEOIP_ORG_EDITION_V6:
+ case GEOIP_DOMAIN_EDITION_V6:
+ case GEOIP_ASNUM_EDITION_V6:
+
+ gcf->org_v6 = 1;
+ return NGX_CONF_OK;
+#endif
+
+ default:
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid GeoIP database \"%V\" type:%d",
+ &value[1], gcf->org->databaseType);
+ return NGX_CONF_ERROR;
+ }
+}
+
+
+static char *
+ngx_stream_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_stream_geoip_conf_t *gcf = conf;
+
+ ngx_str_t *value;
+
+ if (gcf->city) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ gcf->city = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);
+
+ if (gcf->city == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "GeoIP_open(\"%V\") failed", &value[1]);
+
+ return NGX_CONF_ERROR;
+ }
+
+ if (cf->args->nelts == 3) {
+ if (ngx_strcmp(value[2].data, "utf8") == 0) {
+ GeoIP_set_charset(gcf->city, GEOIP_CHARSET_UTF8);
+
+ } else {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter \"%V\"", &value[2]);
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ switch (gcf->city->databaseType) {
+
+ case GEOIP_CITY_EDITION_REV0:
+ case GEOIP_CITY_EDITION_REV1:
+
+ return NGX_CONF_OK;
+
+#if (NGX_HAVE_GEOIP_V6)
+ case GEOIP_CITY_EDITION_REV0_V6:
+ case GEOIP_CITY_EDITION_REV1_V6:
+
+ gcf->city_v6 = 1;
+ return NGX_CONF_OK;
+#endif
+
+ default:
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid GeoIP City database \"%V\" type:%d",
+ &value[1], gcf->city->databaseType);
+ return NGX_CONF_ERROR;
+ }
+}
+
+
+static void
+ngx_stream_geoip_cleanup(void *data)
+{
+ ngx_stream_geoip_conf_t *gcf = data;
+
+ if (gcf->country) {
+ GeoIP_delete(gcf->country);
+ }
+
+ if (gcf->org) {
+ GeoIP_delete(gcf->org);
+ }
+
+ if (gcf->city) {
+ GeoIP_delete(gcf->city);
+ }
+}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_handler.c
^
|
@@ -11,8 +11,10 @@
#include <ngx_stream.h>
+static void ngx_stream_close_connection(ngx_connection_t *c);
static u_char *ngx_stream_log_error(ngx_log_t *log, u_char *buf, size_t len);
-static void ngx_stream_init_session(ngx_connection_t *c);
+static void ngx_stream_proxy_protocol_handler(ngx_event_t *rev);
+static void ngx_stream_init_session_handler(ngx_event_t *rev);
#if (NGX_STREAM_SSL)
static void ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c);
@@ -23,11 +25,11 @@
void
ngx_stream_init_connection(ngx_connection_t *c)
{
- int tcp_nodelay;
u_char text[NGX_SOCKADDR_STRLEN];
size_t len;
- ngx_int_t rc;
ngx_uint_t i;
+ ngx_time_t *tp;
+ ngx_event_t *rev;
struct sockaddr *sa;
ngx_stream_port_t *port;
struct sockaddr_in *sin;
@@ -128,6 +130,10 @@
s->main_conf = addr_conf->ctx->main_conf;
s->srv_conf = addr_conf->ctx->srv_conf;
+#if (NGX_STREAM_SSL)
+ s->ssl = addr_conf->ssl;
+#endif
+
s->connection = c;
c->data = s;
@@ -147,13 +153,168 @@
c->log->action = "initializing connection";
c->log_error = NGX_ERROR_INFO;
+ s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_stream_max_module);
+ if (s->ctx == NULL) {
+ ngx_stream_close_connection(c);
+ return;
+ }
+
cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module);
+ s->variables = ngx_pcalloc(s->connection->pool,
+ cmcf->variables.nelts
+ * sizeof(ngx_stream_variable_value_t));
+
+ if (s->variables == NULL) {
+ ngx_stream_close_connection(c);
+ return;
+ }
+
+ tp = ngx_timeofday();
+ s->start_sec = tp->sec;
+ s->start_msec = tp->msec;
+
+ rev = c->read;
+ rev->handler = ngx_stream_init_session_handler;
+
+ if (addr_conf->proxy_protocol) {
+ c->log->action = "reading PROXY protocol";
+
+ rev->handler = ngx_stream_proxy_protocol_handler;
+
+ if (!rev->ready) {
+ ngx_add_timer(rev, cscf->proxy_protocol_timeout);
+
+ if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+ ngx_stream_finalize_session(s,
+ NGX_STREAM_INTERNAL_SERVER_ERROR);
+ }
+
+ return;
+ }
+ }
+
+ if (ngx_use_accept_mutex) {
+ ngx_post_event(rev, &ngx_posted_events);
+ return;
+ }
+
+ rev->handler(rev);
+}
+
+
+static void
+ngx_stream_proxy_protocol_handler(ngx_event_t *rev)
+{
+ u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER];
+ size_t size;
+ ssize_t n;
+ ngx_err_t err;
+ ngx_connection_t *c;
+ ngx_stream_session_t *s;
+ ngx_stream_core_srv_conf_t *cscf;
+
+ c = rev->data;
+ s = c->data;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
+ "stream PROXY protocol handler");
+
+ if (rev->timedout) {
+ ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
+ ngx_stream_finalize_session(s, NGX_STREAM_OK);
+ return;
+ }
+
+ n = recv(c->fd, (char *) buf, sizeof(buf), MSG_PEEK);
+
+ err = ngx_socket_errno;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "recv(): %z", n);
+
+ if (n == -1) {
+ if (err == NGX_EAGAIN) {
+ rev->ready = 0;
+
+ if (!rev->timer_set) {
+ cscf = ngx_stream_get_module_srv_conf(s,
+ ngx_stream_core_module);
+
+ ngx_add_timer(rev, cscf->proxy_protocol_timeout);
+ }
+
+ if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+ ngx_stream_finalize_session(s,
+ NGX_STREAM_INTERNAL_SERVER_ERROR);
+ }
+
+ return;
+ }
+
+ ngx_connection_error(c, err, "recv() failed");
+
+ ngx_stream_finalize_session(s, NGX_STREAM_OK);
+ return;
+ }
+
+ if (rev->timer_set) {
+ ngx_del_timer(rev);
+ }
+
+ p = ngx_proxy_protocol_read(c, buf, buf + n);
+
+ if (p == NULL) {
+ ngx_stream_finalize_session(s, NGX_STREAM_BAD_REQUEST);
+ return;
+ }
+
+ size = p - buf;
+
+ if (c->recv(c, buf, size) != (ssize_t) size) {
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ ngx_stream_init_session_handler(rev);
+}
+
+
+static void
+ngx_stream_init_session_handler(ngx_event_t *rev)
+{
+ int tcp_nodelay;
+ ngx_int_t rc;
+ ngx_connection_t *c;
+ ngx_stream_session_t *s;
+ ngx_stream_core_srv_conf_t *cscf;
+ ngx_stream_core_main_conf_t *cmcf;
+
+ c = rev->data;
+ s = c->data;
+
+ c->log->action = "initializing session";
+
+ cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module);
+
+ if (cmcf->realip_handler) {
+ rc = cmcf->realip_handler(s);
+
+ if (rc == NGX_ERROR) {
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+ }
+
if (cmcf->limit_conn_handler) {
rc = cmcf->limit_conn_handler(s);
- if (rc != NGX_DECLINED) {
- ngx_stream_close_connection(c);
+ if (rc == NGX_ERROR) {
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ if (rc == NGX_ABORT) {
+ ngx_stream_finalize_session(s, NGX_STREAM_SERVICE_UNAVAILABLE);
return;
}
}
@@ -161,12 +322,19 @@
if (cmcf->access_handler) {
rc = cmcf->access_handler(s);
- if (rc != NGX_OK && rc != NGX_DECLINED) {
- ngx_stream_close_connection(c);
+ if (rc == NGX_ERROR) {
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ if (rc == NGX_ABORT) {
+ ngx_stream_finalize_session(s, NGX_STREAM_FORBIDDEN);
return;
}
}
+ cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
+
if (c->type == SOCK_STREAM
&& cscf->tcp_nodelay
&& c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
@@ -180,7 +348,7 @@
{
ngx_connection_error(c, ngx_socket_errno,
"setsockopt(TCP_NODELAY) failed");
- ngx_stream_close_connection(c);
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
@@ -194,14 +362,14 @@
sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module);
- if (addr_conf->ssl) {
+ if (s->ssl) {
c->log->action = "SSL handshaking";
if (sslcf->ssl.ctx == NULL) {
ngx_log_error(NGX_LOG_ERR, c->log, 0,
"no \"ssl_certificate\" is defined "
"in server listening on SSL port");
- ngx_stream_close_connection(c);
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
@@ -211,27 +379,8 @@
}
#endif
- ngx_stream_init_session(c);
-}
-
-
-static void
-ngx_stream_init_session(ngx_connection_t *c)
-{
- ngx_stream_session_t *s;
- ngx_stream_core_srv_conf_t *cscf;
-
- s = c->data;
c->log->action = "handling client connection";
- cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
-
- s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_stream_max_module);
- if (s->ctx == NULL) {
- ngx_stream_close_connection(c);
- return;
- }
-
cscf->handler(s);
}
@@ -244,15 +393,14 @@
ngx_stream_session_t *s;
ngx_stream_ssl_conf_t *sslcf;
+ s = c->data;
+
if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) {
- ngx_stream_close_connection(c);
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
if (ngx_ssl_handshake(c) == NGX_AGAIN) {
-
- s = c->data;
-
sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module);
ngx_add_timer(c->read, sslcf->handshake_timeout);
@@ -269,8 +417,11 @@
static void
ngx_stream_ssl_handshake_handler(ngx_connection_t *c)
{
+ ngx_stream_session_t *s;
+ ngx_stream_core_srv_conf_t *cscf;
+
if (!c->ssl->handshaked) {
- ngx_stream_close_connection(c);
+ ngx_stream_finalize_session(c->data, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
@@ -278,13 +429,39 @@
ngx_del_timer(c->read);
}
- ngx_stream_init_session(c);
+ c->log->action = "handling client connection";
+
+ s = c->data;
+
+ cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
+
+ cscf->handler(s);
}
#endif
void
+ngx_stream_finalize_session(ngx_stream_session_t *s, ngx_uint_t rc)
+{
+ ngx_stream_core_main_conf_t *cmcf;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "finalize stream session: %i", rc);
+
+ s->status = rc;
+
+ cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module);
+
+ if (cmcf->access_log_handler) {
+ (void) cmcf->access_log_handler(s);
+ }
+
+ ngx_stream_close_connection(s->connection);
+}
+
+
+static void
ngx_stream_close_connection(ngx_connection_t *c)
{
ngx_pool_t *pool;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_limit_conn_module.c
^
|
@@ -11,33 +11,34 @@
typedef struct {
- u_char color;
- u_char len;
- u_short conn;
- u_char data[1];
+ u_char color;
+ u_char len;
+ u_short conn;
+ u_char data[1];
} ngx_stream_limit_conn_node_t;
typedef struct {
- ngx_shm_zone_t *shm_zone;
- ngx_rbtree_node_t *node;
+ ngx_shm_zone_t *shm_zone;
+ ngx_rbtree_node_t *node;
} ngx_stream_limit_conn_cleanup_t;
typedef struct {
- ngx_rbtree_t *rbtree;
+ ngx_rbtree_t *rbtree;
+ ngx_stream_complex_value_t key;
} ngx_stream_limit_conn_ctx_t;
typedef struct {
- ngx_shm_zone_t *shm_zone;
- ngx_uint_t conn;
+ ngx_shm_zone_t *shm_zone;
+ ngx_uint_t conn;
} ngx_stream_limit_conn_limit_t;
typedef struct {
- ngx_array_t limits;
- ngx_uint_t log_level;
+ ngx_array_t limits;
+ ngx_uint_t log_level;
} ngx_stream_limit_conn_conf_t;
@@ -93,28 +94,29 @@
static ngx_stream_module_t ngx_stream_limit_conn_module_ctx = {
+ NULL, /* preconfiguration */
ngx_stream_limit_conn_init, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
ngx_stream_limit_conn_create_conf, /* create server configuration */
- ngx_stream_limit_conn_merge_conf, /* merge server configuration */
+ ngx_stream_limit_conn_merge_conf /* merge server configuration */
};
ngx_module_t ngx_stream_limit_conn_module = {
NGX_MODULE_V1,
- &ngx_stream_limit_conn_module_ctx, /* module context */
- ngx_stream_limit_conn_commands, /* module directives */
- NGX_STREAM_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
+ &ngx_stream_limit_conn_module_ctx, /* module context */
+ ngx_stream_limit_conn_commands, /* module directives */
+ NGX_STREAM_MODULE, /* module type */
+ NULL, /* init master */
+ NULL, /* init module */
+ NULL, /* init process */
+ NULL, /* init thread */
+ NULL, /* exit thread */
+ NULL, /* exit process */
+ NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
@@ -129,48 +131,36 @@
ngx_slab_pool_t *shpool;
ngx_rbtree_node_t *node;
ngx_pool_cleanup_t *cln;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
ngx_stream_limit_conn_ctx_t *ctx;
ngx_stream_limit_conn_node_t *lc;
ngx_stream_limit_conn_conf_t *lccf;
ngx_stream_limit_conn_limit_t *limits;
ngx_stream_limit_conn_cleanup_t *lccln;
- switch (s->connection->sockaddr->sa_family) {
-
- case AF_INET:
- sin = (struct sockaddr_in *) s->connection->sockaddr;
-
- key.len = sizeof(in_addr_t);
- key.data = (u_char *) &sin->sin_addr;
-
- break;
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) s->connection->sockaddr;
-
- key.len = sizeof(struct in6_addr);
- key.data = sin6->sin6_addr.s6_addr;
-
- break;
-#endif
-
- default:
- return NGX_DECLINED;
- }
-
- hash = ngx_crc32_short(key.data, key.len);
-
lccf = ngx_stream_get_module_srv_conf(s, ngx_stream_limit_conn_module);
limits = lccf->limits.elts;
for (i = 0; i < lccf->limits.nelts; i++) {
ctx = limits[i].shm_zone->data;
+ if (ngx_stream_complex_value(s, &ctx->key, &key) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ if (key.len == 0) {
+ continue;
+ }
+
+ if (key.len > 255) {
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+ "the value of the \"%V\" key "
+ "is more than 255 bytes: \"%V\"",
+ &ctx->key.value, &key);
+ continue;
+ }
+
+ hash = ngx_crc32_short(key.data, key.len);
+
shpool = (ngx_slab_pool_t *) limits[i].shm_zone->shm.addr;
ngx_shmtx_lock(&shpool->mutex);
@@ -382,6 +372,19 @@
ctx = shm_zone->data;
if (octx) {
+ if (ctx->key.value.len != octx->key.value.len
+ || ngx_strncmp(ctx->key.value.data, octx->key.value.data,
+ ctx->key.value.len)
+ != 0)
+ {
+ ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
+ "limit_conn_zone \"%V\" uses the \"%V\" key "
+ "while previously it used the \"%V\" key",
+ &shm_zone->shm.name, &ctx->key.value,
+ &octx->key.value);
+ return NGX_ERROR;
+ }
+
ctx->rbtree = octx->rbtree;
return NGX_OK;
@@ -465,12 +468,13 @@
static char *
ngx_stream_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- u_char *p;
- ssize_t size;
- ngx_str_t *value, name, s;
- ngx_uint_t i;
- ngx_shm_zone_t *shm_zone;
- ngx_stream_limit_conn_ctx_t *ctx;
+ u_char *p;
+ ssize_t size;
+ ngx_str_t *value, name, s;
+ ngx_uint_t i;
+ ngx_shm_zone_t *shm_zone;
+ ngx_stream_limit_conn_ctx_t *ctx;
+ ngx_stream_compile_complex_value_t ccv;
value = cf->args->elts;
@@ -479,6 +483,16 @@
return NGX_CONF_ERROR;
}
+ ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &value[1];
+ ccv.complex_value = &ctx->key;
+
+ if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
size = 0;
name.len = 0;
@@ -537,17 +551,11 @@
}
if (shm_zone->data) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "%V \"%V\" is already bound to key "
- "\"$binary_remote_addr\"",
- &cmd->name, &name);
- return NGX_CONF_ERROR;
- }
+ ctx = shm_zone->data;
- if (ngx_strcmp(value[1].data, "$binary_remote_addr") != 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unsupported key \"%V\", use "
- "$binary_remote_addr", &value[1]);
+ "%V \"%V\" is already bound to key \"%V\"",
+ &cmd->name, &name, &ctx->key.value);
return NGX_CONF_ERROR;
}
|
[-]
[+]
|
Added |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_log_module.c
^
|
@@ -0,0 +1,1474 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_stream.h>
+
+#if (NGX_ZLIB)
+#include <zlib.h>
+#endif
+
+
+typedef struct ngx_stream_log_op_s ngx_stream_log_op_t;
+
+typedef u_char *(*ngx_stream_log_op_run_pt) (ngx_stream_session_t *s,
+ u_char *buf, ngx_stream_log_op_t *op);
+
+typedef size_t (*ngx_stream_log_op_getlen_pt) (ngx_stream_session_t *s,
+ uintptr_t data);
+
+
+struct ngx_stream_log_op_s {
+ size_t len;
+ ngx_stream_log_op_getlen_pt getlen;
+ ngx_stream_log_op_run_pt run;
+ uintptr_t data;
+};
+
+
+typedef struct {
+ ngx_str_t name;
+ ngx_array_t *flushes;
+ ngx_array_t *ops; /* array of ngx_stream_log_op_t */
+} ngx_stream_log_fmt_t;
+
+
+typedef struct {
+ ngx_array_t formats; /* array of ngx_stream_log_fmt_t */
+} ngx_stream_log_main_conf_t;
+
+
+typedef struct {
+ u_char *start;
+ u_char *pos;
+ u_char *last;
+
+ ngx_event_t *event;
+ ngx_msec_t flush;
+ ngx_int_t gzip;
+} ngx_stream_log_buf_t;
+
+
+typedef struct {
+ ngx_array_t *lengths;
+ ngx_array_t *values;
+} ngx_stream_log_script_t;
+
+
+typedef struct {
+ ngx_open_file_t *file;
+ ngx_stream_log_script_t *script;
+ time_t disk_full_time;
+ time_t error_log_time;
+ ngx_syslog_peer_t *syslog_peer;
+ ngx_stream_log_fmt_t *format;
+ ngx_stream_complex_value_t *filter;
+} ngx_stream_log_t;
+
+
+typedef struct {
+ ngx_array_t *logs; /* array of ngx_stream_log_t */
+
+ ngx_open_file_cache_t *open_file_cache;
+ time_t open_file_cache_valid;
+ ngx_uint_t open_file_cache_min_uses;
+
+ ngx_uint_t off; /* unsigned off:1 */
+} ngx_stream_log_srv_conf_t;
+
+
+typedef struct {
+ ngx_str_t name;
+ size_t len;
+ ngx_stream_log_op_run_pt run;
+} ngx_stream_log_var_t;
+
+
+static void ngx_stream_log_write(ngx_stream_session_t *s, ngx_stream_log_t *log,
+ u_char *buf, size_t len);
+static ssize_t ngx_stream_log_script_write(ngx_stream_session_t *s,
+ ngx_stream_log_script_t *script, u_char **name, u_char *buf, size_t len);
+
+#if (NGX_ZLIB)
+static ssize_t ngx_stream_log_gzip(ngx_fd_t fd, u_char *buf, size_t len,
+ ngx_int_t level, ngx_log_t *log);
+
+static void *ngx_stream_log_gzip_alloc(void *opaque, u_int items, u_int size);
+static void ngx_stream_log_gzip_free(void *opaque, void *address);
+#endif
+
+static void ngx_stream_log_flush(ngx_open_file_t *file, ngx_log_t *log);
+static void ngx_stream_log_flush_handler(ngx_event_t *ev);
+
+static ngx_int_t ngx_stream_log_variable_compile(ngx_conf_t *cf,
+ ngx_stream_log_op_t *op, ngx_str_t *value);
+static size_t ngx_stream_log_variable_getlen(ngx_stream_session_t *s,
+ uintptr_t data);
+static u_char *ngx_stream_log_variable(ngx_stream_session_t *s, u_char *buf,
+ ngx_stream_log_op_t *op);
+static uintptr_t ngx_stream_log_escape(u_char *dst, u_char *src, size_t size);
+
+
+static void *ngx_stream_log_create_main_conf(ngx_conf_t *cf);
+static void *ngx_stream_log_create_srv_conf(ngx_conf_t *cf);
+static char *ngx_stream_log_merge_srv_conf(ngx_conf_t *cf, void *parent,
+ void *child);
+static char *ngx_stream_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static char *ngx_stream_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static char *ngx_stream_log_compile_format(ngx_conf_t *cf,
+ ngx_array_t *flushes, ngx_array_t *ops, ngx_array_t *args, ngx_uint_t s);
+static char *ngx_stream_log_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static ngx_int_t ngx_stream_log_init(ngx_conf_t *cf);
+
+
+static ngx_command_t ngx_stream_log_commands[] = {
+
+ { ngx_string("log_format"),
+ NGX_STREAM_MAIN_CONF|NGX_CONF_2MORE,
+ ngx_stream_log_set_format,
+ NGX_STREAM_MAIN_CONF_OFFSET,
+ 0,
+ NULL },
+
+ { ngx_string("access_log"),
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
+ ngx_stream_log_set_log,
+ NGX_STREAM_SRV_CONF_OFFSET,
+ 0,
+ NULL },
+
+ { ngx_string("open_log_file_cache"),
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1234,
+ ngx_stream_log_open_file_cache,
+ NGX_STREAM_SRV_CONF_OFFSET,
+ 0,
+ NULL },
+
+ ngx_null_command
+};
+
+
+static ngx_stream_module_t ngx_stream_log_module_ctx = {
+ NULL, /* preconfiguration */
+ ngx_stream_log_init, /* postconfiguration */
+
+ ngx_stream_log_create_main_conf, /* create main configuration */
+ NULL, /* init main configuration */
+
+ ngx_stream_log_create_srv_conf, /* create server configuration */
+ ngx_stream_log_merge_srv_conf /* merge server configuration */
+};
+
+
+ngx_module_t ngx_stream_log_module = {
+ NGX_MODULE_V1,
+ &ngx_stream_log_module_ctx, /* module context */
+ ngx_stream_log_commands, /* module directives */
+ NGX_STREAM_MODULE, /* module type */
+ NULL, /* init master */
+ NULL, /* init module */
+ NULL, /* init process */
+ NULL, /* init thread */
+ NULL, /* exit thread */
+ NULL, /* exit process */
+ NULL, /* exit master */
+ NGX_MODULE_V1_PADDING
+};
+
+
+static ngx_int_t
+ngx_stream_log_handler(ngx_stream_session_t *s)
+{
+ u_char *line, *p;
+ size_t len, size;
+ ssize_t n;
+ ngx_str_t val;
+ ngx_uint_t i, l;
+ ngx_stream_log_t *log;
+ ngx_stream_log_op_t *op;
+ ngx_stream_log_buf_t *buffer;
+ ngx_stream_log_srv_conf_t *lscf;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "stream log handler");
+
+ lscf = ngx_stream_get_module_srv_conf(s, ngx_stream_log_module);
+
+ if (lscf->off || lscf->logs == NULL) {
+ return NGX_OK;
+ }
+
+ log = lscf->logs->elts;
+ for (l = 0; l < lscf->logs->nelts; l++) {
+
+ if (log[l].filter) {
+ if (ngx_stream_complex_value(s, log[l].filter, &val) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ if (val.len == 0 || (val.len == 1 && val.data[0] == '0')) {
+ continue;
+ }
+ }
+
+ if (ngx_time() == log[l].disk_full_time) {
+
+ /*
+ * on FreeBSD writing to a full filesystem with enabled softupdates
+ * may block process for much longer time than writing to non-full
+ * filesystem, so we skip writing to a log for one second
+ */
+
+ continue;
+ }
+
+ ngx_stream_script_flush_no_cacheable_variables(s,
+ log[l].format->flushes);
+
+ len = 0;
+ op = log[l].format->ops->elts;
+ for (i = 0; i < log[l].format->ops->nelts; i++) {
+ if (op[i].len == 0) {
+ len += op[i].getlen(s, op[i].data);
+
+ } else {
+ len += op[i].len;
+ }
+ }
+
+ if (log[l].syslog_peer) {
+
+ /* length of syslog's PRI and HEADER message parts */
+ len += sizeof("<255>Jan 01 00:00:00 ") - 1
+ + ngx_cycle->hostname.len + 1
+ + log[l].syslog_peer->tag.len + 2;
+
+ goto alloc_line;
+ }
+
+ len += NGX_LINEFEED_SIZE;
+
+ buffer = log[l].file ? log[l].file->data : NULL;
+
+ if (buffer) {
+
+ if (len > (size_t) (buffer->last - buffer->pos)) {
+
+ ngx_stream_log_write(s, &log[l], buffer->start,
+ buffer->pos - buffer->start);
+
+ buffer->pos = buffer->start;
+ }
+
+ if (len <= (size_t) (buffer->last - buffer->pos)) {
+
+ p = buffer->pos;
+
+ if (buffer->event && p == buffer->start) {
+ ngx_add_timer(buffer->event, buffer->flush);
+ }
+
+ for (i = 0; i < log[l].format->ops->nelts; i++) {
+ p = op[i].run(s, p, &op[i]);
+ }
+
+ ngx_linefeed(p);
+
+ buffer->pos = p;
+
+ continue;
+ }
+
+ if (buffer->event && buffer->event->timer_set) {
+ ngx_del_timer(buffer->event);
+ }
+ }
+
+ alloc_line:
+
+ line = ngx_pnalloc(s->connection->pool, len);
+ if (line == NULL) {
+ return NGX_ERROR;
+ }
+
+ p = line;
+
+ if (log[l].syslog_peer) {
+ p = ngx_syslog_add_header(log[l].syslog_peer, line);
+ }
+
+ for (i = 0; i < log[l].format->ops->nelts; i++) {
+ p = op[i].run(s, p, &op[i]);
+ }
+
+ if (log[l].syslog_peer) {
+
+ size = p - line;
+
+ n = ngx_syslog_send(log[l].syslog_peer, line, size);
+
+ if (n < 0) {
+ ngx_log_error(NGX_LOG_WARN, s->connection->log, 0,
+ "send() to syslog failed");
+
+ } else if ((size_t) n != size) {
+ ngx_log_error(NGX_LOG_WARN, s->connection->log, 0,
+ "send() to syslog has written only %z of %uz",
+ n, size);
+ }
+
+ continue;
+ }
+
+ ngx_linefeed(p);
+
+ ngx_stream_log_write(s, &log[l], line, p - line);
+ }
+
+ return NGX_OK;
+}
+
+
+static void
+ngx_stream_log_write(ngx_stream_session_t *s, ngx_stream_log_t *log,
+ u_char *buf, size_t len)
+{
+ u_char *name;
+ time_t now;
+ ssize_t n;
+ ngx_err_t err;
+#if (NGX_ZLIB)
+ ngx_stream_log_buf_t *buffer;
+#endif
+
+ if (log->script == NULL) {
+ name = log->file->name.data;
+
+#if (NGX_ZLIB)
+ buffer = log->file->data;
+
+ if (buffer && buffer->gzip) {
+ n = ngx_stream_log_gzip(log->file->fd, buf, len, buffer->gzip,
+ s->connection->log);
+ } else {
+ n = ngx_write_fd(log->file->fd, buf, len);
+ }
+#else
+ n = ngx_write_fd(log->file->fd, buf, len);
+#endif
+
+ } else {
+ name = NULL;
+ n = ngx_stream_log_script_write(s, log->script, &name, buf, len);
+ }
+
+ if (n == (ssize_t) len) {
+ return;
+ }
+
+ now = ngx_time();
+
+ if (n == -1) {
+ err = ngx_errno;
+
+ if (err == NGX_ENOSPC) {
+ log->disk_full_time = now;
+ }
+
+ if (now - log->error_log_time > 59) {
+ ngx_log_error(NGX_LOG_ALERT, s->connection->log, err,
+ ngx_write_fd_n " to \"%s\" failed", name);
+
+ log->error_log_time = now;
+ }
+
+ return;
+ }
+
+ if (now - log->error_log_time > 59) {
+ ngx_log_error(NGX_LOG_ALERT, s->connection->log, 0,
+ ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
+ name, n, len);
+
+ log->error_log_time = now;
+ }
+}
+
+
+static ssize_t
+ngx_stream_log_script_write(ngx_stream_session_t *s,
+ ngx_stream_log_script_t *script, u_char **name, u_char *buf, size_t len)
+{
+ ssize_t n;
+ ngx_str_t log;
+ ngx_open_file_info_t of;
+ ngx_stream_log_srv_conf_t *lscf;
+
+ if (ngx_stream_script_run(s, &log, script->lengths->elts, 1,
+ script->values->elts)
+ == NULL)
+ {
+ /* simulate successful logging */
+ return len;
+ }
+
+ log.data[log.len - 1] = '\0';
+ *name = log.data;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "stream log \"%s\"", log.data);
+
+ lscf = ngx_stream_get_module_srv_conf(s, ngx_stream_log_module);
+
+ ngx_memzero(&of, sizeof(ngx_open_file_info_t));
+
+ of.log = 1;
+ of.valid = lscf->open_file_cache_valid;
+ of.min_uses = lscf->open_file_cache_min_uses;
+ of.directio = NGX_OPEN_FILE_DIRECTIO_OFF;
+
+ if (ngx_open_cached_file(lscf->open_file_cache, &log, &of,
+ s->connection->pool)
+ != NGX_OK)
+ {
+ ngx_log_error(NGX_LOG_CRIT, s->connection->log, ngx_errno,
+ "%s \"%s\" failed", of.failed, log.data);
+ /* simulate successful logging */
+ return len;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "stream log #%d", of.fd);
+
+ n = ngx_write_fd(of.fd, buf, len);
+
+ return n;
+}
+
+
+#if (NGX_ZLIB)
+
+static ssize_t
+ngx_stream_log_gzip(ngx_fd_t fd, u_char *buf, size_t len, ngx_int_t level,
+ ngx_log_t *log)
+{
+ int rc, wbits, memlevel;
+ u_char *out;
+ size_t size;
+ ssize_t n;
+ z_stream zstream;
+ ngx_err_t err;
+ ngx_pool_t *pool;
+
+ wbits = MAX_WBITS;
+ memlevel = MAX_MEM_LEVEL - 1;
+
+ while ((ssize_t) len < ((1 << (wbits - 1)) - 262)) {
+ wbits--;
+ memlevel--;
+ }
+
+ /*
+ * This is a formula from deflateBound() for conservative upper bound of
+ * compressed data plus 18 bytes of gzip wrapper.
+ */
+
+ size = len + ((len + 7) >> 3) + ((len + 63) >> 6) + 5 + 18;
+
+ ngx_memzero(&zstream, sizeof(z_stream));
+
+ pool = ngx_create_pool(256, log);
+ if (pool == NULL) {
+ /* simulate successful logging */
+ return len;
+ }
+
+ pool->log = log;
+
+ zstream.zalloc = ngx_stream_log_gzip_alloc;
+ zstream.zfree = ngx_stream_log_gzip_free;
+ zstream.opaque = pool;
+
+ out = ngx_pnalloc(pool, size);
+ if (out == NULL) {
+ goto done;
+ }
+
+ zstream.next_in = buf;
+ zstream.avail_in = len;
+ zstream.next_out = out;
+ zstream.avail_out = size;
+
+ rc = deflateInit2(&zstream, (int) level, Z_DEFLATED, wbits + 16, memlevel,
+ Z_DEFAULT_STRATEGY);
+
+ if (rc != Z_OK) {
+ ngx_log_error(NGX_LOG_ALERT, log, 0, "deflateInit2() failed: %d", rc);
+ goto done;
+ }
+
+ ngx_log_debug4(NGX_LOG_DEBUG_STREAM, log, 0,
+ "deflate in: ni:%p no:%p ai:%ud ao:%ud",
+ zstream.next_in, zstream.next_out,
+ zstream.avail_in, zstream.avail_out);
+
+ rc = deflate(&zstream, Z_FINISH);
+
+ if (rc != Z_STREAM_END) {
+ ngx_log_error(NGX_LOG_ALERT, log, 0,
+ "deflate(Z_FINISH) failed: %d", rc);
+ goto done;
+ }
+
+ ngx_log_debug5(NGX_LOG_DEBUG_STREAM, log, 0,
+ "deflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
+ zstream.next_in, zstream.next_out,
+ zstream.avail_in, zstream.avail_out,
+ rc);
+
+ size -= zstream.avail_out;
+
+ rc = deflateEnd(&zstream);
+
+ if (rc != Z_OK) {
+ ngx_log_error(NGX_LOG_ALERT, log, 0, "deflateEnd() failed: %d", rc);
+ goto done;
+ }
+
+ n = ngx_write_fd(fd, out, size);
+
+ if (n != (ssize_t) size) {
+ err = (n == -1) ? ngx_errno : 0;
+
+ ngx_destroy_pool(pool);
+
+ ngx_set_errno(err);
+ return -1;
+ }
+
+done:
+
+ ngx_destroy_pool(pool);
+
+ /* simulate successful logging */
+ return len;
+}
+
+
+static void *
+ngx_stream_log_gzip_alloc(void *opaque, u_int items, u_int size)
+{
+ ngx_pool_t *pool = opaque;
+
+ ngx_log_debug2(NGX_LOG_DEBUG_STREAM, pool->log, 0,
+ "gzip alloc: n:%ud s:%ud", items, size);
+
+ return ngx_palloc(pool, items * size);
+}
+
+
+static void
+ngx_stream_log_gzip_free(void *opaque, void *address)
+{
+#if 0
+ ngx_pool_t *pool = opaque;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pool->log, 0,
+ "gzip free: %p", address);
+#endif
+}
+
+#endif
+
+
+static void
+ngx_stream_log_flush(ngx_open_file_t *file, ngx_log_t *log)
+{
+ size_t len;
+ ssize_t n;
+ ngx_stream_log_buf_t *buffer;
+
+ buffer = file->data;
+
+ len = buffer->pos - buffer->start;
+
+ if (len == 0) {
+ return;
+ }
+
+#if (NGX_ZLIB)
+ if (buffer->gzip) {
+ n = ngx_stream_log_gzip(file->fd, buffer->start, len, buffer->gzip,
+ log);
+ } else {
+ n = ngx_write_fd(file->fd, buffer->start, len);
+ }
+#else
+ n = ngx_write_fd(file->fd, buffer->start, len);
+#endif
+
+ if (n == -1) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ ngx_write_fd_n " to \"%s\" failed",
+ file->name.data);
+
+ } else if ((size_t) n != len) {
+ ngx_log_error(NGX_LOG_ALERT, log, 0,
+ ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
+ file->name.data, n, len);
+ }
+
+ buffer->pos = buffer->start;
+
+ if (buffer->event && buffer->event->timer_set) {
+ ngx_del_timer(buffer->event);
+ }
+}
+
+
+static void
+ngx_stream_log_flush_handler(ngx_event_t *ev)
+{
+ ngx_open_file_t *file;
+ ngx_stream_log_buf_t *buffer;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0,
+ "stream log buffer flush handler");
+
+ if (ev->timedout) {
+ ngx_stream_log_flush(ev->data, ev->log);
+ return;
+ }
+
+ /* cancel the flush timer for graceful shutdown */
+
+ file = ev->data;
+ buffer = file->data;
+
+ buffer->event = NULL;
+}
+
+
+static u_char *
+ngx_stream_log_copy_short(ngx_stream_session_t *s, u_char *buf,
+ ngx_stream_log_op_t *op)
+{
+ size_t len;
+ uintptr_t data;
+
+ len = op->len;
+ data = op->data;
+
+ while (len--) {
+ *buf++ = (u_char) (data & 0xff);
+ data >>= 8;
+ }
+
+ return buf;
+}
+
+
+static u_char *
+ngx_stream_log_copy_long(ngx_stream_session_t *s, u_char *buf,
+ ngx_stream_log_op_t *op)
+{
+ return ngx_cpymem(buf, (u_char *) op->data, op->len);
+}
+
+
+static ngx_int_t
+ngx_stream_log_variable_compile(ngx_conf_t *cf, ngx_stream_log_op_t *op,
+ ngx_str_t *value)
+{
+ ngx_int_t index;
+
+ index = ngx_stream_get_variable_index(cf, value);
+ if (index == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ op->len = 0;
+ op->getlen = ngx_stream_log_variable_getlen;
+ op->run = ngx_stream_log_variable;
+ op->data = index;
+
+ return NGX_OK;
+}
+
+
+static size_t
+ngx_stream_log_variable_getlen(ngx_stream_session_t *s, uintptr_t data)
+{
+ uintptr_t len;
+ ngx_stream_variable_value_t *value;
+
+ value = ngx_stream_get_indexed_variable(s, data);
+
+ if (value == NULL || value->not_found) {
+ return 1;
+ }
+
+ len = ngx_stream_log_escape(NULL, value->data, value->len);
+
+ value->escape = len ? 1 : 0;
+
+ return value->len + len * 3;
+}
+
+
+static u_char *
+ngx_stream_log_variable(ngx_stream_session_t *s, u_char *buf,
+ ngx_stream_log_op_t *op)
+{
+ ngx_stream_variable_value_t *value;
+
+ value = ngx_stream_get_indexed_variable(s, op->data);
+
+ if (value == NULL || value->not_found) {
+ *buf = '-';
+ return buf + 1;
+ }
+
+ if (value->escape == 0) {
+ return ngx_cpymem(buf, value->data, value->len);
+
+ } else {
+ return (u_char *) ngx_stream_log_escape(buf, value->data, value->len);
+ }
+}
+
+
+static uintptr_t
+ngx_stream_log_escape(u_char *dst, u_char *src, size_t size)
+{
+ ngx_uint_t n;
+ static u_char hex[] = "0123456789ABCDEF";
+
+ static uint32_t escape[] = {
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+
+ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
+ 0x00000004, /* 0000 0000 0000 0000 0000 0000 0000 0100 */
+
+ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
+ 0x10000000, /* 0001 0000 0000 0000 0000 0000 0000 0000 */
+
+ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
+ 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
+
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ };
+
+
+ if (dst == NULL) {
+
+ /* find the number of the characters to be escaped */
+
+ n = 0;
+
+ while (size) {
+ if (escape[*src >> 5] & (1U << (*src & 0x1f))) {
+ n++;
+ }
+ src++;
+ size--;
+ }
+
+ return (uintptr_t) n;
+ }
+
+ while (size) {
+ if (escape[*src >> 5] & (1U << (*src & 0x1f))) {
+ *dst++ = '\\';
+ *dst++ = 'x';
+ *dst++ = hex[*src >> 4];
+ *dst++ = hex[*src & 0xf];
+ src++;
+
+ } else {
+ *dst++ = *src++;
+ }
+ size--;
+ }
+
+ return (uintptr_t) dst;
+}
+
+
+static void *
+ngx_stream_log_create_main_conf(ngx_conf_t *cf)
+{
+ ngx_stream_log_main_conf_t *conf;
+
+ conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_log_main_conf_t));
+ if (conf == NULL) {
+ return NULL;
+ }
+
+ if (ngx_array_init(&conf->formats, cf->pool, 4,
+ sizeof(ngx_stream_log_fmt_t))
+ != NGX_OK)
+ {
+ return NULL;
+ }
+
+ return conf;
+}
+
+
+static void *
+ngx_stream_log_create_srv_conf(ngx_conf_t *cf)
+{
+ ngx_stream_log_srv_conf_t *conf;
+
+ conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_log_srv_conf_t));
+ if (conf == NULL) {
+ return NULL;
+ }
+
+ conf->open_file_cache = NGX_CONF_UNSET_PTR;
+
+ return conf;
+}
+
+
+static char *
+ngx_stream_log_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
+{
+ ngx_stream_log_srv_conf_t *prev = parent;
+ ngx_stream_log_srv_conf_t *conf = child;
+
+ if (conf->open_file_cache == NGX_CONF_UNSET_PTR) {
+
+ conf->open_file_cache = prev->open_file_cache;
+ conf->open_file_cache_valid = prev->open_file_cache_valid;
+ conf->open_file_cache_min_uses = prev->open_file_cache_min_uses;
+
+ if (conf->open_file_cache == NGX_CONF_UNSET_PTR) {
+ conf->open_file_cache = NULL;
+ }
+ }
+
+ if (conf->logs || conf->off) {
+ return NGX_CONF_OK;
+ }
+
+ conf->logs = prev->logs;
+ conf->off = prev->off;
+
+ return NGX_CONF_OK;
+}
+
+
+static char *
+ngx_stream_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_stream_log_srv_conf_t *lscf = conf;
+
+ ssize_t size;
+ ngx_int_t gzip;
+ ngx_uint_t i, n;
+ ngx_msec_t flush;
+ ngx_str_t *value, name, s;
+ ngx_stream_log_t *log;
+ ngx_syslog_peer_t *peer;
+ ngx_stream_log_buf_t *buffer;
+ ngx_stream_log_fmt_t *fmt;
+ ngx_stream_script_compile_t sc;
+ ngx_stream_log_main_conf_t *lmcf;
+ ngx_stream_compile_complex_value_t ccv;
+
+ value = cf->args->elts;
+
+ if (ngx_strcmp(value[1].data, "off") == 0) {
+ lscf->off = 1;
+ if (cf->args->nelts == 2) {
+ return NGX_CONF_OK;
+ }
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter \"%V\"", &value[2]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (lscf->logs == NULL) {
+ lscf->logs = ngx_array_create(cf->pool, 2, sizeof(ngx_stream_log_t));
+ if (lscf->logs == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ lmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_log_module);
+
+ log = ngx_array_push(lscf->logs);
+ if (log == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ngx_memzero(log, sizeof(ngx_stream_log_t));
+
+
+ if (ngx_strncmp(value[1].data, "syslog:", 7) == 0) {
+
+ peer = ngx_pcalloc(cf->pool, sizeof(ngx_syslog_peer_t));
+ if (peer == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (ngx_syslog_process_conf(cf, peer) != NGX_CONF_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ log->syslog_peer = peer;
+
+ goto process_formats;
+ }
+
+ n = ngx_stream_script_variables_count(&value[1]);
+
+ if (n == 0) {
+ log->file = ngx_conf_open_file(cf->cycle, &value[1]);
+ if (log->file == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ } else {
+ if (ngx_conf_full_name(cf->cycle, &value[1], 0) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ log->script = ngx_pcalloc(cf->pool, sizeof(ngx_stream_log_script_t));
+ if (log->script == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ngx_memzero(&sc, sizeof(ngx_stream_script_compile_t));
+
+ sc.cf = cf;
+ sc.source = &value[1];
+ sc.lengths = &log->script->lengths;
+ sc.values = &log->script->values;
+ sc.variables = n;
+ sc.complete_lengths = 1;
+ sc.complete_values = 1;
+
+ if (ngx_stream_script_compile(&sc) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+process_formats:
+
+ if (cf->args->nelts >= 3) {
+ name = value[2];
+
+ } else {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "log format is not specified");
+ return NGX_CONF_ERROR;
+ }
+
+ fmt = lmcf->formats.elts;
+ for (i = 0; i < lmcf->formats.nelts; i++) {
+ if (fmt[i].name.len == name.len
+ && ngx_strcasecmp(fmt[i].name.data, name.data) == 0)
+ {
+ log->format = &fmt[i];
+ break;
+ }
+ }
+
+ if (log->format == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "unknown log format \"%V\"", &name);
+ return NGX_CONF_ERROR;
+ }
+
+ size = 0;
+ flush = 0;
+ gzip = 0;
+
+ for (i = 3; i < cf->args->nelts; i++) {
+
+ if (ngx_strncmp(value[i].data, "buffer=", 7) == 0) {
+ s.len = value[i].len - 7;
+ s.data = value[i].data + 7;
+
+ size = ngx_parse_size(&s);
+
+ if (size == NGX_ERROR || size == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid buffer size \"%V\"", &s);
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "flush=", 6) == 0) {
+ s.len = value[i].len - 6;
+ s.data = value[i].data + 6;
+
+ flush = ngx_parse_time(&s, 0);
+
+ if (flush == (ngx_msec_t) NGX_ERROR || flush == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid flush time \"%V\"", &s);
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "gzip", 4) == 0
+ && (value[i].len == 4 || value[i].data[4] == '='))
+ {
+#if (NGX_ZLIB)
+ if (size == 0) {
+ size = 64 * 1024;
+ }
+
+ if (value[i].len == 4) {
+ gzip = Z_BEST_SPEED;
+ continue;
+ }
+
+ s.len = value[i].len - 5;
+ s.data = value[i].data + 5;
+
+ gzip = ngx_atoi(s.data, s.len);
+
+ if (gzip < 1 || gzip > 9) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid compression level \"%V\"", &s);
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
+
+#else
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "nginx was built without zlib support");
+ return NGX_CONF_ERROR;
+#endif
+ }
+
+ if (ngx_strncmp(value[i].data, "if=", 3) == 0) {
+ s.len = value[i].len - 3;
+ s.data = value[i].data + 3;
+
+ ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &s;
+ ccv.complex_value = ngx_palloc(cf->pool,
+ sizeof(ngx_stream_complex_value_t));
+ if (ccv.complex_value == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ log->filter = ccv.complex_value;
+
+ continue;
+ }
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (flush && size == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "no buffer is defined for access_log \"%V\"",
+ &value[1]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (size) {
+
+ if (log->script) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "buffered logs cannot have variables in name");
+ return NGX_CONF_ERROR;
+ }
+
+ if (log->syslog_peer) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "logs to syslog cannot be buffered");
+ return NGX_CONF_ERROR;
+ }
+
+ if (log->file->data) {
+ buffer = log->file->data;
+
+ if (buffer->last - buffer->start != size
+ || buffer->flush != flush
+ || buffer->gzip != gzip)
+ {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "access_log \"%V\" already defined "
+ "with conflicting parameters",
+ &value[1]);
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+ }
+
+ buffer = ngx_pcalloc(cf->pool, sizeof(ngx_stream_log_buf_t));
+ if (buffer == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ buffer->start = ngx_pnalloc(cf->pool, size);
+ if (buffer->start == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ buffer->pos = buffer->start;
+ buffer->last = buffer->start + size;
+
+ if (flush) {
+ buffer->event = ngx_pcalloc(cf->pool, sizeof(ngx_event_t));
+ if (buffer->event == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ buffer->event->data = log->file;
+ buffer->event->handler = ngx_stream_log_flush_handler;
+ buffer->event->log = &cf->cycle->new_log;
+ buffer->event->cancelable = 1;
+
+ buffer->flush = flush;
+ }
+
+ buffer->gzip = gzip;
+
+ log->file->flush = ngx_stream_log_flush;
+ log->file->data = buffer;
+ }
+
+ return NGX_CONF_OK;
+}
+
+
+static char *
+ngx_stream_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_stream_log_main_conf_t *lmcf = conf;
+
+ ngx_str_t *value;
+ ngx_uint_t i;
+ ngx_stream_log_fmt_t *fmt;
+
+ value = cf->args->elts;
+
+ fmt = lmcf->formats.elts;
+ for (i = 0; i < lmcf->formats.nelts; i++) {
+ if (fmt[i].name.len == value[1].len
+ && ngx_strcmp(fmt[i].name.data, value[1].data) == 0)
+ {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "duplicate \"log_format\" name \"%V\"",
+ &value[1]);
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ fmt = ngx_array_push(&lmcf->formats);
+ if (fmt == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ fmt->name = value[1];
+
+ fmt->flushes = ngx_array_create(cf->pool, 4, sizeof(ngx_int_t));
+ if (fmt->flushes == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ fmt->ops = ngx_array_create(cf->pool, 16, sizeof(ngx_stream_log_op_t));
+ if (fmt->ops == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ return ngx_stream_log_compile_format(cf, fmt->flushes, fmt->ops,
+ cf->args, 2);
+}
+
+
+static char *
+ngx_stream_log_compile_format(ngx_conf_t *cf, ngx_array_t *flushes,
+ ngx_array_t *ops, ngx_array_t *args, ngx_uint_t s)
+{
+ u_char *data, *p, ch;
+ size_t i, len;
+ ngx_str_t *value, var;
+ ngx_int_t *flush;
+ ngx_uint_t bracket;
+ ngx_stream_log_op_t *op;
+
+ value = args->elts;
+
+ for ( /* void */ ; s < args->nelts; s++) {
+
+ i = 0;
+
+ while (i < value[s].len) {
+
+ op = ngx_array_push(ops);
+ if (op == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ data = &value[s].data[i];
+
+ if (value[s].data[i] == '$') {
+
+ if (++i == value[s].len) {
+ goto invalid;
+ }
+
+ if (value[s].data[i] == '{') {
+ bracket = 1;
+
+ if (++i == value[s].len) {
+ goto invalid;
+ }
+
+ var.data = &value[s].data[i];
+
+ } else {
+ bracket = 0;
+ var.data = &value[s].data[i];
+ }
+
+ for (var.len = 0; i < value[s].len; i++, var.len++) {
+ ch = value[s].data[i];
+
+ if (ch == '}' && bracket) {
+ i++;
+ bracket = 0;
+ break;
+ }
+
+ if ((ch >= 'A' && ch <= 'Z')
+ || (ch >= 'a' && ch <= 'z')
+ || (ch >= '0' && ch <= '9')
+ || ch == '_')
+ {
+ continue;
+ }
+
+ break;
+ }
+
+ if (bracket) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "the closing bracket in \"%V\" "
+ "variable is missing", &var);
+ return NGX_CONF_ERROR;
+ }
+
+ if (var.len == 0) {
+ goto invalid;
+ }
+
+ if (ngx_stream_log_variable_compile(cf, op, &var) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (flushes) {
+
+ flush = ngx_array_push(flushes);
+ if (flush == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *flush = op->data; /* variable index */
+ }
+
+ continue;
+ }
+
+ i++;
+
+ while (i < value[s].len && value[s].data[i] != '$') {
+ i++;
+ }
+
+ len = &value[s].data[i] - data;
+
+ if (len) {
+
+ op->len = len;
+ op->getlen = NULL;
+
+ if (len <= sizeof(uintptr_t)) {
+ op->run = ngx_stream_log_copy_short;
+ op->data = 0;
+
+ while (len--) {
+ op->data <<= 8;
+ op->data |= data[len];
+ }
+
+ } else {
+ op->run = ngx_stream_log_copy_long;
+
+ p = ngx_pnalloc(cf->pool, len);
+ if (p == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ngx_memcpy(p, data, len);
+ op->data = (uintptr_t) p;
+ }
+ }
+ }
+ }
+
+ return NGX_CONF_OK;
+
+invalid:
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%s\"", data);
+
+ return NGX_CONF_ERROR;
+}
+
+
+static char *
+ngx_stream_log_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_stream_log_srv_conf_t *lscf = conf;
+
+ time_t inactive, valid;
+ ngx_str_t *value, s;
+ ngx_int_t max, min_uses;
+ ngx_uint_t i;
+
+ if (lscf->open_file_cache != NGX_CONF_UNSET_PTR) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ max = 0;
+ inactive = 10;
+ valid = 60;
+ min_uses = 1;
+
+ for (i = 1; i < cf->args->nelts; i++) {
+
+ if (ngx_strncmp(value[i].data, "max=", 4) == 0) {
+
+ max = ngx_atoi(value[i].data + 4, value[i].len - 4);
+ if (max == NGX_ERROR) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {
+
+ s.len = value[i].len - 9;
+ s.data = value[i].data + 9;
+
+ inactive = ngx_parse_time(&s, 1);
+ if (inactive == (time_t) NGX_ERROR) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "min_uses=", 9) == 0) {
+
+ min_uses = ngx_atoi(value[i].data + 9, value[i].len - 9);
+ if (min_uses == NGX_ERROR) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "valid=", 6) == 0) {
+
+ s.len = value[i].len - 6;
+ s.data = value[i].data + 6;
+
+ valid = ngx_parse_time(&s, 1);
+ if (valid == (time_t) NGX_ERROR) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strcmp(value[i].data, "off") == 0) {
+
+ lscf->open_file_cache = NULL;
+
+ continue;
+ }
+
+ failed:
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid \"open_log_file_cache\" parameter \"%V\"",
+ &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (lscf->open_file_cache == NULL) {
+ return NGX_CONF_OK;
+ }
+
+ if (max == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"open_log_file_cache\" must have \"max\" parameter");
+ return NGX_CONF_ERROR;
+ }
+
+ lscf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive);
+
+ if (lscf->open_file_cache) {
+
+ lscf->open_file_cache_valid = valid;
+ lscf->open_file_cache_min_uses = min_uses;
+
+ return NGX_CONF_OK;
+ }
+
+ return NGX_CONF_ERROR;
+}
+
+
+static ngx_int_t
+ngx_stream_log_init(ngx_conf_t *cf)
+{
+ ngx_stream_core_main_conf_t *cmcf;
+
+ cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);
+
+ cmcf->access_log_handler = ngx_stream_log_handler;
+
+ return NGX_OK;
+}
|
[-]
[+]
|
Added |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_map_module.c
^
|
@@ -0,0 +1,574 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_stream.h>
+
+
+typedef struct {
+ ngx_uint_t hash_max_size;
+ ngx_uint_t hash_bucket_size;
+} ngx_stream_map_conf_t;
+
+
+typedef struct {
+ ngx_hash_keys_arrays_t keys;
+
+ ngx_array_t *values_hash;
+#if (NGX_PCRE)
+ ngx_array_t regexes;
+#endif
+
+ ngx_stream_variable_value_t *default_value;
+ ngx_conf_t *cf;
+ ngx_uint_t hostnames; /* unsigned hostnames:1 */
+} ngx_stream_map_conf_ctx_t;
+
+
+typedef struct {
+ ngx_stream_map_t map;
+ ngx_stream_complex_value_t value;
+ ngx_stream_variable_value_t *default_value;
+ ngx_uint_t hostnames; /* unsigned hostnames:1 */
+} ngx_stream_map_ctx_t;
+
+
+static int ngx_libc_cdecl ngx_stream_map_cmp_dns_wildcards(const void *one,
+ const void *two);
+static void *ngx_stream_map_create_conf(ngx_conf_t *cf);
+static char *ngx_stream_map_block(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static char *ngx_stream_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf);
+
+
+static ngx_command_t ngx_stream_map_commands[] = {
+
+ { ngx_string("map"),
+ NGX_STREAM_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE2,
+ ngx_stream_map_block,
+ NGX_STREAM_MAIN_CONF_OFFSET,
+ 0,
+ NULL },
+
+ { ngx_string("map_hash_max_size"),
+ NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ NGX_STREAM_MAIN_CONF_OFFSET,
+ offsetof(ngx_stream_map_conf_t, hash_max_size),
+ NULL },
+
+ { ngx_string("map_hash_bucket_size"),
+ NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ NGX_STREAM_MAIN_CONF_OFFSET,
+ offsetof(ngx_stream_map_conf_t, hash_bucket_size),
+ NULL },
+
+ ngx_null_command
+};
+
+
+static ngx_stream_module_t ngx_stream_map_module_ctx = {
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
+
+ ngx_stream_map_create_conf, /* create main configuration */
+ NULL, /* init main configuration */
+
+ NULL, /* create server configuration */
+ NULL /* merge server configuration */
+};
+
+
+ngx_module_t ngx_stream_map_module = {
+ NGX_MODULE_V1,
+ &ngx_stream_map_module_ctx, /* module context */
+ ngx_stream_map_commands, /* module directives */
+ NGX_STREAM_MODULE, /* module type */
+ NULL, /* init master */
+ NULL, /* init module */
+ NULL, /* init process */
+ NULL, /* init thread */
+ NULL, /* exit thread */
+ NULL, /* exit process */
+ NULL, /* exit master */
+ NGX_MODULE_V1_PADDING
+};
+
+
+static ngx_int_t
+ngx_stream_map_variable(ngx_stream_session_t *s, ngx_stream_variable_value_t *v,
+ uintptr_t data)
+{
+ ngx_stream_map_ctx_t *map = (ngx_stream_map_ctx_t *) data;
+
+ ngx_str_t val, str;
+ ngx_stream_complex_value_t *cv;
+ ngx_stream_variable_value_t *value;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "stream map started");
+
+ if (ngx_stream_complex_value(s, &map->value, &val) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ if (map->hostnames && val.len > 0 && val.data[val.len - 1] == '.') {
+ val.len--;
+ }
+
+ value = ngx_stream_map_find(s, &map->map, &val);
+
+ if (value == NULL) {
+ value = map->default_value;
+ }
+
+ if (!value->valid) {
+ cv = (ngx_stream_complex_value_t *) value->data;
+
+ if (ngx_stream_complex_value(s, cv, &str) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->len = str.len;
+ v->data = str.data;
+
+ } else {
+ *v = *value;
+ }
+
+ ngx_log_debug2(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "stream map: \"%V\" \"%v\"", &val, v);
+
+ return NGX_OK;
+}
+
+
+static void *
+ngx_stream_map_create_conf(ngx_conf_t *cf)
+{
+ ngx_stream_map_conf_t *mcf;
+
+ mcf = ngx_palloc(cf->pool, sizeof(ngx_stream_map_conf_t));
+ if (mcf == NULL) {
+ return NULL;
+ }
+
+ mcf->hash_max_size = NGX_CONF_UNSET_UINT;
+ mcf->hash_bucket_size = NGX_CONF_UNSET_UINT;
+
+ return mcf;
+}
+
+
+static char *
+ngx_stream_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_stream_map_conf_t *mcf = conf;
+
+ char *rv;
+ ngx_str_t *value, name;
+ ngx_conf_t save;
+ ngx_pool_t *pool;
+ ngx_hash_init_t hash;
+ ngx_stream_map_ctx_t *map;
+ ngx_stream_variable_t *var;
+ ngx_stream_map_conf_ctx_t ctx;
+ ngx_stream_compile_complex_value_t ccv;
+
+ if (mcf->hash_max_size == NGX_CONF_UNSET_UINT) {
+ mcf->hash_max_size = 2048;
+ }
+
+ if (mcf->hash_bucket_size == NGX_CONF_UNSET_UINT) {
+ mcf->hash_bucket_size = ngx_cacheline_size;
+
+ } else {
+ mcf->hash_bucket_size = ngx_align(mcf->hash_bucket_size,
+ ngx_cacheline_size);
+ }
+
+ map = ngx_pcalloc(cf->pool, sizeof(ngx_stream_map_ctx_t));
+ if (map == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ value = cf->args->elts;
+
+ ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &value[1];
+ ccv.complex_value = &map->value;
+
+ if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ name = value[2];
+
+ if (name.data[0] != '$') {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid variable name \"%V\"", &name);
+ return NGX_CONF_ERROR;
+ }
+
+ name.len--;
+ name.data++;
+
+ var = ngx_stream_add_variable(cf, &name, NGX_STREAM_VAR_CHANGEABLE);
+ if (var == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ var->get_handler = ngx_stream_map_variable;
+ var->data = (uintptr_t) map;
+
+ pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log);
+ if (pool == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ctx.keys.pool = cf->pool;
+ ctx.keys.temp_pool = pool;
+
+ if (ngx_hash_keys_array_init(&ctx.keys, NGX_HASH_LARGE) != NGX_OK) {
+ ngx_destroy_pool(pool);
+ return NGX_CONF_ERROR;
+ }
+
+ ctx.values_hash = ngx_pcalloc(pool, sizeof(ngx_array_t) * ctx.keys.hsize);
+ if (ctx.values_hash == NULL) {
+ ngx_destroy_pool(pool);
+ return NGX_CONF_ERROR;
+ }
+
+#if (NGX_PCRE)
+ if (ngx_array_init(&ctx.regexes, cf->pool, 2,
+ sizeof(ngx_stream_map_regex_t))
+ != NGX_OK)
+ {
+ ngx_destroy_pool(pool);
+ return NGX_CONF_ERROR;
+ }
+#endif
+
+ ctx.default_value = NULL;
+ ctx.cf = &save;
+ ctx.hostnames = 0;
+
+ save = *cf;
+ cf->pool = pool;
+ cf->ctx = &ctx;
+ cf->handler = ngx_stream_map;
+ cf->handler_conf = conf;
+
+ rv = ngx_conf_parse(cf, NULL);
+
+ *cf = save;
+
+ if (rv != NGX_CONF_OK) {
+ ngx_destroy_pool(pool);
+ return rv;
+ }
+
+ map->default_value = ctx.default_value ? ctx.default_value:
+ &ngx_stream_variable_null_value;
+
+ map->hostnames = ctx.hostnames;
+
+ hash.key = ngx_hash_key_lc;
+ hash.max_size = mcf->hash_max_size;
+ hash.bucket_size = mcf->hash_bucket_size;
+ hash.name = "map_hash";
+ hash.pool = cf->pool;
+
+ if (ctx.keys.keys.nelts) {
+ hash.hash = &map->map.hash.hash;
+ hash.temp_pool = NULL;
+
+ if (ngx_hash_init(&hash, ctx.keys.keys.elts, ctx.keys.keys.nelts)
+ != NGX_OK)
+ {
+ ngx_destroy_pool(pool);
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ if (ctx.keys.dns_wc_head.nelts) {
+
+ ngx_qsort(ctx.keys.dns_wc_head.elts,
+ (size_t) ctx.keys.dns_wc_head.nelts,
+ sizeof(ngx_hash_key_t), ngx_stream_map_cmp_dns_wildcards);
+
+ hash.hash = NULL;
+ hash.temp_pool = pool;
+
+ if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wc_head.elts,
+ ctx.keys.dns_wc_head.nelts)
+ != NGX_OK)
+ {
+ ngx_destroy_pool(pool);
+ return NGX_CONF_ERROR;
+ }
+
+ map->map.hash.wc_head = (ngx_hash_wildcard_t *) hash.hash;
+ }
+
+ if (ctx.keys.dns_wc_tail.nelts) {
+
+ ngx_qsort(ctx.keys.dns_wc_tail.elts,
+ (size_t) ctx.keys.dns_wc_tail.nelts,
+ sizeof(ngx_hash_key_t), ngx_stream_map_cmp_dns_wildcards);
+
+ hash.hash = NULL;
+ hash.temp_pool = pool;
+
+ if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wc_tail.elts,
+ ctx.keys.dns_wc_tail.nelts)
+ != NGX_OK)
+ {
+ ngx_destroy_pool(pool);
+ return NGX_CONF_ERROR;
+ }
+
+ map->map.hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash;
+ }
+
+#if (NGX_PCRE)
+
+ if (ctx.regexes.nelts) {
+ map->map.regex = ctx.regexes.elts;
+ map->map.nregex = ctx.regexes.nelts;
+ }
+
+#endif
+
+ ngx_destroy_pool(pool);
+
+ return rv;
+}
+
+
+static int ngx_libc_cdecl
+ngx_stream_map_cmp_dns_wildcards(const void *one, const void *two)
+{
+ ngx_hash_key_t *first, *second;
+
+ first = (ngx_hash_key_t *) one;
+ second = (ngx_hash_key_t *) two;
+
+ return ngx_dns_strcmp(first->key.data, second->key.data);
+}
+
+
+static char *
+ngx_stream_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
+{
+ u_char *data;
+ size_t len;
+ ngx_int_t rv;
+ ngx_str_t *value, v;
+ ngx_uint_t i, key;
+ ngx_stream_map_conf_ctx_t *ctx;
+ ngx_stream_complex_value_t cv, *cvp;
+ ngx_stream_variable_value_t *var, **vp;
+ ngx_stream_compile_complex_value_t ccv;
+
+ ctx = cf->ctx;
+
+ value = cf->args->elts;
+
+ if (cf->args->nelts == 1
+ && ngx_strcmp(value[0].data, "hostnames") == 0)
+ {
+ ctx->hostnames = 1;
+ return NGX_CONF_OK;
+
+ } else if (cf->args->nelts != 2) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid number of the map parameters");
+ return NGX_CONF_ERROR;
+ }
+
+ if (ngx_strcmp(value[0].data, "include") == 0) {
+ return ngx_conf_include(cf, dummy, conf);
+ }
+
+ key = 0;
+
+ for (i = 0; i < value[1].len; i++) {
+ key = ngx_hash(key, value[1].data[i]);
+ }
+
+ key %= ctx->keys.hsize;
+
+ vp = ctx->values_hash[key].elts;
+
+ if (vp) {
+ for (i = 0; i < ctx->values_hash[key].nelts; i++) {
+
+ if (vp[i]->valid) {
+ data = vp[i]->data;
+ len = vp[i]->len;
+
+ } else {
+ cvp = (ngx_stream_complex_value_t *) vp[i]->data;
+ data = cvp->value.data;
+ len = cvp->value.len;
+ }
+
+ if (value[1].len != len) {
+ continue;
+ }
+
+ if (ngx_strncmp(value[1].data, data, len) == 0) {
+ var = vp[i];
+ goto found;
+ }
+ }
+
+ } else {
+ if (ngx_array_init(&ctx->values_hash[key], cf->pool, 4,
+ sizeof(ngx_stream_variable_value_t *))
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ var = ngx_palloc(ctx->keys.pool, sizeof(ngx_stream_variable_value_t));
+ if (var == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ v.len = value[1].len;
+ v.data = ngx_pstrdup(ctx->keys.pool, &value[1]);
+ if (v.data == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
+
+ ccv.cf = ctx->cf;
+ ccv.value = &v;
+ ccv.complex_value = &cv;
+
+ if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (cv.lengths != NULL) {
+ cvp = ngx_palloc(ctx->keys.pool, sizeof(ngx_stream_complex_value_t));
+ if (cvp == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *cvp = cv;
+
+ var->len = 0;
+ var->data = (u_char *) cvp;
+ var->valid = 0;
+
+ } else {
+ var->len = v.len;
+ var->data = v.data;
+ var->valid = 1;
+ }
+
+ var->no_cacheable = 0;
+ var->not_found = 0;
+
+ vp = ngx_array_push(&ctx->values_hash[key]);
+ if (vp == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *vp = var;
+
+found:
+
+ if (ngx_strcmp(value[0].data, "default") == 0) {
+
+ if (ctx->default_value) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "duplicate default map parameter");
+ return NGX_CONF_ERROR;
+ }
+
+ ctx->default_value = var;
+
+ return NGX_CONF_OK;
+ }
+
+#if (NGX_PCRE)
+
+ if (value[0].len && value[0].data[0] == '~') {
+ ngx_regex_compile_t rc;
+ ngx_stream_map_regex_t *regex;
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
+
+ regex = ngx_array_push(&ctx->regexes);
+ if (regex == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ value[0].len--;
+ value[0].data++;
+
+ ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
+
+ if (value[0].data[0] == '*') {
+ value[0].len--;
+ value[0].data++;
+ rc.options = NGX_REGEX_CASELESS;
+ }
+
+ rc.pattern = value[0];
+ rc.err.len = NGX_MAX_CONF_ERRSTR;
+ rc.err.data = errstr;
+
+ regex->regex = ngx_stream_regex_compile(ctx->cf, &rc);
+ if (regex->regex == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ regex->value = var;
+
+ return NGX_CONF_OK;
+ }
+
+#endif
+
+ if (value[0].len && value[0].data[0] == '\\') {
+ value[0].len--;
+ value[0].data++;
+ }
+
+ rv = ngx_hash_add_key(&ctx->keys, &value[0], var,
+ (ctx->hostnames) ? NGX_HASH_WILDCARD_KEY : 0);
+
+ if (rv == NGX_OK) {
+ return NGX_CONF_OK;
+ }
+
+ if (rv == NGX_DECLINED) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid hostname or wildcard \"%V\"", &value[0]);
+ }
+
+ if (rv == NGX_BUSY) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "conflicting parameter \"%V\"", &value[0]);
+ }
+
+ return NGX_CONF_ERROR;
+}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_proxy_module.c
^
|
@@ -12,6 +12,7 @@
typedef struct {
ngx_addr_t *addr;
+ ngx_stream_complex_value_t *value;
#if (NGX_HAVE_TRANSPARENT_PROXY)
ngx_uint_t transparent; /* unsigned transparent:1; */
#endif
@@ -36,7 +37,7 @@
ngx_flag_t ssl_session_reuse;
ngx_uint_t ssl_protocols;
ngx_str_t ssl_ciphers;
- ngx_str_t ssl_name;
+ ngx_stream_complex_value_t *ssl_name;
ngx_flag_t ssl_server_name;
ngx_flag_t ssl_verify;
@@ -51,14 +52,18 @@
#endif
ngx_stream_upstream_srv_conf_t *upstream;
+ ngx_stream_complex_value_t *upstream_value;
} ngx_stream_proxy_srv_conf_t;
static void ngx_stream_proxy_handler(ngx_stream_session_t *s);
+static ngx_int_t ngx_stream_proxy_eval(ngx_stream_session_t *s,
+ ngx_stream_proxy_srv_conf_t *pscf);
static ngx_int_t ngx_stream_proxy_set_local(ngx_stream_session_t *s,
ngx_stream_upstream_t *u, ngx_stream_upstream_local_t *local);
static void ngx_stream_proxy_connect(ngx_stream_session_t *s);
static void ngx_stream_proxy_init_upstream(ngx_stream_session_t *s);
+static void ngx_stream_proxy_resolve_handler(ngx_resolver_ctx_t *ctx);
static void ngx_stream_proxy_upstream_handler(ngx_event_t *ev);
static void ngx_stream_proxy_downstream_handler(ngx_event_t *ev);
static void ngx_stream_proxy_process_connection(ngx_event_t *ev,
@@ -68,7 +73,7 @@
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);
+static void ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_uint_t rc);
static u_char *ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf,
size_t len);
@@ -245,7 +250,7 @@
{ ngx_string("proxy_ssl_name"),
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
+ ngx_stream_set_complex_value_slot,
NGX_STREAM_SRV_CONF_OFFSET,
offsetof(ngx_stream_proxy_srv_conf_t, ssl_name),
NULL },
@@ -313,6 +318,7 @@
static ngx_stream_module_t ngx_stream_proxy_module_ctx = {
+ NULL, /* preconfiguration */
NULL, /* postconfiguration */
NULL, /* create main configuration */
@@ -342,11 +348,16 @@
static void
ngx_stream_proxy_handler(ngx_stream_session_t *s)
{
- u_char *p;
- ngx_connection_t *c;
- ngx_stream_upstream_t *u;
- ngx_stream_proxy_srv_conf_t *pscf;
- ngx_stream_upstream_srv_conf_t *uscf;
+ u_char *p;
+ ngx_str_t *host;
+ ngx_uint_t i;
+ ngx_connection_t *c;
+ ngx_resolver_ctx_t *ctx, temp;
+ ngx_stream_upstream_t *u;
+ ngx_stream_core_srv_conf_t *cscf;
+ ngx_stream_proxy_srv_conf_t *pscf;
+ ngx_stream_upstream_srv_conf_t *uscf, **uscfp;
+ ngx_stream_upstream_main_conf_t *umcf;
c = s->connection;
@@ -357,7 +368,7 @@
u = ngx_pcalloc(c->pool, sizeof(ngx_stream_upstream_t));
if (u == NULL) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
@@ -369,76 +380,240 @@
u->peer.log_error = NGX_ERROR_ERR;
if (ngx_stream_proxy_set_local(s, u, pscf->local) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
u->peer.type = c->type;
- uscf = pscf->upstream;
+ u->proxy_protocol = pscf->proxy_protocol;
+ u->start_sec = ngx_time();
- if (uscf->peer.init(s, uscf) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ c->write->handler = ngx_stream_proxy_downstream_handler;
+ c->read->handler = ngx_stream_proxy_downstream_handler;
+
+ s->upstream_states = ngx_array_create(c->pool, 1,
+ sizeof(ngx_stream_upstream_state_t));
+ if (s->upstream_states == NULL) {
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
- u->peer.start_time = ngx_current_msec;
+ if (c->type == SOCK_STREAM) {
+ p = ngx_pnalloc(c->pool, pscf->buffer_size);
+ if (p == NULL) {
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
- if (pscf->next_upstream_tries
- && u->peer.tries > pscf->next_upstream_tries)
- {
- u->peer.tries = pscf->next_upstream_tries;
+ u->downstream_buf.start = p;
+ u->downstream_buf.end = p + pscf->buffer_size;
+ u->downstream_buf.pos = p;
+ u->downstream_buf.last = p;
+
+ if (u->proxy_protocol
+#if (NGX_STREAM_SSL)
+ && pscf->ssl == NULL
+#endif
+ && pscf->buffer_size >= NGX_PROXY_PROTOCOL_MAX_HEADER)
+ {
+ /* optimization for a typical case */
+
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
+ "stream proxy send PROXY protocol header");
+
+ p = ngx_proxy_protocol_write(c, u->downstream_buf.last,
+ u->downstream_buf.end);
+ if (p == NULL) {
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ u->downstream_buf.last = p;
+ u->proxy_protocol = 0;
+ }
+
+ if (c->read->ready) {
+ ngx_post_event(c->read, &ngx_posted_events);
+ }
}
- u->proxy_protocol = pscf->proxy_protocol;
- u->start_sec = ngx_time();
+ if (pscf->upstream_value) {
+ if (ngx_stream_proxy_eval(s, pscf) != NGX_OK) {
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+ }
- c->write->handler = ngx_stream_proxy_downstream_handler;
- c->read->handler = ngx_stream_proxy_downstream_handler;
+ if (u->resolved == NULL) {
+
+ uscf = pscf->upstream;
+
+ } else {
+
+#if (NGX_STREAM_SSL)
+ u->ssl_name = u->resolved->host;
+#endif
+
+ host = &u->resolved->host;
+
+ if (u->resolved->sockaddr) {
+
+ if (u->resolved->port == 0
+ && u->resolved->sockaddr->sa_family != AF_UNIX)
+ {
+ ngx_log_error(NGX_LOG_ERR, c->log, 0,
+ "no port in upstream \"%V\"", host);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ if (ngx_stream_upstream_create_round_robin_peer(s, u->resolved)
+ != NGX_OK)
+ {
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ ngx_stream_proxy_connect(s);
+
+ return;
+ }
+
+ umcf = ngx_stream_get_module_main_conf(s, ngx_stream_upstream_module);
+
+ uscfp = umcf->upstreams.elts;
+
+ for (i = 0; i < umcf->upstreams.nelts; i++) {
+
+ uscf = uscfp[i];
+
+ if (uscf->host.len == host->len
+ && ((uscf->port == 0 && u->resolved->no_port)
+ || uscf->port == u->resolved->port)
+ && ngx_strncasecmp(uscf->host.data, host->data, host->len) == 0)
+ {
+ goto found;
+ }
+ }
+
+ if (u->resolved->port == 0) {
+ ngx_log_error(NGX_LOG_ERR, c->log, 0,
+ "no port in upstream \"%V\"", host);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ temp.name = *host;
+
+ cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
+
+ ctx = ngx_resolve_start(cscf->resolver, &temp);
+ if (ctx == NULL) {
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ if (ctx == NGX_NO_RESOLVER) {
+ ngx_log_error(NGX_LOG_ERR, c->log, 0,
+ "no resolver defined to resolve %V", host);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ ctx->name = *host;
+ ctx->handler = ngx_stream_proxy_resolve_handler;
+ ctx->data = s;
+ ctx->timeout = cscf->resolver_timeout;
+
+ u->resolved->ctx = ctx;
+
+ if (ngx_resolve_name(ctx) != NGX_OK) {
+ u->resolved->ctx = NULL;
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
- 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);
+found:
+
+ if (uscf == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0, "no upstream configuration");
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
- u->downstream_buf.start = p;
- u->downstream_buf.end = p + pscf->buffer_size;
- u->downstream_buf.pos = p;
- u->downstream_buf.last = p;
-
- if (u->proxy_protocol
#if (NGX_STREAM_SSL)
- && pscf->ssl == NULL
+ u->ssl_name = uscf->host;
#endif
- && pscf->buffer_size >= NGX_PROXY_PROTOCOL_MAX_HEADER)
+
+ if (uscf->peer.init(s, uscf) != NGX_OK) {
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ u->peer.start_time = ngx_current_msec;
+
+ if (pscf->next_upstream_tries
+ && u->peer.tries > pscf->next_upstream_tries)
{
- /* optimization for a typical case */
+ u->peer.tries = pscf->next_upstream_tries;
+ }
- ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
- "stream proxy send PROXY protocol header");
+ ngx_stream_proxy_connect(s);
+}
- p = ngx_proxy_protocol_write(c, u->downstream_buf.last,
- u->downstream_buf.end);
- if (p == NULL) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
- return;
+
+static ngx_int_t
+ngx_stream_proxy_eval(ngx_stream_session_t *s,
+ ngx_stream_proxy_srv_conf_t *pscf)
+{
+ ngx_str_t host;
+ ngx_url_t url;
+ ngx_stream_upstream_t *u;
+
+ if (ngx_stream_complex_value(s, pscf->upstream_value, &host) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ ngx_memzero(&url, sizeof(ngx_url_t));
+
+ url.url = host;
+ url.no_resolve = 1;
+
+ if (ngx_parse_url(s->connection->pool, &url) != NGX_OK) {
+ if (url.err) {
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+ "%s in upstream \"%V\"", url.err, &url.url);
}
- u->downstream_buf.last = p;
- u->proxy_protocol = 0;
+ return NGX_ERROR;
}
- if (c->read->ready) {
- ngx_post_event(c->read, &ngx_posted_events);
+ u = s->upstream;
+
+ u->resolved = ngx_pcalloc(s->connection->pool,
+ sizeof(ngx_stream_upstream_resolved_t));
+ if (u->resolved == NULL) {
+ return NGX_ERROR;
}
- ngx_stream_proxy_connect(s);
+ if (url.addrs && url.addrs[0].sockaddr) {
+ u->resolved->sockaddr = url.addrs[0].sockaddr;
+ u->resolved->socklen = url.addrs[0].socklen;
+ u->resolved->naddrs = 1;
+ u->resolved->host = url.addrs[0].name;
+
+ } else {
+ u->resolved->host = url.host;
+ }
+
+ u->resolved->port = url.port;
+ u->resolved->no_port = url.no_port;
+
+ return NGX_OK;
}
@@ -446,12 +621,9 @@
ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u,
ngx_stream_upstream_local_t *local)
{
- ngx_addr_t *addr;
- ngx_connection_t *c;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
+ ngx_int_t rc;
+ ngx_str_t val;
+ ngx_addr_t *addr;
if (local == NULL) {
u->peer.local = NULL;
@@ -462,45 +634,36 @@
u->peer.transparent = local->transparent;
#endif
- if (local->addr) {
+ if (local->value == NULL) {
u->peer.local = local->addr;
return NGX_OK;
}
- /* $remote_addr */
+ if (ngx_stream_complex_value(s, local->value, &val) != NGX_OK) {
+ return NGX_ERROR;
+ }
- c = s->connection;
+ if (val.len == 0) {
+ return NGX_OK;
+ }
- addr = ngx_palloc(c->pool, sizeof(ngx_addr_t));
+ addr = ngx_palloc(s->connection->pool, sizeof(ngx_addr_t));
if (addr == NULL) {
return NGX_ERROR;
}
- addr->socklen = c->socklen;
-
- addr->sockaddr = ngx_palloc(c->pool, addr->socklen);
- if (addr->sockaddr == NULL) {
+ rc = ngx_parse_addr_port(s->connection->pool, addr, val.data, val.len);
+ if (rc == NGX_ERROR) {
return NGX_ERROR;
}
- ngx_memcpy(addr->sockaddr, c->sockaddr, c->socklen);
-
- switch (addr->sockaddr->sa_family) {
-
- case AF_INET:
- sin = (struct sockaddr_in *) addr->sockaddr;
- sin->sin_port = 0;
- break;
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) addr->sockaddr;
- sin6->sin6_port = 0;
- break;
-#endif
+ if (rc != NGX_OK) {
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+ "invalid local address \"%V\"", &val);
+ return NGX_OK;
}
- addr->name = c->addr_text;
+ addr->name = val;
u->peer.local = addr;
return NGX_OK;
@@ -521,18 +684,36 @@
u = s->upstream;
+ if (u->state) {
+ u->state->response_time = ngx_current_msec - u->state->response_time;
+ }
+
+ u->state = ngx_array_push(s->upstream_states);
+ if (u->state == NULL) {
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ ngx_memzero(u->state, sizeof(ngx_stream_upstream_state_t));
+
+ u->state->connect_time = (ngx_msec_t) -1;
+ u->state->first_byte_time = (ngx_msec_t) -1;
+ u->state->response_time = ngx_current_msec;
+
rc = ngx_event_connect_peer(&u->peer);
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "proxy connect: %i", rc);
if (rc == NGX_ERROR) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
+ u->state->peer = u->peer.name;
+
if (rc == NGX_BUSY) {
ngx_log_error(NGX_LOG_ERR, c->log, 0, "no live upstreams");
- ngx_stream_proxy_finalize(s, NGX_DECLINED);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
return;
}
@@ -640,12 +821,14 @@
}
}
+ u->state->connect_time = ngx_current_msec - u->state->response_time;
+
c->log->action = "proxying connection";
if (u->upstream_buf.start == NULL) {
p = ngx_pnalloc(c->pool, pscf->buffer_size);
if (p == NULL) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
@@ -695,7 +878,7 @@
p = ngx_proxy_protocol_write(c, buf, buf + NGX_PROXY_PROTOCOL_MAX_HEADER);
if (p == NULL) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return NGX_ERROR;
}
@@ -709,7 +892,7 @@
if (n == NGX_AGAIN) {
if (ngx_handle_write_event(pc->write, 0) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return NGX_ERROR;
}
@@ -723,7 +906,7 @@
}
if (n == NGX_ERROR) {
- ngx_stream_proxy_finalize(s, NGX_DECLINED);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
return NGX_ERROR;
}
@@ -739,7 +922,7 @@
ngx_log_error(NGX_LOG_ERR, c->log, 0,
"could not send PROXY protocol header at once");
- ngx_stream_proxy_finalize(s, NGX_DECLINED);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return NGX_ERROR;
}
@@ -791,20 +974,20 @@
if (ngx_ssl_create_connection(pscf->ssl, pc, NGX_SSL_BUFFER|NGX_SSL_CLIENT)
!= NGX_OK)
{
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
if (pscf->ssl_server_name || pscf->ssl_verify) {
if (ngx_stream_proxy_ssl_name(s) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
}
if (pscf->ssl_session_reuse) {
if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
}
@@ -893,10 +1076,13 @@
u = s->upstream;
- name = pscf->ssl_name;
+ if (pscf->ssl_name) {
+ if (ngx_stream_complex_value(s, pscf->ssl_name, &name) != NGX_OK) {
+ return NGX_ERROR;
+ }
- if (name.len == 0) {
- name = pscf->upstream->host;
+ } else {
+ name = u->ssl_name;
}
if (name.len == 0) {
@@ -986,6 +1172,75 @@
static void
+ngx_stream_proxy_resolve_handler(ngx_resolver_ctx_t *ctx)
+{
+ ngx_stream_session_t *s;
+ ngx_stream_upstream_t *u;
+ ngx_stream_proxy_srv_conf_t *pscf;
+ ngx_stream_upstream_resolved_t *ur;
+
+ s = ctx->data;
+
+ u = s->upstream;
+ ur = u->resolved;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "stream upstream resolve");
+
+ if (ctx->state) {
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+ "%V could not be resolved (%i: %s)",
+ &ctx->name, ctx->state,
+ ngx_resolver_strerror(ctx->state));
+
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ ur->naddrs = ctx->naddrs;
+ ur->addrs = ctx->addrs;
+
+#if (NGX_DEBUG)
+ {
+ u_char text[NGX_SOCKADDR_STRLEN];
+ ngx_str_t addr;
+ ngx_uint_t i;
+
+ addr.data = text;
+
+ for (i = 0; i < ctx->naddrs; i++) {
+ addr.len = ngx_sock_ntop(ur->addrs[i].sockaddr, ur->addrs[i].socklen,
+ text, NGX_SOCKADDR_STRLEN, 0);
+
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "name was resolved to %V", &addr);
+ }
+ }
+#endif
+
+ if (ngx_stream_upstream_create_round_robin_peer(s, ur) != NGX_OK) {
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ ngx_resolve_name_done(ctx);
+ ur->ctx = NULL;
+
+ u->peer.start_time = ngx_current_msec;
+
+ pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
+
+ if (pscf->next_upstream_tries
+ && u->peer.tries > pscf->next_upstream_tries)
+ {
+ u->peer.tries = pscf->next_upstream_tries;
+ }
+
+ ngx_stream_proxy_connect(s);
+}
+
+
+static void
ngx_stream_proxy_upstream_handler(ngx_event_t *ev)
{
ngx_stream_proxy_process_connection(ev, !ev->write);
@@ -1017,7 +1272,8 @@
if (!ev->ready) {
if (ngx_handle_read_event(ev, 0) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s,
+ NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
@@ -1051,7 +1307,7 @@
}
ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out");
- ngx_stream_proxy_finalize(s, NGX_DECLINED);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
return;
}
@@ -1061,7 +1317,7 @@
"stream connection delayed");
if (ngx_handle_read_event(ev, 0) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
}
return;
@@ -1179,7 +1435,7 @@
c->log->handler = handler;
- ngx_stream_proxy_finalize(s, NGX_OK);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
return;
}
@@ -1221,7 +1477,7 @@
return;
}
- ngx_stream_proxy_finalize(s, NGX_DECLINED);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
return;
}
@@ -1272,6 +1528,13 @@
}
}
+ if (from_upstream) {
+ if (u->state->first_byte_time == (ngx_msec_t) -1) {
+ u->state->first_byte_time = ngx_current_msec
+ - u->state->response_time;
+ }
+ }
+
if (c->type == SOCK_DGRAM && ++u->responses == pscf->responses)
{
src->read->ready = 0;
@@ -1312,20 +1575,20 @@
c->log->handler = handler;
- ngx_stream_proxy_finalize(s, NGX_OK);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
return;
}
flags = src->read->eof ? NGX_CLOSE_EVENT : 0;
if (!src->shared && ngx_handle_read_event(src->read, flags) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
if (dst) {
if (!dst->shared && ngx_handle_write_event(dst->write, 0) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
@@ -1365,7 +1628,7 @@
|| !pscf->next_upstream
|| (timeout && ngx_current_msec - u->peer.start_time >= timeout))
{
- ngx_stream_proxy_finalize(s, NGX_DECLINED);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
return;
}
@@ -1384,6 +1647,9 @@
}
#endif
+ u->state->bytes_received = u->received;
+ u->state->bytes_sent = pc->sent;
+
ngx_close_connection(pc);
u->peer.connection = NULL;
}
@@ -1393,7 +1659,7 @@
static void
-ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_int_t rc)
+ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_uint_t rc)
{
ngx_connection_t *pc;
ngx_stream_upstream_t *u;
@@ -1407,13 +1673,27 @@
goto noupstream;
}
+ if (u->resolved && u->resolved->ctx) {
+ ngx_resolve_name_done(u->resolved->ctx);
+ u->resolved->ctx = NULL;
+ }
+
+ pc = u->peer.connection;
+
+ if (u->state) {
+ u->state->response_time = ngx_current_msec - u->state->response_time;
+
+ if (pc) {
+ u->state->bytes_received = u->received;
+ u->state->bytes_sent = pc->sent;
+ }
+ }
+
if (u->peer.free && u->peer.sockaddr) {
u->peer.free(&u->peer, u->peer.data, 0);
u->peer.sockaddr = NULL;
}
- pc = u->peer.connection;
-
if (pc) {
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
"close stream proxy upstream connection: %d", pc->fd);
@@ -1431,7 +1711,7 @@
noupstream:
- ngx_stream_close_connection(s->connection);
+ ngx_stream_finalize_session(s, rc);
}
@@ -1481,7 +1761,7 @@
*
* conf->ssl_protocols = 0;
* conf->ssl_ciphers = { 0, NULL };
- * conf->ssl_name = { 0, NULL };
+ * conf->ssl_name = NULL;
* conf->ssl_trusted_certificate = { 0, NULL };
* conf->ssl_crl = { 0, NULL };
* conf->ssl_certificate = { 0, NULL };
@@ -1489,6 +1769,7 @@
*
* conf->ssl = NULL;
* conf->upstream = NULL;
+ * conf->upstream_value = NULL;
*/
conf->connect_timeout = NGX_CONF_UNSET_MSEC;
@@ -1565,7 +1846,9 @@
ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, "DEFAULT");
- ngx_conf_merge_str_value(conf->ssl_name, prev->ssl_name, "");
+ if (conf->ssl_name == NULL) {
+ conf->ssl_name = prev->ssl_name;
+ }
ngx_conf_merge_value(conf->ssl_server_name, prev->ssl_server_name, 0);
@@ -1640,13 +1923,7 @@
}
}
- if (SSL_CTX_set_cipher_list(pscf->ssl->ctx,
- (const char *) pscf->ssl_ciphers.data)
- == 0)
- {
- ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
- "SSL_CTX_set_cipher_list(\"%V\") failed",
- &pscf->ssl_ciphers);
+ if (ngx_ssl_ciphers(cf, pscf->ssl, &pscf->ssl_ciphers, 0) != NGX_OK) {
return NGX_ERROR;
}
@@ -1681,11 +1958,13 @@
{
ngx_stream_proxy_srv_conf_t *pscf = conf;
- ngx_url_t u;
- ngx_str_t *value, *url;
- ngx_stream_core_srv_conf_t *cscf;
+ ngx_url_t u;
+ ngx_str_t *value, *url;
+ ngx_stream_complex_value_t cv;
+ ngx_stream_core_srv_conf_t *cscf;
+ ngx_stream_compile_complex_value_t ccv;
- if (pscf->upstream) {
+ if (pscf->upstream || pscf->upstream_value) {
return "is duplicate";
}
@@ -1697,6 +1976,28 @@
url = &value[1];
+ ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = url;
+ ccv.complex_value = &cv;
+
+ if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (cv.lengths) {
+ pscf->upstream_value = ngx_palloc(cf->pool,
+ sizeof(ngx_stream_complex_value_t));
+ if (pscf->upstream_value == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *pscf->upstream_value = cv;
+
+ return NGX_CONF_OK;
+ }
+
ngx_memzero(&u, sizeof(ngx_url_t));
u.url = *url;
@@ -1716,9 +2017,11 @@
{
ngx_stream_proxy_srv_conf_t *pscf = conf;
- ngx_int_t rc;
- ngx_str_t *value;
- ngx_stream_upstream_local_t *local;
+ ngx_int_t rc;
+ ngx_str_t *value;
+ ngx_stream_complex_value_t cv;
+ ngx_stream_upstream_local_t *local;
+ ngx_stream_compile_complex_value_t ccv;
if (pscf->local != NGX_CONF_UNSET_PTR) {
return "is duplicate";
@@ -1731,20 +2034,39 @@
return NGX_CONF_OK;
}
- local = ngx_palloc(cf->pool, sizeof(ngx_stream_upstream_local_t));
+ ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &value[1];
+ ccv.complex_value = &cv;
+
+ if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ local = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_local_t));
if (local == NULL) {
return NGX_CONF_ERROR;
}
pscf->local = local;
- if (ngx_strcmp(value[1].data, "$remote_addr") != 0) {
+ if (cv.lengths) {
+ local->value = ngx_palloc(cf->pool, sizeof(ngx_stream_complex_value_t));
+ if (local->value == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *local->value = cv;
+
+ } else {
local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
if (local->addr == NULL) {
return NGX_CONF_ERROR;
}
- rc = ngx_parse_addr(cf->pool, local->addr, value[1].data, value[1].len);
+ rc = ngx_parse_addr_port(cf->pool, local->addr, value[1].data,
+ value[1].len);
switch (rc) {
case NGX_OK:
@@ -1765,7 +2087,6 @@
if (ngx_strcmp(value[2].data, "transparent") == 0) {
#if (NGX_HAVE_TRANSPARENT_PROXY)
local->transparent = 1;
-
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"transparent proxying is not supported "
|
[-]
[+]
|
Added |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_realip_module.c
^
|
@@ -0,0 +1,342 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_stream.h>
+
+
+typedef struct {
+ ngx_array_t *from; /* array of ngx_cidr_t */
+} ngx_stream_realip_srv_conf_t;
+
+
+typedef struct {
+ struct sockaddr *sockaddr;
+ socklen_t socklen;
+ ngx_str_t addr_text;
+} ngx_stream_realip_ctx_t;
+
+
+static ngx_int_t ngx_stream_realip_handler(ngx_stream_session_t *s);
+static ngx_int_t ngx_stream_realip_set_addr(ngx_stream_session_t *s,
+ ngx_addr_t *addr);
+static char *ngx_stream_realip_from(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static void *ngx_stream_realip_create_srv_conf(ngx_conf_t *cf);
+static char *ngx_stream_realip_merge_srv_conf(ngx_conf_t *cf, void *parent,
+ void *child);
+static ngx_int_t ngx_stream_realip_add_variables(ngx_conf_t *cf);
+static ngx_int_t ngx_stream_realip_init(ngx_conf_t *cf);
+
+
+static ngx_int_t ngx_stream_realip_remote_addr_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_realip_remote_port_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+
+
+static ngx_command_t ngx_stream_realip_commands[] = {
+
+ { ngx_string("set_real_ip_from"),
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_stream_realip_from,
+ NGX_STREAM_SRV_CONF_OFFSET,
+ 0,
+ NULL },
+
+ ngx_null_command
+};
+
+
+static ngx_stream_module_t ngx_stream_realip_module_ctx = {
+ ngx_stream_realip_add_variables, /* preconfiguration */
+ ngx_stream_realip_init, /* postconfiguration */
+
+ NULL, /* create main configuration */
+ NULL, /* init main configuration */
+
+ ngx_stream_realip_create_srv_conf, /* create server configuration */
+ ngx_stream_realip_merge_srv_conf /* merge server configuration */
+};
+
+
+ngx_module_t ngx_stream_realip_module = {
+ NGX_MODULE_V1,
+ &ngx_stream_realip_module_ctx, /* module context */
+ ngx_stream_realip_commands, /* module directives */
+ NGX_STREAM_MODULE, /* module type */
+ NULL, /* init master */
+ NULL, /* init module */
+ NULL, /* init process */
+ NULL, /* init thread */
+ NULL, /* exit thread */
+ NULL, /* exit process */
+ NULL, /* exit master */
+ NGX_MODULE_V1_PADDING
+};
+
+
+static ngx_stream_variable_t ngx_stream_realip_vars[] = {
+
+ { ngx_string("realip_remote_addr"), NULL,
+ ngx_stream_realip_remote_addr_variable, 0, 0, 0 },
+
+ { ngx_string("realip_remote_port"), NULL,
+ ngx_stream_realip_remote_port_variable, 0, 0, 0 },
+
+ { ngx_null_string, NULL, NULL, 0, 0, 0 }
+};
+
+
+static ngx_int_t
+ngx_stream_realip_handler(ngx_stream_session_t *s)
+{
+ ngx_addr_t addr;
+ ngx_connection_t *c;
+ ngx_stream_realip_srv_conf_t *rscf;
+
+ rscf = ngx_stream_get_module_srv_conf(s, ngx_stream_realip_module);
+
+ if (rscf->from == NULL) {
+ return NGX_DECLINED;
+ }
+
+ c = s->connection;
+
+ if (c->proxy_protocol_addr.len == 0) {
+ return NGX_DECLINED;
+ }
+
+ if (ngx_cidr_match(c->sockaddr, rscf->from) != NGX_OK) {
+ return NGX_DECLINED;
+ }
+
+ if (ngx_parse_addr(c->pool, &addr, c->proxy_protocol_addr.data,
+ c->proxy_protocol_addr.len)
+ != NGX_OK)
+ {
+ return NGX_DECLINED;
+ }
+
+ ngx_inet_set_port(addr.sockaddr, c->proxy_protocol_port);
+
+ return ngx_stream_realip_set_addr(s, &addr);
+}
+
+
+static ngx_int_t
+ngx_stream_realip_set_addr(ngx_stream_session_t *s, ngx_addr_t *addr)
+{
+ size_t len;
+ u_char *p;
+ u_char text[NGX_SOCKADDR_STRLEN];
+ ngx_connection_t *c;
+ ngx_stream_realip_ctx_t *ctx;
+
+ c = s->connection;
+
+ ctx = ngx_palloc(c->pool, sizeof(ngx_stream_realip_ctx_t));
+ if (ctx == NULL) {
+ return NGX_ERROR;
+ }
+
+ len = ngx_sock_ntop(addr->sockaddr, addr->socklen, text,
+ NGX_SOCKADDR_STRLEN, 0);
+ if (len == 0) {
+ return NGX_ERROR;
+ }
+
+ p = ngx_pnalloc(c->pool, len);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(p, text, len);
+
+ ngx_stream_set_ctx(s, ctx, ngx_stream_realip_module);
+
+ ctx->sockaddr = c->sockaddr;
+ ctx->socklen = c->socklen;
+ ctx->addr_text = c->addr_text;
+
+ c->sockaddr = addr->sockaddr;
+ c->socklen = addr->socklen;
+ c->addr_text.len = len;
+ c->addr_text.data = p;
+
+ return NGX_DECLINED;
+}
+
+
+static char *
+ngx_stream_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_stream_realip_srv_conf_t *rscf = conf;
+
+ ngx_int_t rc;
+ ngx_str_t *value;
+ ngx_cidr_t *cidr;
+
+ value = cf->args->elts;
+
+ if (rscf->from == NULL) {
+ rscf->from = ngx_array_create(cf->pool, 2,
+ sizeof(ngx_cidr_t));
+ if (rscf->from == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ cidr = ngx_array_push(rscf->from);
+ if (cidr == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+#if (NGX_HAVE_UNIX_DOMAIN)
+
+ if (ngx_strcmp(value[1].data, "unix:") == 0) {
+ cidr->family = AF_UNIX;
+ return NGX_CONF_OK;
+ }
+
+#endif
+
+ rc = ngx_ptocidr(&value[1], cidr);
+
+ if (rc == NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
+ &value[1]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (rc == NGX_DONE) {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "low address bits of %V are meaningless", &value[1]);
+ }
+
+ return NGX_CONF_OK;
+}
+
+
+static void *
+ngx_stream_realip_create_srv_conf(ngx_conf_t *cf)
+{
+ ngx_stream_realip_srv_conf_t *conf;
+
+ conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_realip_srv_conf_t));
+ if (conf == NULL) {
+ return NULL;
+ }
+
+ /*
+ * set by ngx_pcalloc():
+ *
+ * conf->from = NULL;
+ */
+
+ return conf;
+}
+
+
+static char *
+ngx_stream_realip_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
+{
+ ngx_stream_realip_srv_conf_t *prev = parent;
+ ngx_stream_realip_srv_conf_t *conf = child;
+
+ if (conf->from == NULL) {
+ conf->from = prev->from;
+ }
+
+ return NGX_CONF_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_realip_add_variables(ngx_conf_t *cf)
+{
+ ngx_stream_variable_t *var, *v;
+
+ for (v = ngx_stream_realip_vars; v->name.len; v++) {
+ var = ngx_stream_add_variable(cf, &v->name, v->flags);
+ if (var == NULL) {
+ return NGX_ERROR;
+ }
+
+ var->get_handler = v->get_handler;
+ var->data = v->data;
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_realip_init(ngx_conf_t *cf)
+{
+ ngx_stream_core_main_conf_t *cmcf;
+
+ cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);
+
+ cmcf->realip_handler = ngx_stream_realip_handler;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_realip_remote_addr_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ ngx_str_t *addr_text;
+ ngx_stream_realip_ctx_t *ctx;
+
+ ctx = ngx_stream_get_module_ctx(s, ngx_stream_realip_module);
+
+ addr_text = ctx ? &ctx->addr_text : &s->connection->addr_text;
+
+ v->len = addr_text->len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = addr_text->data;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_realip_remote_port_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ ngx_uint_t port;
+ struct sockaddr *sa;
+ ngx_stream_realip_ctx_t *ctx;
+
+ ctx = ngx_stream_get_module_ctx(s, ngx_stream_realip_module);
+
+ sa = ctx ? ctx->sockaddr : s->connection->sockaddr;
+
+ v->len = 0;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ v->data = ngx_pnalloc(s->connection->pool, sizeof("65535") - 1);
+ if (v->data == NULL) {
+ return NGX_ERROR;
+ }
+
+ port = ngx_inet_get_port(sa);
+
+ if (port > 0 && port < 65536) {
+ v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
+ }
+
+ return NGX_OK;
+}
|
[-]
[+]
|
Added |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_return_module.c
^
|
@@ -0,0 +1,207 @@
+
+/*
+ * Copyright (C) Roman Arutyunyan
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_stream.h>
+
+
+typedef struct {
+ ngx_stream_complex_value_t text;
+} ngx_stream_return_srv_conf_t;
+
+
+typedef struct {
+ ngx_buf_t buf;
+} ngx_stream_return_ctx_t;
+
+
+static void ngx_stream_return_handler(ngx_stream_session_t *s);
+static void ngx_stream_return_write_handler(ngx_event_t *ev);
+
+static void *ngx_stream_return_create_srv_conf(ngx_conf_t *cf);
+static char *ngx_stream_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+
+
+static ngx_command_t ngx_stream_return_commands[] = {
+
+ { ngx_string("return"),
+ NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_stream_return,
+ NGX_STREAM_SRV_CONF_OFFSET,
+ 0,
+ NULL },
+
+ ngx_null_command
+};
+
+
+static ngx_stream_module_t ngx_stream_return_module_ctx = {
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
+
+ NULL, /* create main configuration */
+ NULL, /* init main configuration */
+
+ ngx_stream_return_create_srv_conf, /* create server configuration */
+ NULL /* merge server configuration */
+};
+
+
+ngx_module_t ngx_stream_return_module = {
+ NGX_MODULE_V1,
+ &ngx_stream_return_module_ctx, /* module context */
+ ngx_stream_return_commands, /* module directives */
+ NGX_STREAM_MODULE, /* module type */
+ NULL, /* init master */
+ NULL, /* init module */
+ NULL, /* init process */
+ NULL, /* init thread */
+ NULL, /* exit thread */
+ NULL, /* exit process */
+ NULL, /* exit master */
+ NGX_MODULE_V1_PADDING
+};
+
+
+static void
+ngx_stream_return_handler(ngx_stream_session_t *s)
+{
+ ngx_str_t text;
+ ngx_connection_t *c;
+ ngx_stream_return_ctx_t *ctx;
+ ngx_stream_return_srv_conf_t *rscf;
+
+ c = s->connection;
+
+ c->log->action = "returning text";
+
+ rscf = ngx_stream_get_module_srv_conf(s, ngx_stream_return_module);
+
+ if (ngx_stream_complex_value(s, &rscf->text, &text) != NGX_OK) {
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
+ "stream return text: \"%V\"", &text);
+
+ if (text.len == 0) {
+ ngx_stream_finalize_session(s, NGX_STREAM_OK);
+ return;
+ }
+
+ ctx = ngx_pcalloc(c->pool, sizeof(ngx_stream_return_ctx_t));
+ if (ctx == NULL) {
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ ngx_stream_set_ctx(s, ctx, ngx_stream_return_module);
+
+ ctx->buf.pos = text.data;
+ ctx->buf.last = text.data + text.len;
+
+ c->write->handler = ngx_stream_return_write_handler;
+
+ ngx_stream_return_write_handler(c->write);
+}
+
+
+static void
+ngx_stream_return_write_handler(ngx_event_t *ev)
+{
+ ssize_t n;
+ ngx_buf_t *b;
+ ngx_connection_t *c;
+ ngx_stream_session_t *s;
+ ngx_stream_return_ctx_t *ctx;
+
+ c = ev->data;
+ s = c->data;
+
+ if (ev->timedout) {
+ ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out");
+ ngx_stream_finalize_session(s, NGX_STREAM_OK);
+ return;
+ }
+
+ if (ev->ready) {
+ ctx = ngx_stream_get_module_ctx(s, ngx_stream_return_module);
+
+ b = &ctx->buf;
+
+ n = c->send(c, b->pos, b->last - b->pos);
+ if (n == NGX_ERROR) {
+ ngx_stream_finalize_session(s, NGX_STREAM_OK);
+ return;
+ }
+
+ if (n > 0) {
+ b->pos += n;
+
+ if (b->pos == b->last) {
+ ngx_stream_finalize_session(s, NGX_STREAM_OK);
+ return;
+ }
+ }
+ }
+
+ if (ngx_handle_write_event(ev, 0) != NGX_OK) {
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ ngx_add_timer(ev, 5000);
+}
+
+
+static void *
+ngx_stream_return_create_srv_conf(ngx_conf_t *cf)
+{
+ ngx_stream_return_srv_conf_t *conf;
+
+ conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_return_srv_conf_t));
+ if (conf == NULL) {
+ return NULL;
+ }
+
+ return conf;
+}
+
+
+static char *
+ngx_stream_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_stream_return_srv_conf_t *rscf = conf;
+
+ ngx_str_t *value;
+ ngx_stream_core_srv_conf_t *cscf;
+ ngx_stream_compile_complex_value_t ccv;
+
+ if (rscf->text.value.data) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &value[1];
+ ccv.complex_value = &rscf->text;
+
+ if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ cscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_core_module);
+
+ cscf->handler = ngx_stream_return_handler;
+
+ return NGX_CONF_OK;
+}
|
[-]
[+]
|
Added |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_script.c
^
|
@@ -0,0 +1,921 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_stream.h>
+
+
+static ngx_int_t ngx_stream_script_init_arrays(
+ ngx_stream_script_compile_t *sc);
+static ngx_int_t ngx_stream_script_done(ngx_stream_script_compile_t *sc);
+static ngx_int_t ngx_stream_script_add_copy_code(
+ ngx_stream_script_compile_t *sc, ngx_str_t *value, ngx_uint_t last);
+static ngx_int_t ngx_stream_script_add_var_code(
+ ngx_stream_script_compile_t *sc, ngx_str_t *name);
+#if (NGX_PCRE)
+static ngx_int_t ngx_stream_script_add_capture_code(
+ ngx_stream_script_compile_t *sc, ngx_uint_t n);
+#endif
+static ngx_int_t ngx_stream_script_add_full_name_code(
+ ngx_stream_script_compile_t *sc);
+static size_t ngx_stream_script_full_name_len_code(
+ ngx_stream_script_engine_t *e);
+static void ngx_stream_script_full_name_code(ngx_stream_script_engine_t *e);
+
+
+#define ngx_stream_script_exit (u_char *) &ngx_stream_script_exit_code
+
+static uintptr_t ngx_stream_script_exit_code = (uintptr_t) NULL;
+
+
+void
+ngx_stream_script_flush_complex_value(ngx_stream_session_t *s,
+ ngx_stream_complex_value_t *val)
+{
+ ngx_uint_t *index;
+
+ index = val->flushes;
+
+ if (index) {
+ while (*index != (ngx_uint_t) -1) {
+
+ if (s->variables[*index].no_cacheable) {
+ s->variables[*index].valid = 0;
+ s->variables[*index].not_found = 0;
+ }
+
+ index++;
+ }
+ }
+}
+
+
+ngx_int_t
+ngx_stream_complex_value(ngx_stream_session_t *s,
+ ngx_stream_complex_value_t *val, ngx_str_t *value)
+{
+ size_t len;
+ ngx_stream_script_code_pt code;
+ ngx_stream_script_engine_t e;
+ ngx_stream_script_len_code_pt lcode;
+
+ if (val->lengths == NULL) {
+ *value = val->value;
+ return NGX_OK;
+ }
+
+ ngx_stream_script_flush_complex_value(s, val);
+
+ ngx_memzero(&e, sizeof(ngx_stream_script_engine_t));
+
+ e.ip = val->lengths;
+ e.session = s;
+ e.flushed = 1;
+
+ len = 0;
+
+ while (*(uintptr_t *) e.ip) {
+ lcode = *(ngx_stream_script_len_code_pt *) e.ip;
+ len += lcode(&e);
+ }
+
+ value->len = len;
+ value->data = ngx_pnalloc(s->connection->pool, len);
+ if (value->data == NULL) {
+ return NGX_ERROR;
+ }
+
+ e.ip = val->values;
+ e.pos = value->data;
+ e.buf = *value;
+
+ while (*(uintptr_t *) e.ip) {
+ code = *(ngx_stream_script_code_pt *) e.ip;
+ code((ngx_stream_script_engine_t *) &e);
+ }
+
+ *value = e.buf;
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_stream_compile_complex_value(ngx_stream_compile_complex_value_t *ccv)
+{
+ ngx_str_t *v;
+ ngx_uint_t i, n, nv, nc;
+ ngx_array_t flushes, lengths, values, *pf, *pl, *pv;
+ ngx_stream_script_compile_t sc;
+
+ v = ccv->value;
+
+ nv = 0;
+ nc = 0;
+
+ for (i = 0; i < v->len; i++) {
+ if (v->data[i] == '$') {
+ if (v->data[i + 1] >= '1' && v->data[i + 1] <= '9') {
+ nc++;
+
+ } else {
+ nv++;
+ }
+ }
+ }
+
+ if ((v->len == 0 || v->data[0] != '$')
+ && (ccv->conf_prefix || ccv->root_prefix))
+ {
+ if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ ccv->conf_prefix = 0;
+ ccv->root_prefix = 0;
+ }
+
+ ccv->complex_value->value = *v;
+ ccv->complex_value->flushes = NULL;
+ ccv->complex_value->lengths = NULL;
+ ccv->complex_value->values = NULL;
+
+ if (nv == 0 && nc == 0) {
+ return NGX_OK;
+ }
+
+ n = nv + 1;
+
+ if (ngx_array_init(&flushes, ccv->cf->pool, n, sizeof(ngx_uint_t))
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ n = nv * (2 * sizeof(ngx_stream_script_copy_code_t)
+ + sizeof(ngx_stream_script_var_code_t))
+ + sizeof(uintptr_t);
+
+ if (ngx_array_init(&lengths, ccv->cf->pool, n, 1) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ n = (nv * (2 * sizeof(ngx_stream_script_copy_code_t)
+ + sizeof(ngx_stream_script_var_code_t))
+ + sizeof(uintptr_t)
+ + v->len
+ + sizeof(uintptr_t) - 1)
+ & ~(sizeof(uintptr_t) - 1);
+
+ if (ngx_array_init(&values, ccv->cf->pool, n, 1) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ pf = &flushes;
+ pl = &lengths;
+ pv = &values;
+
+ ngx_memzero(&sc, sizeof(ngx_stream_script_compile_t));
+
+ sc.cf = ccv->cf;
+ sc.source = v;
+ sc.flushes = &pf;
+ sc.lengths = &pl;
+ sc.values = &pv;
+ sc.complete_lengths = 1;
+ sc.complete_values = 1;
+ sc.zero = ccv->zero;
+ sc.conf_prefix = ccv->conf_prefix;
+ sc.root_prefix = ccv->root_prefix;
+
+ if (ngx_stream_script_compile(&sc) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ if (flushes.nelts) {
+ ccv->complex_value->flushes = flushes.elts;
+ ccv->complex_value->flushes[flushes.nelts] = (ngx_uint_t) -1;
+ }
+
+ ccv->complex_value->lengths = lengths.elts;
+ ccv->complex_value->values = values.elts;
+
+ return NGX_OK;
+}
+
+
+char *
+ngx_stream_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf)
+{
+ char *p = conf;
+
+ ngx_str_t *value;
+ ngx_stream_complex_value_t **cv;
+ ngx_stream_compile_complex_value_t ccv;
+
+ cv = (ngx_stream_complex_value_t **) (p + cmd->offset);
+
+ if (*cv != NULL) {
+ return "duplicate";
+ }
+
+ *cv = ngx_palloc(cf->pool, sizeof(ngx_stream_complex_value_t));
+ if (*cv == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ value = cf->args->elts;
+
+ ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &value[1];
+ ccv.complex_value = *cv;
+
+ if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+}
+
+
+ngx_uint_t
+ngx_stream_script_variables_count(ngx_str_t *value)
+{
+ ngx_uint_t i, n;
+
+ for (n = 0, i = 0; i < value->len; i++) {
+ if (value->data[i] == '$') {
+ n++;
+ }
+ }
+
+ return n;
+}
+
+
+ngx_int_t
+ngx_stream_script_compile(ngx_stream_script_compile_t *sc)
+{
+ u_char ch;
+ ngx_str_t name;
+ ngx_uint_t i, bracket;
+
+ if (ngx_stream_script_init_arrays(sc) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ for (i = 0; i < sc->source->len; /* void */ ) {
+
+ name.len = 0;
+
+ if (sc->source->data[i] == '$') {
+
+ if (++i == sc->source->len) {
+ goto invalid_variable;
+ }
+
+ if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') {
+#if (NGX_PCRE)
+ ngx_uint_t n;
+
+ n = sc->source->data[i] - '0';
+
+ if (ngx_stream_script_add_capture_code(sc, n) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ i++;
+
+ continue;
+#else
+ ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0,
+ "using variable \"$%c\" requires "
+ "PCRE library", sc->source->data[i]);
+ return NGX_ERROR;
+#endif
+ }
+
+ if (sc->source->data[i] == '{') {
+ bracket = 1;
+
+ if (++i == sc->source->len) {
+ goto invalid_variable;
+ }
+
+ name.data = &sc->source->data[i];
+
+ } else {
+ bracket = 0;
+ name.data = &sc->source->data[i];
+ }
+
+ for ( /* void */ ; i < sc->source->len; i++, name.len++) {
+ ch = sc->source->data[i];
+
+ if (ch == '}' && bracket) {
+ i++;
+ bracket = 0;
+ break;
+ }
+
+ if ((ch >= 'A' && ch <= 'Z')
+ || (ch >= 'a' && ch <= 'z')
+ || (ch >= '0' && ch <= '9')
+ || ch == '_')
+ {
+ continue;
+ }
+
+ break;
+ }
+
+ if (bracket) {
+ ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0,
+ "the closing bracket in \"%V\" "
+ "variable is missing", &name);
+ return NGX_ERROR;
+ }
+
+ if (name.len == 0) {
+ goto invalid_variable;
+ }
+
+ sc->variables++;
+
+ if (ngx_stream_script_add_var_code(sc, &name) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ continue;
+ }
+
+ name.data = &sc->source->data[i];
+
+ while (i < sc->source->len) {
+
+ if (sc->source->data[i] == '$') {
+ break;
+ }
+
+ i++;
+ name.len++;
+ }
+
+ sc->size += name.len;
+
+ if (ngx_stream_script_add_copy_code(sc, &name, (i == sc->source->len))
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+ }
+
+ return ngx_stream_script_done(sc);
+
+invalid_variable:
+
+ ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, "invalid variable name");
+
+ return NGX_ERROR;
+}
+
+
+u_char *
+ngx_stream_script_run(ngx_stream_session_t *s, ngx_str_t *value,
+ void *code_lengths, size_t len, void *code_values)
+{
+ ngx_uint_t i;
+ ngx_stream_script_code_pt code;
+ ngx_stream_script_engine_t e;
+ ngx_stream_core_main_conf_t *cmcf;
+ ngx_stream_script_len_code_pt lcode;
+
+ cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module);
+
+ for (i = 0; i < cmcf->variables.nelts; i++) {
+ if (s->variables[i].no_cacheable) {
+ s->variables[i].valid = 0;
+ s->variables[i].not_found = 0;
+ }
+ }
+
+ ngx_memzero(&e, sizeof(ngx_stream_script_engine_t));
+
+ e.ip = code_lengths;
+ e.session = s;
+ e.flushed = 1;
+
+ while (*(uintptr_t *) e.ip) {
+ lcode = *(ngx_stream_script_len_code_pt *) e.ip;
+ len += lcode(&e);
+ }
+
+
+ value->len = len;
+ value->data = ngx_pnalloc(s->connection->pool, len);
+ if (value->data == NULL) {
+ return NULL;
+ }
+
+ e.ip = code_values;
+ e.pos = value->data;
+
+ while (*(uintptr_t *) e.ip) {
+ code = *(ngx_stream_script_code_pt *) e.ip;
+ code((ngx_stream_script_engine_t *) &e);
+ }
+
+ return e.pos;
+}
+
+
+void
+ngx_stream_script_flush_no_cacheable_variables(ngx_stream_session_t *s,
+ ngx_array_t *indices)
+{
+ ngx_uint_t n, *index;
+
+ if (indices) {
+ index = indices->elts;
+ for (n = 0; n < indices->nelts; n++) {
+ if (s->variables[index[n]].no_cacheable) {
+ s->variables[index[n]].valid = 0;
+ s->variables[index[n]].not_found = 0;
+ }
+ }
+ }
+}
+
+
+static ngx_int_t
+ngx_stream_script_init_arrays(ngx_stream_script_compile_t *sc)
+{
+ ngx_uint_t n;
+
+ if (sc->flushes && *sc->flushes == NULL) {
+ n = sc->variables ? sc->variables : 1;
+ *sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t));
+ if (*sc->flushes == NULL) {
+ return NGX_ERROR;
+ }
+ }
+
+ if (*sc->lengths == NULL) {
+ n = sc->variables * (2 * sizeof(ngx_stream_script_copy_code_t)
+ + sizeof(ngx_stream_script_var_code_t))
+ + sizeof(uintptr_t);
+
+ *sc->lengths = ngx_array_create(sc->cf->pool, n, 1);
+ if (*sc->lengths == NULL) {
+ return NGX_ERROR;
+ }
+ }
+
+ if (*sc->values == NULL) {
+ n = (sc->variables * (2 * sizeof(ngx_stream_script_copy_code_t)
+ + sizeof(ngx_stream_script_var_code_t))
+ + sizeof(uintptr_t)
+ + sc->source->len
+ + sizeof(uintptr_t) - 1)
+ & ~(sizeof(uintptr_t) - 1);
+
+ *sc->values = ngx_array_create(sc->cf->pool, n, 1);
+ if (*sc->values == NULL) {
+ return NGX_ERROR;
+ }
+ }
+
+ sc->variables = 0;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_script_done(ngx_stream_script_compile_t *sc)
+{
+ ngx_str_t zero;
+ uintptr_t *code;
+
+ if (sc->zero) {
+
+ zero.len = 1;
+ zero.data = (u_char *) "\0";
+
+ if (ngx_stream_script_add_copy_code(sc, &zero, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+ }
+
+ if (sc->conf_prefix || sc->root_prefix) {
+ if (ngx_stream_script_add_full_name_code(sc) != NGX_OK) {
+ return NGX_ERROR;
+ }
+ }
+
+ if (sc->complete_lengths) {
+ code = ngx_stream_script_add_code(*sc->lengths, sizeof(uintptr_t),
+ NULL);
+ if (code == NULL) {
+ return NGX_ERROR;
+ }
+
+ *code = (uintptr_t) NULL;
+ }
+
+ if (sc->complete_values) {
+ code = ngx_stream_script_add_code(*sc->values, sizeof(uintptr_t),
+ &sc->main);
+ if (code == NULL) {
+ return NGX_ERROR;
+ }
+
+ *code = (uintptr_t) NULL;
+ }
+
+ return NGX_OK;
+}
+
+
+void *
+ngx_stream_script_add_code(ngx_array_t *codes, size_t size, void *code)
+{
+ u_char *elts, **p;
+ void *new;
+
+ elts = codes->elts;
+
+ new = ngx_array_push_n(codes, size);
+ if (new == NULL) {
+ return NULL;
+ }
+
+ if (code) {
+ if (elts != codes->elts) {
+ p = code;
+ *p += (u_char *) codes->elts - elts;
+ }
+ }
+
+ return new;
+}
+
+
+static ngx_int_t
+ngx_stream_script_add_copy_code(ngx_stream_script_compile_t *sc,
+ ngx_str_t *value, ngx_uint_t last)
+{
+ u_char *p;
+ size_t size, len, zero;
+ ngx_stream_script_copy_code_t *code;
+
+ zero = (sc->zero && last);
+ len = value->len + zero;
+
+ code = ngx_stream_script_add_code(*sc->lengths,
+ sizeof(ngx_stream_script_copy_code_t),
+ NULL);
+ if (code == NULL) {
+ return NGX_ERROR;
+ }
+
+ code->code = (ngx_stream_script_code_pt) ngx_stream_script_copy_len_code;
+ code->len = len;
+
+ size = (sizeof(ngx_stream_script_copy_code_t) + len + sizeof(uintptr_t) - 1)
+ & ~(sizeof(uintptr_t) - 1);
+
+ code = ngx_stream_script_add_code(*sc->values, size, &sc->main);
+ if (code == NULL) {
+ return NGX_ERROR;
+ }
+
+ code->code = ngx_stream_script_copy_code;
+ code->len = len;
+
+ p = ngx_cpymem((u_char *) code + sizeof(ngx_stream_script_copy_code_t),
+ value->data, value->len);
+
+ if (zero) {
+ *p = '\0';
+ sc->zero = 0;
+ }
+
+ return NGX_OK;
+}
+
+
+size_t
+ngx_stream_script_copy_len_code(ngx_stream_script_engine_t *e)
+{
+ ngx_stream_script_copy_code_t *code;
+
+ code = (ngx_stream_script_copy_code_t *) e->ip;
+
+ e->ip += sizeof(ngx_stream_script_copy_code_t);
+
+ return code->len;
+}
+
+
+void
+ngx_stream_script_copy_code(ngx_stream_script_engine_t *e)
+{
+ u_char *p;
+ ngx_stream_script_copy_code_t *code;
+
+ code = (ngx_stream_script_copy_code_t *) e->ip;
+
+ p = e->pos;
+
+ if (!e->skip) {
+ e->pos = ngx_copy(p, e->ip + sizeof(ngx_stream_script_copy_code_t),
+ code->len);
+ }
+
+ e->ip += sizeof(ngx_stream_script_copy_code_t)
+ + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1));
+
+ ngx_log_debug2(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0,
+ "stream script copy: \"%*s\"", e->pos - p, p);
+}
+
+
+static ngx_int_t
+ngx_stream_script_add_var_code(ngx_stream_script_compile_t *sc, ngx_str_t *name)
+{
+ ngx_int_t index, *p;
+ ngx_stream_script_var_code_t *code;
+
+ index = ngx_stream_get_variable_index(sc->cf, name);
+
+ if (index == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ if (sc->flushes) {
+ p = ngx_array_push(*sc->flushes);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ *p = index;
+ }
+
+ code = ngx_stream_script_add_code(*sc->lengths,
+ sizeof(ngx_stream_script_var_code_t),
+ NULL);
+ if (code == NULL) {
+ return NGX_ERROR;
+ }
+
+ code->code = (ngx_stream_script_code_pt)
+ ngx_stream_script_copy_var_len_code;
+ code->index = (uintptr_t) index;
+
+ code = ngx_stream_script_add_code(*sc->values,
+ sizeof(ngx_stream_script_var_code_t),
+ &sc->main);
+ if (code == NULL) {
+ return NGX_ERROR;
+ }
+
+ code->code = ngx_stream_script_copy_var_code;
+ code->index = (uintptr_t) index;
+
+ return NGX_OK;
+}
+
+
+size_t
+ngx_stream_script_copy_var_len_code(ngx_stream_script_engine_t *e)
+{
+ ngx_stream_variable_value_t *value;
+ ngx_stream_script_var_code_t *code;
+
+ code = (ngx_stream_script_var_code_t *) e->ip;
+
+ e->ip += sizeof(ngx_stream_script_var_code_t);
+
+ if (e->flushed) {
+ value = ngx_stream_get_indexed_variable(e->session, code->index);
+
+ } else {
+ value = ngx_stream_get_flushed_variable(e->session, code->index);
+ }
+
+ if (value && !value->not_found) {
+ return value->len;
+ }
+
+ return 0;
+}
+
+
+void
+ngx_stream_script_copy_var_code(ngx_stream_script_engine_t *e)
+{
+ u_char *p;
+ ngx_stream_variable_value_t *value;
+ ngx_stream_script_var_code_t *code;
+
+ code = (ngx_stream_script_var_code_t *) e->ip;
+
+ e->ip += sizeof(ngx_stream_script_var_code_t);
+
+ if (!e->skip) {
+
+ if (e->flushed) {
+ value = ngx_stream_get_indexed_variable(e->session, code->index);
+
+ } else {
+ value = ngx_stream_get_flushed_variable(e->session, code->index);
+ }
+
+ if (value && !value->not_found) {
+ p = e->pos;
+ e->pos = ngx_copy(p, value->data, value->len);
+
+ ngx_log_debug2(NGX_LOG_DEBUG_STREAM,
+ e->session->connection->log, 0,
+ "stream script var: \"%*s\"", e->pos - p, p);
+ }
+ }
+}
+
+
+#if (NGX_PCRE)
+
+static ngx_int_t
+ngx_stream_script_add_capture_code(ngx_stream_script_compile_t *sc,
+ ngx_uint_t n)
+{
+ ngx_stream_script_copy_capture_code_t *code;
+
+ code = ngx_stream_script_add_code(*sc->lengths,
+ sizeof(ngx_stream_script_copy_capture_code_t),
+ NULL);
+ if (code == NULL) {
+ return NGX_ERROR;
+ }
+
+ code->code = (ngx_stream_script_code_pt)
+ ngx_stream_script_copy_capture_len_code;
+ code->n = 2 * n;
+
+
+ code = ngx_stream_script_add_code(*sc->values,
+ sizeof(ngx_stream_script_copy_capture_code_t),
+ &sc->main);
+ if (code == NULL) {
+ return NGX_ERROR;
+ }
+
+ code->code = ngx_stream_script_copy_capture_code;
+ code->n = 2 * n;
+
+ if (sc->ncaptures < n) {
+ sc->ncaptures = n;
+ }
+
+ return NGX_OK;
+}
+
+
+size_t
+ngx_stream_script_copy_capture_len_code(ngx_stream_script_engine_t *e)
+{
+ int *cap;
+ ngx_uint_t n;
+ ngx_stream_session_t *s;
+ ngx_stream_script_copy_capture_code_t *code;
+
+ s = e->session;
+
+ code = (ngx_stream_script_copy_capture_code_t *) e->ip;
+
+ e->ip += sizeof(ngx_stream_script_copy_capture_code_t);
+
+ n = code->n;
+
+ if (n < s->ncaptures) {
+ cap = s->captures;
+ return cap[n + 1] - cap[n];
+ }
+
+ return 0;
+}
+
+
+void
+ngx_stream_script_copy_capture_code(ngx_stream_script_engine_t *e)
+{
+ int *cap;
+ u_char *p, *pos;
+ ngx_uint_t n;
+ ngx_stream_session_t *s;
+ ngx_stream_script_copy_capture_code_t *code;
+
+ s = e->session;
+
+ code = (ngx_stream_script_copy_capture_code_t *) e->ip;
+
+ e->ip += sizeof(ngx_stream_script_copy_capture_code_t);
+
+ n = code->n;
+
+ pos = e->pos;
+
+ if (n < s->ncaptures) {
+ cap = s->captures;
+ p = s->captures_data;
+ e->pos = ngx_copy(pos, &p[cap[n]], cap[n + 1] - cap[n]);
+ }
+
+ ngx_log_debug2(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0,
+ "stream script capture: \"%*s\"", e->pos - pos, pos);
+}
+
+#endif
+
+
+static ngx_int_t
+ngx_stream_script_add_full_name_code(ngx_stream_script_compile_t *sc)
+{
+ ngx_stream_script_full_name_code_t *code;
+
+ code = ngx_stream_script_add_code(*sc->lengths,
+ sizeof(ngx_stream_script_full_name_code_t),
+ NULL);
+ if (code == NULL) {
+ return NGX_ERROR;
+ }
+
+ code->code = (ngx_stream_script_code_pt)
+ ngx_stream_script_full_name_len_code;
+ code->conf_prefix = sc->conf_prefix;
+
+ code = ngx_stream_script_add_code(*sc->values,
+ sizeof(ngx_stream_script_full_name_code_t), &sc->main);
+ if (code == NULL) {
+ return NGX_ERROR;
+ }
+
+ code->code = ngx_stream_script_full_name_code;
+ code->conf_prefix = sc->conf_prefix;
+
+ return NGX_OK;
+}
+
+
+static size_t
+ngx_stream_script_full_name_len_code(ngx_stream_script_engine_t *e)
+{
+ ngx_stream_script_full_name_code_t *code;
+
+ code = (ngx_stream_script_full_name_code_t *) e->ip;
+
+ e->ip += sizeof(ngx_stream_script_full_name_code_t);
+
+ return code->conf_prefix ? ngx_cycle->conf_prefix.len:
+ ngx_cycle->prefix.len;
+}
+
+
+static void
+ngx_stream_script_full_name_code(ngx_stream_script_engine_t *e)
+{
+ ngx_stream_script_full_name_code_t *code;
+
+ ngx_str_t value, *prefix;
+
+ code = (ngx_stream_script_full_name_code_t *) e->ip;
+
+ value.data = e->buf.data;
+ value.len = e->pos - e->buf.data;
+
+ prefix = code->conf_prefix ? (ngx_str_t *) &ngx_cycle->conf_prefix:
+ (ngx_str_t *) &ngx_cycle->prefix;
+
+ if (ngx_get_full_name(e->session->connection->pool, prefix, &value)
+ != NGX_OK)
+ {
+ e->ip = ngx_stream_script_exit;
+ return;
+ }
+
+ e->buf = value;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0,
+ "stream script fullname: \"%V\"", &value);
+
+ e->ip += sizeof(ngx_stream_script_full_name_code_t);
+}
|
[-]
[+]
|
Added |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_script.h
^
|
@@ -0,0 +1,127 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_STREAM_SCRIPT_H_INCLUDED_
+#define _NGX_STREAM_SCRIPT_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_stream.h>
+
+
+typedef struct {
+ u_char *ip;
+ u_char *pos;
+ ngx_stream_variable_value_t *sp;
+
+ ngx_str_t buf;
+ ngx_str_t line;
+
+ unsigned flushed:1;
+ unsigned skip:1;
+
+ ngx_stream_session_t *session;
+} ngx_stream_script_engine_t;
+
+
+typedef struct {
+ ngx_conf_t *cf;
+ ngx_str_t *source;
+
+ ngx_array_t **flushes;
+ ngx_array_t **lengths;
+ ngx_array_t **values;
+
+ ngx_uint_t variables;
+ ngx_uint_t ncaptures;
+ ngx_uint_t size;
+
+ void *main;
+
+ unsigned complete_lengths:1;
+ unsigned complete_values:1;
+ unsigned zero:1;
+ unsigned conf_prefix:1;
+ unsigned root_prefix:1;
+} ngx_stream_script_compile_t;
+
+
+typedef struct {
+ ngx_str_t value;
+ ngx_uint_t *flushes;
+ void *lengths;
+ void *values;
+} ngx_stream_complex_value_t;
+
+
+typedef struct {
+ ngx_conf_t *cf;
+ ngx_str_t *value;
+ ngx_stream_complex_value_t *complex_value;
+
+ unsigned zero:1;
+ unsigned conf_prefix:1;
+ unsigned root_prefix:1;
+} ngx_stream_compile_complex_value_t;
+
+
+typedef void (*ngx_stream_script_code_pt) (ngx_stream_script_engine_t *e);
+typedef size_t (*ngx_stream_script_len_code_pt) (ngx_stream_script_engine_t *e);
+
+
+typedef struct {
+ ngx_stream_script_code_pt code;
+ uintptr_t len;
+} ngx_stream_script_copy_code_t;
+
+
+typedef struct {
+ ngx_stream_script_code_pt code;
+ uintptr_t index;
+} ngx_stream_script_var_code_t;
+
+
+typedef struct {
+ ngx_stream_script_code_pt code;
+ uintptr_t n;
+} ngx_stream_script_copy_capture_code_t;
+
+
+typedef struct {
+ ngx_stream_script_code_pt code;
+ uintptr_t conf_prefix;
+} ngx_stream_script_full_name_code_t;
+
+
+void ngx_stream_script_flush_complex_value(ngx_stream_session_t *s,
+ ngx_stream_complex_value_t *val);
+ngx_int_t ngx_stream_complex_value(ngx_stream_session_t *s,
+ ngx_stream_complex_value_t *val, ngx_str_t *value);
+ngx_int_t ngx_stream_compile_complex_value(
+ ngx_stream_compile_complex_value_t *ccv);
+char *ngx_stream_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+
+
+ngx_uint_t ngx_stream_script_variables_count(ngx_str_t *value);
+ngx_int_t ngx_stream_script_compile(ngx_stream_script_compile_t *sc);
+u_char *ngx_stream_script_run(ngx_stream_session_t *s, ngx_str_t *value,
+ void *code_lengths, size_t reserved, void *code_values);
+void ngx_stream_script_flush_no_cacheable_variables(ngx_stream_session_t *s,
+ ngx_array_t *indices);
+
+void *ngx_stream_script_add_code(ngx_array_t *codes, size_t size, void *code);
+
+size_t ngx_stream_script_copy_len_code(ngx_stream_script_engine_t *e);
+void ngx_stream_script_copy_code(ngx_stream_script_engine_t *e);
+size_t ngx_stream_script_copy_var_len_code(ngx_stream_script_engine_t *e);
+void ngx_stream_script_copy_var_code(ngx_stream_script_engine_t *e);
+size_t ngx_stream_script_copy_capture_len_code(ngx_stream_script_engine_t *e);
+void ngx_stream_script_copy_capture_code(ngx_stream_script_engine_t *e);
+
+#endif /* _NGX_STREAM_SCRIPT_H_INCLUDED_ */
|
[-]
[+]
|
Added |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_split_clients_module.c
^
|
@@ -0,0 +1,244 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_stream.h>
+
+
+typedef struct {
+ uint32_t percent;
+ ngx_stream_variable_value_t value;
+} ngx_stream_split_clients_part_t;
+
+
+typedef struct {
+ ngx_stream_complex_value_t value;
+ ngx_array_t parts;
+} ngx_stream_split_clients_ctx_t;
+
+
+static char *ngx_conf_split_clients_block(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static char *ngx_stream_split_clients(ngx_conf_t *cf, ngx_command_t *dummy,
+ void *conf);
+
+static ngx_command_t ngx_stream_split_clients_commands[] = {
+
+ { ngx_string("split_clients"),
+ NGX_STREAM_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE2,
+ ngx_conf_split_clients_block,
+ NGX_STREAM_MAIN_CONF_OFFSET,
+ 0,
+ NULL },
+
+ ngx_null_command
+};
+
+
+static ngx_stream_module_t ngx_stream_split_clients_module_ctx = {
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
+
+ NULL, /* create main configuration */
+ NULL, /* init main configuration */
+
+ NULL, /* create server configuration */
+ NULL /* merge server configuration */
+};
+
+
+ngx_module_t ngx_stream_split_clients_module = {
+ NGX_MODULE_V1,
+ &ngx_stream_split_clients_module_ctx, /* module context */
+ ngx_stream_split_clients_commands, /* module directives */
+ NGX_STREAM_MODULE, /* module type */
+ NULL, /* init master */
+ NULL, /* init module */
+ NULL, /* init process */
+ NULL, /* init thread */
+ NULL, /* exit thread */
+ NULL, /* exit process */
+ NULL, /* exit master */
+ NGX_MODULE_V1_PADDING
+};
+
+
+static ngx_int_t
+ngx_stream_split_clients_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ ngx_stream_split_clients_ctx_t *ctx =
+ (ngx_stream_split_clients_ctx_t *) data;
+
+ uint32_t hash;
+ ngx_str_t val;
+ ngx_uint_t i;
+ ngx_stream_split_clients_part_t *part;
+
+ *v = ngx_stream_variable_null_value;
+
+ if (ngx_stream_complex_value(s, &ctx->value, &val) != NGX_OK) {
+ return NGX_OK;
+ }
+
+ hash = ngx_murmur_hash2(val.data, val.len);
+
+ part = ctx->parts.elts;
+
+ for (i = 0; i < ctx->parts.nelts; i++) {
+
+ ngx_log_debug2(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "stream split: %uD %uD", hash, part[i].percent);
+
+ if (hash < part[i].percent || part[i].percent == 0) {
+ *v = part[i].value;
+ return NGX_OK;
+ }
+ }
+
+ return NGX_OK;
+}
+
+
+static char *
+ngx_conf_split_clients_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ char *rv;
+ uint32_t sum, last;
+ ngx_str_t *value, name;
+ ngx_uint_t i;
+ ngx_conf_t save;
+ ngx_stream_variable_t *var;
+ ngx_stream_split_clients_ctx_t *ctx;
+ ngx_stream_split_clients_part_t *part;
+ ngx_stream_compile_complex_value_t ccv;
+
+ ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_split_clients_ctx_t));
+ if (ctx == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ value = cf->args->elts;
+
+ ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &value[1];
+ ccv.complex_value = &ctx->value;
+
+ if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ name = value[2];
+
+ if (name.data[0] != '$') {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid variable name \"%V\"", &name);
+ return NGX_CONF_ERROR;
+ }
+
+ name.len--;
+ name.data++;
+
+ var = ngx_stream_add_variable(cf, &name, NGX_STREAM_VAR_CHANGEABLE);
+ if (var == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ var->get_handler = ngx_stream_split_clients_variable;
+ var->data = (uintptr_t) ctx;
+
+ if (ngx_array_init(&ctx->parts, cf->pool, 2,
+ sizeof(ngx_stream_split_clients_part_t))
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
+ }
+
+ save = *cf;
+ cf->ctx = ctx;
+ cf->handler = ngx_stream_split_clients;
+ cf->handler_conf = conf;
+
+ rv = ngx_conf_parse(cf, NULL);
+
+ *cf = save;
+
+ if (rv != NGX_CONF_OK) {
+ return rv;
+ }
+
+ sum = 0;
+ last = 0;
+ part = ctx->parts.elts;
+
+ for (i = 0; i < ctx->parts.nelts; i++) {
+ sum = part[i].percent ? sum + part[i].percent : 10000;
+ if (sum > 10000) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "percent total is greater than 100%%");
+ return NGX_CONF_ERROR;
+ }
+
+ if (part[i].percent) {
+ last += part[i].percent * (uint64_t) 0xffffffff / 10000;
+ part[i].percent = last;
+ }
+ }
+
+ return rv;
+}
+
+
+static char *
+ngx_stream_split_clients(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
+{
+ ngx_int_t n;
+ ngx_str_t *value;
+ ngx_stream_split_clients_ctx_t *ctx;
+ ngx_stream_split_clients_part_t *part;
+
+ ctx = cf->ctx;
+ value = cf->args->elts;
+
+ part = ngx_array_push(&ctx->parts);
+ if (part == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (value[0].len == 1 && value[0].data[0] == '*') {
+ part->percent = 0;
+
+ } else {
+ if (value[0].len == 0 || value[0].data[value[0].len - 1] != '%') {
+ goto invalid;
+ }
+
+ n = ngx_atofp(value[0].data, value[0].len - 1, 2);
+ if (n == NGX_ERROR || n == 0) {
+ goto invalid;
+ }
+
+ part->percent = (uint32_t) n;
+ }
+
+ part->value.len = value[1].len;
+ part->value.valid = 1;
+ part->value.no_cacheable = 0;
+ part->value.not_found = 0;
+ part->value.data = value[1].data;
+
+ return NGX_CONF_OK;
+
+invalid:
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid percent value \"%V\"", &value[0]);
+ return NGX_CONF_ERROR;
+}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_ssl_module.c
^
|
@@ -10,10 +10,20 @@
#include <ngx_stream.h>
+typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
+ ngx_pool_t *pool, ngx_str_t *s);
+
+
#define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5"
#define NGX_DEFAULT_ECDH_CURVE "auto"
+static ngx_int_t ngx_stream_ssl_static_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_ssl_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+
+static ngx_int_t ngx_stream_ssl_add_variables(ngx_conf_t *cf);
static void *ngx_stream_ssl_create_conf(ngx_conf_t *cf);
static char *ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent,
void *child);
@@ -132,6 +142,7 @@
static ngx_stream_module_t ngx_stream_ssl_module_ctx = {
+ ngx_stream_ssl_add_variables, /* preconfiguration */
NULL, /* postconfiguration */
NULL, /* create main configuration */
@@ -158,9 +169,112 @@
};
+static ngx_stream_variable_t ngx_stream_ssl_vars[] = {
+
+ { ngx_string("ssl_protocol"), NULL, ngx_stream_ssl_static_variable,
+ (uintptr_t) ngx_ssl_get_protocol, NGX_STREAM_VAR_CHANGEABLE, 0 },
+
+ { ngx_string("ssl_cipher"), NULL, ngx_stream_ssl_static_variable,
+ (uintptr_t) ngx_ssl_get_cipher_name, NGX_STREAM_VAR_CHANGEABLE, 0 },
+
+ { ngx_string("ssl_session_id"), NULL, ngx_stream_ssl_variable,
+ (uintptr_t) ngx_ssl_get_session_id, NGX_STREAM_VAR_CHANGEABLE, 0 },
+
+ { ngx_string("ssl_session_reused"), NULL, ngx_stream_ssl_variable,
+ (uintptr_t) ngx_ssl_get_session_reused, NGX_STREAM_VAR_CHANGEABLE, 0 },
+
+ { ngx_string("ssl_server_name"), NULL, ngx_stream_ssl_variable,
+ (uintptr_t) ngx_ssl_get_server_name, NGX_STREAM_VAR_CHANGEABLE, 0 },
+
+ { ngx_null_string, NULL, NULL, 0, 0, 0 }
+};
+
+
static ngx_str_t ngx_stream_ssl_sess_id_ctx = ngx_string("STREAM");
+static ngx_int_t
+ngx_stream_ssl_static_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data;
+
+ size_t len;
+ ngx_str_t str;
+
+ if (s->connection->ssl) {
+
+ (void) handler(s->connection, NULL, &str);
+
+ v->data = str.data;
+
+ for (len = 0; v->data[len]; len++) { /* void */ }
+
+ v->len = len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ return NGX_OK;
+ }
+
+ v->not_found = 1;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_ssl_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data;
+
+ ngx_str_t str;
+
+ if (s->connection->ssl) {
+
+ if (handler(s->connection, s->connection->pool, &str) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ v->len = str.len;
+ v->data = str.data;
+
+ if (v->len) {
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ return NGX_OK;
+ }
+ }
+
+ v->not_found = 1;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_ssl_add_variables(ngx_conf_t *cf)
+{
+ ngx_stream_variable_t *var, *v;
+
+ for (v = ngx_stream_ssl_vars; v->name.len; v++) {
+ var = ngx_stream_add_variable(cf, &v->name, v->flags);
+ if (var == NULL) {
+ return NGX_ERROR;
+ }
+
+ var->get_handler = v->get_handler;
+ var->data = v->data;
+ }
+
+ return NGX_OK;
+}
+
+
static void *
ngx_stream_ssl_create_conf(ngx_conf_t *cf)
{
@@ -266,24 +380,13 @@
return NGX_CONF_ERROR;
}
- if (SSL_CTX_set_cipher_list(conf->ssl.ctx,
- (const char *) conf->ciphers.data)
- == 0)
+ if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers,
+ conf->prefer_server_ciphers)
+ != NGX_OK)
{
- ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
- "SSL_CTX_set_cipher_list(\"%V\") failed",
- &conf->ciphers);
return NGX_CONF_ERROR;
}
- if (conf->prefer_server_ciphers) {
- SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
- }
-
-#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER)
- SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback);
-#endif
-
if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
return NGX_CONF_ERROR;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_upstream.c
^
|
@@ -10,6 +10,14 @@
#include <ngx_stream.h>
+static ngx_int_t ngx_stream_upstream_add_variables(ngx_conf_t *cf);
+static ngx_int_t ngx_stream_upstream_addr_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_upstream_response_time_variable(
+ ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_upstream_bytes_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+
static char *ngx_stream_upstream(ngx_conf_t *cf, ngx_command_t *cmd,
void *dummy);
static char *ngx_stream_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd,
@@ -39,13 +47,14 @@
static ngx_stream_module_t ngx_stream_upstream_module_ctx = {
+ ngx_stream_upstream_add_variables, /* preconfiguration */
NULL, /* postconfiguration */
ngx_stream_upstream_create_main_conf, /* create main configuration */
ngx_stream_upstream_init_main_conf, /* init main configuration */
NULL, /* create server configuration */
- NULL, /* merge server configuration */
+ NULL /* merge server configuration */
};
@@ -65,6 +74,232 @@
};
+static ngx_stream_variable_t ngx_stream_upstream_vars[] = {
+
+ { ngx_string("upstream_addr"), NULL,
+ ngx_stream_upstream_addr_variable, 0,
+ NGX_STREAM_VAR_NOCACHEABLE, 0 },
+
+ { ngx_string("upstream_bytes_sent"), NULL,
+ ngx_stream_upstream_bytes_variable, 0,
+ NGX_STREAM_VAR_NOCACHEABLE, 0 },
+
+ { ngx_string("upstream_connect_time"), NULL,
+ ngx_stream_upstream_response_time_variable, 2,
+ NGX_STREAM_VAR_NOCACHEABLE, 0 },
+
+ { ngx_string("upstream_first_byte_time"), NULL,
+ ngx_stream_upstream_response_time_variable, 1,
+ NGX_STREAM_VAR_NOCACHEABLE, 0 },
+
+ { ngx_string("upstream_session_time"), NULL,
+ ngx_stream_upstream_response_time_variable, 0,
+ NGX_STREAM_VAR_NOCACHEABLE, 0 },
+
+ { ngx_string("upstream_bytes_received"), NULL,
+ ngx_stream_upstream_bytes_variable, 1,
+ NGX_STREAM_VAR_NOCACHEABLE, 0 },
+
+ { ngx_null_string, NULL, NULL, 0, 0, 0 }
+};
+
+
+static ngx_int_t
+ngx_stream_upstream_add_variables(ngx_conf_t *cf)
+{
+ ngx_stream_variable_t *var, *v;
+
+ for (v = ngx_stream_upstream_vars; v->name.len; v++) {
+ var = ngx_stream_add_variable(cf, &v->name, v->flags);
+ if (var == NULL) {
+ return NGX_ERROR;
+ }
+
+ var->get_handler = v->get_handler;
+ var->data = v->data;
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_upstream_addr_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ u_char *p;
+ size_t len;
+ ngx_uint_t i;
+ ngx_stream_upstream_state_t *state;
+
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ if (s->upstream_states == NULL || s->upstream_states->nelts == 0) {
+ v->not_found = 1;
+ return NGX_OK;
+ }
+
+ len = 0;
+ state = s->upstream_states->elts;
+
+ for (i = 0; i < s->upstream_states->nelts; i++) {
+ if (state[i].peer) {
+ len += state[i].peer->len;
+ }
+
+ len += 2;
+ }
+
+ p = ngx_pnalloc(s->connection->pool, len);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ v->data = p;
+
+ i = 0;
+
+ for ( ;; ) {
+ if (state[i].peer) {
+ p = ngx_cpymem(p, state[i].peer->data, state[i].peer->len);
+ }
+
+ if (++i == s->upstream_states->nelts) {
+ break;
+ }
+
+ *p++ = ',';
+ *p++ = ' ';
+ }
+
+ v->len = p - v->data;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_upstream_bytes_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ u_char *p;
+ size_t len;
+ ngx_uint_t i;
+ ngx_stream_upstream_state_t *state;
+
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ if (s->upstream_states == NULL || s->upstream_states->nelts == 0) {
+ v->not_found = 1;
+ return NGX_OK;
+ }
+
+ len = s->upstream_states->nelts * (NGX_OFF_T_LEN + 2);
+
+ p = ngx_pnalloc(s->connection->pool, len);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ v->data = p;
+
+ i = 0;
+ state = s->upstream_states->elts;
+
+ for ( ;; ) {
+
+ if (data == 1) {
+ p = ngx_sprintf(p, "%O", state[i].bytes_received);
+
+ } else {
+ p = ngx_sprintf(p, "%O", state[i].bytes_sent);
+ }
+
+ if (++i == s->upstream_states->nelts) {
+ break;
+ }
+
+ *p++ = ',';
+ *p++ = ' ';
+ }
+
+ v->len = p - v->data;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_upstream_response_time_variable(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ u_char *p;
+ size_t len;
+ ngx_uint_t i;
+ ngx_msec_int_t ms;
+ ngx_stream_upstream_state_t *state;
+
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ if (s->upstream_states == NULL || s->upstream_states->nelts == 0) {
+ v->not_found = 1;
+ return NGX_OK;
+ }
+
+ len = s->upstream_states->nelts * (NGX_TIME_T_LEN + 4 + 2);
+
+ p = ngx_pnalloc(s->connection->pool, len);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ v->data = p;
+
+ i = 0;
+ state = s->upstream_states->elts;
+
+ for ( ;; ) {
+
+ if (data == 1) {
+ if (state[i].first_byte_time == (ngx_msec_t) -1) {
+ *p++ = '-';
+ goto next;
+ }
+
+ ms = state[i].first_byte_time;
+
+ } else if (data == 2 && state[i].connect_time != (ngx_msec_t) -1) {
+ ms = state[i].connect_time;
+
+ } else {
+ ms = state[i].response_time;
+ }
+
+ ms = ngx_max(ms, 0);
+ p = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000);
+
+ next:
+
+ if (++i == s->upstream_states->nelts) {
+ break;
+ }
+
+ *p++ = ',';
+ *p++ = ' ';
+ }
+
+ v->len = p - v->data;
+
+ return NGX_OK;
+}
+
+
static char *
ngx_stream_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
{
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_upstream.h
^
|
@@ -79,6 +79,32 @@
typedef struct {
+ ngx_msec_t response_time;
+ ngx_msec_t connect_time;
+ ngx_msec_t first_byte_time;
+ off_t bytes_sent;
+ off_t bytes_received;
+
+ ngx_str_t *peer;
+} ngx_stream_upstream_state_t;
+
+
+typedef struct {
+ ngx_str_t host;
+ in_port_t port;
+ ngx_uint_t no_port; /* unsigned no_port:1 */
+
+ ngx_uint_t naddrs;
+ ngx_resolver_addr_t *addrs;
+
+ struct sockaddr *sockaddr;
+ socklen_t socklen;
+
+ ngx_resolver_ctx_t *ctx;
+} ngx_stream_upstream_resolved_t;
+
+
+typedef struct {
ngx_peer_connection_t peer;
ngx_buf_t downstream_buf;
ngx_buf_t upstream_buf;
@@ -88,6 +114,8 @@
#if (NGX_STREAM_SSL)
ngx_str_t ssl_name;
#endif
+ ngx_stream_upstream_resolved_t *resolved;
+ ngx_stream_upstream_state_t *state;
unsigned connected:1;
unsigned proxy_protocol:1;
} ngx_stream_upstream_t;
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_upstream_hash_module.c
^
|
@@ -23,6 +23,7 @@
typedef struct {
+ ngx_stream_complex_value_t key;
ngx_stream_upstream_chash_points_t *points;
} ngx_stream_upstream_hash_srv_conf_t;
@@ -76,13 +77,14 @@
static ngx_stream_module_t ngx_stream_upstream_hash_module_ctx = {
+ NULL, /* preconfiguration */
NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
ngx_stream_upstream_hash_create_conf, /* create server configuration */
- NULL, /* merge server configuration */
+ NULL /* merge server configuration */
};
@@ -140,7 +142,9 @@
hcf = ngx_stream_conf_upstream_srv_conf(us,
ngx_stream_upstream_hash_module);
- hp->key = s->connection->addr_text;
+ if (ngx_stream_complex_value(s, &hcf->key, &hp->key) != NGX_OK) {
+ return NGX_ERROR;
+ }
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
"upstream hash key:\"%V\"", &hp->key);
@@ -615,15 +619,21 @@
static char *
ngx_stream_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- ngx_str_t *value;
- ngx_stream_upstream_srv_conf_t *uscf;
+ ngx_stream_upstream_hash_srv_conf_t *hcf = conf;
+
+ ngx_str_t *value;
+ ngx_stream_upstream_srv_conf_t *uscf;
+ ngx_stream_compile_complex_value_t ccv;
value = cf->args->elts;
- if (ngx_strcmp(value[1].data, "$remote_addr")) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unsupported hash key \"%V\", use $remote_addr",
- &value[1]);
+ ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &value[1];
+ ccv.complex_value = &hcf->key;
+
+ if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
return NGX_CONF_ERROR;
}
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_upstream_least_conn_module.c
^
|
@@ -32,13 +32,14 @@
static ngx_stream_module_t ngx_stream_upstream_least_conn_module_ctx = {
+ NULL, /* preconfiguration */
NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
NULL, /* create server configuration */
- NULL, /* merge server configuration */
+ NULL /* merge server configuration */
};
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_upstream_round_robin.c
^
|
@@ -23,6 +23,10 @@
ngx_peer_connection_t *pc, void *data);
static void ngx_stream_upstream_save_round_robin_peer_session(
ngx_peer_connection_t *pc, void *data);
+static ngx_int_t ngx_stream_upstream_empty_set_session(
+ ngx_peer_connection_t *pc, void *data);
+static void ngx_stream_upstream_empty_save_session(ngx_peer_connection_t *pc,
+ void *data);
#endif
@@ -293,6 +297,123 @@
ngx_int_t
+ngx_stream_upstream_create_round_robin_peer(ngx_stream_session_t *s,
+ ngx_stream_upstream_resolved_t *ur)
+{
+ u_char *p;
+ size_t len;
+ socklen_t socklen;
+ ngx_uint_t i, n;
+ struct sockaddr *sockaddr;
+ ngx_stream_upstream_rr_peer_t *peer, **peerp;
+ ngx_stream_upstream_rr_peers_t *peers;
+ ngx_stream_upstream_rr_peer_data_t *rrp;
+
+ rrp = s->upstream->peer.data;
+
+ if (rrp == NULL) {
+ rrp = ngx_palloc(s->connection->pool,
+ sizeof(ngx_stream_upstream_rr_peer_data_t));
+ if (rrp == NULL) {
+ return NGX_ERROR;
+ }
+
+ s->upstream->peer.data = rrp;
+ }
+
+ peers = ngx_pcalloc(s->connection->pool,
+ sizeof(ngx_stream_upstream_rr_peers_t));
+ if (peers == NULL) {
+ return NGX_ERROR;
+ }
+
+ peer = ngx_pcalloc(s->connection->pool,
+ sizeof(ngx_stream_upstream_rr_peer_t) * ur->naddrs);
+ if (peer == NULL) {
+ return NGX_ERROR;
+ }
+
+ peers->single = (ur->naddrs == 1);
+ peers->number = ur->naddrs;
+ peers->name = &ur->host;
+
+ if (ur->sockaddr) {
+ peer[0].sockaddr = ur->sockaddr;
+ peer[0].socklen = ur->socklen;
+ peer[0].name = ur->host;
+ peer[0].weight = 1;
+ peer[0].effective_weight = 1;
+ peer[0].current_weight = 0;
+ peer[0].max_fails = 1;
+ peer[0].fail_timeout = 10;
+ peers->peer = peer;
+
+ } else {
+ peerp = &peers->peer;
+
+ for (i = 0; i < ur->naddrs; i++) {
+
+ socklen = ur->addrs[i].socklen;
+
+ sockaddr = ngx_palloc(s->connection->pool, socklen);
+ if (sockaddr == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(sockaddr, ur->addrs[i].sockaddr, socklen);
+ ngx_inet_set_port(sockaddr, ur->port);
+
+ p = ngx_pnalloc(s->connection->pool, NGX_SOCKADDR_STRLEN);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1);
+
+ peer[i].sockaddr = sockaddr;
+ peer[i].socklen = socklen;
+ peer[i].name.len = len;
+ peer[i].name.data = p;
+ peer[i].weight = 1;
+ peer[i].effective_weight = 1;
+ peer[i].current_weight = 0;
+ peer[i].max_fails = 1;
+ peer[i].fail_timeout = 10;
+ *peerp = &peer[i];
+ peerp = &peer[i].next;
+ }
+ }
+
+ rrp->peers = peers;
+ rrp->current = NULL;
+
+ if (rrp->peers->number <= 8 * sizeof(uintptr_t)) {
+ rrp->tried = &rrp->data;
+ rrp->data = 0;
+
+ } else {
+ n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
+ / (8 * sizeof(uintptr_t));
+
+ rrp->tried = ngx_pcalloc(s->connection->pool, n * sizeof(uintptr_t));
+ if (rrp->tried == NULL) {
+ return NGX_ERROR;
+ }
+ }
+
+ s->upstream->peer.get = ngx_stream_upstream_get_round_robin_peer;
+ s->upstream->peer.free = ngx_stream_upstream_free_round_robin_peer;
+ s->upstream->peer.tries = ngx_stream_upstream_tries(rrp->peers);
+#if (NGX_STREAM_SSL)
+ s->upstream->peer.set_session = ngx_stream_upstream_empty_set_session;
+ s->upstream->peer.save_session = ngx_stream_upstream_empty_save_session;
+#endif
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
ngx_stream_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
{
ngx_stream_upstream_rr_peer_data_t *rrp = data;
@@ -699,4 +820,18 @@
}
}
+
+static ngx_int_t
+ngx_stream_upstream_empty_set_session(ngx_peer_connection_t *pc, void *data)
+{
+ return NGX_OK;
+}
+
+
+static void
+ngx_stream_upstream_empty_save_session(ngx_peer_connection_t *pc, void *data)
+{
+ return;
+}
+
#endif
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_upstream_round_robin.h
^
|
@@ -130,6 +130,8 @@
ngx_stream_upstream_srv_conf_t *us);
ngx_int_t ngx_stream_upstream_init_round_robin_peer(ngx_stream_session_t *s,
ngx_stream_upstream_srv_conf_t *us);
+ngx_int_t ngx_stream_upstream_create_round_robin_peer(ngx_stream_session_t *s,
+ ngx_stream_upstream_resolved_t *ur);
ngx_int_t ngx_stream_upstream_get_round_robin_peer(ngx_peer_connection_t *pc,
void *data);
void ngx_stream_upstream_free_round_robin_peer(ngx_peer_connection_t *pc,
|
[-]
[+]
|
Changed |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_upstream_zone_module.c
^
|
@@ -32,13 +32,14 @@
static ngx_stream_module_t ngx_stream_upstream_zone_module_ctx = {
+ NULL, /* preconfiguration */
NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
NULL, /* create server configuration */
- NULL, /* merge server configuration */
+ NULL /* merge server configuration */
};
|
[-]
[+]
|
Added |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_variables.c
^
|
@@ -0,0 +1,1106 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_stream.h>
+#include <nginx.h>
+
+
+static ngx_int_t ngx_stream_variable_binary_remote_addr(
+ ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_variable_remote_addr(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_variable_remote_port(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_variable_proxy_protocol_addr(
+ ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_variable_proxy_protocol_port(
+ ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_variable_server_addr(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_variable_server_port(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_variable_bytes(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_variable_session_time(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_variable_status(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_variable_connection(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+
+static ngx_int_t ngx_stream_variable_nginx_version(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_variable_hostname(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_variable_pid(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_variable_msec(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_variable_time_iso8601(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_variable_time_local(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_stream_variable_protocol(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+
+
+static ngx_stream_variable_t ngx_stream_core_variables[] = {
+
+ { ngx_string("binary_remote_addr"), NULL,
+ ngx_stream_variable_binary_remote_addr, 0, 0, 0 },
+
+ { ngx_string("remote_addr"), NULL,
+ ngx_stream_variable_remote_addr, 0, 0, 0 },
+
+ { ngx_string("remote_port"), NULL,
+ ngx_stream_variable_remote_port, 0, 0, 0 },
+
+ { ngx_string("proxy_protocol_addr"), NULL,
+ ngx_stream_variable_proxy_protocol_addr, 0, 0, 0 },
+
+ { ngx_string("proxy_protocol_port"), NULL,
+ ngx_stream_variable_proxy_protocol_port, 0, 0, 0 },
+
+ { ngx_string("server_addr"), NULL,
+ ngx_stream_variable_server_addr, 0, 0, 0 },
+
+ { ngx_string("server_port"), NULL,
+ ngx_stream_variable_server_port, 0, 0, 0 },
+
+ { ngx_string("bytes_sent"), NULL, ngx_stream_variable_bytes,
+ 0, 0, 0 },
+
+ { ngx_string("bytes_received"), NULL, ngx_stream_variable_bytes,
+ 1, 0, 0 },
+
+ { ngx_string("session_time"), NULL, ngx_stream_variable_session_time,
+ 0, NGX_STREAM_VAR_NOCACHEABLE, 0 },
+
+ { ngx_string("status"), NULL, ngx_stream_variable_status,
+ 0, NGX_STREAM_VAR_NOCACHEABLE, 0 },
+
+ { ngx_string("connection"), NULL,
+ ngx_stream_variable_connection, 0, 0, 0 },
+
+ { ngx_string("nginx_version"), NULL, ngx_stream_variable_nginx_version,
+ 0, 0, 0 },
+
+ { ngx_string("hostname"), NULL, ngx_stream_variable_hostname,
+ 0, 0, 0 },
+
+ { ngx_string("pid"), NULL, ngx_stream_variable_pid,
+ 0, 0, 0 },
+
+ { ngx_string("msec"), NULL, ngx_stream_variable_msec,
+ 0, NGX_STREAM_VAR_NOCACHEABLE, 0 },
+
+ { ngx_string("time_iso8601"), NULL, ngx_stream_variable_time_iso8601,
+ 0, NGX_STREAM_VAR_NOCACHEABLE, 0 },
+
+ { ngx_string("time_local"), NULL, ngx_stream_variable_time_local,
+ 0, NGX_STREAM_VAR_NOCACHEABLE, 0 },
+
+ { ngx_string("protocol"), NULL,
+ ngx_stream_variable_protocol, 0, 0, 0 },
+
+ { ngx_null_string, NULL, NULL, 0, 0, 0 }
+};
+
+
+ngx_stream_variable_value_t ngx_stream_variable_null_value =
+ ngx_stream_variable("");
+ngx_stream_variable_value_t ngx_stream_variable_true_value =
+ ngx_stream_variable("1");
+
+
+ngx_stream_variable_t *
+ngx_stream_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
+{
+ ngx_int_t rc;
+ ngx_uint_t i;
+ ngx_hash_key_t *key;
+ ngx_stream_variable_t *v;
+ ngx_stream_core_main_conf_t *cmcf;
+
+ if (name->len == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid variable name \"$\"");
+ return NULL;
+ }
+
+ cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);
+
+ key = cmcf->variables_keys->keys.elts;
+ for (i = 0; i < cmcf->variables_keys->keys.nelts; i++) {
+ if (name->len != key[i].key.len
+ || ngx_strncasecmp(name->data, key[i].key.data, name->len) != 0)
+ {
+ continue;
+ }
+
+ v = key[i].value;
+
+ if (!(v->flags & NGX_STREAM_VAR_CHANGEABLE)) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "the duplicate \"%V\" variable", name);
+ return NULL;
+ }
+
+ return v;
+ }
+
+ v = ngx_palloc(cf->pool, sizeof(ngx_stream_variable_t));
+ if (v == NULL) {
+ return NULL;
+ }
+
+ v->name.len = name->len;
+ v->name.data = ngx_pnalloc(cf->pool, name->len);
+ if (v->name.data == NULL) {
+ return NULL;
+ }
+
+ ngx_strlow(v->name.data, name->data, name->len);
+
+ v->set_handler = NULL;
+ v->get_handler = NULL;
+ v->data = 0;
+ v->flags = flags;
+ v->index = 0;
+
+ rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, 0);
+
+ if (rc == NGX_ERROR) {
+ return NULL;
+ }
+
+ if (rc == NGX_BUSY) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "conflicting variable name \"%V\"", name);
+ return NULL;
+ }
+
+ return v;
+}
+
+
+ngx_int_t
+ngx_stream_get_variable_index(ngx_conf_t *cf, ngx_str_t *name)
+{
+ ngx_uint_t i;
+ ngx_stream_variable_t *v;
+ ngx_stream_core_main_conf_t *cmcf;
+
+ if (name->len == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid variable name \"$\"");
+ return NGX_ERROR;
+ }
+
+ cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);
+
+ v = cmcf->variables.elts;
+
+ if (v == NULL) {
+ if (ngx_array_init(&cmcf->variables, cf->pool, 4,
+ sizeof(ngx_stream_variable_t))
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ } else {
+ for (i = 0; i < cmcf->variables.nelts; i++) {
+ if (name->len != v[i].name.len
+ || ngx_strncasecmp(name->data, v[i].name.data, name->len) != 0)
+ {
+ continue;
+ }
+
+ return i;
+ }
+ }
+
+ v = ngx_array_push(&cmcf->variables);
+ if (v == NULL) {
+ return NGX_ERROR;
+ }
+
+ v->name.len = name->len;
+ v->name.data = ngx_pnalloc(cf->pool, name->len);
+ if (v->name.data == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_strlow(v->name.data, name->data, name->len);
+
+ v->set_handler = NULL;
+ v->get_handler = NULL;
+ v->data = 0;
+ v->flags = 0;
+ v->index = cmcf->variables.nelts - 1;
+
+ return v->index;
+}
+
+
+ngx_stream_variable_value_t *
+ngx_stream_get_indexed_variable(ngx_stream_session_t *s, ngx_uint_t index)
+{
+ ngx_stream_variable_t *v;
+ ngx_stream_core_main_conf_t *cmcf;
+
+ cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module);
+
+ if (cmcf->variables.nelts <= index) {
+ ngx_log_error(NGX_LOG_ALERT, s->connection->log, 0,
+ "unknown variable index: %ui", index);
+ return NULL;
+ }
+
+ if (s->variables[index].not_found || s->variables[index].valid) {
+ return &s->variables[index];
+ }
+
+ v = cmcf->variables.elts;
+
+ if (v[index].get_handler(s, &s->variables[index], v[index].data)
+ == NGX_OK)
+ {
+ if (v[index].flags & NGX_STREAM_VAR_NOCACHEABLE) {
+ s->variables[index].no_cacheable = 1;
+ }
+
+ return &s->variables[index];
+ }
+
+ s->variables[index].valid = 0;
+ s->variables[index].not_found = 1;
+
+ return NULL;
+}
+
+
+ngx_stream_variable_value_t *
+ngx_stream_get_flushed_variable(ngx_stream_session_t *s, ngx_uint_t index)
+{
+ ngx_stream_variable_value_t *v;
+
+ v = &s->variables[index];
+
+ if (v->valid || v->not_found) {
+ if (!v->no_cacheable) {
+ return v;
+ }
+
+ v->valid = 0;
+ v->not_found = 0;
+ }
+
+ return ngx_stream_get_indexed_variable(s, index);
+}
+
+
+ngx_stream_variable_value_t *
+ngx_stream_get_variable(ngx_stream_session_t *s, ngx_str_t *name,
+ ngx_uint_t key)
+{
+ ngx_stream_variable_t *v;
+ ngx_stream_variable_value_t *vv;
+ ngx_stream_core_main_conf_t *cmcf;
+
+ cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module);
+
+ v = ngx_hash_find(&cmcf->variables_hash, key, name->data, name->len);
+
+ if (v) {
+ if (v->flags & NGX_STREAM_VAR_INDEXED) {
+ return ngx_stream_get_flushed_variable(s, v->index);
+
+ } else {
+
+ vv = ngx_palloc(s->connection->pool,
+ sizeof(ngx_stream_variable_value_t));
+
+ if (vv && v->get_handler(s, vv, v->data) == NGX_OK) {
+ return vv;
+ }
+
+ return NULL;
+ }
+ }
+
+ vv = ngx_palloc(s->connection->pool, sizeof(ngx_stream_variable_value_t));
+ if (vv == NULL) {
+ return NULL;
+ }
+
+ vv->not_found = 1;
+
+ return vv;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_binary_remote_addr(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+ {
+ struct sockaddr_in *sin;
+#if (NGX_HAVE_INET6)
+ struct sockaddr_in6 *sin6;
+#endif
+
+ switch (s->connection->sockaddr->sa_family) {
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *) s->connection->sockaddr;
+
+ v->len = sizeof(struct in6_addr);
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = sin6->sin6_addr.s6_addr;
+
+ break;
+#endif
+
+ default: /* AF_INET */
+ sin = (struct sockaddr_in *) s->connection->sockaddr;
+
+ v->len = sizeof(in_addr_t);
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = (u_char *) &sin->sin_addr;
+
+ break;
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_remote_addr(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ v->len = s->connection->addr_text.len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = s->connection->addr_text.data;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_remote_port(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ ngx_uint_t port;
+
+ v->len = 0;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ v->data = ngx_pnalloc(s->connection->pool, sizeof("65535") - 1);
+ if (v->data == NULL) {
+ return NGX_ERROR;
+ }
+
+ port = ngx_inet_get_port(s->connection->sockaddr);
+
+ if (port > 0 && port < 65536) {
+ v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_proxy_protocol_addr(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ v->len = s->connection->proxy_protocol_addr.len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = s->connection->proxy_protocol_addr.data;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_proxy_protocol_port(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ ngx_uint_t port;
+
+ v->len = 0;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ v->data = ngx_pnalloc(s->connection->pool, sizeof("65535") - 1);
+ if (v->data == NULL) {
+ return NGX_ERROR;
+ }
+
+ port = s->connection->proxy_protocol_port;
+
+ if (port > 0 && port < 65536) {
+ v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_server_addr(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ ngx_str_t str;
+ u_char addr[NGX_SOCKADDR_STRLEN];
+
+ str.len = NGX_SOCKADDR_STRLEN;
+ str.data = addr;
+
+ if (ngx_connection_local_sockaddr(s->connection, &str, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ str.data = ngx_pnalloc(s->connection->pool, str.len);
+ if (str.data == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(str.data, addr, str.len);
+
+ v->len = str.len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = str.data;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_server_port(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ ngx_uint_t port;
+
+ v->len = 0;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ if (ngx_connection_local_sockaddr(s->connection, NULL, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ v->data = ngx_pnalloc(s->connection->pool, sizeof("65535") - 1);
+ if (v->data == NULL) {
+ return NGX_ERROR;
+ }
+
+ port = ngx_inet_get_port(s->connection->local_sockaddr);
+
+ if (port > 0 && port < 65536) {
+ v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_bytes(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ u_char *p;
+
+ p = ngx_pnalloc(s->connection->pool, NGX_OFF_T_LEN);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ if (data == 1) {
+ v->len = ngx_sprintf(p, "%O", s->received) - p;
+
+ } else {
+ v->len = ngx_sprintf(p, "%O", s->connection->sent) - p;
+ }
+
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = p;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_session_time(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ u_char *p;
+ ngx_time_t *tp;
+ ngx_msec_int_t ms;
+
+ p = ngx_pnalloc(s->connection->pool, NGX_TIME_T_LEN + 4);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ tp = ngx_timeofday();
+
+ ms = (ngx_msec_int_t)
+ ((tp->sec - s->start_sec) * 1000 + (tp->msec - s->start_msec));
+ ms = ngx_max(ms, 0);
+
+ v->len = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000) - p;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = p;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_status(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ v->data = ngx_pnalloc(s->connection->pool, NGX_INT_T_LEN);
+ if (v->data == NULL) {
+ return NGX_ERROR;
+ }
+
+ v->len = ngx_sprintf(v->data, "%03ui", s->status) - v->data;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_connection(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ u_char *p;
+
+ p = ngx_pnalloc(s->connection->pool, NGX_ATOMIC_T_LEN);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ v->len = ngx_sprintf(p, "%uA", s->connection->number) - p;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = p;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_nginx_version(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ v->len = sizeof(NGINX_VERSION) - 1;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = (u_char *) NGINX_VERSION;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_hostname(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ v->len = ngx_cycle->hostname.len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = ngx_cycle->hostname.data;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_pid(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ u_char *p;
+
+ p = ngx_pnalloc(s->connection->pool, NGX_INT64_LEN);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ v->len = ngx_sprintf(p, "%P", ngx_pid) - p;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = p;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_msec(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ u_char *p;
+ ngx_time_t *tp;
+
+ p = ngx_pnalloc(s->connection->pool, NGX_TIME_T_LEN + 4);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ tp = ngx_timeofday();
+
+ v->len = ngx_sprintf(p, "%T.%03M", tp->sec, tp->msec) - p;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = p;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_time_iso8601(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ u_char *p;
+
+ p = ngx_pnalloc(s->connection->pool, ngx_cached_http_log_iso8601.len);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(p, ngx_cached_http_log_iso8601.data,
+ ngx_cached_http_log_iso8601.len);
+
+ v->len = ngx_cached_http_log_iso8601.len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = p;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_time_local(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ u_char *p;
+
+ p = ngx_pnalloc(s->connection->pool, ngx_cached_http_log_time.len);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(p, ngx_cached_http_log_time.data, ngx_cached_http_log_time.len);
+
+ v->len = ngx_cached_http_log_time.len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = p;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_stream_variable_protocol(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ v->len = 3;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = (u_char *) (s->connection->type == SOCK_DGRAM ? "UDP" : "TCP");
+
+ return NGX_OK;
+}
+
+
+void *
+ngx_stream_map_find(ngx_stream_session_t *s, ngx_stream_map_t *map,
+ ngx_str_t *match)
+{
+ void *value;
+ u_char *low;
+ size_t len;
+ ngx_uint_t key;
+
+ len = match->len;
+
+ if (len) {
+ low = ngx_pnalloc(s->connection->pool, len);
+ if (low == NULL) {
+ return NULL;
+ }
+
+ } else {
+ low = NULL;
+ }
+
+ key = ngx_hash_strlow(low, match->data, len);
+
+ value = ngx_hash_find_combined(&map->hash, key, low, len);
+ if (value) {
+ return value;
+ }
+
+#if (NGX_PCRE)
+
+ if (len && map->nregex) {
+ ngx_int_t n;
+ ngx_uint_t i;
+ ngx_stream_map_regex_t *reg;
+
+ reg = map->regex;
+
+ for (i = 0; i < map->nregex; i++) {
+
+ n = ngx_stream_regex_exec(s, reg[i].regex, match);
+
+ if (n == NGX_OK) {
+ return reg[i].value;
+ }
+
+ if (n == NGX_DECLINED) {
+ continue;
+ }
+
+ /* NGX_ERROR */
+
+ return NULL;
+ }
+ }
+
+#endif
+
+ return NULL;
+}
+
+
+#if (NGX_PCRE)
+
+static ngx_int_t
+ngx_stream_variable_not_found(ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data)
+{
+ v->not_found = 1;
+ return NGX_OK;
+}
+
+
+ngx_stream_regex_t *
+ngx_stream_regex_compile(ngx_conf_t *cf, ngx_regex_compile_t *rc)
+{
+ u_char *p;
+ size_t size;
+ ngx_str_t name;
+ ngx_uint_t i, n;
+ ngx_stream_variable_t *v;
+ ngx_stream_regex_t *re;
+ ngx_stream_regex_variable_t *rv;
+ ngx_stream_core_main_conf_t *cmcf;
+
+ rc->pool = cf->pool;
+
+ if (ngx_regex_compile(rc) != NGX_OK) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc->err);
+ return NULL;
+ }
+
+ re = ngx_pcalloc(cf->pool, sizeof(ngx_stream_regex_t));
+ if (re == NULL) {
+ return NULL;
+ }
+
+ re->regex = rc->regex;
+ re->ncaptures = rc->captures;
+ re->name = rc->pattern;
+
+ cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);
+ cmcf->ncaptures = ngx_max(cmcf->ncaptures, re->ncaptures);
+
+ n = (ngx_uint_t) rc->named_captures;
+
+ if (n == 0) {
+ return re;
+ }
+
+ rv = ngx_palloc(rc->pool, n * sizeof(ngx_stream_regex_variable_t));
+ if (rv == NULL) {
+ return NULL;
+ }
+
+ re->variables = rv;
+ re->nvariables = n;
+
+ size = rc->name_size;
+ p = rc->names;
+
+ for (i = 0; i < n; i++) {
+ rv[i].capture = 2 * ((p[0] << 8) + p[1]);
+
+ name.data = &p[2];
+ name.len = ngx_strlen(name.data);
+
+ v = ngx_stream_add_variable(cf, &name, NGX_STREAM_VAR_CHANGEABLE);
+ if (v == NULL) {
+ return NULL;
+ }
+
+ rv[i].index = ngx_stream_get_variable_index(cf, &name);
+ if (rv[i].index == NGX_ERROR) {
+ return NULL;
+ }
+
+ v->get_handler = ngx_stream_variable_not_found;
+
+ p += size;
+ }
+
+ return re;
+}
+
+
+ngx_int_t
+ngx_stream_regex_exec(ngx_stream_session_t *s, ngx_stream_regex_t *re,
+ ngx_str_t *str)
+{
+ ngx_int_t rc, index;
+ ngx_uint_t i, n, len;
+ ngx_stream_variable_value_t *vv;
+ ngx_stream_core_main_conf_t *cmcf;
+
+ cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module);
+
+ if (re->ncaptures) {
+ len = cmcf->ncaptures;
+
+ if (s->captures == NULL) {
+ s->captures = ngx_palloc(s->connection->pool, len * sizeof(int));
+ if (s->captures == NULL) {
+ return NGX_ERROR;
+ }
+ }
+
+ } else {
+ len = 0;
+ }
+
+ rc = ngx_regex_exec(re->regex, str, s->captures, len);
+
+ if (rc == NGX_REGEX_NO_MATCHED) {
+ return NGX_DECLINED;
+ }
+
+ if (rc < 0) {
+ ngx_log_error(NGX_LOG_ALERT, s->connection->log, 0,
+ ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"",
+ rc, str, &re->name);
+ return NGX_ERROR;
+ }
+
+ for (i = 0; i < re->nvariables; i++) {
+
+ n = re->variables[i].capture;
+ index = re->variables[i].index;
+ vv = &s->variables[index];
+
+ vv->len = s->captures[n + 1] - s->captures[n];
+ vv->valid = 1;
+ vv->no_cacheable = 0;
+ vv->not_found = 0;
+ vv->data = &str->data[s->captures[n]];
+
+#if (NGX_DEBUG)
+ {
+ ngx_stream_variable_t *v;
+
+ v = cmcf->variables.elts;
+
+ ngx_log_debug2(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "stream regex set $%V to \"%v\"", &v[index].name, vv);
+ }
+#endif
+ }
+
+ s->ncaptures = rc * 2;
+ s->captures_data = str->data;
+
+ return NGX_OK;
+}
+
+#endif
+
+
+ngx_int_t
+ngx_stream_variables_add_core_vars(ngx_conf_t *cf)
+{
+ ngx_int_t rc;
+ ngx_stream_variable_t *cv, *v;
+ ngx_stream_core_main_conf_t *cmcf;
+
+ cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);
+
+ cmcf->variables_keys = ngx_pcalloc(cf->temp_pool,
+ sizeof(ngx_hash_keys_arrays_t));
+ if (cmcf->variables_keys == NULL) {
+ return NGX_ERROR;
+ }
+
+ cmcf->variables_keys->pool = cf->pool;
+ cmcf->variables_keys->temp_pool = cf->pool;
+
+ if (ngx_hash_keys_array_init(cmcf->variables_keys, NGX_HASH_SMALL)
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ for (cv = ngx_stream_core_variables; cv->name.len; cv++) {
+ v = ngx_palloc(cf->pool, sizeof(ngx_stream_variable_t));
+ if (v == NULL) {
+ return NGX_ERROR;
+ }
+
+ *v = *cv;
+
+ rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v,
+ NGX_HASH_READONLY_KEY);
+
+ if (rc == NGX_OK) {
+ continue;
+ }
+
+ if (rc == NGX_BUSY) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "conflicting variable name \"%V\"", &v->name);
+ }
+
+ return NGX_ERROR;
+ }
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_stream_variables_init_vars(ngx_conf_t *cf)
+{
+ ngx_uint_t i, n;
+ ngx_hash_key_t *key;
+ ngx_hash_init_t hash;
+ ngx_stream_variable_t *v, *av;
+ ngx_stream_core_main_conf_t *cmcf;
+
+ /* set the handlers for the indexed stream variables */
+
+ cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);
+
+ v = cmcf->variables.elts;
+ key = cmcf->variables_keys->keys.elts;
+
+ for (i = 0; i < cmcf->variables.nelts; i++) {
+
+ for (n = 0; n < cmcf->variables_keys->keys.nelts; n++) {
+
+ av = key[n].value;
+
+ if (v[i].name.len == key[n].key.len
+ && ngx_strncmp(v[i].name.data, key[n].key.data, v[i].name.len)
+ == 0)
+ {
+ v[i].get_handler = av->get_handler;
+ v[i].data = av->data;
+
+ av->flags |= NGX_STREAM_VAR_INDEXED;
+ v[i].flags = av->flags;
+
+ av->index = i;
+
+ if (av->get_handler == NULL) {
+ break;
+ }
+
+ goto next;
+ }
+ }
+
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "unknown \"%V\" variable", &v[i].name);
+
+ return NGX_ERROR;
+
+ next:
+ continue;
+ }
+
+
+ for (n = 0; n < cmcf->variables_keys->keys.nelts; n++) {
+ av = key[n].value;
+
+ if (av->flags & NGX_STREAM_VAR_NOHASH) {
+ key[n].key.data = NULL;
+ }
+ }
+
+
+ hash.hash = &cmcf->variables_hash;
+ hash.key = ngx_hash_key;
+ hash.max_size = cmcf->variables_hash_max_size;
+ hash.bucket_size = cmcf->variables_hash_bucket_size;
+ hash.name = "variables_hash";
+ hash.pool = cf->pool;
+ hash.temp_pool = NULL;
+
+ if (ngx_hash_init(&hash, cmcf->variables_keys->keys.elts,
+ cmcf->variables_keys->keys.nelts)
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ cmcf->variables_keys = NULL;
+
+ return NGX_OK;
+}
|
[-]
[+]
|
Added |
nginx-1.11.4.tar.bz2/src/stream/ngx_stream_variables.h
^
|
@@ -0,0 +1,109 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_STREAM_VARIABLES_H_INCLUDED_
+#define _NGX_STREAM_VARIABLES_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_stream.h>
+
+
+typedef ngx_variable_value_t ngx_stream_variable_value_t;
+
+#define ngx_stream_variable(v) { sizeof(v) - 1, 1, 0, 0, 0, (u_char *) v }
+
+typedef struct ngx_stream_variable_s ngx_stream_variable_t;
+
+typedef void (*ngx_stream_set_variable_pt) (ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+typedef ngx_int_t (*ngx_stream_get_variable_pt) (ngx_stream_session_t *s,
+ ngx_stream_variable_value_t *v, uintptr_t data);
+
+
+#define NGX_STREAM_VAR_CHANGEABLE 1
+#define NGX_STREAM_VAR_NOCACHEABLE 2
+#define NGX_STREAM_VAR_INDEXED 4
+#define NGX_STREAM_VAR_NOHASH 8
+
+
+struct ngx_stream_variable_s {
+ ngx_str_t name; /* must be first to build the hash */
+ ngx_stream_set_variable_pt set_handler;
+ ngx_stream_get_variable_pt get_handler;
+ uintptr_t data;
+ ngx_uint_t flags;
+ ngx_uint_t index;
+};
+
+
+ngx_stream_variable_t *ngx_stream_add_variable(ngx_conf_t *cf, ngx_str_t *name,
+ ngx_uint_t flags);
+ngx_int_t ngx_stream_get_variable_index(ngx_conf_t *cf, ngx_str_t *name);
+ngx_stream_variable_value_t *ngx_stream_get_indexed_variable(
+ ngx_stream_session_t *s, ngx_uint_t index);
+ngx_stream_variable_value_t *ngx_stream_get_flushed_variable(
+ ngx_stream_session_t *s, ngx_uint_t index);
+
+ngx_stream_variable_value_t *ngx_stream_get_variable(ngx_stream_session_t *s,
+ ngx_str_t *name, ngx_uint_t key);
+
+
+#if (NGX_PCRE)
+
+typedef struct {
+ ngx_uint_t capture;
+ ngx_int_t index;
+} ngx_stream_regex_variable_t;
+
+
+typedef struct {
+ ngx_regex_t *regex;
+ ngx_uint_t ncaptures;
+ ngx_stream_regex_variable_t *variables;
+ ngx_uint_t nvariables;
+ ngx_str_t name;
+} ngx_stream_regex_t;
+
+
+typedef struct {
+ ngx_stream_regex_t *regex;
+ void *value;
+} ngx_stream_map_regex_t;
+
+
+ngx_stream_regex_t *ngx_stream_regex_compile(ngx_conf_t *cf,
+ ngx_regex_compile_t *rc);
+ngx_int_t ngx_stream_regex_exec(ngx_stream_session_t *s, ngx_stream_regex_t *re,
+ ngx_str_t *str);
+
+#endif
+
+
+typedef struct {
+ ngx_hash_combined_t hash;
+#if (NGX_PCRE)
+ ngx_stream_map_regex_t *regex;
+ ngx_uint_t nregex;
+#endif
+} ngx_stream_map_t;
+
+
+void *ngx_stream_map_find(ngx_stream_session_t *s, ngx_stream_map_t *map,
+ ngx_str_t *match);
+
+
+ngx_int_t ngx_stream_variables_add_core_vars(ngx_conf_t *cf);
+ngx_int_t ngx_stream_variables_init_vars(ngx_conf_t *cf);
+
+
+extern ngx_stream_variable_value_t ngx_stream_variable_null_value;
+extern ngx_stream_variable_value_t ngx_stream_variable_true_value;
+
+
+#endif /* _NGX_STREAM_VARIABLES_H_INCLUDED_ */
|
|
Deleted |
nginx-rtmp-module-1.1.8.tar.bz2
^
|
[-]
[+]
|
Changed |
nginx-rtmp-module-1.1.9.tar.bz2/config
^
|
@@ -1,6 +1,6 @@
ngx_addon_name="ngx_rtmp_module"
-CORE_MODULES="$CORE_MODULES
+RTMP_CORE_MODULES=" \
ngx_rtmp_module \
ngx_rtmp_core_module \
ngx_rtmp_cmd_module \
@@ -15,6 +15,7 @@
ngx_rtmp_relay_module \
ngx_rtmp_exec_module \
ngx_rtmp_auto_push_module \
+ ngx_rtmp_auto_push_index_module \
ngx_rtmp_notify_module \
ngx_rtmp_log_module \
ngx_rtmp_limit_module \
@@ -23,13 +24,13 @@
"
-HTTP_MODULES="$HTTP_MODULES \
+RTMP_HTTP_MODULES=" \
ngx_rtmp_stat_module \
ngx_rtmp_control_module \
"
-NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
+RTMP_DEPS=" \
$ngx_addon_dir/ngx_rtmp_amf.h \
$ngx_addon_dir/ngx_rtmp_bandwidth.h \
$ngx_addon_dir/ngx_rtmp_cmd_module.h \
@@ -50,7 +51,7 @@
"
-NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
+RTMP_CORE_SRCS=" \
$ngx_addon_dir/ngx_rtmp.c \
$ngx_addon_dir/ngx_rtmp_init.c \
$ngx_addon_dir/ngx_rtmp_handshake.c \
@@ -70,8 +71,6 @@
$ngx_addon_dir/ngx_rtmp_flv_module.c \
$ngx_addon_dir/ngx_rtmp_mp4_module.c \
$ngx_addon_dir/ngx_rtmp_netcall_module.c \
- $ngx_addon_dir/ngx_rtmp_stat_module.c \
- $ngx_addon_dir/ngx_rtmp_control_module.c \
$ngx_addon_dir/ngx_rtmp_relay_module.c \
$ngx_addon_dir/ngx_rtmp_bandwidth.c \
$ngx_addon_dir/ngx_rtmp_exec_module.c \
@@ -86,7 +85,49 @@
$ngx_addon_dir/hls/ngx_rtmp_mpegts.c \
$ngx_addon_dir/dash/ngx_rtmp_mp4.c \
"
-CFLAGS="$CFLAGS -I$ngx_addon_dir"
+
+
+RTMP_HTTP_SRCS=" \
+ $ngx_addon_dir/ngx_rtmp_stat_module.c \
+ $ngx_addon_dir/ngx_rtmp_control_module.c \
+ "
+
+if [ -f auto/module ] ; then
+ ngx_module_incs=$ngx_addon_dir
+ ngx_module_deps=$RTMP_DEPS
+
+ if [ $ngx_module_link = DYNAMIC ] ; then
+ ngx_module_name="$RTMP_CORE_MODULES $RTMP_HTTP_MODULES"
+ ngx_module_srcs="$RTMP_CORE_SRCS $RTMP_HTTP_SRCS"
+
+ . auto/module
+
+ else
+ ngx_module_type=CORE
+ ngx_module_name=$RTMP_CORE_MODULES
+ ngx_module_srcs=$RTMP_CORE_SRCS
+
+ . auto/module
+
+
+ ngx_module_type=HTTP
+ ngx_module_name=$RTMP_HTTP_MODULES
+ ngx_module_incs=
+ ngx_module_deps=
+ ngx_module_srcs=$RTMP_HTTP_SRCS
+
+ . auto/module
+ fi
+
+else
+ CORE_MODULES="$CORE_MODULES $RTMP_CORE_MODULES"
+ HTTP_MODULES="$HTTP_MODULES $RTMP_HTTP_MODULES"
+
+ NGX_ADDON_DEPS="$NGX_ADDON_DEPS $RTMP_DEPS"
+ NGX_ADDON_SRCS="$NGX_ADDON_SRCS $RTMP_CORE_SRCS $RTMP_HTTP_SRCS"
+
+ CFLAGS="$CFLAGS -I$ngx_addon_dir"
+fi
USE_OPENSSL=YES
|
[-]
[+]
|
Changed |
nginx-rtmp-module-1.1.9.tar.bz2/ngx_rtmp.c
^
|
@@ -87,6 +87,7 @@
ngx_uint_t i, m, mi, s;
ngx_conf_t pcf;
ngx_array_t ports;
+ ngx_module_t **modules;
ngx_rtmp_listen_t *listen;
ngx_rtmp_module_t *module;
ngx_rtmp_conf_ctx_t *ctx;
@@ -102,6 +103,12 @@
/* count the number of the rtmp modules and set up their indices */
+#if (nginx_version >= 1009011)
+
+ ngx_rtmp_max_module = ngx_count_modules(cf->cycle, NGX_RTMP_MODULE);
+
+#else
+
ngx_rtmp_max_module = 0;
for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_RTMP_MODULE) {
@@ -111,6 +118,8 @@
ngx_modules[m]->ctx_index = ngx_rtmp_max_module++;
}
+#endif
+
/* the rtmp main_conf context, it is the same in the all rtmp contexts */
@@ -148,13 +157,19 @@
* of the all rtmp modules
*/
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_RTMP_MODULE) {
+#if (nginx_version >= 1009011)
+ modules = cf->cycle->modules;
+#else
+ modules = ngx_modules;
+#endif
+
+ for (m = 0; modules[m]; m++) {
+ if (modules[m]->type != NGX_RTMP_MODULE) {
continue;
}
- module = ngx_modules[m]->ctx;
- mi = ngx_modules[m]->ctx_index;
+ module = modules[m]->ctx;
+ mi = modules[m]->ctx_index;
if (module->create_main_conf) {
ctx->main_conf[mi] = module->create_main_conf(cf);
@@ -181,12 +196,12 @@
pcf = *cf;
cf->ctx = ctx;
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_RTMP_MODULE) {
+ for (m = 0; modules[m]; m++) {
+ if (modules[m]->type != NGX_RTMP_MODULE) {
continue;
}
- module = ngx_modules[m]->ctx;
+ module = modules[m]->ctx;
if (module->preconfiguration) {
if (module->preconfiguration(cf) != NGX_OK) {
@@ -212,13 +227,13 @@
cmcf = ctx->main_conf[ngx_rtmp_core_module.ctx_index];
cscfp = cmcf->servers.elts;
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_RTMP_MODULE) {
+ for (m = 0; modules[m]; m++) {
+ if (modules[m]->type != NGX_RTMP_MODULE) {
continue;
}
- module = ngx_modules[m]->ctx;
- mi = ngx_modules[m]->ctx_index;
+ module = modules[m]->ctx;
+ mi = modules[m]->ctx_index;
/* init rtmp{} main_conf's */
@@ -283,12 +298,12 @@
return NGX_CONF_ERROR;
}
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_RTMP_MODULE) {
+ for (m = 0; modules[m]; m++) {
+ if (modules[m]->type != NGX_RTMP_MODULE) {
continue;
}
- module = ngx_modules[m]->ctx;
+ module = modules[m]->ctx;
if (module->postconfiguration) {
if (module->postconfiguration(cf) != NGX_OK) {
|
[-]
[+]
|
Changed |
nginx-rtmp-module-1.1.9.tar.bz2/ngx_rtmp_auto_push_module.c
^
|
@@ -93,6 +93,34 @@
};
+static ngx_rtmp_module_t ngx_rtmp_auto_push_index_module_ctx = {
+ NULL, /* preconfiguration */
+ NULL, /* postconfiguration */
+ NULL, /* create main configuration */
+ NULL, /* init main configuration */
+ NULL, /* create server configuration */
+ NULL, /* merge server configuration */
+ NULL, /* create app configuration */
+ NULL /* merge app configuration */
+};
+
+
+ngx_module_t ngx_rtmp_auto_push_index_module = {
+ NGX_MODULE_V1,
+ &ngx_rtmp_auto_push_index_module_ctx, /* module context */
+ NULL, /* module directives */
+ NGX_RTMP_MODULE, /* module type */
+ NULL, /* init master */
+ NULL, /* init module */
+ NULL, /* init process */
+ NULL, /* init thread */
+ NULL, /* exit thread */
+ NULL, /* exit process */
+ NULL, /* exit master */
+ NGX_MODULE_V1_PADDING
+};
+
+
#define NGX_RTMP_AUTO_PUSH_SOCKNAME "nginx-rtmp"
@@ -324,7 +352,7 @@
apcf = (ngx_rtmp_auto_push_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
ngx_rtmp_auto_push_module);
- ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_auto_push_module);
+ ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_auto_push_index_module);
if (ctx == NULL) {
return;
}
@@ -461,14 +489,14 @@
goto next;
}
- ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_auto_push_module);
+ ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_auto_push_index_module);
if (ctx == NULL) {
ctx = ngx_palloc(s->connection->pool,
sizeof(ngx_rtmp_auto_push_ctx_t));
if (ctx == NULL) {
goto next;
}
- ngx_rtmp_set_ctx(s, ctx, ngx_rtmp_auto_push_module);
+ ngx_rtmp_set_ctx(s, ctx, ngx_rtmp_auto_push_index_module);
}
ngx_memzero(ctx, sizeof(*ctx));
@@ -508,7 +536,7 @@
goto next;
}
- ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_auto_push_module);
+ ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_auto_push_index_module);
if (ctx) {
if (ctx->push_evt.timer_set) {
ngx_del_timer(&ctx->push_evt);
@@ -532,7 +560,7 @@
slot, &rctx->app, &rctx->name);
pctx = ngx_rtmp_get_module_ctx(rctx->publish->session,
- ngx_rtmp_auto_push_module);
+ ngx_rtmp_auto_push_index_module);
if (pctx == NULL) {
goto next;
}
|
[-]
[+]
|
Changed |
nginx-rtmp-module-1.1.9.tar.bz2/ngx_rtmp_core_module.c
^
|
@@ -332,6 +332,7 @@
void *mconf;
ngx_uint_t m;
ngx_conf_t pcf;
+ ngx_module_t **modules;
ngx_rtmp_module_t *module;
ngx_rtmp_conf_ctx_t *ctx, *rtmp_ctx;
ngx_rtmp_core_srv_conf_t *cscf, **cscfp;
@@ -357,12 +358,18 @@
return NGX_CONF_ERROR;
}
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_RTMP_MODULE) {
+#if (nginx_version >= 1009011)
+ modules = cf->cycle->modules;
+#else
+ modules = ngx_modules;
+#endif
+
+ for (m = 0; modules[m]; m++) {
+ if (modules[m]->type != NGX_RTMP_MODULE) {
continue;
}
- module = ngx_modules[m]->ctx;
+ module = modules[m]->ctx;
if (module->create_srv_conf) {
mconf = module->create_srv_conf(cf);
@@ -370,7 +377,7 @@
return NGX_CONF_ERROR;
}
- ctx->srv_conf[ngx_modules[m]->ctx_index] = mconf;
+ ctx->srv_conf[modules[m]->ctx_index] = mconf;
}
if (module->create_app_conf) {
@@ -379,7 +386,7 @@
return NGX_CONF_ERROR;
}
- ctx->app_conf[ngx_modules[m]->ctx_index] = mconf;
+ ctx->app_conf[modules[m]->ctx_index] = mconf;
}
}
@@ -419,6 +426,7 @@
ngx_int_t i;
ngx_str_t *value;
ngx_conf_t save;
+ ngx_module_t **modules;
ngx_rtmp_module_t *module;
ngx_rtmp_conf_ctx_t *ctx, *pctx;
ngx_rtmp_core_srv_conf_t *cscf;
@@ -438,17 +446,22 @@
return NGX_CONF_ERROR;
}
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->type != NGX_RTMP_MODULE) {
+#if (nginx_version >= 1009011)
+ modules = cf->cycle->modules;
+#else
+ modules = ngx_modules;
+#endif
+
+ for (i = 0; modules[i]; i++) {
+ if (modules[i]->type != NGX_RTMP_MODULE) {
continue;
}
- module = ngx_modules[i]->ctx;
+ module = modules[i]->ctx;
if (module->create_app_conf) {
- ctx->app_conf[ngx_modules[i]->ctx_index] =
- module->create_app_conf(cf);
- if (ctx->app_conf[ngx_modules[i]->ctx_index] == NULL) {
+ ctx->app_conf[modules[i]->ctx_index] = module->create_app_conf(cf);
+ if (ctx->app_conf[modules[i]->ctx_index] == NULL) {
return NGX_CONF_ERROR;
}
}
@@ -489,6 +502,7 @@
ngx_str_t *value;
ngx_url_t u;
ngx_uint_t i, m;
+ ngx_module_t **modules;
struct sockaddr *sa;
ngx_rtmp_listen_t *ls;
struct sockaddr_in *sin;
@@ -545,7 +559,9 @@
break;
}
- if (ngx_memcmp(ls[i].sockaddr + off, u.sockaddr + off, len) != 0) {
+ if (ngx_memcmp(ls[i].sockaddr + off, (u_char *) &u.sockaddr + off, len)
+ != 0)
+ {
continue;
}
@@ -565,14 +581,20 @@
ngx_memzero(ls, sizeof(ngx_rtmp_listen_t));
- ngx_memcpy(ls->sockaddr, u.sockaddr, u.socklen);
+ ngx_memcpy(ls->sockaddr, (u_char *) &u.sockaddr, u.socklen);
ls->socklen = u.socklen;
ls->wildcard = u.wildcard;
ls->ctx = cf->ctx;
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_RTMP_MODULE) {
+#if (nginx_version >= 1009011)
+ modules = cf->cycle->modules;
+#else
+ modules = ngx_modules;
+#endif
+
+ for (m = 0; modules[m]; m++) {
+ if (modules[m]->type != NGX_RTMP_MODULE) {
continue;
}
}
|
[-]
[+]
|
Changed |
nginx-rtmp-module-1.1.9.tar.bz2/ngx_rtmp_record_module.c
^
|
@@ -1195,6 +1195,7 @@
ngx_int_t i;
ngx_str_t *value;
ngx_conf_t save;
+ ngx_module_t **modules;
ngx_rtmp_module_t *module;
ngx_rtmp_core_app_conf_t *cacf, **pcacf, *rcacf;
ngx_rtmp_record_app_conf_t *racf, **pracf, *rracf;
@@ -1221,17 +1222,22 @@
return NGX_CONF_ERROR;
}
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->type != NGX_RTMP_MODULE) {
+#if (nginx_version >= 1009011)
+ modules = cf->cycle->modules;
+#else
+ modules = ngx_modules;
+#endif
+
+ for (i = 0; modules[i]; i++) {
+ if (modules[i]->type != NGX_RTMP_MODULE) {
continue;
}
- module = ngx_modules[i]->ctx;
+ module = modules[i]->ctx;
if (module->create_app_conf) {
- ctx->app_conf[ngx_modules[i]->ctx_index] =
- module->create_app_conf(cf);
- if (ctx->app_conf[ngx_modules[i]->ctx_index] == NULL) {
+ ctx->app_conf[modules[i]->ctx_index] = module->create_app_conf(cf);
+ if (ctx->app_conf[modules[i]->ctx_index] == NULL) {
return NGX_CONF_ERROR;
}
}
|
|
Deleted |
openssl-1.0.2h.tar.bz2
^
|
|
Deleted |
openssl-1.0.2i.tar.bz2
^
|