nginxtra 1.8.1.12 → 1.10.1.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/nginxtra +1 -1
- data/bin/nginxtra_rails +1 -1
- data/lib/nginxtra/version.rb +1 -1
- data/vendor/nginx/CHANGES +363 -25
- data/vendor/nginx/CHANGES.ru +365 -21
- data/vendor/nginx/LICENSE +2 -2
- data/vendor/nginx/auto/cc/conf +32 -0
- data/vendor/nginx/auto/cc/gcc +1 -1
- data/vendor/nginx/auto/cc/icc +2 -2
- data/vendor/nginx/auto/cc/msvc +29 -8
- data/vendor/nginx/auto/cc/name +2 -25
- data/vendor/nginx/auto/cc/sunc +3 -0
- data/vendor/nginx/auto/endianness +7 -2
- data/vendor/nginx/auto/install +60 -26
- data/vendor/nginx/auto/lib/conf +4 -4
- data/vendor/nginx/auto/lib/geoip/conf +6 -1
- data/vendor/nginx/auto/lib/libgd/conf +6 -1
- data/vendor/nginx/auto/lib/libxslt/conf +11 -2
- data/vendor/nginx/auto/lib/make +1 -1
- data/vendor/nginx/auto/lib/md5/conf +2 -2
- data/vendor/nginx/auto/lib/md5/make +2 -2
- data/vendor/nginx/auto/lib/openssl/conf +52 -3
- data/vendor/nginx/auto/lib/openssl/make +1 -1
- data/vendor/nginx/auto/lib/pcre/conf +2 -2
- data/vendor/nginx/auto/lib/pcre/make +2 -2
- data/vendor/nginx/auto/lib/perl/conf +6 -3
- data/vendor/nginx/auto/lib/perl/make +4 -1
- data/vendor/nginx/auto/lib/sha1/conf +2 -2
- data/vendor/nginx/auto/lib/sha1/make +2 -2
- data/vendor/nginx/auto/lib/zlib/conf +2 -2
- data/vendor/nginx/auto/lib/zlib/make +2 -2
- data/vendor/nginx/auto/make +281 -16
- data/vendor/nginx/auto/module +122 -0
- data/vendor/nginx/auto/modules +909 -178
- data/vendor/nginx/auto/options +81 -19
- data/vendor/nginx/auto/os/conf +9 -0
- data/vendor/nginx/auto/os/darwin +3 -0
- data/vendor/nginx/auto/os/freebsd +0 -20
- data/vendor/nginx/auto/os/linux +0 -12
- data/vendor/nginx/auto/os/win32 +5 -1
- data/vendor/nginx/auto/sources +11 -311
- data/vendor/nginx/auto/summary +1 -0
- data/vendor/nginx/auto/types/sizeof +5 -3
- data/vendor/nginx/auto/types/typedef +9 -4
- data/vendor/nginx/auto/types/uintptr_t +7 -2
- data/vendor/nginx/auto/unix +72 -12
- data/vendor/nginx/conf/fastcgi.conf +1 -0
- data/vendor/nginx/conf/fastcgi_params +1 -0
- data/vendor/nginx/conf/scgi_params +1 -0
- data/vendor/nginx/conf/uwsgi_params +1 -0
- data/vendor/nginx/configure +1 -1
- data/vendor/nginx/contrib/vim/syntax/nginx.vim +2 -2
- data/vendor/nginx/man/nginx.8 +6 -2
- data/vendor/nginx/src/core/nginx.c +281 -114
- data/vendor/nginx/src/core/nginx.h +2 -2
- data/vendor/nginx/src/core/ngx_conf_file.c +54 -13
- data/vendor/nginx/src/core/ngx_conf_file.h +8 -52
- data/vendor/nginx/src/core/ngx_config.h +0 -5
- data/vendor/nginx/src/core/ngx_connection.c +270 -37
- data/vendor/nginx/src/core/ngx_connection.h +35 -12
- data/vendor/nginx/src/core/ngx_core.h +4 -0
- data/vendor/nginx/src/core/ngx_crypt.c +2 -2
- data/vendor/nginx/src/core/ngx_cycle.c +72 -25
- data/vendor/nginx/src/core/ngx_cycle.h +28 -39
- data/vendor/nginx/src/core/ngx_file.c +14 -5
- data/vendor/nginx/src/core/ngx_file.h +2 -0
- data/vendor/nginx/src/core/ngx_hash.c +13 -1
- data/vendor/nginx/src/core/ngx_inet.c +20 -18
- data/vendor/nginx/src/core/ngx_log.c +12 -12
- data/vendor/nginx/src/core/ngx_log.h +13 -6
- data/vendor/nginx/src/core/ngx_module.c +360 -0
- data/vendor/nginx/src/core/ngx_module.h +307 -0
- data/vendor/nginx/src/core/ngx_open_file_cache.c +2 -2
- data/vendor/nginx/src/core/ngx_output_chain.c +8 -4
- data/vendor/nginx/src/core/ngx_palloc.c +42 -44
- data/vendor/nginx/src/{http/ngx_http_parse_time.c → core/ngx_parse_time.c} +2 -3
- data/vendor/nginx/src/core/ngx_parse_time.h +22 -0
- data/vendor/nginx/src/core/ngx_proxy_protocol.c +50 -1
- data/vendor/nginx/src/core/ngx_proxy_protocol.h +3 -1
- data/vendor/nginx/src/core/ngx_regex.c +1 -38
- data/vendor/nginx/src/core/ngx_resolver.c +1814 -320
- data/vendor/nginx/src/core/ngx_resolver.h +67 -10
- data/vendor/nginx/src/core/ngx_rwlock.c +120 -0
- data/vendor/nginx/src/core/ngx_rwlock.h +21 -0
- data/vendor/nginx/src/core/ngx_slab.c +6 -5
- data/vendor/nginx/src/core/ngx_string.c +1 -1
- data/vendor/nginx/src/core/ngx_syslog.c +11 -3
- data/vendor/nginx/src/core/ngx_syslog.h +2 -1
- data/vendor/nginx/src/core/ngx_thread_pool.c +4 -0
- data/vendor/nginx/src/core/ngx_times.c +2 -2
- data/vendor/nginx/src/event/modules/ngx_devpoll_module.c +3 -1
- data/vendor/nginx/src/event/modules/ngx_epoll_module.c +5 -2
- data/vendor/nginx/src/event/modules/ngx_eventport_module.c +5 -5
- data/vendor/nginx/src/event/modules/ngx_kqueue_module.c +15 -8
- data/vendor/nginx/src/event/modules/ngx_poll_module.c +0 -10
- data/vendor/nginx/src/event/modules/ngx_select_module.c +0 -10
- data/vendor/nginx/src/event/ngx_event.c +60 -103
- data/vendor/nginx/src/event/ngx_event.h +22 -26
- data/vendor/nginx/src/event/ngx_event_accept.c +414 -88
- data/vendor/nginx/src/event/ngx_event_connect.c +27 -18
- data/vendor/nginx/src/event/ngx_event_connect.h +1 -0
- data/vendor/nginx/src/event/ngx_event_openssl.c +65 -25
- data/vendor/nginx/src/event/ngx_event_openssl.h +17 -0
- data/vendor/nginx/src/event/ngx_event_openssl_stapling.c +73 -7
- data/vendor/nginx/src/event/ngx_event_pipe.c +85 -27
- data/vendor/nginx/src/event/ngx_event_pipe.h +10 -0
- data/vendor/nginx/src/http/modules/ngx_http_auth_basic_module.c +1 -1
- data/vendor/nginx/src/http/modules/ngx_http_auth_request_module.c +2 -2
- data/vendor/nginx/src/http/modules/ngx_http_chunked_filter_module.c +2 -2
- data/vendor/nginx/src/http/modules/ngx_http_dav_module.c +6 -6
- data/vendor/nginx/src/http/modules/ngx_http_fastcgi_module.c +17 -11
- data/vendor/nginx/src/http/modules/ngx_http_gzip_filter_module.c +2 -2
- data/vendor/nginx/src/http/modules/ngx_http_headers_filter_module.c +9 -9
- data/vendor/nginx/src/http/modules/ngx_http_image_filter_module.c +2 -2
- data/vendor/nginx/src/http/modules/ngx_http_limit_conn_module.c +2 -2
- data/vendor/nginx/src/http/modules/ngx_http_limit_req_module.c +0 -7
- data/vendor/nginx/src/http/modules/ngx_http_map_module.c +6 -6
- data/vendor/nginx/src/http/modules/ngx_http_memcached_module.c +2 -1
- data/vendor/nginx/src/http/modules/ngx_http_mp4_module.c +13 -13
- data/vendor/nginx/src/http/modules/ngx_http_not_modified_filter_module.c +2 -2
- data/vendor/nginx/src/http/modules/ngx_http_proxy_module.c +26 -21
- data/vendor/nginx/src/http/modules/ngx_http_random_index_module.c +1 -1
- data/vendor/nginx/src/http/modules/ngx_http_range_filter_module.c +26 -8
- data/vendor/nginx/src/http/modules/ngx_http_realip_module.c +73 -3
- data/vendor/nginx/src/http/modules/ngx_http_referer_module.c +1 -1
- data/vendor/nginx/src/http/modules/ngx_http_rewrite_module.c +6 -6
- data/vendor/nginx/src/http/modules/ngx_http_scgi_module.c +5 -3
- data/vendor/nginx/src/http/modules/ngx_http_slice_filter_module.c +526 -0
- data/vendor/nginx/src/http/modules/ngx_http_ssi_filter_module.c +7 -7
- data/vendor/nginx/src/http/modules/ngx_http_ssl_module.c +19 -16
- data/vendor/nginx/src/http/modules/ngx_http_static_module.c +1 -1
- data/vendor/nginx/src/http/modules/ngx_http_stub_status_module.c +1 -1
- data/vendor/nginx/src/http/modules/ngx_http_sub_filter_module.c +373 -173
- data/vendor/nginx/src/http/modules/ngx_http_upstream_hash_module.c +72 -46
- data/vendor/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +18 -30
- data/vendor/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c +50 -39
- data/vendor/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c +38 -129
- data/vendor/nginx/src/http/modules/ngx_http_upstream_zone_module.c +246 -0
- data/vendor/nginx/src/http/modules/ngx_http_uwsgi_module.c +6 -5
- data/vendor/nginx/src/http/modules/perl/nginx.xs +9 -9
- data/vendor/nginx/src/http/ngx_http.c +46 -43
- data/vendor/nginx/src/http/ngx_http.h +4 -9
- data/vendor/nginx/src/http/ngx_http_cache.h +4 -0
- data/vendor/nginx/src/http/ngx_http_copy_filter_module.c +13 -5
- data/vendor/nginx/src/http/ngx_http_core_module.c +92 -91
- data/vendor/nginx/src/http/ngx_http_core_module.h +12 -8
- data/vendor/nginx/src/http/ngx_http_file_cache.c +61 -10
- data/vendor/nginx/src/http/ngx_http_request.c +37 -50
- data/vendor/nginx/src/http/ngx_http_request.h +10 -15
- data/vendor/nginx/src/http/ngx_http_request_body.c +64 -88
- data/vendor/nginx/src/http/ngx_http_script.c +3 -3
- data/vendor/nginx/src/http/ngx_http_special_response.c +1 -4
- data/vendor/nginx/src/http/ngx_http_upstream.c +245 -109
- data/vendor/nginx/src/http/ngx_http_upstream.h +11 -5
- data/vendor/nginx/src/http/ngx_http_upstream_round_robin.c +212 -65
- data/vendor/nginx/src/http/ngx_http_upstream_round_robin.h +66 -5
- data/vendor/nginx/src/http/ngx_http_variables.c +28 -15
- data/vendor/nginx/src/http/ngx_http_write_filter_module.c +1 -1
- data/vendor/nginx/src/http/v2/ngx_http_v2.c +4349 -0
- data/vendor/nginx/src/http/v2/ngx_http_v2.h +337 -0
- data/vendor/nginx/src/http/v2/ngx_http_v2_filter_module.c +1391 -0
- data/vendor/nginx/src/http/v2/ngx_http_v2_huff_decode.c +2714 -0
- data/vendor/nginx/src/http/v2/ngx_http_v2_huff_encode.c +254 -0
- data/vendor/nginx/src/http/v2/ngx_http_v2_module.c +469 -0
- data/vendor/nginx/src/http/{ngx_http_spdy_module.h → v2/ngx_http_v2_module.h} +10 -9
- data/vendor/nginx/src/http/v2/ngx_http_v2_table.c +349 -0
- data/vendor/nginx/src/mail/ngx_mail.c +49 -82
- data/vendor/nginx/src/mail/ngx_mail.h +16 -23
- data/vendor/nginx/src/mail/ngx_mail_auth_http_module.c +1 -1
- data/vendor/nginx/src/mail/ngx_mail_core_module.c +60 -34
- data/vendor/nginx/src/mail/ngx_mail_handler.c +17 -12
- data/vendor/nginx/src/mail/ngx_mail_proxy_module.c +1 -14
- data/vendor/nginx/src/mail/ngx_mail_smtp_handler.c +1 -1
- data/vendor/nginx/src/mail/ngx_mail_ssl_module.c +5 -5
- data/vendor/nginx/src/os/unix/ngx_atomic.h +10 -10
- data/vendor/nginx/src/os/unix/ngx_channel.h +4 -4
- data/vendor/nginx/src/os/unix/ngx_darwin_config.h +2 -0
- data/vendor/nginx/src/os/unix/ngx_darwin_init.c +1 -0
- data/vendor/nginx/src/os/unix/ngx_dlopen.c +28 -0
- data/vendor/nginx/src/os/unix/ngx_dlopen.h +31 -0
- data/vendor/nginx/src/os/unix/ngx_errno.h +1 -0
- data/vendor/nginx/src/os/unix/ngx_file_aio_read.c +1 -1
- data/vendor/nginx/src/os/unix/ngx_files.c +313 -80
- data/vendor/nginx/src/os/unix/ngx_files.h +5 -2
- data/vendor/nginx/src/os/unix/ngx_freebsd_config.h +3 -1
- data/vendor/nginx/src/os/unix/ngx_freebsd_init.c +1 -0
- data/vendor/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c +13 -0
- data/vendor/nginx/src/os/unix/ngx_linux.h +0 -2
- data/vendor/nginx/src/os/unix/ngx_linux_aio_read.c +1 -1
- data/vendor/nginx/src/os/unix/ngx_linux_config.h +2 -6
- data/vendor/nginx/src/os/unix/ngx_linux_init.c +1 -33
- data/vendor/nginx/src/os/unix/ngx_linux_sendfile_chain.c +55 -12
- data/vendor/nginx/src/os/unix/ngx_os.h +3 -9
- data/vendor/nginx/src/os/unix/ngx_posix_config.h +14 -1
- data/vendor/nginx/src/os/unix/ngx_posix_init.c +2 -1
- data/vendor/nginx/src/os/unix/ngx_process.c +1 -1
- data/vendor/nginx/src/os/unix/ngx_process_cycle.c +25 -51
- data/vendor/nginx/src/os/unix/ngx_process_cycle.h +1 -0
- data/vendor/nginx/src/os/unix/ngx_readv_chain.c +24 -28
- data/vendor/nginx/src/os/unix/ngx_recv.c +30 -79
- data/vendor/nginx/src/os/unix/ngx_send.c +1 -1
- data/vendor/nginx/src/os/unix/ngx_setaffinity.c +14 -30
- data/vendor/nginx/src/os/unix/ngx_setaffinity.h +15 -1
- data/vendor/nginx/src/os/unix/ngx_solaris_config.h +2 -0
- data/vendor/nginx/src/os/unix/ngx_solaris_init.c +1 -0
- data/vendor/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c +23 -0
- data/vendor/nginx/src/os/unix/ngx_sunpro_amd64.il +3 -3
- data/vendor/nginx/src/os/unix/ngx_sunpro_x86.il +3 -3
- data/vendor/nginx/src/os/unix/ngx_udp_recv.c +5 -48
- data/vendor/nginx/src/os/unix/ngx_udp_send.c +56 -0
- data/vendor/nginx/src/stream/ngx_stream.c +564 -0
- data/vendor/nginx/src/stream/ngx_stream.h +212 -0
- data/vendor/nginx/src/stream/ngx_stream_access_module.c +451 -0
- data/vendor/nginx/src/stream/ngx_stream_core_module.c +562 -0
- data/vendor/nginx/src/stream/ngx_stream_handler.c +344 -0
- data/vendor/nginx/src/stream/ngx_stream_limit_conn_module.c +632 -0
- data/vendor/nginx/src/stream/ngx_stream_proxy_module.c +1674 -0
- data/vendor/nginx/src/stream/ngx_stream_ssl_module.c +460 -0
- data/vendor/nginx/src/stream/ngx_stream_ssl_module.h +49 -0
- data/vendor/nginx/src/stream/ngx_stream_upstream.c +464 -0
- data/vendor/nginx/src/stream/ngx_stream_upstream.h +107 -0
- data/vendor/nginx/src/stream/ngx_stream_upstream_hash_module.c +656 -0
- data/vendor/nginx/src/stream/ngx_stream_upstream_least_conn_module.c +307 -0
- data/vendor/nginx/src/stream/ngx_stream_upstream_round_robin.c +702 -0
- data/vendor/nginx/src/stream/ngx_stream_upstream_round_robin.h +139 -0
- data/vendor/nginx/src/stream/ngx_stream_upstream_zone_module.c +242 -0
- metadata +39 -15
- data/vendor/nginx/src/event/modules/ngx_aio_module.c +0 -171
- data/vendor/nginx/src/event/modules/ngx_rtsig_module.c +0 -735
- data/vendor/nginx/src/http/ngx_http_spdy.c +0 -3701
- data/vendor/nginx/src/http/ngx_http_spdy.h +0 -261
- data/vendor/nginx/src/http/ngx_http_spdy_filter_module.c +0 -1222
- data/vendor/nginx/src/http/ngx_http_spdy_module.c +0 -408
- data/vendor/nginx/src/os/unix/ngx_aio_read.c +0 -109
- data/vendor/nginx/src/os/unix/ngx_aio_read_chain.c +0 -78
- data/vendor/nginx/src/os/unix/ngx_aio_write.c +0 -109
- data/vendor/nginx/src/os/unix/ngx_aio_write_chain.c +0 -100
@@ -7,13 +7,12 @@
|
|
7
7
|
|
8
8
|
#include <ngx_config.h>
|
9
9
|
#include <ngx_core.h>
|
10
|
-
#include <ngx_http.h>
|
11
10
|
|
12
11
|
|
13
12
|
static ngx_uint_t mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
14
13
|
|
15
14
|
time_t
|
16
|
-
|
15
|
+
ngx_parse_http_time(u_char *value, size_t len)
|
17
16
|
{
|
18
17
|
u_char *p, *end;
|
19
18
|
ngx_int_t month;
|
@@ -221,7 +220,7 @@ ngx_http_parse_time(u_char *value, size_t len)
|
|
221
220
|
}
|
222
221
|
|
223
222
|
if (hour > 23 || min > 59 || sec > 59) {
|
224
|
-
|
223
|
+
return NGX_ERROR;
|
225
224
|
}
|
226
225
|
|
227
226
|
if (day == 29 && month == 1) {
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
/*
|
3
|
+
* Copyright (C) Igor Sysoev
|
4
|
+
* Copyright (C) Nginx, Inc.
|
5
|
+
*/
|
6
|
+
|
7
|
+
|
8
|
+
#ifndef _NGX_PARSE_TIME_H_INCLUDED_
|
9
|
+
#define _NGX_PARSE_TIME_H_INCLUDED_
|
10
|
+
|
11
|
+
|
12
|
+
#include <ngx_config.h>
|
13
|
+
#include <ngx_core.h>
|
14
|
+
|
15
|
+
|
16
|
+
time_t ngx_parse_http_time(u_char *value, size_t len);
|
17
|
+
|
18
|
+
/* compatibility */
|
19
|
+
#define ngx_http_parse_time(value, len) ngx_parse_http_time(value, len)
|
20
|
+
|
21
|
+
|
22
|
+
#endif /* _NGX_PARSE_TIME_H_INCLUDED_ */
|
@@ -10,7 +10,7 @@
|
|
10
10
|
|
11
11
|
|
12
12
|
u_char *
|
13
|
-
|
13
|
+
ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last)
|
14
14
|
{
|
15
15
|
size_t len;
|
16
16
|
u_char ch, *p, *addr;
|
@@ -89,3 +89,52 @@ invalid:
|
|
89
89
|
|
90
90
|
return NULL;
|
91
91
|
}
|
92
|
+
|
93
|
+
|
94
|
+
u_char *
|
95
|
+
ngx_proxy_protocol_write(ngx_connection_t *c, u_char *buf, u_char *last)
|
96
|
+
{
|
97
|
+
ngx_uint_t port, lport;
|
98
|
+
|
99
|
+
if (last - buf < NGX_PROXY_PROTOCOL_MAX_HEADER) {
|
100
|
+
return NULL;
|
101
|
+
}
|
102
|
+
|
103
|
+
if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
|
104
|
+
return NULL;
|
105
|
+
}
|
106
|
+
|
107
|
+
switch (c->sockaddr->sa_family) {
|
108
|
+
|
109
|
+
case AF_INET:
|
110
|
+
buf = ngx_cpymem(buf, "PROXY TCP4 ", sizeof("PROXY TCP4 ") - 1);
|
111
|
+
|
112
|
+
port = ntohs(((struct sockaddr_in *) c->sockaddr)->sin_port);
|
113
|
+
lport = ntohs(((struct sockaddr_in *) c->local_sockaddr)->sin_port);
|
114
|
+
|
115
|
+
break;
|
116
|
+
|
117
|
+
#if (NGX_HAVE_INET6)
|
118
|
+
case AF_INET6:
|
119
|
+
buf = ngx_cpymem(buf, "PROXY TCP6 ", sizeof("PROXY TCP6 ") - 1);
|
120
|
+
|
121
|
+
port = ntohs(((struct sockaddr_in6 *) c->sockaddr)->sin6_port);
|
122
|
+
lport = ntohs(((struct sockaddr_in6 *) c->local_sockaddr)->sin6_port);
|
123
|
+
|
124
|
+
break;
|
125
|
+
#endif
|
126
|
+
|
127
|
+
default:
|
128
|
+
return ngx_cpymem(buf, "PROXY UNKNOWN" CRLF,
|
129
|
+
sizeof("PROXY UNKNOWN" CRLF) - 1);
|
130
|
+
}
|
131
|
+
|
132
|
+
buf += ngx_sock_ntop(c->sockaddr, c->socklen, buf, last - buf, 0);
|
133
|
+
|
134
|
+
*buf++ = ' ';
|
135
|
+
|
136
|
+
buf += ngx_sock_ntop(c->local_sockaddr, c->local_socklen, buf, last - buf,
|
137
|
+
0);
|
138
|
+
|
139
|
+
return ngx_slprintf(buf, last, " %ui %ui" CRLF, port, lport);
|
140
|
+
}
|
@@ -16,7 +16,9 @@
|
|
16
16
|
#define NGX_PROXY_PROTOCOL_MAX_HEADER 107
|
17
17
|
|
18
18
|
|
19
|
-
u_char *
|
19
|
+
u_char *ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf,
|
20
|
+
u_char *last);
|
21
|
+
u_char *ngx_proxy_protocol_write(ngx_connection_t *c, u_char *buf,
|
20
22
|
u_char *last);
|
21
23
|
|
22
24
|
|
@@ -32,7 +32,7 @@ static ngx_conf_post_t ngx_regex_pcre_jit_post = { ngx_regex_pcre_jit };
|
|
32
32
|
static ngx_command_t ngx_regex_commands[] = {
|
33
33
|
|
34
34
|
{ ngx_string("pcre_jit"),
|
35
|
-
NGX_MAIN_CONF|NGX_DIRECT_CONF|
|
35
|
+
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
|
36
36
|
ngx_conf_set_flag_slot,
|
37
37
|
0,
|
38
38
|
offsetof(ngx_regex_conf_t, pcre_jit),
|
@@ -80,17 +80,6 @@ ngx_regex_init(void)
|
|
80
80
|
static ngx_inline void
|
81
81
|
ngx_regex_malloc_init(ngx_pool_t *pool)
|
82
82
|
{
|
83
|
-
#if (NGX_OLD_THREADS)
|
84
|
-
ngx_core_tls_t *tls;
|
85
|
-
|
86
|
-
if (ngx_threaded) {
|
87
|
-
tls = ngx_thread_get_tls(ngx_core_tls_key);
|
88
|
-
tls->pool = pool;
|
89
|
-
return;
|
90
|
-
}
|
91
|
-
|
92
|
-
#endif
|
93
|
-
|
94
83
|
ngx_pcre_pool = pool;
|
95
84
|
}
|
96
85
|
|
@@ -98,17 +87,6 @@ ngx_regex_malloc_init(ngx_pool_t *pool)
|
|
98
87
|
static ngx_inline void
|
99
88
|
ngx_regex_malloc_done(void)
|
100
89
|
{
|
101
|
-
#if (NGX_OLD_THREADS)
|
102
|
-
ngx_core_tls_t *tls;
|
103
|
-
|
104
|
-
if (ngx_threaded) {
|
105
|
-
tls = ngx_thread_get_tls(ngx_core_tls_key);
|
106
|
-
tls->pool = NULL;
|
107
|
-
return;
|
108
|
-
}
|
109
|
-
|
110
|
-
#endif
|
111
|
-
|
112
90
|
ngx_pcre_pool = NULL;
|
113
91
|
}
|
114
92
|
|
@@ -253,23 +231,8 @@ static void * ngx_libc_cdecl
|
|
253
231
|
ngx_regex_malloc(size_t size)
|
254
232
|
{
|
255
233
|
ngx_pool_t *pool;
|
256
|
-
#if (NGX_OLD_THREADS)
|
257
|
-
ngx_core_tls_t *tls;
|
258
|
-
|
259
|
-
if (ngx_threaded) {
|
260
|
-
tls = ngx_thread_get_tls(ngx_core_tls_key);
|
261
|
-
pool = tls->pool;
|
262
|
-
|
263
|
-
} else {
|
264
|
-
pool = ngx_pcre_pool;
|
265
|
-
}
|
266
|
-
|
267
|
-
#else
|
268
|
-
|
269
234
|
pool = ngx_pcre_pool;
|
270
235
|
|
271
|
-
#endif
|
272
|
-
|
273
236
|
if (pool) {
|
274
237
|
return ngx_palloc(pool, size);
|
275
238
|
}
|
@@ -12,6 +12,9 @@
|
|
12
12
|
|
13
13
|
#define NGX_RESOLVER_UDP_SIZE 4096
|
14
14
|
|
15
|
+
#define NGX_RESOLVER_TCP_RSIZE (2 + 65535)
|
16
|
+
#define NGX_RESOLVER_TCP_WSIZE 8192
|
17
|
+
|
15
18
|
|
16
19
|
typedef struct {
|
17
20
|
u_char ident_hi;
|
@@ -53,7 +56,8 @@ typedef struct {
|
|
53
56
|
((u_char *) (n) - offsetof(ngx_resolver_node_t, node))
|
54
57
|
|
55
58
|
|
56
|
-
ngx_int_t ngx_udp_connect(
|
59
|
+
ngx_int_t ngx_udp_connect(ngx_resolver_connection_t *rec);
|
60
|
+
ngx_int_t ngx_tcp_connect(ngx_resolver_connection_t *rec);
|
57
61
|
|
58
62
|
|
59
63
|
static void ngx_resolver_cleanup(void *data);
|
@@ -64,23 +68,37 @@ static void ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree,
|
|
64
68
|
ngx_queue_t *queue);
|
65
69
|
static ngx_int_t ngx_resolver_send_query(ngx_resolver_t *r,
|
66
70
|
ngx_resolver_node_t *rn);
|
71
|
+
static ngx_int_t ngx_resolver_send_udp_query(ngx_resolver_t *r,
|
72
|
+
ngx_resolver_connection_t *rec, u_char *query, u_short qlen);
|
73
|
+
static ngx_int_t ngx_resolver_send_tcp_query(ngx_resolver_t *r,
|
74
|
+
ngx_resolver_connection_t *rec, u_char *query, u_short qlen);
|
67
75
|
static ngx_int_t ngx_resolver_create_name_query(ngx_resolver_t *r,
|
68
76
|
ngx_resolver_node_t *rn, ngx_str_t *name);
|
77
|
+
static ngx_int_t ngx_resolver_create_srv_query(ngx_resolver_t *r,
|
78
|
+
ngx_resolver_node_t *rn, ngx_str_t *name);
|
69
79
|
static ngx_int_t ngx_resolver_create_addr_query(ngx_resolver_t *r,
|
70
|
-
ngx_resolver_node_t *rn,
|
80
|
+
ngx_resolver_node_t *rn, ngx_resolver_addr_t *addr);
|
71
81
|
static void ngx_resolver_resend_handler(ngx_event_t *ev);
|
72
82
|
static time_t ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree,
|
73
83
|
ngx_queue_t *queue);
|
74
|
-
static
|
84
|
+
static ngx_uint_t ngx_resolver_resend_empty(ngx_resolver_t *r);
|
85
|
+
static void ngx_resolver_udp_read(ngx_event_t *rev);
|
86
|
+
static void ngx_resolver_tcp_write(ngx_event_t *wev);
|
87
|
+
static void ngx_resolver_tcp_read(ngx_event_t *rev);
|
75
88
|
static void ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf,
|
76
|
-
size_t n);
|
89
|
+
size_t n, ngx_uint_t tcp);
|
77
90
|
static void ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t n,
|
78
91
|
ngx_uint_t ident, ngx_uint_t code, ngx_uint_t qtype,
|
79
|
-
ngx_uint_t nan, ngx_uint_t ans);
|
92
|
+
ngx_uint_t nan, ngx_uint_t trunc, ngx_uint_t ans);
|
93
|
+
static void ngx_resolver_process_srv(ngx_resolver_t *r, u_char *buf, size_t n,
|
94
|
+
ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan,
|
95
|
+
ngx_uint_t trunc, ngx_uint_t ans);
|
80
96
|
static void ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
|
81
97
|
ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan);
|
82
98
|
static ngx_resolver_node_t *ngx_resolver_lookup_name(ngx_resolver_t *r,
|
83
99
|
ngx_str_t *name, uint32_t hash);
|
100
|
+
static ngx_resolver_node_t *ngx_resolver_lookup_srv(ngx_resolver_t *r,
|
101
|
+
ngx_str_t *name, uint32_t hash);
|
84
102
|
static ngx_resolver_node_t *ngx_resolver_lookup_addr(ngx_resolver_t *r,
|
85
103
|
in_addr_t addr);
|
86
104
|
static void ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t *temp,
|
@@ -94,9 +112,14 @@ static void *ngx_resolver_calloc(ngx_resolver_t *r, size_t size);
|
|
94
112
|
static void ngx_resolver_free(ngx_resolver_t *r, void *p);
|
95
113
|
static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p);
|
96
114
|
static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size);
|
97
|
-
static
|
115
|
+
static ngx_resolver_addr_t *ngx_resolver_export(ngx_resolver_t *r,
|
98
116
|
ngx_resolver_node_t *rn, ngx_uint_t rotate);
|
117
|
+
static void ngx_resolver_report_srv(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx);
|
99
118
|
static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len);
|
119
|
+
static void ngx_resolver_resolve_srv_names(ngx_resolver_ctx_t *ctx,
|
120
|
+
ngx_resolver_node_t *rn);
|
121
|
+
static void ngx_resolver_srv_names_handler(ngx_resolver_ctx_t *ctx);
|
122
|
+
static ngx_int_t ngx_resolver_cmp_srvs(const void *one, const void *two);
|
100
123
|
|
101
124
|
#if (NGX_HAVE_INET6)
|
102
125
|
static void ngx_resolver_rbtree_insert_addr6_value(ngx_rbtree_node_t *temp,
|
@@ -109,12 +132,12 @@ static ngx_resolver_node_t *ngx_resolver_lookup_addr6(ngx_resolver_t *r,
|
|
109
132
|
ngx_resolver_t *
|
110
133
|
ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
|
111
134
|
{
|
112
|
-
ngx_str_t
|
113
|
-
ngx_url_t
|
114
|
-
ngx_uint_t
|
115
|
-
ngx_resolver_t
|
116
|
-
ngx_pool_cleanup_t
|
117
|
-
|
135
|
+
ngx_str_t s;
|
136
|
+
ngx_url_t u;
|
137
|
+
ngx_uint_t i, j;
|
138
|
+
ngx_resolver_t *r;
|
139
|
+
ngx_pool_cleanup_t *cln;
|
140
|
+
ngx_resolver_connection_t *rec;
|
118
141
|
|
119
142
|
cln = ngx_pool_cleanup_add(cf->pool, 0);
|
120
143
|
if (cln == NULL) {
|
@@ -138,13 +161,18 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
|
|
138
161
|
ngx_rbtree_init(&r->name_rbtree, &r->name_sentinel,
|
139
162
|
ngx_resolver_rbtree_insert_value);
|
140
163
|
|
164
|
+
ngx_rbtree_init(&r->srv_rbtree, &r->srv_sentinel,
|
165
|
+
ngx_resolver_rbtree_insert_value);
|
166
|
+
|
141
167
|
ngx_rbtree_init(&r->addr_rbtree, &r->addr_sentinel,
|
142
168
|
ngx_rbtree_insert_value);
|
143
169
|
|
144
170
|
ngx_queue_init(&r->name_resend_queue);
|
171
|
+
ngx_queue_init(&r->srv_resend_queue);
|
145
172
|
ngx_queue_init(&r->addr_resend_queue);
|
146
173
|
|
147
174
|
ngx_queue_init(&r->name_expire_queue);
|
175
|
+
ngx_queue_init(&r->srv_expire_queue);
|
148
176
|
ngx_queue_init(&r->addr_expire_queue);
|
149
177
|
|
150
178
|
#if (NGX_HAVE_INET6)
|
@@ -164,6 +192,7 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
|
|
164
192
|
r->ident = -1;
|
165
193
|
|
166
194
|
r->resend_timeout = 5;
|
195
|
+
r->tcp_timeout = 5;
|
167
196
|
r->expire = 30;
|
168
197
|
r->valid = 0;
|
169
198
|
|
@@ -171,8 +200,8 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
|
|
171
200
|
r->log_level = NGX_LOG_ERR;
|
172
201
|
|
173
202
|
if (n) {
|
174
|
-
if (ngx_array_init(&r->
|
175
|
-
sizeof(
|
203
|
+
if (ngx_array_init(&r->connections, cf->pool, n,
|
204
|
+
sizeof(ngx_resolver_connection_t))
|
176
205
|
!= NGX_OK)
|
177
206
|
{
|
178
207
|
return NULL;
|
@@ -229,17 +258,18 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
|
|
229
258
|
return NULL;
|
230
259
|
}
|
231
260
|
|
232
|
-
|
233
|
-
if (
|
261
|
+
rec = ngx_array_push_n(&r->connections, u.naddrs);
|
262
|
+
if (rec == NULL) {
|
234
263
|
return NULL;
|
235
264
|
}
|
236
265
|
|
237
|
-
ngx_memzero(
|
266
|
+
ngx_memzero(rec, u.naddrs * sizeof(ngx_resolver_connection_t));
|
238
267
|
|
239
268
|
for (j = 0; j < u.naddrs; j++) {
|
240
|
-
|
241
|
-
|
242
|
-
|
269
|
+
rec[j].sockaddr = u.addrs[j].sockaddr;
|
270
|
+
rec[j].socklen = u.addrs[j].socklen;
|
271
|
+
rec[j].server = u.addrs[j].name;
|
272
|
+
rec[j].resolver = r;
|
243
273
|
}
|
244
274
|
}
|
245
275
|
|
@@ -252,8 +282,8 @@ ngx_resolver_cleanup(void *data)
|
|
252
282
|
{
|
253
283
|
ngx_resolver_t *r = data;
|
254
284
|
|
255
|
-
ngx_uint_t
|
256
|
-
|
285
|
+
ngx_uint_t i;
|
286
|
+
ngx_resolver_connection_t *rec;
|
257
287
|
|
258
288
|
if (r) {
|
259
289
|
ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
|
@@ -261,6 +291,8 @@ ngx_resolver_cleanup(void *data)
|
|
261
291
|
|
262
292
|
ngx_resolver_cleanup_tree(r, &r->name_rbtree);
|
263
293
|
|
294
|
+
ngx_resolver_cleanup_tree(r, &r->srv_rbtree);
|
295
|
+
|
264
296
|
ngx_resolver_cleanup_tree(r, &r->addr_rbtree);
|
265
297
|
|
266
298
|
#if (NGX_HAVE_INET6)
|
@@ -272,11 +304,25 @@ ngx_resolver_cleanup(void *data)
|
|
272
304
|
}
|
273
305
|
|
274
306
|
|
275
|
-
|
307
|
+
rec = r->connections.elts;
|
308
|
+
|
309
|
+
for (i = 0; i < r->connections.nelts; i++) {
|
310
|
+
if (rec[i].udp) {
|
311
|
+
ngx_close_connection(rec[i].udp);
|
312
|
+
}
|
313
|
+
|
314
|
+
if (rec[i].tcp) {
|
315
|
+
ngx_close_connection(rec[i].tcp);
|
316
|
+
}
|
317
|
+
|
318
|
+
if (rec[i].read_buf) {
|
319
|
+
ngx_resolver_free(r, rec[i].read_buf->start);
|
320
|
+
ngx_resolver_free(r, rec[i].read_buf);
|
321
|
+
}
|
276
322
|
|
277
|
-
|
278
|
-
|
279
|
-
|
323
|
+
if (rec[i].write_buf) {
|
324
|
+
ngx_resolver_free(r, rec[i].write_buf->start);
|
325
|
+
ngx_resolver_free(r, rec[i].write_buf);
|
280
326
|
}
|
281
327
|
}
|
282
328
|
|
@@ -339,7 +385,7 @@ ngx_resolve_start(ngx_resolver_t *r, ngx_resolver_ctx_t *temp)
|
|
339
385
|
}
|
340
386
|
}
|
341
387
|
|
342
|
-
if (r->
|
388
|
+
if (r->connections.nelts == 0) {
|
343
389
|
return NGX_NO_RESOLVER;
|
344
390
|
}
|
345
391
|
|
@@ -356,7 +402,9 @@ ngx_resolve_start(ngx_resolver_t *r, ngx_resolver_ctx_t *temp)
|
|
356
402
|
ngx_int_t
|
357
403
|
ngx_resolve_name(ngx_resolver_ctx_t *ctx)
|
358
404
|
{
|
405
|
+
size_t slen;
|
359
406
|
ngx_int_t rc;
|
407
|
+
ngx_str_t name;
|
360
408
|
ngx_resolver_t *r;
|
361
409
|
|
362
410
|
r = ctx->resolver;
|
@@ -373,9 +421,41 @@ ngx_resolve_name(ngx_resolver_ctx_t *ctx)
|
|
373
421
|
return NGX_OK;
|
374
422
|
}
|
375
423
|
|
376
|
-
|
424
|
+
if (ctx->service.len) {
|
425
|
+
slen = ctx->service.len;
|
426
|
+
|
427
|
+
if (ngx_strlchr(ctx->service.data,
|
428
|
+
ctx->service.data + ctx->service.len, '.')
|
429
|
+
== NULL)
|
430
|
+
{
|
431
|
+
slen += sizeof("_._tcp") - 1;
|
432
|
+
}
|
433
|
+
|
434
|
+
name.len = slen + 1 + ctx->name.len;
|
435
|
+
|
436
|
+
name.data = ngx_resolver_alloc(r, name.len);
|
437
|
+
if (name.data == NULL) {
|
438
|
+
return NGX_ERROR;
|
439
|
+
}
|
440
|
+
|
441
|
+
if (slen == ctx->service.len) {
|
442
|
+
ngx_sprintf(name.data, "%V.%V", &ctx->service, &ctx->name);
|
443
|
+
|
444
|
+
} else {
|
445
|
+
ngx_sprintf(name.data, "_%V._tcp.%V", &ctx->service, &ctx->name);
|
446
|
+
}
|
447
|
+
|
448
|
+
/* lock name mutex */
|
449
|
+
|
450
|
+
rc = ngx_resolve_name_locked(r, ctx, &name);
|
451
|
+
|
452
|
+
ngx_resolver_free(r, name.data);
|
453
|
+
|
454
|
+
} else {
|
455
|
+
/* lock name mutex */
|
377
456
|
|
378
|
-
|
457
|
+
rc = ngx_resolve_name_locked(r, ctx, &ctx->name);
|
458
|
+
}
|
379
459
|
|
380
460
|
if (rc == NGX_OK) {
|
381
461
|
return NGX_OK;
|
@@ -402,6 +482,7 @@ ngx_resolve_name(ngx_resolver_ctx_t *ctx)
|
|
402
482
|
void
|
403
483
|
ngx_resolve_name_done(ngx_resolver_ctx_t *ctx)
|
404
484
|
{
|
485
|
+
ngx_uint_t i;
|
405
486
|
ngx_resolver_t *r;
|
406
487
|
ngx_resolver_ctx_t *w, **p;
|
407
488
|
ngx_resolver_node_t *rn;
|
@@ -421,6 +502,23 @@ ngx_resolve_name_done(ngx_resolver_ctx_t *ctx)
|
|
421
502
|
|
422
503
|
/* lock name mutex */
|
423
504
|
|
505
|
+
if (ctx->nsrvs) {
|
506
|
+
for (i = 0; i < ctx->nsrvs; i++) {
|
507
|
+
if (ctx->srvs[i].ctx) {
|
508
|
+
ngx_resolve_name_done(ctx->srvs[i].ctx);
|
509
|
+
}
|
510
|
+
|
511
|
+
if (ctx->srvs[i].addrs) {
|
512
|
+
ngx_resolver_free(r, ctx->srvs[i].addrs->sockaddr);
|
513
|
+
ngx_resolver_free(r, ctx->srvs[i].addrs);
|
514
|
+
}
|
515
|
+
|
516
|
+
ngx_resolver_free(r, ctx->srvs[i].name.data);
|
517
|
+
}
|
518
|
+
|
519
|
+
ngx_resolver_free(r, ctx->srvs);
|
520
|
+
}
|
521
|
+
|
424
522
|
if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
|
425
523
|
|
426
524
|
rn = ctx->node;
|
@@ -439,15 +537,20 @@ ngx_resolve_name_done(ngx_resolver_ctx_t *ctx)
|
|
439
537
|
p = &w->next;
|
440
538
|
w = w->next;
|
441
539
|
}
|
442
|
-
}
|
443
540
|
|
444
|
-
|
445
|
-
|
541
|
+
ngx_log_error(NGX_LOG_ALERT, r->log, 0,
|
542
|
+
"could not cancel %V resolving", &ctx->name);
|
543
|
+
}
|
446
544
|
}
|
447
545
|
|
448
546
|
done:
|
449
547
|
|
450
|
-
|
548
|
+
if (ctx->service.len) {
|
549
|
+
ngx_resolver_expire(r, &r->srv_rbtree, &r->srv_expire_queue);
|
550
|
+
|
551
|
+
} else {
|
552
|
+
ngx_resolver_expire(r, &r->name_rbtree, &r->name_expire_queue);
|
553
|
+
}
|
451
554
|
|
452
555
|
/* unlock name mutex */
|
453
556
|
|
@@ -460,6 +563,10 @@ done:
|
|
460
563
|
ngx_resolver_free_locked(r, ctx);
|
461
564
|
|
462
565
|
/* unlock alloc mutex */
|
566
|
+
|
567
|
+
if (r->event->timer_set && ngx_resolver_resend_empty(r)) {
|
568
|
+
ngx_del_timer(r->event);
|
569
|
+
}
|
463
570
|
}
|
464
571
|
|
465
572
|
|
@@ -470,16 +577,31 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx,
|
|
470
577
|
uint32_t hash;
|
471
578
|
ngx_int_t rc;
|
472
579
|
ngx_str_t cname;
|
473
|
-
ngx_uint_t naddrs;
|
474
|
-
|
580
|
+
ngx_uint_t i, naddrs;
|
581
|
+
ngx_queue_t *resend_queue, *expire_queue;
|
582
|
+
ngx_rbtree_t *tree;
|
475
583
|
ngx_resolver_ctx_t *next, *last;
|
584
|
+
ngx_resolver_addr_t *addrs;
|
476
585
|
ngx_resolver_node_t *rn;
|
477
586
|
|
478
587
|
ngx_strlow(name->data, name->data, name->len);
|
479
588
|
|
480
589
|
hash = ngx_crc32_short(name->data, name->len);
|
481
590
|
|
482
|
-
|
591
|
+
if (ctx->service.len) {
|
592
|
+
rn = ngx_resolver_lookup_srv(r, name, hash);
|
593
|
+
|
594
|
+
tree = &r->srv_rbtree;
|
595
|
+
resend_queue = &r->srv_resend_queue;
|
596
|
+
expire_queue = &r->srv_expire_queue;
|
597
|
+
|
598
|
+
} else {
|
599
|
+
rn = ngx_resolver_lookup_name(r, name, hash);
|
600
|
+
|
601
|
+
tree = &r->name_rbtree;
|
602
|
+
resend_queue = &r->name_resend_queue;
|
603
|
+
expire_queue = &r->name_expire_queue;
|
604
|
+
}
|
483
605
|
|
484
606
|
if (rn) {
|
485
607
|
|
@@ -494,7 +616,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx,
|
|
494
616
|
|
495
617
|
rn->expire = ngx_time() + r->expire;
|
496
618
|
|
497
|
-
ngx_queue_insert_head(
|
619
|
+
ngx_queue_insert_head(expire_queue, &rn->queue);
|
498
620
|
|
499
621
|
naddrs = (rn->naddrs == (u_short) -1) ? 0 : rn->naddrs;
|
500
622
|
#if (NGX_HAVE_INET6)
|
@@ -520,6 +642,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx,
|
|
520
642
|
|
521
643
|
do {
|
522
644
|
ctx->state = NGX_OK;
|
645
|
+
ctx->valid = rn->valid;
|
523
646
|
ctx->naddrs = naddrs;
|
524
647
|
|
525
648
|
if (addrs == NULL) {
|
@@ -549,6 +672,23 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx,
|
|
549
672
|
return NGX_OK;
|
550
673
|
}
|
551
674
|
|
675
|
+
if (rn->nsrvs) {
|
676
|
+
last->next = rn->waiting;
|
677
|
+
rn->waiting = NULL;
|
678
|
+
|
679
|
+
/* unlock name mutex */
|
680
|
+
|
681
|
+
do {
|
682
|
+
next = ctx->next;
|
683
|
+
|
684
|
+
ngx_resolver_resolve_srv_names(ctx, rn);
|
685
|
+
|
686
|
+
ctx = next;
|
687
|
+
} while (ctx);
|
688
|
+
|
689
|
+
return NGX_OK;
|
690
|
+
}
|
691
|
+
|
552
692
|
/* NGX_RESOLVE_CNAME */
|
553
693
|
|
554
694
|
if (ctx->recursion++ < NGX_RESOLVER_MAX_RECURSION) {
|
@@ -566,6 +706,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx,
|
|
566
706
|
|
567
707
|
do {
|
568
708
|
ctx->state = NGX_RESOLVE_NXDOMAIN;
|
709
|
+
ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
|
569
710
|
next = ctx->next;
|
570
711
|
|
571
712
|
ctx->handler(ctx);
|
@@ -578,7 +719,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx,
|
|
578
719
|
|
579
720
|
if (rn->waiting) {
|
580
721
|
|
581
|
-
if (ctx->event == NULL) {
|
722
|
+
if (ctx->event == NULL && ctx->timeout) {
|
582
723
|
ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
|
583
724
|
if (ctx->event == NULL) {
|
584
725
|
return NGX_ERROR;
|
@@ -630,6 +771,16 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx,
|
|
630
771
|
}
|
631
772
|
#endif
|
632
773
|
|
774
|
+
if (rn->nsrvs) {
|
775
|
+
for (i = 0; i < rn->nsrvs; i++) {
|
776
|
+
if (rn->u.srvs[i].name.data) {
|
777
|
+
ngx_resolver_free_locked(r, rn->u.srvs[i].name.data);
|
778
|
+
}
|
779
|
+
}
|
780
|
+
|
781
|
+
ngx_resolver_free_locked(r, rn->u.srvs);
|
782
|
+
}
|
783
|
+
|
633
784
|
/* unlock alloc mutex */
|
634
785
|
|
635
786
|
} else {
|
@@ -652,17 +803,22 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx,
|
|
652
803
|
rn->query6 = NULL;
|
653
804
|
#endif
|
654
805
|
|
655
|
-
ngx_rbtree_insert(
|
806
|
+
ngx_rbtree_insert(tree, &rn->node);
|
656
807
|
}
|
657
808
|
|
658
|
-
|
809
|
+
if (ctx->service.len) {
|
810
|
+
rc = ngx_resolver_create_srv_query(r, rn, name);
|
811
|
+
|
812
|
+
} else {
|
813
|
+
rc = ngx_resolver_create_name_query(r, rn, name);
|
814
|
+
}
|
659
815
|
|
660
816
|
if (rc == NGX_ERROR) {
|
661
817
|
goto failed;
|
662
818
|
}
|
663
819
|
|
664
820
|
if (rc == NGX_DECLINED) {
|
665
|
-
ngx_rbtree_delete(
|
821
|
+
ngx_rbtree_delete(tree, &rn->node);
|
666
822
|
|
667
823
|
ngx_resolver_free(r, rn->query);
|
668
824
|
ngx_resolver_free(r, rn->name);
|
@@ -680,16 +836,24 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx,
|
|
680
836
|
return NGX_OK;
|
681
837
|
}
|
682
838
|
|
839
|
+
rn->last_connection = r->last_connection++;
|
840
|
+
if (r->last_connection == r->connections.nelts) {
|
841
|
+
r->last_connection = 0;
|
842
|
+
}
|
843
|
+
|
683
844
|
rn->naddrs = (u_short) -1;
|
845
|
+
rn->tcp = 0;
|
684
846
|
#if (NGX_HAVE_INET6)
|
685
847
|
rn->naddrs6 = r->ipv6 ? (u_short) -1 : 0;
|
848
|
+
rn->tcp6 = 0;
|
686
849
|
#endif
|
850
|
+
rn->nsrvs = 0;
|
687
851
|
|
688
852
|
if (ngx_resolver_send_query(r, rn) != NGX_OK) {
|
689
853
|
goto failed;
|
690
854
|
}
|
691
855
|
|
692
|
-
if (ctx->event == NULL) {
|
856
|
+
if (ctx->event == NULL && ctx->timeout) {
|
693
857
|
ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
|
694
858
|
if (ctx->event == NULL) {
|
695
859
|
goto failed;
|
@@ -703,13 +867,13 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx,
|
|
703
867
|
ngx_add_timer(ctx->event, ctx->timeout);
|
704
868
|
}
|
705
869
|
|
706
|
-
if (ngx_queue_empty(
|
870
|
+
if (ngx_queue_empty(resend_queue)) {
|
707
871
|
ngx_add_timer(r->event, (ngx_msec_t) (r->resend_timeout * 1000));
|
708
872
|
}
|
709
873
|
|
710
874
|
rn->expire = ngx_time() + r->resend_timeout;
|
711
875
|
|
712
|
-
ngx_queue_insert_head(
|
876
|
+
ngx_queue_insert_head(resend_queue, &rn->queue);
|
713
877
|
|
714
878
|
rn->code = 0;
|
715
879
|
rn->cnlen = 0;
|
@@ -728,7 +892,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx,
|
|
728
892
|
|
729
893
|
failed:
|
730
894
|
|
731
|
-
ngx_rbtree_delete(
|
895
|
+
ngx_rbtree_delete(tree, &rn->node);
|
732
896
|
|
733
897
|
if (rn->query) {
|
734
898
|
ngx_resolver_free(r, rn->query);
|
@@ -821,6 +985,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
|
|
821
985
|
/* unlock addr mutex */
|
822
986
|
|
823
987
|
ctx->state = NGX_OK;
|
988
|
+
ctx->valid = rn->valid;
|
824
989
|
|
825
990
|
ctx->handler(ctx);
|
826
991
|
|
@@ -831,17 +996,19 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
|
|
831
996
|
|
832
997
|
if (rn->waiting) {
|
833
998
|
|
834
|
-
ctx->event
|
835
|
-
|
836
|
-
|
837
|
-
|
999
|
+
if (ctx->event == NULL && ctx->timeout) {
|
1000
|
+
ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
|
1001
|
+
if (ctx->event == NULL) {
|
1002
|
+
return NGX_ERROR;
|
1003
|
+
}
|
838
1004
|
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
1005
|
+
ctx->event->handler = ngx_resolver_timeout_handler;
|
1006
|
+
ctx->event->data = ctx;
|
1007
|
+
ctx->event->log = r->log;
|
1008
|
+
ctx->ident = -1;
|
843
1009
|
|
844
|
-
|
1010
|
+
ngx_add_timer(ctx->event, ctx->timeout);
|
1011
|
+
}
|
845
1012
|
|
846
1013
|
ctx->next = rn->waiting;
|
847
1014
|
rn->waiting = ctx;
|
@@ -892,26 +1059,36 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
|
|
892
1059
|
goto failed;
|
893
1060
|
}
|
894
1061
|
|
1062
|
+
rn->last_connection = r->last_connection++;
|
1063
|
+
if (r->last_connection == r->connections.nelts) {
|
1064
|
+
r->last_connection = 0;
|
1065
|
+
}
|
1066
|
+
|
895
1067
|
rn->naddrs = (u_short) -1;
|
1068
|
+
rn->tcp = 0;
|
896
1069
|
#if (NGX_HAVE_INET6)
|
897
1070
|
rn->naddrs6 = (u_short) -1;
|
1071
|
+
rn->tcp6 = 0;
|
898
1072
|
#endif
|
1073
|
+
rn->nsrvs = 0;
|
899
1074
|
|
900
1075
|
if (ngx_resolver_send_query(r, rn) != NGX_OK) {
|
901
1076
|
goto failed;
|
902
1077
|
}
|
903
1078
|
|
904
|
-
ctx->event
|
905
|
-
|
906
|
-
|
907
|
-
|
1079
|
+
if (ctx->event == NULL && ctx->timeout) {
|
1080
|
+
ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
|
1081
|
+
if (ctx->event == NULL) {
|
1082
|
+
goto failed;
|
1083
|
+
}
|
908
1084
|
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
1085
|
+
ctx->event->handler = ngx_resolver_timeout_handler;
|
1086
|
+
ctx->event->data = ctx;
|
1087
|
+
ctx->event->log = r->log;
|
1088
|
+
ctx->ident = -1;
|
913
1089
|
|
914
|
-
|
1090
|
+
ngx_add_timer(ctx->event, ctx->timeout);
|
1091
|
+
}
|
915
1092
|
|
916
1093
|
if (ngx_queue_empty(resend_queue)) {
|
917
1094
|
ngx_add_timer(r->event, (ngx_msec_t) (r->resend_timeout * 1000));
|
@@ -1042,6 +1219,10 @@ done:
|
|
1042
1219
|
ngx_resolver_free_locked(r, ctx);
|
1043
1220
|
|
1044
1221
|
/* unlock alloc mutex */
|
1222
|
+
|
1223
|
+
if (r->event->timer_set && ngx_resolver_resend_empty(r)) {
|
1224
|
+
ngx_del_timer(r->event);
|
1225
|
+
}
|
1045
1226
|
}
|
1046
1227
|
|
1047
1228
|
|
@@ -1085,59 +1266,158 @@ ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue)
|
|
1085
1266
|
static ngx_int_t
|
1086
1267
|
ngx_resolver_send_query(ngx_resolver_t *r, ngx_resolver_node_t *rn)
|
1087
1268
|
{
|
1088
|
-
|
1089
|
-
|
1269
|
+
ngx_int_t rc;
|
1270
|
+
ngx_resolver_connection_t *rec;
|
1090
1271
|
|
1091
|
-
|
1272
|
+
rec = r->connections.elts;
|
1273
|
+
rec = &rec[rn->last_connection];
|
1092
1274
|
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1275
|
+
if (rec->log.handler == NULL) {
|
1276
|
+
rec->log = *r->log;
|
1277
|
+
rec->log.handler = ngx_resolver_log_error;
|
1278
|
+
rec->log.data = rec;
|
1279
|
+
rec->log.action = "resolving";
|
1096
1280
|
}
|
1097
1281
|
|
1098
|
-
if (
|
1099
|
-
|
1100
|
-
|
1101
|
-
uc->log.handler = ngx_resolver_log_error;
|
1102
|
-
uc->log.data = uc;
|
1103
|
-
uc->log.action = "resolving";
|
1282
|
+
if (rn->naddrs == (u_short) -1) {
|
1283
|
+
rc = rn->tcp ? ngx_resolver_send_tcp_query(r, rec, rn->query, rn->qlen)
|
1284
|
+
: ngx_resolver_send_udp_query(r, rec, rn->query, rn->qlen);
|
1104
1285
|
|
1105
|
-
if (
|
1106
|
-
return
|
1286
|
+
if (rc != NGX_OK) {
|
1287
|
+
return rc;
|
1107
1288
|
}
|
1108
|
-
|
1109
|
-
uc->connection->data = r;
|
1110
|
-
uc->connection->read->handler = ngx_resolver_read_response;
|
1111
|
-
uc->connection->read->resolver = 1;
|
1112
1289
|
}
|
1113
1290
|
|
1114
|
-
|
1115
|
-
n = ngx_send(uc->connection, rn->query, rn->qlen);
|
1291
|
+
#if (NGX_HAVE_INET6)
|
1116
1292
|
|
1117
|
-
|
1118
|
-
|
1293
|
+
if (rn->query6 && rn->naddrs6 == (u_short) -1) {
|
1294
|
+
rc = rn->tcp6
|
1295
|
+
? ngx_resolver_send_tcp_query(r, rec, rn->query6, rn->qlen)
|
1296
|
+
: ngx_resolver_send_udp_query(r, rec, rn->query6, rn->qlen);
|
1297
|
+
|
1298
|
+
if (rc != NGX_OK) {
|
1299
|
+
return rc;
|
1119
1300
|
}
|
1301
|
+
}
|
1302
|
+
|
1303
|
+
#endif
|
1304
|
+
|
1305
|
+
return NGX_OK;
|
1306
|
+
}
|
1307
|
+
|
1308
|
+
|
1309
|
+
static ngx_int_t
|
1310
|
+
ngx_resolver_send_udp_query(ngx_resolver_t *r, ngx_resolver_connection_t *rec,
|
1311
|
+
u_char *query, u_short qlen)
|
1312
|
+
{
|
1313
|
+
ssize_t n;
|
1120
1314
|
|
1121
|
-
|
1122
|
-
|
1315
|
+
if (rec->udp == NULL) {
|
1316
|
+
if (ngx_udp_connect(rec) != NGX_OK) {
|
1123
1317
|
return NGX_ERROR;
|
1124
1318
|
}
|
1319
|
+
|
1320
|
+
rec->udp->data = rec;
|
1321
|
+
rec->udp->read->handler = ngx_resolver_udp_read;
|
1322
|
+
rec->udp->read->resolver = 1;
|
1125
1323
|
}
|
1126
1324
|
|
1127
|
-
|
1128
|
-
if (rn->query6 && rn->naddrs6 == (u_short) -1) {
|
1129
|
-
n = ngx_send(uc->connection, rn->query6, rn->qlen);
|
1325
|
+
n = ngx_send(rec->udp, query, qlen);
|
1130
1326
|
|
1131
|
-
|
1132
|
-
|
1327
|
+
if (n == -1) {
|
1328
|
+
return NGX_ERROR;
|
1329
|
+
}
|
1330
|
+
|
1331
|
+
if ((size_t) n != (size_t) qlen) {
|
1332
|
+
ngx_log_error(NGX_LOG_CRIT, &rec->log, 0, "send() incomplete");
|
1333
|
+
return NGX_ERROR;
|
1334
|
+
}
|
1335
|
+
|
1336
|
+
return NGX_OK;
|
1337
|
+
}
|
1338
|
+
|
1339
|
+
|
1340
|
+
static ngx_int_t
|
1341
|
+
ngx_resolver_send_tcp_query(ngx_resolver_t *r, ngx_resolver_connection_t *rec,
|
1342
|
+
u_char *query, u_short qlen)
|
1343
|
+
{
|
1344
|
+
ngx_buf_t *b;
|
1345
|
+
ngx_int_t rc;
|
1346
|
+
|
1347
|
+
rc = NGX_OK;
|
1348
|
+
|
1349
|
+
if (rec->tcp == NULL) {
|
1350
|
+
b = rec->read_buf;
|
1351
|
+
|
1352
|
+
if (b == NULL) {
|
1353
|
+
b = ngx_resolver_calloc(r, sizeof(ngx_buf_t));
|
1354
|
+
if (b == NULL) {
|
1355
|
+
return NGX_ERROR;
|
1356
|
+
}
|
1357
|
+
|
1358
|
+
b->start = ngx_resolver_alloc(r, NGX_RESOLVER_TCP_RSIZE);
|
1359
|
+
if (b->start == NULL) {
|
1360
|
+
ngx_resolver_free(r, b);
|
1361
|
+
return NGX_ERROR;
|
1362
|
+
}
|
1363
|
+
|
1364
|
+
b->end = b->start + NGX_RESOLVER_TCP_RSIZE;
|
1365
|
+
|
1366
|
+
rec->read_buf = b;
|
1367
|
+
}
|
1368
|
+
|
1369
|
+
b->pos = b->start;
|
1370
|
+
b->last = b->start;
|
1371
|
+
|
1372
|
+
b = rec->write_buf;
|
1373
|
+
|
1374
|
+
if (b == NULL) {
|
1375
|
+
b = ngx_resolver_calloc(r, sizeof(ngx_buf_t));
|
1376
|
+
if (b == NULL) {
|
1377
|
+
return NGX_ERROR;
|
1378
|
+
}
|
1379
|
+
|
1380
|
+
b->start = ngx_resolver_alloc(r, NGX_RESOLVER_TCP_WSIZE);
|
1381
|
+
if (b->start == NULL) {
|
1382
|
+
ngx_resolver_free(r, b);
|
1383
|
+
return NGX_ERROR;
|
1384
|
+
}
|
1385
|
+
|
1386
|
+
b->end = b->start + NGX_RESOLVER_TCP_WSIZE;
|
1387
|
+
|
1388
|
+
rec->write_buf = b;
|
1133
1389
|
}
|
1134
1390
|
|
1135
|
-
|
1136
|
-
|
1391
|
+
b->pos = b->start;
|
1392
|
+
b->last = b->start;
|
1393
|
+
|
1394
|
+
rc = ngx_tcp_connect(rec);
|
1395
|
+
if (rc == NGX_ERROR) {
|
1137
1396
|
return NGX_ERROR;
|
1138
1397
|
}
|
1398
|
+
|
1399
|
+
rec->tcp->data = rec;
|
1400
|
+
rec->tcp->write->handler = ngx_resolver_tcp_write;
|
1401
|
+
rec->tcp->read->handler = ngx_resolver_tcp_read;
|
1402
|
+
rec->tcp->read->resolver = 1;
|
1403
|
+
|
1404
|
+
ngx_add_timer(rec->tcp->write, (ngx_msec_t) (r->tcp_timeout * 1000));
|
1405
|
+
}
|
1406
|
+
|
1407
|
+
b = rec->write_buf;
|
1408
|
+
|
1409
|
+
if (b->end - b->last < 2 + qlen) {
|
1410
|
+
ngx_log_error(NGX_LOG_CRIT, &rec->log, 0, "buffer overflow");
|
1411
|
+
return NGX_ERROR;
|
1412
|
+
}
|
1413
|
+
|
1414
|
+
*b->last++ = (u_char) (qlen >> 8);
|
1415
|
+
*b->last++ = (u_char) qlen;
|
1416
|
+
b->last = ngx_cpymem(b->last, query, qlen);
|
1417
|
+
|
1418
|
+
if (rc == NGX_OK) {
|
1419
|
+
ngx_resolver_tcp_write(rec->tcp->write);
|
1139
1420
|
}
|
1140
|
-
#endif
|
1141
1421
|
|
1142
1422
|
return NGX_OK;
|
1143
1423
|
}
|
@@ -1146,7 +1426,7 @@ ngx_resolver_send_query(ngx_resolver_t *r, ngx_resolver_node_t *rn)
|
|
1146
1426
|
static void
|
1147
1427
|
ngx_resolver_resend_handler(ngx_event_t *ev)
|
1148
1428
|
{
|
1149
|
-
time_t timer, atimer, ntimer;
|
1429
|
+
time_t timer, atimer, stimer, ntimer;
|
1150
1430
|
#if (NGX_HAVE_INET6)
|
1151
1431
|
time_t a6timer;
|
1152
1432
|
#endif
|
@@ -1161,6 +1441,8 @@ ngx_resolver_resend_handler(ngx_event_t *ev)
|
|
1161
1441
|
|
1162
1442
|
ntimer = ngx_resolver_resend(r, &r->name_rbtree, &r->name_resend_queue);
|
1163
1443
|
|
1444
|
+
stimer = ngx_resolver_resend(r, &r->srv_rbtree, &r->srv_resend_queue);
|
1445
|
+
|
1164
1446
|
/* unlock name mutex */
|
1165
1447
|
|
1166
1448
|
/* lock addr mutex */
|
@@ -1188,6 +1470,13 @@ ngx_resolver_resend_handler(ngx_event_t *ev)
|
|
1188
1470
|
timer = ngx_min(timer, atimer);
|
1189
1471
|
}
|
1190
1472
|
|
1473
|
+
if (timer == 0) {
|
1474
|
+
timer = stimer;
|
1475
|
+
|
1476
|
+
} else if (stimer) {
|
1477
|
+
timer = ngx_min(timer, stimer);
|
1478
|
+
}
|
1479
|
+
|
1191
1480
|
#if (NGX_HAVE_INET6)
|
1192
1481
|
|
1193
1482
|
if (timer == 0) {
|
@@ -1235,6 +1524,10 @@ ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue)
|
|
1235
1524
|
|
1236
1525
|
if (rn->waiting) {
|
1237
1526
|
|
1527
|
+
if (++rn->last_connection == r->connections.nelts) {
|
1528
|
+
rn->last_connection = 0;
|
1529
|
+
}
|
1530
|
+
|
1238
1531
|
(void) ngx_resolver_send_query(r, rn);
|
1239
1532
|
|
1240
1533
|
rn->expire = now + r->resend_timeout;
|
@@ -1251,14 +1544,27 @@ ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue)
|
|
1251
1544
|
}
|
1252
1545
|
|
1253
1546
|
|
1547
|
+
static ngx_uint_t
|
1548
|
+
ngx_resolver_resend_empty(ngx_resolver_t *r)
|
1549
|
+
{
|
1550
|
+
return ngx_queue_empty(&r->name_resend_queue)
|
1551
|
+
#if (NGX_HAVE_INET6)
|
1552
|
+
&& ngx_queue_empty(&r->addr6_resend_queue)
|
1553
|
+
#endif
|
1554
|
+
&& ngx_queue_empty(&r->addr_resend_queue);
|
1555
|
+
}
|
1556
|
+
|
1557
|
+
|
1254
1558
|
static void
|
1255
|
-
|
1559
|
+
ngx_resolver_udp_read(ngx_event_t *rev)
|
1256
1560
|
{
|
1257
|
-
ssize_t
|
1258
|
-
ngx_connection_t
|
1259
|
-
|
1561
|
+
ssize_t n;
|
1562
|
+
ngx_connection_t *c;
|
1563
|
+
ngx_resolver_connection_t *rec;
|
1564
|
+
u_char buf[NGX_RESOLVER_UDP_SIZE];
|
1260
1565
|
|
1261
1566
|
c = rev->data;
|
1567
|
+
rec = c->data;
|
1262
1568
|
|
1263
1569
|
do {
|
1264
1570
|
n = ngx_udp_recv(c, buf, NGX_RESOLVER_UDP_SIZE);
|
@@ -1267,73 +1573,202 @@ ngx_resolver_read_response(ngx_event_t *rev)
|
|
1267
1573
|
return;
|
1268
1574
|
}
|
1269
1575
|
|
1270
|
-
ngx_resolver_process_response(
|
1576
|
+
ngx_resolver_process_response(rec->resolver, buf, n, 0);
|
1271
1577
|
|
1272
1578
|
} while (rev->ready);
|
1273
1579
|
}
|
1274
1580
|
|
1275
1581
|
|
1276
1582
|
static void
|
1277
|
-
|
1583
|
+
ngx_resolver_tcp_write(ngx_event_t *wev)
|
1278
1584
|
{
|
1279
|
-
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1585
|
+
off_t sent;
|
1586
|
+
ssize_t n;
|
1587
|
+
ngx_buf_t *b;
|
1588
|
+
ngx_resolver_t *r;
|
1589
|
+
ngx_connection_t *c;
|
1590
|
+
ngx_resolver_connection_t *rec;
|
1591
|
+
|
1592
|
+
c = wev->data;
|
1593
|
+
rec = c->data;
|
1594
|
+
b = rec->write_buf;
|
1595
|
+
r = rec->resolver;
|
1596
|
+
|
1597
|
+
if (wev->timedout) {
|
1598
|
+
goto failed;
|
1292
1599
|
}
|
1293
1600
|
|
1294
|
-
|
1601
|
+
sent = c->sent;
|
1295
1602
|
|
1296
|
-
|
1297
|
-
|
1298
|
-
nqs = (response->nqs_hi << 8) + response->nqs_lo;
|
1299
|
-
nan = (response->nan_hi << 8) + response->nan_lo;
|
1603
|
+
while (wev->ready && b->pos < b->last) {
|
1604
|
+
n = ngx_send(c, b->pos, b->last - b->pos);
|
1300
1605
|
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1304
|
-
(response->nns_hi << 8) + response->nns_lo,
|
1305
|
-
(response->nar_hi << 8) + response->nar_lo);
|
1606
|
+
if (n == NGX_AGAIN) {
|
1607
|
+
break;
|
1608
|
+
}
|
1306
1609
|
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1610
|
+
if (n == NGX_ERROR) {
|
1611
|
+
goto failed;
|
1612
|
+
}
|
1613
|
+
|
1614
|
+
b->pos += n;
|
1312
1615
|
}
|
1313
1616
|
|
1314
|
-
|
1617
|
+
if (b->pos != b->start) {
|
1618
|
+
b->last = ngx_movemem(b->start, b->pos, b->last - b->pos);
|
1619
|
+
b->pos = b->start;
|
1620
|
+
}
|
1315
1621
|
|
1316
|
-
if (
|
1622
|
+
if (c->sent != sent) {
|
1623
|
+
ngx_add_timer(wev, (ngx_msec_t) (r->tcp_timeout * 1000));
|
1624
|
+
}
|
1317
1625
|
|
1318
|
-
|
1626
|
+
if (ngx_handle_write_event(wev, 0) != NGX_OK) {
|
1627
|
+
goto failed;
|
1628
|
+
}
|
1319
1629
|
|
1320
|
-
|
1321
|
-
q != ngx_queue_sentinel(&r->name_resend_queue) && times++ < 100;
|
1322
|
-
q = ngx_queue_next(q))
|
1323
|
-
{
|
1324
|
-
rn = ngx_queue_data(q, ngx_resolver_node_t, queue);
|
1325
|
-
qident = (rn->query[0] << 8) + rn->query[1];
|
1630
|
+
return;
|
1326
1631
|
|
1327
|
-
|
1328
|
-
goto dns_error_name;
|
1329
|
-
}
|
1632
|
+
failed:
|
1330
1633
|
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1634
|
+
ngx_close_connection(c);
|
1635
|
+
rec->tcp = NULL;
|
1636
|
+
}
|
1334
1637
|
|
1335
|
-
|
1336
|
-
|
1638
|
+
|
1639
|
+
static void
|
1640
|
+
ngx_resolver_tcp_read(ngx_event_t *rev)
|
1641
|
+
{
|
1642
|
+
u_char *p;
|
1643
|
+
size_t size;
|
1644
|
+
ssize_t n;
|
1645
|
+
u_short qlen;
|
1646
|
+
ngx_buf_t *b;
|
1647
|
+
ngx_resolver_t *r;
|
1648
|
+
ngx_connection_t *c;
|
1649
|
+
ngx_resolver_connection_t *rec;
|
1650
|
+
|
1651
|
+
c = rev->data;
|
1652
|
+
rec = c->data;
|
1653
|
+
b = rec->read_buf;
|
1654
|
+
r = rec->resolver;
|
1655
|
+
|
1656
|
+
while (rev->ready) {
|
1657
|
+
n = ngx_recv(c, b->last, b->end - b->last);
|
1658
|
+
|
1659
|
+
if (n == NGX_AGAIN) {
|
1660
|
+
break;
|
1661
|
+
}
|
1662
|
+
|
1663
|
+
if (n == NGX_ERROR || n == 0) {
|
1664
|
+
goto failed;
|
1665
|
+
}
|
1666
|
+
|
1667
|
+
b->last += n;
|
1668
|
+
|
1669
|
+
for ( ;; ) {
|
1670
|
+
p = b->pos;
|
1671
|
+
size = b->last - p;
|
1672
|
+
|
1673
|
+
if (size < 2) {
|
1674
|
+
break;
|
1675
|
+
}
|
1676
|
+
|
1677
|
+
qlen = (u_short) *p++ << 8;
|
1678
|
+
qlen += *p++;
|
1679
|
+
|
1680
|
+
if (size < (size_t) (2 + qlen)) {
|
1681
|
+
break;
|
1682
|
+
}
|
1683
|
+
|
1684
|
+
ngx_resolver_process_response(r, p, qlen, 1);
|
1685
|
+
|
1686
|
+
b->pos += 2 + qlen;
|
1687
|
+
}
|
1688
|
+
|
1689
|
+
if (b->pos != b->start) {
|
1690
|
+
b->last = ngx_movemem(b->start, b->pos, b->last - b->pos);
|
1691
|
+
b->pos = b->start;
|
1692
|
+
}
|
1693
|
+
}
|
1694
|
+
|
1695
|
+
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
1696
|
+
goto failed;
|
1697
|
+
}
|
1698
|
+
|
1699
|
+
return;
|
1700
|
+
|
1701
|
+
failed:
|
1702
|
+
|
1703
|
+
ngx_close_connection(c);
|
1704
|
+
rec->tcp = NULL;
|
1705
|
+
}
|
1706
|
+
|
1707
|
+
|
1708
|
+
static void
|
1709
|
+
ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n,
|
1710
|
+
ngx_uint_t tcp)
|
1711
|
+
{
|
1712
|
+
char *err;
|
1713
|
+
ngx_uint_t i, times, ident, qident, flags, code, nqs, nan, trunc,
|
1714
|
+
qtype, qclass;
|
1715
|
+
#if (NGX_HAVE_INET6)
|
1716
|
+
ngx_uint_t qident6;
|
1717
|
+
#endif
|
1718
|
+
ngx_queue_t *q;
|
1719
|
+
ngx_resolver_qs_t *qs;
|
1720
|
+
ngx_resolver_hdr_t *response;
|
1721
|
+
ngx_resolver_node_t *rn;
|
1722
|
+
|
1723
|
+
if (n < sizeof(ngx_resolver_hdr_t)) {
|
1724
|
+
goto short_response;
|
1725
|
+
}
|
1726
|
+
|
1727
|
+
response = (ngx_resolver_hdr_t *) buf;
|
1728
|
+
|
1729
|
+
ident = (response->ident_hi << 8) + response->ident_lo;
|
1730
|
+
flags = (response->flags_hi << 8) + response->flags_lo;
|
1731
|
+
nqs = (response->nqs_hi << 8) + response->nqs_lo;
|
1732
|
+
nan = (response->nan_hi << 8) + response->nan_lo;
|
1733
|
+
trunc = flags & 0x0200;
|
1734
|
+
|
1735
|
+
ngx_log_debug6(NGX_LOG_DEBUG_CORE, r->log, 0,
|
1736
|
+
"resolver DNS response %ui fl:%04Xi %ui/%ui/%ud/%ud",
|
1737
|
+
ident, flags, nqs, nan,
|
1738
|
+
(response->nns_hi << 8) + response->nns_lo,
|
1739
|
+
(response->nar_hi << 8) + response->nar_lo);
|
1740
|
+
|
1741
|
+
/* response to a standard query */
|
1742
|
+
if ((flags & 0xf870) != 0x8000 || (trunc && tcp)) {
|
1743
|
+
ngx_log_error(r->log_level, r->log, 0,
|
1744
|
+
"invalid %s DNS response %ui fl:%04Xi",
|
1745
|
+
tcp ? "TCP" : "UDP", ident, flags);
|
1746
|
+
return;
|
1747
|
+
}
|
1748
|
+
|
1749
|
+
code = flags & 0xf;
|
1750
|
+
|
1751
|
+
if (code == NGX_RESOLVE_FORMERR) {
|
1752
|
+
|
1753
|
+
times = 0;
|
1754
|
+
|
1755
|
+
for (q = ngx_queue_head(&r->name_resend_queue);
|
1756
|
+
q != ngx_queue_sentinel(&r->name_resend_queue) && times++ < 100;
|
1757
|
+
q = ngx_queue_next(q))
|
1758
|
+
{
|
1759
|
+
rn = ngx_queue_data(q, ngx_resolver_node_t, queue);
|
1760
|
+
qident = (rn->query[0] << 8) + rn->query[1];
|
1761
|
+
|
1762
|
+
if (qident == ident) {
|
1763
|
+
goto dns_error_name;
|
1764
|
+
}
|
1765
|
+
|
1766
|
+
#if (NGX_HAVE_INET6)
|
1767
|
+
if (rn->query6) {
|
1768
|
+
qident6 = (rn->query6[0] << 8) + rn->query6[1];
|
1769
|
+
|
1770
|
+
if (qident6 == ident) {
|
1771
|
+
goto dns_error_name;
|
1337
1772
|
}
|
1338
1773
|
}
|
1339
1774
|
#endif
|
@@ -1397,11 +1832,18 @@ found:
|
|
1397
1832
|
case NGX_RESOLVE_AAAA:
|
1398
1833
|
#endif
|
1399
1834
|
|
1400
|
-
ngx_resolver_process_a(r, buf, n, ident, code, qtype, nan,
|
1835
|
+
ngx_resolver_process_a(r, buf, n, ident, code, qtype, nan, trunc,
|
1401
1836
|
i + sizeof(ngx_resolver_qs_t));
|
1402
1837
|
|
1403
1838
|
break;
|
1404
1839
|
|
1840
|
+
case NGX_RESOLVE_SRV:
|
1841
|
+
|
1842
|
+
ngx_resolver_process_srv(r, buf, n, ident, code, nan, trunc,
|
1843
|
+
i + sizeof(ngx_resolver_qs_t));
|
1844
|
+
|
1845
|
+
break;
|
1846
|
+
|
1405
1847
|
case NGX_RESOLVE_PTR:
|
1406
1848
|
|
1407
1849
|
ngx_resolver_process_ptr(r, buf, n, ident, code, nan);
|
@@ -1431,7 +1873,7 @@ dns_error_name:
|
|
1431
1873
|
ngx_log_error(r->log_level, r->log, 0,
|
1432
1874
|
"DNS error (%ui: %s), query id:%ui, name:\"%*s\"",
|
1433
1875
|
code, ngx_resolver_strerror(code), ident,
|
1434
|
-
rn->nlen, rn->name);
|
1876
|
+
(size_t) rn->nlen, rn->name);
|
1435
1877
|
return;
|
1436
1878
|
|
1437
1879
|
dns_error:
|
@@ -1444,28 +1886,29 @@ dns_error:
|
|
1444
1886
|
|
1445
1887
|
|
1446
1888
|
static void
|
1447
|
-
ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t
|
1889
|
+
ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t n,
|
1448
1890
|
ngx_uint_t ident, ngx_uint_t code, ngx_uint_t qtype,
|
1449
|
-
ngx_uint_t nan, ngx_uint_t ans)
|
1891
|
+
ngx_uint_t nan, ngx_uint_t trunc, ngx_uint_t ans)
|
1450
1892
|
{
|
1451
|
-
char
|
1452
|
-
u_char
|
1453
|
-
size_t
|
1454
|
-
int32_t
|
1455
|
-
uint32_t
|
1456
|
-
in_addr_t
|
1457
|
-
ngx_str_t
|
1458
|
-
|
1459
|
-
ngx_uint_t type, class, qident, naddrs, a, i, n, start;
|
1893
|
+
char *err;
|
1894
|
+
u_char *cname;
|
1895
|
+
size_t len;
|
1896
|
+
int32_t ttl;
|
1897
|
+
uint32_t hash;
|
1898
|
+
in_addr_t *addr;
|
1899
|
+
ngx_str_t name;
|
1900
|
+
ngx_uint_t type, class, qident, naddrs, a, i, j, start;
|
1460
1901
|
#if (NGX_HAVE_INET6)
|
1461
|
-
struct in6_addr
|
1902
|
+
struct in6_addr *addr6;
|
1462
1903
|
#endif
|
1463
|
-
ngx_resolver_an_t
|
1464
|
-
ngx_resolver_ctx_t
|
1465
|
-
ngx_resolver_node_t
|
1904
|
+
ngx_resolver_an_t *an;
|
1905
|
+
ngx_resolver_ctx_t *ctx, *next;
|
1906
|
+
ngx_resolver_node_t *rn;
|
1907
|
+
ngx_resolver_addr_t *addrs;
|
1908
|
+
ngx_resolver_connection_t *rec;
|
1466
1909
|
|
1467
1910
|
if (ngx_resolver_copy(r, &name, buf,
|
1468
|
-
buf + sizeof(ngx_resolver_hdr_t), buf +
|
1911
|
+
buf + sizeof(ngx_resolver_hdr_t), buf + n)
|
1469
1912
|
!= NGX_OK)
|
1470
1913
|
{
|
1471
1914
|
return;
|
@@ -1498,6 +1941,11 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
|
|
1498
1941
|
goto failed;
|
1499
1942
|
}
|
1500
1943
|
|
1944
|
+
if (trunc && rn->tcp6) {
|
1945
|
+
ngx_resolver_free(r, name.data);
|
1946
|
+
goto failed;
|
1947
|
+
}
|
1948
|
+
|
1501
1949
|
qident = (rn->query6[0] << 8) + rn->query6[1];
|
1502
1950
|
|
1503
1951
|
break;
|
@@ -1512,6 +1960,11 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
|
|
1512
1960
|
goto failed;
|
1513
1961
|
}
|
1514
1962
|
|
1963
|
+
if (trunc && rn->tcp) {
|
1964
|
+
ngx_resolver_free(r, name.data);
|
1965
|
+
goto failed;
|
1966
|
+
}
|
1967
|
+
|
1515
1968
|
qident = (rn->query[0] << 8) + rn->query[1];
|
1516
1969
|
}
|
1517
1970
|
|
@@ -1525,6 +1978,45 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
|
|
1525
1978
|
|
1526
1979
|
ngx_resolver_free(r, name.data);
|
1527
1980
|
|
1981
|
+
if (trunc) {
|
1982
|
+
|
1983
|
+
ngx_queue_remove(&rn->queue);
|
1984
|
+
|
1985
|
+
if (rn->waiting == NULL) {
|
1986
|
+
ngx_rbtree_delete(&r->name_rbtree, &rn->node);
|
1987
|
+
ngx_resolver_free_node(r, rn);
|
1988
|
+
goto next;
|
1989
|
+
}
|
1990
|
+
|
1991
|
+
rec = r->connections.elts;
|
1992
|
+
rec = &rec[rn->last_connection];
|
1993
|
+
|
1994
|
+
switch (qtype) {
|
1995
|
+
|
1996
|
+
#if (NGX_HAVE_INET6)
|
1997
|
+
case NGX_RESOLVE_AAAA:
|
1998
|
+
|
1999
|
+
rn->tcp6 = 1;
|
2000
|
+
|
2001
|
+
(void) ngx_resolver_send_tcp_query(r, rec, rn->query6, rn->qlen);
|
2002
|
+
|
2003
|
+
break;
|
2004
|
+
#endif
|
2005
|
+
|
2006
|
+
default: /* NGX_RESOLVE_A */
|
2007
|
+
|
2008
|
+
rn->tcp = 1;
|
2009
|
+
|
2010
|
+
(void) ngx_resolver_send_tcp_query(r, rec, rn->query, rn->qlen);
|
2011
|
+
}
|
2012
|
+
|
2013
|
+
rn->expire = ngx_time() + r->resend_timeout;
|
2014
|
+
|
2015
|
+
ngx_queue_insert_head(&r->name_resend_queue, &rn->queue);
|
2016
|
+
|
2017
|
+
goto next;
|
2018
|
+
}
|
2019
|
+
|
1528
2020
|
if (code == 0 && rn->code) {
|
1529
2021
|
code = rn->code;
|
1530
2022
|
}
|
@@ -1604,6 +2096,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
|
|
1604
2096
|
while (next) {
|
1605
2097
|
ctx = next;
|
1606
2098
|
ctx->state = code;
|
2099
|
+
ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
|
1607
2100
|
next = ctx->next;
|
1608
2101
|
|
1609
2102
|
ctx->handler(ctx);
|
@@ -1622,7 +2115,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
|
|
1622
2115
|
|
1623
2116
|
start = i;
|
1624
2117
|
|
1625
|
-
while (i <
|
2118
|
+
while (i < n) {
|
1626
2119
|
|
1627
2120
|
if (buf[i] & 0xc0) {
|
1628
2121
|
i += 2;
|
@@ -1648,7 +2141,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
|
|
1648
2141
|
|
1649
2142
|
found:
|
1650
2143
|
|
1651
|
-
if (i + sizeof(ngx_resolver_an_t) >=
|
2144
|
+
if (i + sizeof(ngx_resolver_an_t) >= n) {
|
1652
2145
|
goto short_response;
|
1653
2146
|
}
|
1654
2147
|
|
@@ -1688,7 +2181,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
|
|
1688
2181
|
goto invalid;
|
1689
2182
|
}
|
1690
2183
|
|
1691
|
-
if (i + 4 >
|
2184
|
+
if (i + 4 > n) {
|
1692
2185
|
goto short_response;
|
1693
2186
|
}
|
1694
2187
|
|
@@ -1709,7 +2202,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
|
|
1709
2202
|
goto invalid;
|
1710
2203
|
}
|
1711
2204
|
|
1712
|
-
if (i + 16 >
|
2205
|
+
if (i + 16 > n) {
|
1713
2206
|
goto short_response;
|
1714
2207
|
}
|
1715
2208
|
|
@@ -1790,7 +2283,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
|
|
1790
2283
|
#endif
|
1791
2284
|
}
|
1792
2285
|
|
1793
|
-
|
2286
|
+
j = 0;
|
1794
2287
|
i = ans;
|
1795
2288
|
|
1796
2289
|
for (a = 0; a < nan; a++) {
|
@@ -1819,10 +2312,10 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
|
|
1819
2312
|
|
1820
2313
|
if (type == NGX_RESOLVE_A) {
|
1821
2314
|
|
1822
|
-
addr[
|
2315
|
+
addr[j] = htonl((buf[i] << 24) + (buf[i + 1] << 16)
|
1823
2316
|
+ (buf[i + 2] << 8) + (buf[i + 3]));
|
1824
2317
|
|
1825
|
-
if (++
|
2318
|
+
if (++j == naddrs) {
|
1826
2319
|
|
1827
2320
|
#if (NGX_HAVE_INET6)
|
1828
2321
|
if (rn->naddrs6 == (u_short) -1) {
|
@@ -1837,9 +2330,9 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
|
|
1837
2330
|
#if (NGX_HAVE_INET6)
|
1838
2331
|
else if (type == NGX_RESOLVE_AAAA) {
|
1839
2332
|
|
1840
|
-
ngx_memcpy(addr6[
|
2333
|
+
ngx_memcpy(addr6[j].s6_addr, &buf[i], 16);
|
1841
2334
|
|
1842
|
-
if (++
|
2335
|
+
if (++j == naddrs) {
|
1843
2336
|
|
1844
2337
|
if (rn->naddrs == (u_short) -1) {
|
1845
2338
|
goto next;
|
@@ -1918,6 +2411,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
|
|
1918
2411
|
while (next) {
|
1919
2412
|
ctx = next;
|
1920
2413
|
ctx->state = NGX_OK;
|
2414
|
+
ctx->valid = rn->valid;
|
1921
2415
|
ctx->naddrs = naddrs;
|
1922
2416
|
|
1923
2417
|
if (addrs == NULL) {
|
@@ -1964,7 +2458,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
|
|
1964
2458
|
goto next;
|
1965
2459
|
}
|
1966
2460
|
|
1967
|
-
if (ngx_resolver_copy(r, &name, buf, cname, buf +
|
2461
|
+
if (ngx_resolver_copy(r, &name, buf, cname, buf + n) != NGX_OK) {
|
1968
2462
|
goto failed;
|
1969
2463
|
}
|
1970
2464
|
|
@@ -2047,128 +2541,654 @@ next:
|
|
2047
2541
|
|
2048
2542
|
|
2049
2543
|
static void
|
2050
|
-
|
2051
|
-
ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan
|
2544
|
+
ngx_resolver_process_srv(ngx_resolver_t *r, u_char *buf, size_t n,
|
2545
|
+
ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan,
|
2546
|
+
ngx_uint_t trunc, ngx_uint_t ans)
|
2052
2547
|
{
|
2053
|
-
char
|
2054
|
-
|
2055
|
-
|
2056
|
-
|
2057
|
-
|
2058
|
-
|
2059
|
-
|
2060
|
-
|
2061
|
-
|
2062
|
-
|
2063
|
-
|
2064
|
-
|
2065
|
-
ngx_resolver_node_t *rn;
|
2066
|
-
#if (NGX_HAVE_INET6)
|
2067
|
-
uint32_t hash;
|
2068
|
-
ngx_int_t digit;
|
2069
|
-
struct in6_addr addr6;
|
2070
|
-
#endif
|
2548
|
+
char *err;
|
2549
|
+
u_char *cname;
|
2550
|
+
size_t len;
|
2551
|
+
int32_t ttl;
|
2552
|
+
uint32_t hash;
|
2553
|
+
ngx_str_t name;
|
2554
|
+
ngx_uint_t type, qident, class, start, nsrvs, a, i, j;
|
2555
|
+
ngx_resolver_an_t *an;
|
2556
|
+
ngx_resolver_ctx_t *ctx, *next;
|
2557
|
+
ngx_resolver_srv_t *srvs;
|
2558
|
+
ngx_resolver_node_t *rn;
|
2559
|
+
ngx_resolver_connection_t *rec;
|
2071
2560
|
|
2072
|
-
if (ngx_resolver_copy(r,
|
2561
|
+
if (ngx_resolver_copy(r, &name, buf,
|
2073
2562
|
buf + sizeof(ngx_resolver_hdr_t), buf + n)
|
2074
2563
|
!= NGX_OK)
|
2075
2564
|
{
|
2076
2565
|
return;
|
2077
2566
|
}
|
2078
2567
|
|
2079
|
-
|
2080
|
-
|
2081
|
-
addr = 0;
|
2082
|
-
i = sizeof(ngx_resolver_hdr_t);
|
2568
|
+
ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver qs:%V", &name);
|
2083
2569
|
|
2084
|
-
|
2085
|
-
len = buf[i++];
|
2570
|
+
hash = ngx_crc32_short(name.data, name.len);
|
2086
2571
|
|
2087
|
-
|
2088
|
-
if (octet == NGX_ERROR || octet > 255) {
|
2089
|
-
goto invalid_in_addr_arpa;
|
2090
|
-
}
|
2572
|
+
rn = ngx_resolver_lookup_srv(r, &name, hash);
|
2091
2573
|
|
2092
|
-
|
2093
|
-
|
2574
|
+
if (rn == NULL || rn->query == NULL) {
|
2575
|
+
ngx_log_error(r->log_level, r->log, 0,
|
2576
|
+
"unexpected response for %V", &name);
|
2577
|
+
ngx_resolver_free(r, name.data);
|
2578
|
+
goto failed;
|
2094
2579
|
}
|
2095
2580
|
|
2096
|
-
if (
|
2097
|
-
|
2098
|
-
|
2099
|
-
|
2100
|
-
|
2101
|
-
rn = ngx_resolver_lookup_addr(r, addr);
|
2102
|
-
|
2103
|
-
tree = &r->addr_rbtree;
|
2104
|
-
expire_queue = &r->addr_expire_queue;
|
2581
|
+
if (trunc && rn->tcp) {
|
2582
|
+
ngx_resolver_free(r, name.data);
|
2583
|
+
goto failed;
|
2584
|
+
}
|
2105
2585
|
|
2106
|
-
|
2107
|
-
name.len = ngx_inet_ntop(AF_INET, &addr, text, NGX_SOCKADDR_STRLEN);
|
2108
|
-
name.data = text;
|
2586
|
+
qident = (rn->query[0] << 8) + rn->query[1];
|
2109
2587
|
|
2110
|
-
|
2588
|
+
if (ident != qident) {
|
2589
|
+
ngx_log_error(r->log_level, r->log, 0,
|
2590
|
+
"wrong ident %ui response for %V, expect %ui",
|
2591
|
+
ident, &name, qident);
|
2592
|
+
ngx_resolver_free(r, name.data);
|
2593
|
+
goto failed;
|
2111
2594
|
}
|
2112
2595
|
|
2113
|
-
|
2596
|
+
ngx_resolver_free(r, name.data);
|
2114
2597
|
|
2115
|
-
|
2598
|
+
if (trunc) {
|
2116
2599
|
|
2117
|
-
|
2600
|
+
ngx_queue_remove(&rn->queue);
|
2118
2601
|
|
2119
|
-
|
2120
|
-
|
2121
|
-
|
2602
|
+
if (rn->waiting == NULL) {
|
2603
|
+
ngx_rbtree_delete(&r->srv_rbtree, &rn->node);
|
2604
|
+
ngx_resolver_free_node(r, rn);
|
2605
|
+
return;
|
2122
2606
|
}
|
2123
2607
|
|
2124
|
-
|
2125
|
-
|
2126
|
-
goto invalid_ip6_arpa;
|
2127
|
-
}
|
2608
|
+
rec = r->connections.elts;
|
2609
|
+
rec = &rec[rn->last_connection];
|
2128
2610
|
|
2129
|
-
|
2611
|
+
rn->tcp = 1;
|
2130
2612
|
|
2131
|
-
|
2132
|
-
goto invalid_ip6_arpa;
|
2133
|
-
}
|
2613
|
+
(void) ngx_resolver_send_tcp_query(r, rec, rn->query, rn->qlen);
|
2134
2614
|
|
2135
|
-
|
2136
|
-
if (digit == NGX_ERROR) {
|
2137
|
-
goto invalid_ip6_arpa;
|
2138
|
-
}
|
2615
|
+
rn->expire = ngx_time() + r->resend_timeout;
|
2139
2616
|
|
2140
|
-
|
2617
|
+
ngx_queue_insert_head(&r->srv_resend_queue, &rn->queue);
|
2618
|
+
|
2619
|
+
return;
|
2141
2620
|
}
|
2142
2621
|
|
2143
|
-
if (
|
2144
|
-
|
2622
|
+
if (code == 0 && rn->code) {
|
2623
|
+
code = rn->code;
|
2624
|
+
}
|
2145
2625
|
|
2146
|
-
|
2626
|
+
if (code == 0 && nan == 0) {
|
2627
|
+
code = NGX_RESOLVE_NXDOMAIN;
|
2628
|
+
}
|
2147
2629
|
|
2148
|
-
|
2149
|
-
|
2630
|
+
if (code) {
|
2631
|
+
next = rn->waiting;
|
2632
|
+
rn->waiting = NULL;
|
2150
2633
|
|
2151
|
-
|
2152
|
-
expire_queue = &r->addr6_expire_queue;
|
2634
|
+
ngx_queue_remove(&rn->queue);
|
2153
2635
|
|
2154
|
-
|
2155
|
-
name.data = text;
|
2636
|
+
ngx_rbtree_delete(&r->srv_rbtree, &rn->node);
|
2156
2637
|
|
2157
|
-
|
2158
|
-
|
2638
|
+
while (next) {
|
2639
|
+
ctx = next;
|
2640
|
+
ctx->state = code;
|
2641
|
+
ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
|
2642
|
+
next = ctx->next;
|
2159
2643
|
|
2160
|
-
|
2161
|
-
|
2644
|
+
ctx->handler(ctx);
|
2645
|
+
}
|
2162
2646
|
|
2163
|
-
|
2164
|
-
"invalid in-addr.arpa or ip6.arpa name in DNS response");
|
2165
|
-
return;
|
2647
|
+
ngx_resolver_free_node(r, rn);
|
2166
2648
|
|
2167
|
-
|
2649
|
+
return;
|
2650
|
+
}
|
2651
|
+
|
2652
|
+
i = ans;
|
2653
|
+
nsrvs = 0;
|
2654
|
+
cname = NULL;
|
2655
|
+
|
2656
|
+
for (a = 0; a < nan; a++) {
|
2657
|
+
|
2658
|
+
start = i;
|
2659
|
+
|
2660
|
+
while (i < n) {
|
2661
|
+
|
2662
|
+
if (buf[i] & 0xc0) {
|
2663
|
+
i += 2;
|
2664
|
+
goto found;
|
2665
|
+
}
|
2666
|
+
|
2667
|
+
if (buf[i] == 0) {
|
2668
|
+
i++;
|
2669
|
+
goto test_length;
|
2670
|
+
}
|
2671
|
+
|
2672
|
+
i += 1 + buf[i];
|
2673
|
+
}
|
2674
|
+
|
2675
|
+
goto short_response;
|
2676
|
+
|
2677
|
+
test_length:
|
2678
|
+
|
2679
|
+
if (i - start < 2) {
|
2680
|
+
err = "invalid name DNS response";
|
2681
|
+
goto invalid;
|
2682
|
+
}
|
2683
|
+
|
2684
|
+
found:
|
2685
|
+
|
2686
|
+
if (i + sizeof(ngx_resolver_an_t) >= n) {
|
2687
|
+
goto short_response;
|
2688
|
+
}
|
2689
|
+
|
2690
|
+
an = (ngx_resolver_an_t *) &buf[i];
|
2691
|
+
|
2692
|
+
type = (an->type_hi << 8) + an->type_lo;
|
2693
|
+
class = (an->class_hi << 8) + an->class_lo;
|
2694
|
+
len = (an->len_hi << 8) + an->len_lo;
|
2695
|
+
ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16)
|
2696
|
+
+ (an->ttl[2] << 8) + (an->ttl[3]);
|
2697
|
+
|
2698
|
+
if (class != 1) {
|
2699
|
+
ngx_log_error(r->log_level, r->log, 0,
|
2700
|
+
"unexpected RR class %ui", class);
|
2701
|
+
goto failed;
|
2702
|
+
}
|
2703
|
+
|
2704
|
+
if (ttl < 0) {
|
2705
|
+
ttl = 0;
|
2706
|
+
}
|
2707
|
+
|
2708
|
+
rn->ttl = ngx_min(rn->ttl, (uint32_t) ttl);
|
2709
|
+
|
2710
|
+
i += sizeof(ngx_resolver_an_t);
|
2711
|
+
|
2712
|
+
switch (type) {
|
2713
|
+
|
2714
|
+
case NGX_RESOLVE_SRV:
|
2715
|
+
|
2716
|
+
if (i + 6 > n) {
|
2717
|
+
goto short_response;
|
2718
|
+
}
|
2719
|
+
|
2720
|
+
if (ngx_resolver_copy(r, NULL, buf, &buf[i + 6], buf + n)
|
2721
|
+
!= NGX_OK)
|
2722
|
+
{
|
2723
|
+
goto failed;
|
2724
|
+
}
|
2725
|
+
|
2726
|
+
nsrvs++;
|
2727
|
+
|
2728
|
+
break;
|
2729
|
+
|
2730
|
+
case NGX_RESOLVE_CNAME:
|
2731
|
+
|
2732
|
+
cname = &buf[i];
|
2733
|
+
|
2734
|
+
break;
|
2735
|
+
|
2736
|
+
case NGX_RESOLVE_DNAME:
|
2737
|
+
|
2738
|
+
break;
|
2739
|
+
|
2740
|
+
default:
|
2741
|
+
|
2742
|
+
ngx_log_error(r->log_level, r->log, 0,
|
2743
|
+
"unexpected RR type %ui", type);
|
2744
|
+
}
|
2745
|
+
|
2746
|
+
i += len;
|
2747
|
+
}
|
2748
|
+
|
2749
|
+
ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
|
2750
|
+
"resolver nsrvs:%ui cname:%p ttl:%uD",
|
2751
|
+
nsrvs, cname, rn->ttl);
|
2752
|
+
|
2753
|
+
if (nsrvs) {
|
2754
|
+
|
2755
|
+
srvs = ngx_resolver_calloc(r, nsrvs * sizeof(ngx_resolver_srv_t));
|
2756
|
+
if (srvs == NULL) {
|
2757
|
+
goto failed;
|
2758
|
+
}
|
2759
|
+
|
2760
|
+
rn->u.srvs = srvs;
|
2761
|
+
rn->nsrvs = (u_short) nsrvs;
|
2762
|
+
|
2763
|
+
j = 0;
|
2764
|
+
i = ans;
|
2765
|
+
|
2766
|
+
for (a = 0; a < nan; a++) {
|
2767
|
+
|
2768
|
+
for ( ;; ) {
|
2769
|
+
|
2770
|
+
if (buf[i] & 0xc0) {
|
2771
|
+
i += 2;
|
2772
|
+
break;
|
2773
|
+
}
|
2774
|
+
|
2775
|
+
if (buf[i] == 0) {
|
2776
|
+
i++;
|
2777
|
+
break;
|
2778
|
+
}
|
2779
|
+
|
2780
|
+
i += 1 + buf[i];
|
2781
|
+
}
|
2782
|
+
|
2783
|
+
an = (ngx_resolver_an_t *) &buf[i];
|
2784
|
+
|
2785
|
+
type = (an->type_hi << 8) + an->type_lo;
|
2786
|
+
len = (an->len_hi << 8) + an->len_lo;
|
2787
|
+
|
2788
|
+
i += sizeof(ngx_resolver_an_t);
|
2789
|
+
|
2790
|
+
if (type == NGX_RESOLVE_SRV) {
|
2791
|
+
|
2792
|
+
srvs[j].priority = (buf[i] << 8) + buf[i + 1];
|
2793
|
+
srvs[j].weight = (buf[i + 2] << 8) + buf[i + 3];
|
2794
|
+
|
2795
|
+
if (srvs[j].weight == 0) {
|
2796
|
+
srvs[j].weight = 1;
|
2797
|
+
}
|
2798
|
+
|
2799
|
+
srvs[j].port = (buf[i + 4] << 8) + buf[i + 5];
|
2800
|
+
|
2801
|
+
if (ngx_resolver_copy(r, &srvs[j].name, buf, &buf[i + 6],
|
2802
|
+
buf + n)
|
2803
|
+
!= NGX_OK)
|
2804
|
+
{
|
2805
|
+
goto failed;
|
2806
|
+
}
|
2807
|
+
|
2808
|
+
j++;
|
2809
|
+
}
|
2810
|
+
|
2811
|
+
i += len;
|
2812
|
+
}
|
2813
|
+
|
2814
|
+
ngx_sort(srvs, nsrvs, sizeof(ngx_resolver_srv_t),
|
2815
|
+
ngx_resolver_cmp_srvs);
|
2816
|
+
|
2817
|
+
ngx_resolver_free(r, rn->query);
|
2818
|
+
rn->query = NULL;
|
2819
|
+
|
2820
|
+
ngx_queue_remove(&rn->queue);
|
2821
|
+
|
2822
|
+
rn->valid = ngx_time() + (r->valid ? r->valid : (time_t) rn->ttl);
|
2823
|
+
rn->expire = ngx_time() + r->expire;
|
2824
|
+
|
2825
|
+
ngx_queue_insert_head(&r->srv_expire_queue, &rn->queue);
|
2826
|
+
|
2827
|
+
next = rn->waiting;
|
2828
|
+
rn->waiting = NULL;
|
2829
|
+
|
2830
|
+
while (next) {
|
2831
|
+
ctx = next;
|
2832
|
+
next = ctx->next;
|
2833
|
+
|
2834
|
+
ngx_resolver_resolve_srv_names(ctx, rn);
|
2835
|
+
}
|
2836
|
+
|
2837
|
+
return;
|
2838
|
+
}
|
2839
|
+
|
2840
|
+
rn->nsrvs = 0;
|
2841
|
+
|
2842
|
+
if (cname) {
|
2843
|
+
|
2844
|
+
/* CNAME only */
|
2845
|
+
|
2846
|
+
if (ngx_resolver_copy(r, &name, buf, cname, buf + n) != NGX_OK) {
|
2847
|
+
goto failed;
|
2848
|
+
}
|
2849
|
+
|
2850
|
+
ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0,
|
2851
|
+
"resolver cname:\"%V\"", &name);
|
2852
|
+
|
2853
|
+
ngx_queue_remove(&rn->queue);
|
2854
|
+
|
2855
|
+
rn->cnlen = (u_short) name.len;
|
2856
|
+
rn->u.cname = name.data;
|
2857
|
+
|
2858
|
+
rn->valid = ngx_time() + (r->valid ? r->valid : (time_t) rn->ttl);
|
2859
|
+
rn->expire = ngx_time() + r->expire;
|
2860
|
+
|
2861
|
+
ngx_queue_insert_head(&r->srv_expire_queue, &rn->queue);
|
2862
|
+
|
2863
|
+
ngx_resolver_free(r, rn->query);
|
2864
|
+
rn->query = NULL;
|
2865
|
+
#if (NGX_HAVE_INET6)
|
2866
|
+
rn->query6 = NULL;
|
2867
|
+
#endif
|
2868
|
+
|
2869
|
+
ctx = rn->waiting;
|
2870
|
+
rn->waiting = NULL;
|
2871
|
+
|
2872
|
+
if (ctx) {
|
2873
|
+
|
2874
|
+
if (ctx->recursion++ >= NGX_RESOLVER_MAX_RECURSION) {
|
2875
|
+
|
2876
|
+
/* unlock name mutex */
|
2877
|
+
|
2878
|
+
do {
|
2879
|
+
ctx->state = NGX_RESOLVE_NXDOMAIN;
|
2880
|
+
next = ctx->next;
|
2881
|
+
|
2882
|
+
ctx->handler(ctx);
|
2883
|
+
|
2884
|
+
ctx = next;
|
2885
|
+
} while (ctx);
|
2886
|
+
|
2887
|
+
return;
|
2888
|
+
}
|
2889
|
+
|
2890
|
+
for (next = ctx; next; next = next->next) {
|
2891
|
+
next->node = NULL;
|
2892
|
+
}
|
2893
|
+
|
2894
|
+
(void) ngx_resolve_name_locked(r, ctx, &name);
|
2895
|
+
}
|
2896
|
+
|
2897
|
+
/* unlock name mutex */
|
2898
|
+
|
2899
|
+
return;
|
2900
|
+
}
|
2901
|
+
|
2902
|
+
ngx_log_error(r->log_level, r->log, 0, "no SRV type in DNS response");
|
2903
|
+
|
2904
|
+
return;
|
2905
|
+
|
2906
|
+
short_response:
|
2907
|
+
|
2908
|
+
err = "short DNS response";
|
2909
|
+
|
2910
|
+
invalid:
|
2911
|
+
|
2912
|
+
/* unlock name mutex */
|
2913
|
+
|
2914
|
+
ngx_log_error(r->log_level, r->log, 0, err);
|
2915
|
+
|
2916
|
+
return;
|
2917
|
+
|
2918
|
+
failed:
|
2919
|
+
|
2920
|
+
/* unlock name mutex */
|
2921
|
+
|
2922
|
+
return;
|
2923
|
+
}
|
2924
|
+
|
2925
|
+
|
2926
|
+
static void
|
2927
|
+
ngx_resolver_resolve_srv_names(ngx_resolver_ctx_t *ctx, ngx_resolver_node_t *rn)
|
2928
|
+
{
|
2929
|
+
ngx_uint_t i;
|
2930
|
+
ngx_resolver_t *r;
|
2931
|
+
ngx_resolver_ctx_t *cctx;
|
2932
|
+
ngx_resolver_srv_name_t *srvs;
|
2933
|
+
|
2934
|
+
r = ctx->resolver;
|
2935
|
+
|
2936
|
+
ctx->node = NULL;
|
2937
|
+
ctx->state = NGX_OK;
|
2938
|
+
ctx->valid = rn->valid;
|
2939
|
+
ctx->count = rn->nsrvs;
|
2940
|
+
|
2941
|
+
srvs = ngx_resolver_calloc(r, rn->nsrvs * sizeof(ngx_resolver_srv_name_t));
|
2942
|
+
if (srvs == NULL) {
|
2943
|
+
goto failed;
|
2944
|
+
}
|
2945
|
+
|
2946
|
+
ctx->srvs = srvs;
|
2947
|
+
ctx->nsrvs = rn->nsrvs;
|
2948
|
+
|
2949
|
+
for (i = 0; i < rn->nsrvs; i++) {
|
2950
|
+
srvs[i].name.data = ngx_resolver_alloc(r, rn->u.srvs[i].name.len);
|
2951
|
+
if (srvs[i].name.data == NULL) {
|
2952
|
+
goto failed;
|
2953
|
+
}
|
2954
|
+
|
2955
|
+
srvs[i].name.len = rn->u.srvs[i].name.len;
|
2956
|
+
ngx_memcpy(srvs[i].name.data, rn->u.srvs[i].name.data,
|
2957
|
+
srvs[i].name.len);
|
2958
|
+
|
2959
|
+
cctx = ngx_resolve_start(r, NULL);
|
2960
|
+
if (cctx == NULL) {
|
2961
|
+
goto failed;
|
2962
|
+
}
|
2963
|
+
|
2964
|
+
cctx->name = srvs[i].name;
|
2965
|
+
cctx->handler = ngx_resolver_srv_names_handler;
|
2966
|
+
cctx->data = ctx;
|
2967
|
+
cctx->srvs = &srvs[i];
|
2968
|
+
cctx->timeout = 0;
|
2969
|
+
|
2970
|
+
srvs[i].priority = rn->u.srvs[i].priority;
|
2971
|
+
srvs[i].weight = rn->u.srvs[i].weight;
|
2972
|
+
srvs[i].port = rn->u.srvs[i].port;
|
2973
|
+
srvs[i].ctx = cctx;
|
2974
|
+
|
2975
|
+
if (ngx_resolve_name(cctx) == NGX_ERROR) {
|
2976
|
+
srvs[i].ctx = NULL;
|
2977
|
+
goto failed;
|
2978
|
+
}
|
2979
|
+
}
|
2980
|
+
|
2981
|
+
return;
|
2982
|
+
|
2983
|
+
failed:
|
2984
|
+
|
2985
|
+
ctx->state = NGX_ERROR;
|
2986
|
+
ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
|
2987
|
+
|
2988
|
+
ctx->handler(ctx);
|
2989
|
+
}
|
2990
|
+
|
2991
|
+
|
2992
|
+
static void
|
2993
|
+
ngx_resolver_srv_names_handler(ngx_resolver_ctx_t *cctx)
|
2994
|
+
{
|
2995
|
+
ngx_uint_t i;
|
2996
|
+
u_char (*sockaddr)[NGX_SOCKADDRLEN];
|
2997
|
+
ngx_addr_t *addrs;
|
2998
|
+
ngx_resolver_t *r;
|
2999
|
+
struct sockaddr_in *sin;
|
3000
|
+
ngx_resolver_ctx_t *ctx;
|
3001
|
+
ngx_resolver_srv_name_t *srv;
|
3002
|
+
#if (NGX_HAVE_INET6)
|
3003
|
+
struct sockaddr_in6 *sin6;
|
3004
|
+
#endif
|
3005
|
+
|
3006
|
+
r = cctx->resolver;
|
3007
|
+
ctx = cctx->data;
|
3008
|
+
srv = cctx->srvs;
|
3009
|
+
|
3010
|
+
ctx->count--;
|
3011
|
+
|
3012
|
+
srv->ctx = NULL;
|
3013
|
+
|
3014
|
+
if (cctx->naddrs) {
|
3015
|
+
|
3016
|
+
ctx->valid = ngx_min(ctx->valid, cctx->valid);
|
3017
|
+
|
3018
|
+
addrs = ngx_resolver_calloc(r, cctx->naddrs * sizeof(ngx_addr_t));
|
3019
|
+
if (addrs == NULL) {
|
3020
|
+
ngx_resolve_name_done(cctx);
|
3021
|
+
|
3022
|
+
ctx->state = NGX_ERROR;
|
3023
|
+
ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
|
3024
|
+
|
3025
|
+
ctx->handler(ctx);
|
3026
|
+
return;
|
3027
|
+
}
|
3028
|
+
|
3029
|
+
sockaddr = ngx_resolver_alloc(r, cctx->naddrs * NGX_SOCKADDRLEN);
|
3030
|
+
if (sockaddr == NULL) {
|
3031
|
+
ngx_resolver_free(r, addrs);
|
3032
|
+
ngx_resolve_name_done(cctx);
|
3033
|
+
|
3034
|
+
ctx->state = NGX_ERROR;
|
3035
|
+
ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
|
3036
|
+
|
3037
|
+
ctx->handler(ctx);
|
3038
|
+
return;
|
3039
|
+
}
|
3040
|
+
|
3041
|
+
for (i = 0; i < cctx->naddrs; i++) {
|
3042
|
+
addrs[i].sockaddr = (struct sockaddr *) sockaddr[i];
|
3043
|
+
addrs[i].socklen = cctx->addrs[i].socklen;
|
3044
|
+
|
3045
|
+
ngx_memcpy(sockaddr[i], cctx->addrs[i].sockaddr,
|
3046
|
+
addrs[i].socklen);
|
3047
|
+
|
3048
|
+
switch (addrs[i].sockaddr->sa_family) {
|
3049
|
+
#if (NGX_HAVE_INET6)
|
3050
|
+
case AF_INET6:
|
3051
|
+
sin6 = (struct sockaddr_in6 *) addrs[i].sockaddr;
|
3052
|
+
sin6->sin6_port = htons(srv->port);
|
3053
|
+
break;
|
3054
|
+
#endif
|
3055
|
+
default: /* AF_INET */
|
3056
|
+
sin = (struct sockaddr_in *) addrs[i].sockaddr;
|
3057
|
+
sin->sin_port = htons(srv->port);
|
3058
|
+
}
|
3059
|
+
}
|
3060
|
+
|
3061
|
+
srv->addrs = addrs;
|
3062
|
+
srv->naddrs = cctx->naddrs;
|
3063
|
+
}
|
3064
|
+
|
3065
|
+
ngx_resolve_name_done(cctx);
|
3066
|
+
|
3067
|
+
if (ctx->count == 0) {
|
3068
|
+
ngx_resolver_report_srv(r, ctx);
|
3069
|
+
}
|
3070
|
+
}
|
3071
|
+
|
3072
|
+
|
3073
|
+
static void
|
3074
|
+
ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
|
3075
|
+
ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan)
|
3076
|
+
{
|
3077
|
+
char *err;
|
3078
|
+
size_t len;
|
3079
|
+
in_addr_t addr;
|
3080
|
+
int32_t ttl;
|
3081
|
+
ngx_int_t octet;
|
3082
|
+
ngx_str_t name;
|
3083
|
+
ngx_uint_t mask, type, class, qident, a, i, start;
|
3084
|
+
ngx_queue_t *expire_queue;
|
3085
|
+
ngx_rbtree_t *tree;
|
3086
|
+
ngx_resolver_an_t *an;
|
3087
|
+
ngx_resolver_ctx_t *ctx, *next;
|
3088
|
+
ngx_resolver_node_t *rn;
|
3089
|
+
#if (NGX_HAVE_INET6)
|
3090
|
+
uint32_t hash;
|
3091
|
+
ngx_int_t digit;
|
3092
|
+
struct in6_addr addr6;
|
3093
|
+
#endif
|
3094
|
+
|
3095
|
+
if (ngx_resolver_copy(r, &name, buf,
|
3096
|
+
buf + sizeof(ngx_resolver_hdr_t), buf + n)
|
3097
|
+
!= NGX_OK)
|
3098
|
+
{
|
3099
|
+
return;
|
3100
|
+
}
|
3101
|
+
|
3102
|
+
ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver qs:%V", &name);
|
3103
|
+
|
3104
|
+
/* AF_INET */
|
3105
|
+
|
3106
|
+
addr = 0;
|
3107
|
+
i = sizeof(ngx_resolver_hdr_t);
|
3108
|
+
|
3109
|
+
for (mask = 0; mask < 32; mask += 8) {
|
3110
|
+
len = buf[i++];
|
3111
|
+
|
3112
|
+
octet = ngx_atoi(&buf[i], len);
|
3113
|
+
if (octet == NGX_ERROR || octet > 255) {
|
3114
|
+
goto invalid_in_addr_arpa;
|
3115
|
+
}
|
3116
|
+
|
3117
|
+
addr += octet << mask;
|
3118
|
+
i += len;
|
3119
|
+
}
|
3120
|
+
|
3121
|
+
if (ngx_strcasecmp(&buf[i], (u_char *) "\7in-addr\4arpa") == 0) {
|
3122
|
+
i += sizeof("\7in-addr\4arpa");
|
3123
|
+
|
3124
|
+
/* lock addr mutex */
|
3125
|
+
|
3126
|
+
rn = ngx_resolver_lookup_addr(r, addr);
|
3127
|
+
|
3128
|
+
tree = &r->addr_rbtree;
|
3129
|
+
expire_queue = &r->addr_expire_queue;
|
3130
|
+
|
3131
|
+
goto valid;
|
3132
|
+
}
|
3133
|
+
|
3134
|
+
invalid_in_addr_arpa:
|
3135
|
+
|
3136
|
+
#if (NGX_HAVE_INET6)
|
3137
|
+
|
3138
|
+
i = sizeof(ngx_resolver_hdr_t);
|
3139
|
+
|
3140
|
+
for (octet = 15; octet >= 0; octet--) {
|
3141
|
+
if (buf[i++] != '\1') {
|
3142
|
+
goto invalid_ip6_arpa;
|
3143
|
+
}
|
3144
|
+
|
3145
|
+
digit = ngx_hextoi(&buf[i++], 1);
|
3146
|
+
if (digit == NGX_ERROR) {
|
3147
|
+
goto invalid_ip6_arpa;
|
3148
|
+
}
|
3149
|
+
|
3150
|
+
addr6.s6_addr[octet] = (u_char) digit;
|
3151
|
+
|
3152
|
+
if (buf[i++] != '\1') {
|
3153
|
+
goto invalid_ip6_arpa;
|
3154
|
+
}
|
3155
|
+
|
3156
|
+
digit = ngx_hextoi(&buf[i++], 1);
|
3157
|
+
if (digit == NGX_ERROR) {
|
3158
|
+
goto invalid_ip6_arpa;
|
3159
|
+
}
|
3160
|
+
|
3161
|
+
addr6.s6_addr[octet] += (u_char) (digit * 16);
|
3162
|
+
}
|
3163
|
+
|
3164
|
+
if (ngx_strcasecmp(&buf[i], (u_char *) "\3ip6\4arpa") == 0) {
|
3165
|
+
i += sizeof("\3ip6\4arpa");
|
3166
|
+
|
3167
|
+
/* lock addr mutex */
|
3168
|
+
|
3169
|
+
hash = ngx_crc32_short(addr6.s6_addr, 16);
|
3170
|
+
rn = ngx_resolver_lookup_addr6(r, &addr6, hash);
|
3171
|
+
|
3172
|
+
tree = &r->addr6_rbtree;
|
3173
|
+
expire_queue = &r->addr6_expire_queue;
|
3174
|
+
|
3175
|
+
goto valid;
|
3176
|
+
}
|
3177
|
+
|
3178
|
+
invalid_ip6_arpa:
|
3179
|
+
#endif
|
3180
|
+
|
3181
|
+
ngx_log_error(r->log_level, r->log, 0,
|
3182
|
+
"invalid in-addr.arpa or ip6.arpa name in DNS response");
|
3183
|
+
ngx_resolver_free(r, name.data);
|
3184
|
+
return;
|
3185
|
+
|
3186
|
+
valid:
|
2168
3187
|
|
2169
3188
|
if (rn == NULL || rn->query == NULL) {
|
2170
3189
|
ngx_log_error(r->log_level, r->log, 0,
|
2171
3190
|
"unexpected response for %V", &name);
|
3191
|
+
ngx_resolver_free(r, name.data);
|
2172
3192
|
goto failed;
|
2173
3193
|
}
|
2174
3194
|
|
@@ -2178,9 +3198,12 @@ valid:
|
|
2178
3198
|
ngx_log_error(r->log_level, r->log, 0,
|
2179
3199
|
"wrong ident %ui response for %V, expect %ui",
|
2180
3200
|
ident, &name, qident);
|
3201
|
+
ngx_resolver_free(r, name.data);
|
2181
3202
|
goto failed;
|
2182
3203
|
}
|
2183
3204
|
|
3205
|
+
ngx_resolver_free(r, name.data);
|
3206
|
+
|
2184
3207
|
if (code == 0 && nan == 0) {
|
2185
3208
|
code = NGX_RESOLVE_NXDOMAIN;
|
2186
3209
|
}
|
@@ -2198,6 +3221,7 @@ valid:
|
|
2198
3221
|
while (next) {
|
2199
3222
|
ctx = next;
|
2200
3223
|
ctx->state = code;
|
3224
|
+
ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
|
2201
3225
|
next = ctx->next;
|
2202
3226
|
|
2203
3227
|
ctx->handler(ctx);
|
@@ -2210,45 +3234,91 @@ valid:
|
|
2210
3234
|
|
2211
3235
|
i += sizeof(ngx_resolver_qs_t);
|
2212
3236
|
|
2213
|
-
|
3237
|
+
for (a = 0; a < nan; a++) {
|
3238
|
+
|
3239
|
+
start = i;
|
3240
|
+
|
3241
|
+
while (i < n) {
|
3242
|
+
|
3243
|
+
if (buf[i] & 0xc0) {
|
3244
|
+
i += 2;
|
3245
|
+
goto found;
|
3246
|
+
}
|
3247
|
+
|
3248
|
+
if (buf[i] == 0) {
|
3249
|
+
i++;
|
3250
|
+
goto test_length;
|
3251
|
+
}
|
3252
|
+
|
3253
|
+
i += 1 + buf[i];
|
3254
|
+
}
|
3255
|
+
|
2214
3256
|
goto short_response;
|
2215
|
-
}
|
2216
3257
|
|
2217
|
-
|
3258
|
+
test_length:
|
2218
3259
|
|
2219
|
-
|
2220
|
-
|
2221
|
-
|
2222
|
-
|
3260
|
+
if (i - start < 2) {
|
3261
|
+
err = "invalid name in DNS response";
|
3262
|
+
goto invalid;
|
3263
|
+
}
|
2223
3264
|
|
2224
|
-
|
3265
|
+
found:
|
2225
3266
|
|
2226
|
-
|
2227
|
-
|
2228
|
-
|
2229
|
-
+ (an->ttl[2] << 8) + (an->ttl[3]);
|
3267
|
+
if (i + sizeof(ngx_resolver_an_t) >= n) {
|
3268
|
+
goto short_response;
|
3269
|
+
}
|
2230
3270
|
|
2231
|
-
|
2232
|
-
ngx_log_error(r->log_level, r->log, 0,
|
2233
|
-
"unexpected RR class %ui", class);
|
2234
|
-
goto failed;
|
2235
|
-
}
|
3271
|
+
an = (ngx_resolver_an_t *) &buf[i];
|
2236
3272
|
|
2237
|
-
|
2238
|
-
|
2239
|
-
|
3273
|
+
type = (an->type_hi << 8) + an->type_lo;
|
3274
|
+
class = (an->class_hi << 8) + an->class_lo;
|
3275
|
+
len = (an->len_hi << 8) + an->len_lo;
|
3276
|
+
ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16)
|
3277
|
+
+ (an->ttl[2] << 8) + (an->ttl[3]);
|
2240
3278
|
|
2241
|
-
|
2242
|
-
|
2243
|
-
|
2244
|
-
|
3279
|
+
if (class != 1) {
|
3280
|
+
ngx_log_error(r->log_level, r->log, 0,
|
3281
|
+
"unexpected RR class %ui", class);
|
3282
|
+
goto failed;
|
3283
|
+
}
|
3284
|
+
|
3285
|
+
if (ttl < 0) {
|
3286
|
+
ttl = 0;
|
3287
|
+
}
|
2245
3288
|
|
2246
|
-
|
3289
|
+
ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
|
3290
|
+
"resolver qt:%ui cl:%ui len:%uz",
|
3291
|
+
type, class, len);
|
2247
3292
|
|
2248
|
-
|
2249
|
-
|
3293
|
+
i += sizeof(ngx_resolver_an_t);
|
3294
|
+
|
3295
|
+
switch (type) {
|
3296
|
+
|
3297
|
+
case NGX_RESOLVE_PTR:
|
3298
|
+
|
3299
|
+
goto ptr;
|
3300
|
+
|
3301
|
+
case NGX_RESOLVE_CNAME:
|
3302
|
+
|
3303
|
+
break;
|
3304
|
+
|
3305
|
+
default:
|
3306
|
+
|
3307
|
+
ngx_log_error(r->log_level, r->log, 0,
|
3308
|
+
"unexpected RR type %ui", type);
|
3309
|
+
}
|
3310
|
+
|
3311
|
+
i += len;
|
2250
3312
|
}
|
2251
3313
|
|
3314
|
+
/* unlock addr mutex */
|
3315
|
+
|
3316
|
+
ngx_log_error(r->log_level, r->log, 0,
|
3317
|
+
"no PTR type in DNS response");
|
3318
|
+
return;
|
3319
|
+
|
3320
|
+
ptr:
|
3321
|
+
|
2252
3322
|
if (ngx_resolver_copy(r, &name, buf, buf + i, buf + n) != NGX_OK) {
|
2253
3323
|
goto failed;
|
2254
3324
|
}
|
@@ -2286,6 +3356,7 @@ valid:
|
|
2286
3356
|
while (next) {
|
2287
3357
|
ctx = next;
|
2288
3358
|
ctx->state = NGX_OK;
|
3359
|
+
ctx->valid = rn->valid;
|
2289
3360
|
ctx->name = name;
|
2290
3361
|
next = ctx->next;
|
2291
3362
|
|
@@ -2317,14 +3388,55 @@ failed:
|
|
2317
3388
|
|
2318
3389
|
|
2319
3390
|
static ngx_resolver_node_t *
|
2320
|
-
ngx_resolver_lookup_name(ngx_resolver_t *r, ngx_str_t *name, uint32_t hash)
|
3391
|
+
ngx_resolver_lookup_name(ngx_resolver_t *r, ngx_str_t *name, uint32_t hash)
|
3392
|
+
{
|
3393
|
+
ngx_int_t rc;
|
3394
|
+
ngx_rbtree_node_t *node, *sentinel;
|
3395
|
+
ngx_resolver_node_t *rn;
|
3396
|
+
|
3397
|
+
node = r->name_rbtree.root;
|
3398
|
+
sentinel = r->name_rbtree.sentinel;
|
3399
|
+
|
3400
|
+
while (node != sentinel) {
|
3401
|
+
|
3402
|
+
if (hash < node->key) {
|
3403
|
+
node = node->left;
|
3404
|
+
continue;
|
3405
|
+
}
|
3406
|
+
|
3407
|
+
if (hash > node->key) {
|
3408
|
+
node = node->right;
|
3409
|
+
continue;
|
3410
|
+
}
|
3411
|
+
|
3412
|
+
/* hash == node->key */
|
3413
|
+
|
3414
|
+
rn = ngx_resolver_node(node);
|
3415
|
+
|
3416
|
+
rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen);
|
3417
|
+
|
3418
|
+
if (rc == 0) {
|
3419
|
+
return rn;
|
3420
|
+
}
|
3421
|
+
|
3422
|
+
node = (rc < 0) ? node->left : node->right;
|
3423
|
+
}
|
3424
|
+
|
3425
|
+
/* not found */
|
3426
|
+
|
3427
|
+
return NULL;
|
3428
|
+
}
|
3429
|
+
|
3430
|
+
|
3431
|
+
static ngx_resolver_node_t *
|
3432
|
+
ngx_resolver_lookup_srv(ngx_resolver_t *r, ngx_str_t *name, uint32_t hash)
|
2321
3433
|
{
|
2322
3434
|
ngx_int_t rc;
|
2323
3435
|
ngx_rbtree_node_t *node, *sentinel;
|
2324
3436
|
ngx_resolver_node_t *rn;
|
2325
3437
|
|
2326
|
-
node = r->
|
2327
|
-
sentinel = r->
|
3438
|
+
node = r->srv_rbtree.root;
|
3439
|
+
sentinel = r->srv_rbtree.sentinel;
|
2328
3440
|
|
2329
3441
|
while (node != sentinel) {
|
2330
3442
|
|
@@ -2644,9 +3756,97 @@ ngx_resolver_create_name_query(ngx_resolver_t *r, ngx_resolver_node_t *rn,
|
|
2644
3756
|
}
|
2645
3757
|
|
2646
3758
|
|
3759
|
+
static ngx_int_t
|
3760
|
+
ngx_resolver_create_srv_query(ngx_resolver_t *r, ngx_resolver_node_t *rn,
|
3761
|
+
ngx_str_t *name)
|
3762
|
+
{
|
3763
|
+
u_char *p, *s;
|
3764
|
+
size_t len, nlen;
|
3765
|
+
ngx_uint_t ident;
|
3766
|
+
ngx_resolver_qs_t *qs;
|
3767
|
+
ngx_resolver_hdr_t *query;
|
3768
|
+
|
3769
|
+
nlen = name->len ? (1 + name->len + 1) : 1;
|
3770
|
+
|
3771
|
+
len = sizeof(ngx_resolver_hdr_t) + nlen + sizeof(ngx_resolver_qs_t);
|
3772
|
+
|
3773
|
+
p = ngx_resolver_alloc(r, len);
|
3774
|
+
if (p == NULL) {
|
3775
|
+
return NGX_ERROR;
|
3776
|
+
}
|
3777
|
+
|
3778
|
+
rn->qlen = (u_short) len;
|
3779
|
+
rn->query = p;
|
3780
|
+
|
3781
|
+
query = (ngx_resolver_hdr_t *) p;
|
3782
|
+
|
3783
|
+
ident = ngx_random();
|
3784
|
+
|
3785
|
+
ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
|
3786
|
+
"resolve: \"%V\" SRV %i", name, ident & 0xffff);
|
3787
|
+
|
3788
|
+
query->ident_hi = (u_char) ((ident >> 8) & 0xff);
|
3789
|
+
query->ident_lo = (u_char) (ident & 0xff);
|
3790
|
+
|
3791
|
+
/* recursion query */
|
3792
|
+
query->flags_hi = 1; query->flags_lo = 0;
|
3793
|
+
|
3794
|
+
/* one question */
|
3795
|
+
query->nqs_hi = 0; query->nqs_lo = 1;
|
3796
|
+
query->nan_hi = 0; query->nan_lo = 0;
|
3797
|
+
query->nns_hi = 0; query->nns_lo = 0;
|
3798
|
+
query->nar_hi = 0; query->nar_lo = 0;
|
3799
|
+
|
3800
|
+
p += sizeof(ngx_resolver_hdr_t) + nlen;
|
3801
|
+
|
3802
|
+
qs = (ngx_resolver_qs_t *) p;
|
3803
|
+
|
3804
|
+
/* query type */
|
3805
|
+
qs->type_hi = 0; qs->type_lo = NGX_RESOLVE_SRV;
|
3806
|
+
|
3807
|
+
/* IN query class */
|
3808
|
+
qs->class_hi = 0; qs->class_lo = 1;
|
3809
|
+
|
3810
|
+
/* converts "www.example.com" to "\3www\7example\3com\0" */
|
3811
|
+
|
3812
|
+
len = 0;
|
3813
|
+
p--;
|
3814
|
+
*p-- = '\0';
|
3815
|
+
|
3816
|
+
if (name->len == 0) {
|
3817
|
+
return NGX_DECLINED;
|
3818
|
+
}
|
3819
|
+
|
3820
|
+
for (s = name->data + name->len - 1; s >= name->data; s--) {
|
3821
|
+
if (*s != '.') {
|
3822
|
+
*p = *s;
|
3823
|
+
len++;
|
3824
|
+
|
3825
|
+
} else {
|
3826
|
+
if (len == 0 || len > 255) {
|
3827
|
+
return NGX_DECLINED;
|
3828
|
+
}
|
3829
|
+
|
3830
|
+
*p = (u_char) len;
|
3831
|
+
len = 0;
|
3832
|
+
}
|
3833
|
+
|
3834
|
+
p--;
|
3835
|
+
}
|
3836
|
+
|
3837
|
+
if (len == 0 || len > 255) {
|
3838
|
+
return NGX_DECLINED;
|
3839
|
+
}
|
3840
|
+
|
3841
|
+
*p = (u_char) len;
|
3842
|
+
|
3843
|
+
return NGX_OK;
|
3844
|
+
}
|
3845
|
+
|
3846
|
+
|
2647
3847
|
static ngx_int_t
|
2648
3848
|
ngx_resolver_create_addr_query(ngx_resolver_t *r, ngx_resolver_node_t *rn,
|
2649
|
-
|
3849
|
+
ngx_resolver_addr_t *addr)
|
2650
3850
|
{
|
2651
3851
|
u_char *p, *d;
|
2652
3852
|
size_t len;
|
@@ -2850,6 +4050,8 @@ ngx_resolver_timeout_handler(ngx_event_t *ev)
|
|
2850
4050
|
static void
|
2851
4051
|
ngx_resolver_free_node(ngx_resolver_t *r, ngx_resolver_node_t *rn)
|
2852
4052
|
{
|
4053
|
+
ngx_uint_t i;
|
4054
|
+
|
2853
4055
|
/* lock alloc mutex */
|
2854
4056
|
|
2855
4057
|
if (rn->query) {
|
@@ -2874,6 +4076,16 @@ ngx_resolver_free_node(ngx_resolver_t *r, ngx_resolver_node_t *rn)
|
|
2874
4076
|
}
|
2875
4077
|
#endif
|
2876
4078
|
|
4079
|
+
if (rn->nsrvs) {
|
4080
|
+
for (i = 0; i < rn->nsrvs; i++) {
|
4081
|
+
if (rn->u.srvs[i].name.data) {
|
4082
|
+
ngx_resolver_free_locked(r, rn->u.srvs[i].name.data);
|
4083
|
+
}
|
4084
|
+
}
|
4085
|
+
|
4086
|
+
ngx_resolver_free_locked(r, rn->u.srvs);
|
4087
|
+
}
|
4088
|
+
|
2877
4089
|
ngx_resolver_free_locked(r, rn);
|
2878
4090
|
|
2879
4091
|
/* unlock alloc mutex */
|
@@ -2945,15 +4157,15 @@ ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size)
|
|
2945
4157
|
}
|
2946
4158
|
|
2947
4159
|
|
2948
|
-
static
|
4160
|
+
static ngx_resolver_addr_t *
|
2949
4161
|
ngx_resolver_export(ngx_resolver_t *r, ngx_resolver_node_t *rn,
|
2950
4162
|
ngx_uint_t rotate)
|
2951
4163
|
{
|
2952
|
-
ngx_addr_t *dst;
|
2953
4164
|
ngx_uint_t d, i, j, n;
|
2954
4165
|
u_char (*sockaddr)[NGX_SOCKADDRLEN];
|
2955
4166
|
in_addr_t *addr;
|
2956
4167
|
struct sockaddr_in *sin;
|
4168
|
+
ngx_resolver_addr_t *dst;
|
2957
4169
|
#if (NGX_HAVE_INET6)
|
2958
4170
|
struct in6_addr *addr6;
|
2959
4171
|
struct sockaddr_in6 *sin6;
|
@@ -2964,7 +4176,7 @@ ngx_resolver_export(ngx_resolver_t *r, ngx_resolver_node_t *rn,
|
|
2964
4176
|
n += rn->naddrs6;
|
2965
4177
|
#endif
|
2966
4178
|
|
2967
|
-
dst = ngx_resolver_calloc(r, n * sizeof(
|
4179
|
+
dst = ngx_resolver_calloc(r, n * sizeof(ngx_resolver_addr_t));
|
2968
4180
|
if (dst == NULL) {
|
2969
4181
|
return NULL;
|
2970
4182
|
}
|
@@ -3028,6 +4240,99 @@ ngx_resolver_export(ngx_resolver_t *r, ngx_resolver_node_t *rn,
|
|
3028
4240
|
}
|
3029
4241
|
|
3030
4242
|
|
4243
|
+
static void
|
4244
|
+
ngx_resolver_report_srv(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
|
4245
|
+
{
|
4246
|
+
ngx_uint_t naddrs, nsrvs, nw, i, j, k, l, m, n, w;
|
4247
|
+
ngx_resolver_addr_t *addrs;
|
4248
|
+
ngx_resolver_srv_name_t *srvs;
|
4249
|
+
|
4250
|
+
naddrs = 0;
|
4251
|
+
|
4252
|
+
for (i = 0; i < ctx->nsrvs; i++) {
|
4253
|
+
naddrs += ctx->srvs[i].naddrs;
|
4254
|
+
}
|
4255
|
+
|
4256
|
+
if (naddrs == 0) {
|
4257
|
+
ctx->state = NGX_RESOLVE_NXDOMAIN;
|
4258
|
+
ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
|
4259
|
+
|
4260
|
+
ctx->handler(ctx);
|
4261
|
+
return;
|
4262
|
+
}
|
4263
|
+
|
4264
|
+
addrs = ngx_resolver_calloc(r, naddrs * sizeof(ngx_resolver_addr_t));
|
4265
|
+
if (addrs == NULL) {
|
4266
|
+
ctx->state = NGX_ERROR;
|
4267
|
+
ctx->valid = ngx_time() + (r->valid ? r->valid : 10);
|
4268
|
+
|
4269
|
+
ctx->handler(ctx);
|
4270
|
+
return;
|
4271
|
+
}
|
4272
|
+
|
4273
|
+
srvs = ctx->srvs;
|
4274
|
+
nsrvs = ctx->nsrvs;
|
4275
|
+
|
4276
|
+
i = 0;
|
4277
|
+
n = 0;
|
4278
|
+
|
4279
|
+
do {
|
4280
|
+
nw = 0;
|
4281
|
+
|
4282
|
+
for (j = i; j < nsrvs; j++) {
|
4283
|
+
if (srvs[j].priority != srvs[i].priority) {
|
4284
|
+
break;
|
4285
|
+
}
|
4286
|
+
|
4287
|
+
nw += srvs[j].naddrs * srvs[j].weight;
|
4288
|
+
}
|
4289
|
+
|
4290
|
+
if (nw == 0) {
|
4291
|
+
goto next_srv;
|
4292
|
+
}
|
4293
|
+
|
4294
|
+
w = ngx_random() % nw;
|
4295
|
+
|
4296
|
+
for (k = i; k < j; k++) {
|
4297
|
+
if (w < srvs[k].naddrs * srvs[k].weight) {
|
4298
|
+
break;
|
4299
|
+
}
|
4300
|
+
|
4301
|
+
w -= srvs[k].naddrs * srvs[k].weight;
|
4302
|
+
}
|
4303
|
+
|
4304
|
+
for (l = i; l < j; l++) {
|
4305
|
+
|
4306
|
+
for (m = 0; m < srvs[k].naddrs; m++) {
|
4307
|
+
addrs[n].socklen = srvs[k].addrs[m].socklen;
|
4308
|
+
addrs[n].sockaddr = srvs[k].addrs[m].sockaddr;
|
4309
|
+
addrs[n].name = srvs[k].name;
|
4310
|
+
addrs[n].priority = srvs[k].priority;
|
4311
|
+
addrs[n].weight = srvs[k].weight;
|
4312
|
+
n++;
|
4313
|
+
}
|
4314
|
+
|
4315
|
+
if (++k == j) {
|
4316
|
+
k = i;
|
4317
|
+
}
|
4318
|
+
}
|
4319
|
+
|
4320
|
+
next_srv:
|
4321
|
+
|
4322
|
+
i = j;
|
4323
|
+
|
4324
|
+
} while (i < ctx->nsrvs);
|
4325
|
+
|
4326
|
+
ctx->state = NGX_OK;
|
4327
|
+
ctx->addrs = addrs;
|
4328
|
+
ctx->naddrs = naddrs;
|
4329
|
+
|
4330
|
+
ctx->handler(ctx);
|
4331
|
+
|
4332
|
+
ngx_resolver_free(r, addrs);
|
4333
|
+
}
|
4334
|
+
|
4335
|
+
|
3031
4336
|
char *
|
3032
4337
|
ngx_resolver_strerror(ngx_int_t err)
|
3033
4338
|
{
|
@@ -3054,8 +4359,8 @@ ngx_resolver_strerror(ngx_int_t err)
|
|
3054
4359
|
static u_char *
|
3055
4360
|
ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len)
|
3056
4361
|
{
|
3057
|
-
u_char
|
3058
|
-
|
4362
|
+
u_char *p;
|
4363
|
+
ngx_resolver_connection_t *rec;
|
3059
4364
|
|
3060
4365
|
p = buf;
|
3061
4366
|
|
@@ -3064,10 +4369,10 @@ ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len)
|
|
3064
4369
|
len -= p - buf;
|
3065
4370
|
}
|
3066
4371
|
|
3067
|
-
|
4372
|
+
rec = log->data;
|
3068
4373
|
|
3069
|
-
if (
|
3070
|
-
p = ngx_snprintf(p, len, ", resolver: %V", &
|
4374
|
+
if (rec) {
|
4375
|
+
p = ngx_snprintf(p, len, ", resolver: %V", &rec->server);
|
3071
4376
|
}
|
3072
4377
|
|
3073
4378
|
return p;
|
@@ -3075,7 +4380,7 @@ ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len)
|
|
3075
4380
|
|
3076
4381
|
|
3077
4382
|
ngx_int_t
|
3078
|
-
ngx_udp_connect(
|
4383
|
+
ngx_udp_connect(ngx_resolver_connection_t *rec)
|
3079
4384
|
{
|
3080
4385
|
int rc;
|
3081
4386
|
ngx_int_t event;
|
@@ -3083,21 +4388,21 @@ ngx_udp_connect(ngx_udp_connection_t *uc)
|
|
3083
4388
|
ngx_socket_t s;
|
3084
4389
|
ngx_connection_t *c;
|
3085
4390
|
|
3086
|
-
s = ngx_socket(
|
4391
|
+
s = ngx_socket(rec->sockaddr->sa_family, SOCK_DGRAM, 0);
|
3087
4392
|
|
3088
|
-
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &
|
4393
|
+
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &rec->log, 0, "UDP socket %d", s);
|
3089
4394
|
|
3090
4395
|
if (s == (ngx_socket_t) -1) {
|
3091
|
-
ngx_log_error(NGX_LOG_ALERT, &
|
4396
|
+
ngx_log_error(NGX_LOG_ALERT, &rec->log, ngx_socket_errno,
|
3092
4397
|
ngx_socket_n " failed");
|
3093
4398
|
return NGX_ERROR;
|
3094
4399
|
}
|
3095
4400
|
|
3096
|
-
c = ngx_get_connection(s, &
|
4401
|
+
c = ngx_get_connection(s, &rec->log);
|
3097
4402
|
|
3098
4403
|
if (c == NULL) {
|
3099
4404
|
if (ngx_close_socket(s) == -1) {
|
3100
|
-
ngx_log_error(NGX_LOG_ALERT, &
|
4405
|
+
ngx_log_error(NGX_LOG_ALERT, &rec->log, ngx_socket_errno,
|
3101
4406
|
ngx_close_socket_n "failed");
|
3102
4407
|
}
|
3103
4408
|
|
@@ -3105,7 +4410,7 @@ ngx_udp_connect(ngx_udp_connection_t *uc)
|
|
3105
4410
|
}
|
3106
4411
|
|
3107
4412
|
if (ngx_nonblocking(s) == -1) {
|
3108
|
-
ngx_log_error(NGX_LOG_ALERT, &
|
4413
|
+
ngx_log_error(NGX_LOG_ALERT, &rec->log, ngx_socket_errno,
|
3109
4414
|
ngx_nonblocking_n " failed");
|
3110
4415
|
|
3111
4416
|
goto failed;
|
@@ -3114,22 +4419,22 @@ ngx_udp_connect(ngx_udp_connection_t *uc)
|
|
3114
4419
|
rev = c->read;
|
3115
4420
|
wev = c->write;
|
3116
4421
|
|
3117
|
-
rev->log = &
|
3118
|
-
wev->log = &
|
4422
|
+
rev->log = &rec->log;
|
4423
|
+
wev->log = &rec->log;
|
3119
4424
|
|
3120
|
-
|
4425
|
+
rec->udp = c;
|
3121
4426
|
|
3122
4427
|
c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
|
3123
4428
|
|
3124
|
-
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, &
|
3125
|
-
"connect to %V, fd:%d #%uA", &
|
4429
|
+
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, &rec->log, 0,
|
4430
|
+
"connect to %V, fd:%d #%uA", &rec->server, s, c->number);
|
3126
4431
|
|
3127
|
-
rc = connect(s,
|
4432
|
+
rc = connect(s, rec->sockaddr, rec->socklen);
|
3128
4433
|
|
3129
|
-
/* TODO:
|
4434
|
+
/* TODO: iocp */
|
3130
4435
|
|
3131
4436
|
if (rc == -1) {
|
3132
|
-
ngx_log_error(NGX_LOG_CRIT, &
|
4437
|
+
ngx_log_error(NGX_LOG_CRIT, &rec->log, ngx_socket_errno,
|
3133
4438
|
"connect() failed");
|
3134
4439
|
|
3135
4440
|
goto failed;
|
@@ -3138,31 +4443,220 @@ ngx_udp_connect(ngx_udp_connection_t *uc)
|
|
3138
4443
|
/* UDP sockets are always ready to write */
|
3139
4444
|
wev->ready = 1;
|
3140
4445
|
|
3141
|
-
|
4446
|
+
event = (ngx_event_flags & NGX_USE_CLEAR_EVENT) ?
|
4447
|
+
/* kqueue, epoll */ NGX_CLEAR_EVENT:
|
4448
|
+
/* select, poll, /dev/poll */ NGX_LEVEL_EVENT;
|
4449
|
+
/* eventport event type has no meaning: oneshot only */
|
4450
|
+
|
4451
|
+
if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) {
|
4452
|
+
goto failed;
|
4453
|
+
}
|
4454
|
+
|
4455
|
+
return NGX_OK;
|
4456
|
+
|
4457
|
+
failed:
|
4458
|
+
|
4459
|
+
ngx_close_connection(c);
|
4460
|
+
rec->udp = NULL;
|
4461
|
+
|
4462
|
+
return NGX_ERROR;
|
4463
|
+
}
|
4464
|
+
|
4465
|
+
|
4466
|
+
ngx_int_t
|
4467
|
+
ngx_tcp_connect(ngx_resolver_connection_t *rec)
|
4468
|
+
{
|
4469
|
+
int rc;
|
4470
|
+
ngx_int_t event;
|
4471
|
+
ngx_err_t err;
|
4472
|
+
ngx_uint_t level;
|
4473
|
+
ngx_socket_t s;
|
4474
|
+
ngx_event_t *rev, *wev;
|
4475
|
+
ngx_connection_t *c;
|
4476
|
+
|
4477
|
+
s = ngx_socket(rec->sockaddr->sa_family, SOCK_STREAM, 0);
|
4478
|
+
|
4479
|
+
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &rec->log, 0, "TCP socket %d", s);
|
4480
|
+
|
4481
|
+
if (s == (ngx_socket_t) -1) {
|
4482
|
+
ngx_log_error(NGX_LOG_ALERT, &rec->log, ngx_socket_errno,
|
4483
|
+
ngx_socket_n " failed");
|
4484
|
+
return NGX_ERROR;
|
4485
|
+
}
|
4486
|
+
|
4487
|
+
c = ngx_get_connection(s, &rec->log);
|
4488
|
+
|
4489
|
+
if (c == NULL) {
|
4490
|
+
if (ngx_close_socket(s) == -1) {
|
4491
|
+
ngx_log_error(NGX_LOG_ALERT, &rec->log, ngx_socket_errno,
|
4492
|
+
ngx_close_socket_n "failed");
|
4493
|
+
}
|
4494
|
+
|
4495
|
+
return NGX_ERROR;
|
4496
|
+
}
|
4497
|
+
|
4498
|
+
if (ngx_nonblocking(s) == -1) {
|
4499
|
+
ngx_log_error(NGX_LOG_ALERT, &rec->log, ngx_socket_errno,
|
4500
|
+
ngx_nonblocking_n " failed");
|
4501
|
+
|
4502
|
+
goto failed;
|
4503
|
+
}
|
4504
|
+
|
4505
|
+
rev = c->read;
|
4506
|
+
wev = c->write;
|
4507
|
+
|
4508
|
+
rev->log = &rec->log;
|
4509
|
+
wev->log = &rec->log;
|
4510
|
+
|
4511
|
+
rec->tcp = c;
|
4512
|
+
|
4513
|
+
c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
|
4514
|
+
|
4515
|
+
if (ngx_add_conn) {
|
4516
|
+
if (ngx_add_conn(c) == NGX_ERROR) {
|
4517
|
+
goto failed;
|
4518
|
+
}
|
4519
|
+
}
|
4520
|
+
|
4521
|
+
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, &rec->log, 0,
|
4522
|
+
"connect to %V, fd:%d #%uA", &rec->server, s, c->number);
|
4523
|
+
|
4524
|
+
rc = connect(s, rec->sockaddr, rec->socklen);
|
4525
|
+
|
4526
|
+
if (rc == -1) {
|
4527
|
+
err = ngx_socket_errno;
|
4528
|
+
|
4529
|
+
|
4530
|
+
if (err != NGX_EINPROGRESS
|
4531
|
+
#if (NGX_WIN32)
|
4532
|
+
/* Winsock returns WSAEWOULDBLOCK (NGX_EAGAIN) */
|
4533
|
+
&& err != NGX_EAGAIN
|
4534
|
+
#endif
|
4535
|
+
)
|
4536
|
+
{
|
4537
|
+
if (err == NGX_ECONNREFUSED
|
4538
|
+
#if (NGX_LINUX)
|
4539
|
+
/*
|
4540
|
+
* Linux returns EAGAIN instead of ECONNREFUSED
|
4541
|
+
* for unix sockets if listen queue is full
|
4542
|
+
*/
|
4543
|
+
|| err == NGX_EAGAIN
|
4544
|
+
#endif
|
4545
|
+
|| err == NGX_ECONNRESET
|
4546
|
+
|| err == NGX_ENETDOWN
|
4547
|
+
|| err == NGX_ENETUNREACH
|
4548
|
+
|| err == NGX_EHOSTDOWN
|
4549
|
+
|| err == NGX_EHOSTUNREACH)
|
4550
|
+
{
|
4551
|
+
level = NGX_LOG_ERR;
|
4552
|
+
|
4553
|
+
} else {
|
4554
|
+
level = NGX_LOG_CRIT;
|
4555
|
+
}
|
4556
|
+
|
4557
|
+
ngx_log_error(level, c->log, err, "connect() to %V failed",
|
4558
|
+
&rec->server);
|
4559
|
+
|
4560
|
+
ngx_close_connection(c);
|
4561
|
+
rec->tcp = NULL;
|
4562
|
+
|
4563
|
+
return NGX_ERROR;
|
4564
|
+
}
|
4565
|
+
}
|
4566
|
+
|
4567
|
+
if (ngx_add_conn) {
|
4568
|
+
if (rc == -1) {
|
4569
|
+
|
4570
|
+
/* NGX_EINPROGRESS */
|
4571
|
+
|
4572
|
+
return NGX_AGAIN;
|
4573
|
+
}
|
4574
|
+
|
4575
|
+
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, &rec->log, 0, "connected");
|
4576
|
+
|
4577
|
+
wev->ready = 1;
|
4578
|
+
|
4579
|
+
return NGX_OK;
|
4580
|
+
}
|
4581
|
+
|
4582
|
+
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
|
3142
4583
|
|
3143
|
-
|
3144
|
-
|
3145
|
-
/* select, poll, /dev/poll */ NGX_LEVEL_EVENT;
|
3146
|
-
/* eventport event type has no meaning: oneshot only */
|
4584
|
+
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &rec->log, ngx_socket_errno,
|
4585
|
+
"connect(): %d", rc);
|
3147
4586
|
|
3148
|
-
if (
|
4587
|
+
if (ngx_blocking(s) == -1) {
|
4588
|
+
ngx_log_error(NGX_LOG_ALERT, &rec->log, ngx_socket_errno,
|
4589
|
+
ngx_blocking_n " failed");
|
3149
4590
|
goto failed;
|
3150
4591
|
}
|
3151
4592
|
|
4593
|
+
/*
|
4594
|
+
* FreeBSD's aio allows to post an operation on non-connected socket.
|
4595
|
+
* NT does not support it.
|
4596
|
+
*
|
4597
|
+
* TODO: check in Win32, etc. As workaround we can use NGX_ONESHOT_EVENT
|
4598
|
+
*/
|
4599
|
+
|
4600
|
+
rev->ready = 1;
|
4601
|
+
wev->ready = 1;
|
4602
|
+
|
4603
|
+
return NGX_OK;
|
4604
|
+
}
|
4605
|
+
|
4606
|
+
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
|
4607
|
+
|
4608
|
+
/* kqueue */
|
4609
|
+
|
4610
|
+
event = NGX_CLEAR_EVENT;
|
4611
|
+
|
3152
4612
|
} else {
|
3153
|
-
/* rtsig */
|
3154
4613
|
|
3155
|
-
|
4614
|
+
/* select, poll, /dev/poll */
|
4615
|
+
|
4616
|
+
event = NGX_LEVEL_EVENT;
|
4617
|
+
}
|
4618
|
+
|
4619
|
+
if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) {
|
4620
|
+
goto failed;
|
4621
|
+
}
|
4622
|
+
|
4623
|
+
if (rc == -1) {
|
4624
|
+
|
4625
|
+
/* NGX_EINPROGRESS */
|
4626
|
+
|
4627
|
+
if (ngx_add_event(wev, NGX_WRITE_EVENT, event) != NGX_OK) {
|
3156
4628
|
goto failed;
|
3157
4629
|
}
|
4630
|
+
|
4631
|
+
return NGX_AGAIN;
|
3158
4632
|
}
|
3159
4633
|
|
4634
|
+
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, &rec->log, 0, "connected");
|
4635
|
+
|
4636
|
+
wev->ready = 1;
|
4637
|
+
|
3160
4638
|
return NGX_OK;
|
3161
4639
|
|
3162
4640
|
failed:
|
3163
4641
|
|
3164
4642
|
ngx_close_connection(c);
|
3165
|
-
|
4643
|
+
rec->tcp = NULL;
|
3166
4644
|
|
3167
4645
|
return NGX_ERROR;
|
3168
4646
|
}
|
4647
|
+
|
4648
|
+
|
4649
|
+
static ngx_int_t
|
4650
|
+
ngx_resolver_cmp_srvs(const void *one, const void *two)
|
4651
|
+
{
|
4652
|
+
ngx_int_t p1, p2;
|
4653
|
+
ngx_resolver_srv_t *first, *second;
|
4654
|
+
|
4655
|
+
first = (ngx_resolver_srv_t *) one;
|
4656
|
+
second = (ngx_resolver_srv_t *) two;
|
4657
|
+
|
4658
|
+
p1 = first->priority;
|
4659
|
+
p2 = second->priority;
|
4660
|
+
|
4661
|
+
return p1 - p2;
|
4662
|
+
}
|