Compare commits
22 commits
quic
...
stable-1.8
Author | SHA1 | Date | |
---|---|---|---|
|
994edecbb5 | ||
|
620cb8ebb3 | ||
|
fa8de0e110 | ||
|
8e2ba53330 | ||
|
7b5920d9a9 | ||
|
6c42b28bdd | ||
|
92c27f267f | ||
|
824eae78fb | ||
|
4bcb833c89 | ||
|
144aa35280 | ||
|
f38b4d5a56 | ||
|
fe6e13e579 | ||
|
238a4d5ea9 | ||
|
7bb45d91cf | ||
|
3f6c0e604a | ||
|
774bd67fc5 | ||
|
e084afb726 | ||
|
dcdd591615 | ||
|
736f30b216 | ||
|
7097e2a683 | ||
|
b6c7cb0523 | ||
|
7e42c2cd3e |
14 changed files with 373 additions and 148 deletions
|
@ -5,6 +5,179 @@
|
|||
<change_log title="nginx">
|
||||
|
||||
|
||||
<changes ver="1.8.1" date="26.01.2016">
|
||||
|
||||
<change type="security">
|
||||
<para lang="ru">
|
||||
при использовании директивы resolver
|
||||
во время обработки ответов DNS-сервера
|
||||
могло происходить разыменование некорректного адреса,
|
||||
что позволяло атакующему,
|
||||
имеющему возможность подделывать UDP-пакеты от DNS-сервера,
|
||||
вызвать segmentation fault в рабочем процессе (CVE-2016-0742).
|
||||
</para>
|
||||
<para lang="en">
|
||||
invalid pointer dereference might occur
|
||||
during DNS server response processing
|
||||
if the "resolver" directive was used,
|
||||
allowing an attacker who is able to forge UDP packets from the DNS server
|
||||
to cause segmentation fault in a worker process (CVE-2016-0742).
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="security">
|
||||
<para lang="ru">
|
||||
при использовании директивы resolver
|
||||
во время обработки CNAME-записей
|
||||
могло произойти обращение к ранее освобождённой памяти,
|
||||
что позволяло атакующему,
|
||||
имеющему возможность инициировать преобразование произвольных имён в адреса,
|
||||
вызвать segmentation fault в рабочем процессе,
|
||||
а также потенциально могло иметь другие последствия (CVE-2016-0746).
|
||||
</para>
|
||||
<para lang="en">
|
||||
use-after-free condition might occur
|
||||
during CNAME response processing
|
||||
if the "resolver" directive was used,
|
||||
allowing an attacker who is able to trigger name resolution
|
||||
to cause segmentation fault in a worker process,
|
||||
or might have potential other impact (CVE-2016-0746).
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="security">
|
||||
<para lang="ru">
|
||||
при использовании директивы resolver
|
||||
во время обработки CNAME-записей
|
||||
не во всех случаях проверялось ограничение
|
||||
на максимальное количество записей в цепочке,
|
||||
что позволяло атакующему,
|
||||
имеющему возможность инициировать преобразование произвольных имён в адреса,
|
||||
вызвать чрезмерное потребление ресурсов рабочими процессами (CVE-2016-0747).
|
||||
</para>
|
||||
<para lang="en">
|
||||
CNAME resolution was insufficiently limited
|
||||
if the "resolver" directive was used,
|
||||
allowing an attacker who is able to trigger arbitrary name resolution
|
||||
to cause excessive resource consumption in worker processes (CVE-2016-0747).
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
параметр proxy_protocol директивы listen не работал,
|
||||
если не был указан в первой директиве listen для данного listen-сокета.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "proxy_protocol" parameter of the "listen" directive did not work
|
||||
if not specified in the first "listen" directive for a listen socket.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
nginx мог не запускаться на некоторых старых версиях Linux;
|
||||
ошибка появилась в 1.7.11.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx might fail to start on some old Linux variants;
|
||||
the bug had appeared in 1.7.11.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
при совместном использовании директив try_files и alias
|
||||
внутри location'а, заданного регулярным выражением,
|
||||
в рабочем процессе мог произойти segmentation fault;
|
||||
ошибка появилась в 1.7.1.
|
||||
</para>
|
||||
<para lang="en">
|
||||
a segmentation fault might occur in a worker process
|
||||
if the "try_files" and "alias" directives were used
|
||||
inside a location given by a regular expression;
|
||||
the bug had appeared in 1.7.1.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
директива try_files внутри вложенного location'а, заданного регулярным
|
||||
выражением, работала неправильно, если во внешнем location'е использовалась
|
||||
директива alias.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "try_files" directive inside a nested location
|
||||
given by a regular expression worked incorrectly
|
||||
if the "alias" directive was used in the outer location.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
при использовании кэша
|
||||
в логах могли появляться сообщения "header already sent";
|
||||
ошибка появилась в 1.7.5.
|
||||
</para>
|
||||
<para lang="en">
|
||||
"header already sent" alerts might appear in logs
|
||||
when using cache;
|
||||
the bug had appeared in 1.7.5.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
при использовании различных настроек ssl_session_cache
|
||||
в разных виртуальных серверах
|
||||
в рабочем процессе мог произойти segmentation fault.
|
||||
</para>
|
||||
<para lang="en">
|
||||
a segmentation fault might occur in a worker process
|
||||
if different ssl_session_cache settings were used
|
||||
in different virtual servers.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
директива expires могла не срабатывать при использовании переменных.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "expires" directive might not work when using variables.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
если nginx был собран с модулем ngx_http_spdy_module,
|
||||
протокол SPDY мог быть использован клиентом,
|
||||
даже если не был указан параметр spdy директивы listen.
|
||||
</para>
|
||||
<para lang="en">
|
||||
if nginx was built with the ngx_http_spdy_module
|
||||
it was possible to use the SPDY protocol
|
||||
even if the "spdy" parameter of the "listen" directive was not specified.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="1.8.0" date="21.04.2015">
|
||||
|
||||
<change>
|
||||
<para lang="ru">
|
||||
Стабильная ветка 1.8.x.
|
||||
</para>
|
||||
<para lang="en">
|
||||
1.8.x stable branch.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="1.7.12" date="07.04.2015">
|
||||
|
||||
<change type="feature">
|
||||
|
|
|
@ -5,9 +5,9 @@ NGINX = nginx-$(VER)
|
|||
TEMP = tmp
|
||||
|
||||
OBJS = objs.msvc8
|
||||
OPENSSL = openssl-1.0.1m
|
||||
OPENSSL = openssl-1.0.1q
|
||||
ZLIB = zlib-1.2.8
|
||||
PCRE = pcre-8.35
|
||||
PCRE = pcre-8.38
|
||||
|
||||
|
||||
release: export
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
#define _NGINX_H_INCLUDED_
|
||||
|
||||
|
||||
#define nginx_version 1007013
|
||||
#define NGINX_VERSION "1.7.13"
|
||||
#define nginx_version 1008001
|
||||
#define NGINX_VERSION "1.8.1"
|
||||
#define NGINX_VER "nginx/" NGINX_VERSION
|
||||
|
||||
#ifdef NGX_BUILD
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
#define _NGX_CORE_H_INCLUDED_
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
|
||||
|
||||
typedef struct ngx_module_s ngx_module_t;
|
||||
typedef struct ngx_conf_s ngx_conf_t;
|
||||
typedef struct ngx_cycle_s ngx_cycle_t;
|
||||
|
|
|
@ -188,7 +188,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
|
|||
break;
|
||||
|
||||
case 'm':
|
||||
if (*p == 's') {
|
||||
if (p < last && *p == 's') {
|
||||
if (is_sec || step >= st_msec) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
|
|
@ -59,15 +59,15 @@ ngx_int_t ngx_udp_connect(ngx_udp_connection_t *uc);
|
|||
static void ngx_resolver_cleanup(void *data);
|
||||
static void ngx_resolver_cleanup_tree(ngx_resolver_t *r, ngx_rbtree_t *tree);
|
||||
static ngx_int_t ngx_resolve_name_locked(ngx_resolver_t *r,
|
||||
ngx_resolver_ctx_t *ctx);
|
||||
ngx_resolver_ctx_t *ctx, ngx_str_t *name);
|
||||
static void ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree,
|
||||
ngx_queue_t *queue);
|
||||
static ngx_int_t ngx_resolver_send_query(ngx_resolver_t *r,
|
||||
ngx_resolver_node_t *rn);
|
||||
static ngx_int_t ngx_resolver_create_name_query(ngx_resolver_node_t *rn,
|
||||
ngx_resolver_ctx_t *ctx);
|
||||
static ngx_int_t ngx_resolver_create_addr_query(ngx_resolver_node_t *rn,
|
||||
ngx_resolver_ctx_t *ctx);
|
||||
static ngx_int_t ngx_resolver_create_name_query(ngx_resolver_t *r,
|
||||
ngx_resolver_node_t *rn, ngx_str_t *name);
|
||||
static ngx_int_t ngx_resolver_create_addr_query(ngx_resolver_t *r,
|
||||
ngx_resolver_node_t *rn, ngx_addr_t *addr);
|
||||
static void ngx_resolver_resend_handler(ngx_event_t *ev);
|
||||
static time_t ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree,
|
||||
ngx_queue_t *queue);
|
||||
|
@ -375,7 +375,7 @@ ngx_resolve_name(ngx_resolver_ctx_t *ctx)
|
|||
|
||||
/* lock name mutex */
|
||||
|
||||
rc = ngx_resolve_name_locked(r, ctx);
|
||||
rc = ngx_resolve_name_locked(r, ctx, &ctx->name);
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
return NGX_OK;
|
||||
|
@ -402,7 +402,6 @@ ngx_resolve_name(ngx_resolver_ctx_t *ctx)
|
|||
void
|
||||
ngx_resolve_name_done(ngx_resolver_ctx_t *ctx)
|
||||
{
|
||||
uint32_t hash;
|
||||
ngx_resolver_t *r;
|
||||
ngx_resolver_ctx_t *w, **p;
|
||||
ngx_resolver_node_t *rn;
|
||||
|
@ -422,11 +421,9 @@ ngx_resolve_name_done(ngx_resolver_ctx_t *ctx)
|
|||
|
||||
/* lock name mutex */
|
||||
|
||||
if (ctx->state == NGX_AGAIN) {
|
||||
if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
|
||||
|
||||
hash = ngx_crc32_short(ctx->name.data, ctx->name.len);
|
||||
|
||||
rn = ngx_resolver_lookup_name(r, &ctx->name, hash);
|
||||
rn = ctx->node;
|
||||
|
||||
if (rn) {
|
||||
p = &rn->waiting;
|
||||
|
@ -467,23 +464,28 @@ done:
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
|
||||
ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx,
|
||||
ngx_str_t *name)
|
||||
{
|
||||
uint32_t hash;
|
||||
ngx_int_t rc;
|
||||
ngx_str_t cname;
|
||||
ngx_uint_t naddrs;
|
||||
ngx_addr_t *addrs;
|
||||
ngx_resolver_ctx_t *next;
|
||||
ngx_resolver_ctx_t *next, *last;
|
||||
ngx_resolver_node_t *rn;
|
||||
|
||||
ngx_strlow(ctx->name.data, ctx->name.data, ctx->name.len);
|
||||
ngx_strlow(name->data, name->data, name->len);
|
||||
|
||||
hash = ngx_crc32_short(ctx->name.data, ctx->name.len);
|
||||
hash = ngx_crc32_short(name->data, name->len);
|
||||
|
||||
rn = ngx_resolver_lookup_name(r, &ctx->name, hash);
|
||||
rn = ngx_resolver_lookup_name(r, name, hash);
|
||||
|
||||
if (rn) {
|
||||
|
||||
/* ctx can be a list after NGX_RESOLVE_CNAME */
|
||||
for (last = ctx; last->next; last = last->next);
|
||||
|
||||
if (rn->valid >= ngx_time()) {
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, "resolve cached");
|
||||
|
@ -511,7 +513,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
ctx->next = rn->waiting;
|
||||
last->next = rn->waiting;
|
||||
rn->waiting = NULL;
|
||||
|
||||
/* unlock name mutex */
|
||||
|
@ -551,13 +553,13 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
|
|||
|
||||
if (ctx->recursion++ < NGX_RESOLVER_MAX_RECURSION) {
|
||||
|
||||
ctx->name.len = rn->cnlen;
|
||||
ctx->name.data = rn->u.cname;
|
||||
cname.len = rn->cnlen;
|
||||
cname.data = rn->u.cname;
|
||||
|
||||
return ngx_resolve_name_locked(r, ctx);
|
||||
return ngx_resolve_name_locked(r, ctx, &cname);
|
||||
}
|
||||
|
||||
ctx->next = rn->waiting;
|
||||
last->next = rn->waiting;
|
||||
rn->waiting = NULL;
|
||||
|
||||
/* unlock name mutex */
|
||||
|
@ -576,10 +578,29 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
|
|||
|
||||
if (rn->waiting) {
|
||||
|
||||
ctx->next = rn->waiting;
|
||||
if (ctx->event == NULL) {
|
||||
ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
|
||||
if (ctx->event == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ctx->event->handler = ngx_resolver_timeout_handler;
|
||||
ctx->event->data = ctx;
|
||||
ctx->event->log = r->log;
|
||||
ctx->ident = -1;
|
||||
|
||||
ngx_add_timer(ctx->event, ctx->timeout);
|
||||
}
|
||||
|
||||
last->next = rn->waiting;
|
||||
rn->waiting = ctx;
|
||||
ctx->state = NGX_AGAIN;
|
||||
|
||||
do {
|
||||
ctx->node = rn;
|
||||
ctx = ctx->next;
|
||||
} while (ctx);
|
||||
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
|
@ -618,14 +639,14 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
rn->name = ngx_resolver_dup(r, ctx->name.data, ctx->name.len);
|
||||
rn->name = ngx_resolver_dup(r, name->data, name->len);
|
||||
if (rn->name == NULL) {
|
||||
ngx_resolver_free(r, rn);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
rn->node.key = hash;
|
||||
rn->nlen = (u_short) ctx->name.len;
|
||||
rn->nlen = (u_short) name->len;
|
||||
rn->query = NULL;
|
||||
#if (NGX_HAVE_INET6)
|
||||
rn->query6 = NULL;
|
||||
|
@ -634,7 +655,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
|
|||
ngx_rbtree_insert(&r->name_rbtree, &rn->node);
|
||||
}
|
||||
|
||||
rc = ngx_resolver_create_name_query(rn, ctx);
|
||||
rc = ngx_resolver_create_name_query(r, rn, name);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
goto failed;
|
||||
|
@ -647,8 +668,14 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
|
|||
ngx_resolver_free(r, rn->name);
|
||||
ngx_resolver_free(r, rn);
|
||||
|
||||
ctx->state = NGX_RESOLVE_NXDOMAIN;
|
||||
ctx->handler(ctx);
|
||||
do {
|
||||
ctx->state = NGX_RESOLVE_NXDOMAIN;
|
||||
next = ctx->next;
|
||||
|
||||
ctx->handler(ctx);
|
||||
|
||||
ctx = next;
|
||||
} while (ctx);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
@ -669,9 +696,9 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
|
|||
}
|
||||
|
||||
ctx->event->handler = ngx_resolver_timeout_handler;
|
||||
ctx->event->data = rn;
|
||||
ctx->event->data = ctx;
|
||||
ctx->event->log = r->log;
|
||||
rn->ident = -1;
|
||||
ctx->ident = -1;
|
||||
|
||||
ngx_add_timer(ctx->event, ctx->timeout);
|
||||
}
|
||||
|
@ -692,6 +719,11 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
|
|||
|
||||
ctx->state = NGX_AGAIN;
|
||||
|
||||
do {
|
||||
ctx->node = rn;
|
||||
ctx = ctx->next;
|
||||
} while (ctx);
|
||||
|
||||
return NGX_AGAIN;
|
||||
|
||||
failed:
|
||||
|
@ -799,9 +831,22 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
|
|||
|
||||
if (rn->waiting) {
|
||||
|
||||
ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
|
||||
if (ctx->event == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ctx->event->handler = ngx_resolver_timeout_handler;
|
||||
ctx->event->data = ctx;
|
||||
ctx->event->log = r->log;
|
||||
ctx->ident = -1;
|
||||
|
||||
ngx_add_timer(ctx->event, ctx->timeout);
|
||||
|
||||
ctx->next = rn->waiting;
|
||||
rn->waiting = ctx;
|
||||
ctx->state = NGX_AGAIN;
|
||||
ctx->node = rn;
|
||||
|
||||
/* unlock addr mutex */
|
||||
|
||||
|
@ -843,7 +888,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
|
|||
ngx_rbtree_insert(tree, &rn->node);
|
||||
}
|
||||
|
||||
if (ngx_resolver_create_addr_query(rn, ctx) != NGX_OK) {
|
||||
if (ngx_resolver_create_addr_query(r, rn, &ctx->addr) != NGX_OK) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -862,9 +907,9 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
|
|||
}
|
||||
|
||||
ctx->event->handler = ngx_resolver_timeout_handler;
|
||||
ctx->event->data = rn;
|
||||
ctx->event->data = ctx;
|
||||
ctx->event->log = r->log;
|
||||
rn->ident = -1;
|
||||
ctx->ident = -1;
|
||||
|
||||
ngx_add_timer(ctx->event, ctx->timeout);
|
||||
|
||||
|
@ -887,6 +932,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
|
|||
/* unlock addr mutex */
|
||||
|
||||
ctx->state = NGX_AGAIN;
|
||||
ctx->node = rn;
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
|
@ -917,17 +963,11 @@ failed:
|
|||
void
|
||||
ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
|
||||
{
|
||||
in_addr_t addr;
|
||||
ngx_queue_t *expire_queue;
|
||||
ngx_rbtree_t *tree;
|
||||
ngx_resolver_t *r;
|
||||
ngx_resolver_ctx_t *w, **p;
|
||||
struct sockaddr_in *sin;
|
||||
ngx_resolver_node_t *rn;
|
||||
#if (NGX_HAVE_INET6)
|
||||
uint32_t hash;
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
|
||||
r = ctx->resolver;
|
||||
|
||||
|
@ -954,23 +994,9 @@ ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
|
|||
|
||||
/* lock addr mutex */
|
||||
|
||||
if (ctx->state == NGX_AGAIN) {
|
||||
if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
|
||||
|
||||
switch (ctx->addr.sockaddr->sa_family) {
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *) ctx->addr.sockaddr;
|
||||
hash = ngx_crc32_short(sin6->sin6_addr.s6_addr, 16);
|
||||
rn = ngx_resolver_lookup_addr6(r, &sin6->sin6_addr, hash);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default: /* AF_INET */
|
||||
sin = (struct sockaddr_in *) ctx->addr.sockaddr;
|
||||
addr = ntohl(sin->sin_addr.s_addr);
|
||||
rn = ngx_resolver_lookup_addr(r, addr);
|
||||
}
|
||||
rn = ctx->node;
|
||||
|
||||
if (rn) {
|
||||
p = &rn->waiting;
|
||||
|
@ -1292,7 +1318,7 @@ ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n)
|
|||
times = 0;
|
||||
|
||||
for (q = ngx_queue_head(&r->name_resend_queue);
|
||||
q != ngx_queue_sentinel(&r->name_resend_queue) || times++ < 100;
|
||||
q != ngx_queue_sentinel(&r->name_resend_queue) && times++ < 100;
|
||||
q = ngx_queue_next(q))
|
||||
{
|
||||
rn = ngx_queue_data(q, ngx_resolver_node_t, queue);
|
||||
|
@ -1955,21 +1981,40 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
|
|||
|
||||
ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
|
||||
|
||||
ctx = rn->waiting;
|
||||
rn->waiting = NULL;
|
||||
|
||||
if (ctx) {
|
||||
ctx->name = name;
|
||||
|
||||
(void) ngx_resolve_name_locked(r, ctx);
|
||||
}
|
||||
|
||||
ngx_resolver_free(r, rn->query);
|
||||
rn->query = NULL;
|
||||
#if (NGX_HAVE_INET6)
|
||||
rn->query6 = NULL;
|
||||
#endif
|
||||
|
||||
ctx = rn->waiting;
|
||||
rn->waiting = NULL;
|
||||
|
||||
if (ctx) {
|
||||
|
||||
if (ctx->recursion++ >= NGX_RESOLVER_MAX_RECURSION) {
|
||||
|
||||
/* unlock name mutex */
|
||||
|
||||
do {
|
||||
ctx->state = NGX_RESOLVE_NXDOMAIN;
|
||||
next = ctx->next;
|
||||
|
||||
ctx->handler(ctx);
|
||||
|
||||
ctx = next;
|
||||
} while (ctx);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (next = ctx; next; next = next->next) {
|
||||
next->node = NULL;
|
||||
}
|
||||
|
||||
(void) ngx_resolve_name_locked(r, ctx, &name);
|
||||
}
|
||||
|
||||
/* unlock name mutex */
|
||||
|
||||
return;
|
||||
|
@ -2476,27 +2521,23 @@ ngx_resolver_rbtree_insert_addr6_value(ngx_rbtree_node_t *temp,
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
|
||||
ngx_resolver_create_name_query(ngx_resolver_t *r, ngx_resolver_node_t *rn,
|
||||
ngx_str_t *name)
|
||||
{
|
||||
u_char *p, *s;
|
||||
size_t len, nlen;
|
||||
ngx_uint_t ident;
|
||||
#if (NGX_HAVE_INET6)
|
||||
ngx_resolver_t *r;
|
||||
#endif
|
||||
ngx_resolver_qs_t *qs;
|
||||
ngx_resolver_hdr_t *query;
|
||||
|
||||
nlen = ctx->name.len ? (1 + ctx->name.len + 1) : 1;
|
||||
nlen = name->len ? (1 + name->len + 1) : 1;
|
||||
|
||||
len = sizeof(ngx_resolver_hdr_t) + nlen + sizeof(ngx_resolver_qs_t);
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
r = ctx->resolver;
|
||||
|
||||
p = ngx_resolver_alloc(ctx->resolver, r->ipv6 ? len * 2 : len);
|
||||
p = ngx_resolver_alloc(r, r->ipv6 ? len * 2 : len);
|
||||
#else
|
||||
p = ngx_resolver_alloc(ctx->resolver, len);
|
||||
p = ngx_resolver_alloc(r, len);
|
||||
#endif
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
|
@ -2515,8 +2556,8 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
|
|||
|
||||
ident = ngx_random();
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->resolver->log, 0,
|
||||
"resolve: \"%V\" A %i", &ctx->name, ident & 0xffff);
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
|
||||
"resolve: \"%V\" A %i", name, ident & 0xffff);
|
||||
|
||||
query->ident_hi = (u_char) ((ident >> 8) & 0xff);
|
||||
query->ident_lo = (u_char) (ident & 0xff);
|
||||
|
@ -2546,11 +2587,11 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
|
|||
p--;
|
||||
*p-- = '\0';
|
||||
|
||||
if (ctx->name.len == 0) {
|
||||
if (name->len == 0) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
for (s = ctx->name.data + ctx->name.len - 1; s >= ctx->name.data; s--) {
|
||||
for (s = name->data + name->len - 1; s >= name->data; s--) {
|
||||
if (*s != '.') {
|
||||
*p = *s;
|
||||
len++;
|
||||
|
@ -2586,8 +2627,8 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
|
|||
|
||||
ident = ngx_random();
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->resolver->log, 0,
|
||||
"resolve: \"%V\" AAAA %i", &ctx->name, ident & 0xffff);
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
|
||||
"resolve: \"%V\" AAAA %i", name, ident & 0xffff);
|
||||
|
||||
query->ident_hi = (u_char) ((ident >> 8) & 0xff);
|
||||
query->ident_lo = (u_char) (ident & 0xff);
|
||||
|
@ -2604,11 +2645,12 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
|
||||
ngx_resolver_create_addr_query(ngx_resolver_t *r, ngx_resolver_node_t *rn,
|
||||
ngx_addr_t *addr)
|
||||
{
|
||||
u_char *p, *d;
|
||||
size_t len;
|
||||
in_addr_t addr;
|
||||
in_addr_t inaddr;
|
||||
ngx_int_t n;
|
||||
ngx_uint_t ident;
|
||||
ngx_resolver_hdr_t *query;
|
||||
|
@ -2617,7 +2659,7 @@ ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
|
|||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
|
||||
switch (ctx->addr.sockaddr->sa_family) {
|
||||
switch (addr->sockaddr->sa_family) {
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
case AF_INET6:
|
||||
|
@ -2634,7 +2676,7 @@ ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
|
|||
+ sizeof(ngx_resolver_qs_t);
|
||||
}
|
||||
|
||||
p = ngx_resolver_alloc(ctx->resolver, len);
|
||||
p = ngx_resolver_alloc(r, len);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -2658,11 +2700,11 @@ ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
|
|||
|
||||
p += sizeof(ngx_resolver_hdr_t);
|
||||
|
||||
switch (ctx->addr.sockaddr->sa_family) {
|
||||
switch (addr->sockaddr->sa_family) {
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *) ctx->addr.sockaddr;
|
||||
sin6 = (struct sockaddr_in6 *) addr->sockaddr;
|
||||
|
||||
for (n = 15; n >= 0; n--) {
|
||||
p = ngx_sprintf(p, "\1%xd\1%xd",
|
||||
|
@ -2677,11 +2719,11 @@ ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
|
|||
|
||||
default: /* AF_INET */
|
||||
|
||||
sin = (struct sockaddr_in *) ctx->addr.sockaddr;
|
||||
addr = ntohl(sin->sin_addr.s_addr);
|
||||
sin = (struct sockaddr_in *) addr->sockaddr;
|
||||
inaddr = ntohl(sin->sin_addr.s_addr);
|
||||
|
||||
for (n = 0; n < 32; n += 8) {
|
||||
d = ngx_sprintf(&p[1], "%ud", (addr >> n) & 0xff);
|
||||
d = ngx_sprintf(&p[1], "%ud", (inaddr >> n) & 0xff);
|
||||
*p = (u_char) (d - &p[1]);
|
||||
p = d;
|
||||
}
|
||||
|
@ -2795,21 +2837,13 @@ done:
|
|||
static void
|
||||
ngx_resolver_timeout_handler(ngx_event_t *ev)
|
||||
{
|
||||
ngx_resolver_ctx_t *ctx, *next;
|
||||
ngx_resolver_node_t *rn;
|
||||
ngx_resolver_ctx_t *ctx;
|
||||
|
||||
rn = ev->data;
|
||||
ctx = rn->waiting;
|
||||
rn->waiting = NULL;
|
||||
ctx = ev->data;
|
||||
|
||||
do {
|
||||
ctx->state = NGX_RESOLVE_TIMEDOUT;
|
||||
next = ctx->next;
|
||||
ctx->state = NGX_RESOLVE_TIMEDOUT;
|
||||
|
||||
ctx->handler(ctx);
|
||||
|
||||
ctx = next;
|
||||
} while (ctx);
|
||||
ctx->handler(ctx);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -51,15 +51,11 @@ typedef void (*ngx_resolver_handler_pt)(ngx_resolver_ctx_t *ctx);
|
|||
|
||||
|
||||
typedef struct {
|
||||
/* PTR: resolved name, A: name to resolve */
|
||||
u_char *name;
|
||||
|
||||
ngx_rbtree_node_t node;
|
||||
ngx_queue_t queue;
|
||||
|
||||
/* event ident must be after 3 pointers as in ngx_connection_t */
|
||||
ngx_int_t ident;
|
||||
|
||||
ngx_rbtree_node_t node;
|
||||
/* PTR: resolved name, A: name to resolve */
|
||||
u_char *name;
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
/* PTR: IPv6 address to resolve (IPv4 address is in rbtree node key) */
|
||||
|
@ -147,6 +143,9 @@ struct ngx_resolver_ctx_s {
|
|||
ngx_resolver_t *resolver;
|
||||
ngx_udp_connection_t *udp_connection;
|
||||
|
||||
/* event ident must be after 3 pointers as in ngx_connection_t */
|
||||
ngx_int_t ident;
|
||||
|
||||
ngx_int_t state;
|
||||
ngx_str_t name;
|
||||
|
||||
|
@ -162,6 +161,8 @@ struct ngx_resolver_ctx_s {
|
|||
ngx_uint_t quick; /* unsigned quick:1; */
|
||||
ngx_uint_t recursion;
|
||||
ngx_event_t *event;
|
||||
|
||||
ngx_resolver_node_t *node;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -329,7 +329,7 @@ ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer)
|
|||
|
||||
#if (NGX_HAVE_EVENTFD)
|
||||
if (ngx_epoll_notify_init(cycle->log) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
ngx_epoll_module_ctx.actions.notify = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1038,6 +1038,8 @@ ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
|
|||
sc->buffer = ((flags & NGX_SSL_BUFFER) != 0);
|
||||
sc->buffer_size = ssl->buffer_size;
|
||||
|
||||
sc->session_ctx = ssl->ctx;
|
||||
|
||||
sc->connection = SSL_new(ssl->ctx);
|
||||
|
||||
if (sc->connection == NULL) {
|
||||
|
@ -2303,7 +2305,7 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
|
|||
|
||||
c = ngx_ssl_get_connection(ssl_conn);
|
||||
|
||||
ssl_ctx = SSL_get_SSL_CTX(ssl_conn);
|
||||
ssl_ctx = c->ssl->session_ctx;
|
||||
shm_zone = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_cache_index);
|
||||
|
||||
cache = shm_zone->data;
|
||||
|
@ -2441,21 +2443,17 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
|
|||
ngx_ssl_sess_id_t *sess_id;
|
||||
ngx_ssl_session_cache_t *cache;
|
||||
u_char buf[NGX_SSL_MAX_SESSION_SIZE];
|
||||
#if (NGX_DEBUG)
|
||||
ngx_connection_t *c;
|
||||
#endif
|
||||
|
||||
hash = ngx_crc32_short(id, (size_t) len);
|
||||
*copy = 0;
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
c = ngx_ssl_get_connection(ssl_conn);
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"ssl get session: %08XD:%d", hash, len);
|
||||
#endif
|
||||
|
||||
shm_zone = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl_conn),
|
||||
shm_zone = SSL_CTX_get_ex_data(c->ssl->session_ctx,
|
||||
ngx_ssl_session_cache_index);
|
||||
|
||||
cache = shm_zone->data;
|
||||
|
@ -2834,13 +2832,14 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
|
|||
SSL_CTX *ssl_ctx;
|
||||
ngx_uint_t i;
|
||||
ngx_array_t *keys;
|
||||
ngx_connection_t *c;
|
||||
ngx_ssl_session_ticket_key_t *key;
|
||||
#if (NGX_DEBUG)
|
||||
u_char buf[32];
|
||||
ngx_connection_t *c;
|
||||
#endif
|
||||
|
||||
ssl_ctx = SSL_get_SSL_CTX(ssl_conn);
|
||||
c = ngx_ssl_get_connection(ssl_conn);
|
||||
ssl_ctx = c->ssl->session_ctx;
|
||||
|
||||
keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_ticket_keys_index);
|
||||
if (keys == NULL) {
|
||||
|
@ -2849,10 +2848,6 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
|
|||
|
||||
key = keys->elts;
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
c = ngx_ssl_get_connection(ssl_conn);
|
||||
#endif
|
||||
|
||||
if (enc == 1) {
|
||||
/* encrypt session ticket */
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
ngx_ssl_conn_t *connection;
|
||||
SSL_CTX *session_ctx;
|
||||
|
||||
ngx_int_t last;
|
||||
ngx_buf_t *buf;
|
||||
|
|
|
@ -1220,7 +1220,7 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
|||
{
|
||||
u_char *p;
|
||||
size_t len, off;
|
||||
ngx_uint_t i, default_server;
|
||||
ngx_uint_t i, default_server, proxy_protocol;
|
||||
struct sockaddr *sa;
|
||||
ngx_http_conf_addr_t *addr;
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
|
@ -1281,6 +1281,8 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
|||
/* preserve default_server bit during listen options overwriting */
|
||||
default_server = addr[i].opt.default_server;
|
||||
|
||||
proxy_protocol = lsopt->proxy_protocol || addr[i].opt.proxy_protocol;
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
ssl = lsopt->ssl || addr[i].opt.ssl;
|
||||
#endif
|
||||
|
@ -1314,6 +1316,7 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
|||
}
|
||||
|
||||
addr[i].opt.default_server = default_server;
|
||||
addr[i].opt.proxy_protocol = proxy_protocol;
|
||||
#if (NGX_HTTP_SSL)
|
||||
addr[i].opt.ssl = ssl;
|
||||
#endif
|
||||
|
|
|
@ -1272,7 +1272,9 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
|
|||
|
||||
*e.pos = '\0';
|
||||
|
||||
if (alias && ngx_strncmp(name, clcf->name.data, alias) == 0) {
|
||||
if (alias && alias != NGX_MAX_SIZE_T_VALUE
|
||||
&& ngx_strncmp(name, r->uri.data, alias) == 0)
|
||||
{
|
||||
ngx_memmove(name, name + alias, len - alias);
|
||||
path.len -= alias;
|
||||
}
|
||||
|
@ -1355,6 +1357,8 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
|
|||
}
|
||||
|
||||
} else {
|
||||
name = r->uri.data;
|
||||
|
||||
r->uri.len = alias + path.len;
|
||||
r->uri.data = ngx_pnalloc(r->pool, r->uri.len);
|
||||
if (r->uri.data == NULL) {
|
||||
|
@ -1362,8 +1366,8 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
|
|||
return NGX_OK;
|
||||
}
|
||||
|
||||
p = ngx_copy(r->uri.data, clcf->name.data, alias);
|
||||
ngx_memcpy(p, name, path.len);
|
||||
p = ngx_copy(r->uri.data, name, alias);
|
||||
ngx_memcpy(p, path.data, path.len);
|
||||
}
|
||||
|
||||
ngx_http_set_exten(r);
|
||||
|
|
|
@ -770,24 +770,32 @@ ngx_http_ssl_handshake_handler(ngx_connection_t *c)
|
|||
{
|
||||
unsigned int len;
|
||||
const unsigned char *data;
|
||||
ngx_http_connection_t *hc;
|
||||
static const ngx_str_t spdy = ngx_string(NGX_SPDY_NPN_NEGOTIATED);
|
||||
|
||||
hc = c->data;
|
||||
|
||||
if (hc->addr_conf->spdy) {
|
||||
|
||||
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
||||
SSL_get0_alpn_selected(c->ssl->connection, &data, &len);
|
||||
SSL_get0_alpn_selected(c->ssl->connection, &data, &len);
|
||||
|
||||
#ifdef TLSEXT_TYPE_next_proto_neg
|
||||
if (len == 0) {
|
||||
SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
|
||||
}
|
||||
if (len == 0) {
|
||||
SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* TLSEXT_TYPE_next_proto_neg */
|
||||
SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
|
||||
SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
|
||||
#endif
|
||||
|
||||
if (len == spdy.len && ngx_strncmp(data, spdy.data, spdy.len) == 0) {
|
||||
ngx_http_spdy_init(c->read);
|
||||
return;
|
||||
if (len == spdy.len
|
||||
&& ngx_strncmp(data, spdy.data, spdy.len) == 0)
|
||||
{
|
||||
ngx_http_spdy_init(c->read);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -530,15 +530,24 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
|
|||
|
||||
r->write_event_handler = ngx_http_request_empty_handler;
|
||||
|
||||
if (rc == NGX_DONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
rc = ngx_http_upstream_cache_send(r, u);
|
||||
|
||||
if (rc == NGX_DONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == NGX_HTTP_UPSTREAM_INVALID_HEADER) {
|
||||
rc = NGX_DECLINED;
|
||||
r->cached = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc != NGX_DECLINED) {
|
||||
ngx_http_finalize_request(r, rc);
|
||||
return;
|
||||
|
@ -833,13 +842,7 @@ ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
|
||||
case NGX_OK:
|
||||
|
||||
rc = ngx_http_upstream_cache_send(r, u);
|
||||
|
||||
if (rc != NGX_HTTP_UPSTREAM_INVALID_HEADER) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
break;
|
||||
return NGX_OK;
|
||||
|
||||
case NGX_HTTP_CACHE_STALE:
|
||||
|
||||
|
|
Loading…
Reference in a new issue