Mercurial > hg > nginx
annotate src/core/ngx_resolver.c @ 5476:950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Fri, 06 Dec 2013 14:30:28 +0400 |
parents | 07dd5bd222ac |
children | 98876ce2a7fd |
rev | line source |
---|---|
583 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
583 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_event.h> | |
11 | |
12 | |
1649 | 13 #define NGX_RESOLVER_UDP_SIZE 4096 |
14 | |
15 | |
583 | 16 typedef struct { |
1649 | 17 u_char ident_hi; |
18 u_char ident_lo; | |
19 u_char flags_hi; | |
20 u_char flags_lo; | |
21 u_char nqs_hi; | |
22 u_char nqs_lo; | |
23 u_char nan_hi; | |
24 u_char nan_lo; | |
25 u_char nns_hi; | |
26 u_char nns_lo; | |
27 u_char nar_hi; | |
28 u_char nar_lo; | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
29 } ngx_resolver_hdr_t; |
1649 | 30 |
31 | |
32 typedef struct { | |
33 u_char type_hi; | |
34 u_char type_lo; | |
35 u_char class_hi; | |
36 u_char class_lo; | |
37 } ngx_resolver_qs_t; | |
38 | |
39 | |
40 typedef struct { | |
41 u_char type_hi; | |
42 u_char type_lo; | |
43 u_char class_hi; | |
44 u_char class_lo; | |
45 u_char ttl[4]; | |
46 u_char len_hi; | |
47 u_char len_lo; | |
48 } ngx_resolver_an_t; | |
49 | |
50 | |
51 ngx_int_t ngx_udp_connect(ngx_udp_connection_t *uc); | |
52 | |
53 | |
1906 | 54 static void ngx_resolver_cleanup(void *data); |
55 static void ngx_resolver_cleanup_tree(ngx_resolver_t *r, ngx_rbtree_t *tree); | |
1649 | 56 static ngx_int_t ngx_resolve_name_locked(ngx_resolver_t *r, |
57 ngx_resolver_ctx_t *ctx); | |
58 static void ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree, | |
59 ngx_queue_t *queue); | |
60 static ngx_int_t ngx_resolver_send_query(ngx_resolver_t *r, | |
61 ngx_resolver_node_t *rn); | |
62 static ngx_int_t ngx_resolver_create_name_query(ngx_resolver_node_t *rn, | |
63 ngx_resolver_ctx_t *ctx); | |
64 static ngx_int_t ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, | |
65 ngx_resolver_ctx_t *ctx); | |
66 static void ngx_resolver_resend_handler(ngx_event_t *ev); | |
67 static time_t ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree, | |
68 ngx_queue_t *queue); | |
69 static void ngx_resolver_read_response(ngx_event_t *rev); | |
70 static void ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, | |
71 size_t n); | |
72 static void ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t n, | |
1742
268b81386fe4
no answers in DNS response should be NXDOMAIN
Igor Sysoev <igor@sysoev.ru>
parents:
1741
diff
changeset
|
73 ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan, ngx_uint_t ans); |
1649 | 74 static void ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n, |
1742
268b81386fe4
no answers in DNS response should be NXDOMAIN
Igor Sysoev <igor@sysoev.ru>
parents:
1741
diff
changeset
|
75 ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan); |
1649 | 76 static ngx_resolver_node_t *ngx_resolver_lookup_name(ngx_resolver_t *r, |
77 ngx_str_t *name, uint32_t hash); | |
78 static ngx_resolver_node_t *ngx_resolver_lookup_addr(ngx_resolver_t *r, | |
79 in_addr_t addr); | |
80 static void ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t *temp, | |
81 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); | |
82 static ngx_int_t ngx_resolver_copy(ngx_resolver_t *r, ngx_str_t *name, | |
83 u_char *buf, u_char *src, u_char *last); | |
84 static void ngx_resolver_timeout_handler(ngx_event_t *ev); | |
85 static void ngx_resolver_free_node(ngx_resolver_t *r, ngx_resolver_node_t *rn); | |
86 static void *ngx_resolver_alloc(ngx_resolver_t *r, size_t size); | |
1903 | 87 static void *ngx_resolver_calloc(ngx_resolver_t *r, size_t size); |
1649 | 88 static void ngx_resolver_free(ngx_resolver_t *r, void *p); |
89 static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p); | |
90 static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size); | |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
91 static ngx_addr_t *ngx_resolver_export(ngx_resolver_t *r, in_addr_t *src, |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
92 ngx_uint_t n, ngx_uint_t rotate); |
3408
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
93 static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len); |
1649 | 94 |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
95 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
96 static void ngx_resolver_rbtree_insert_addr6_value(ngx_rbtree_node_t *temp, |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
97 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
98 static ngx_resolver_node_t *ngx_resolver_lookup_addr6(ngx_resolver_t *r, |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
99 struct in6_addr *addr, uint32_t hash); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
100 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
101 |
1649 | 102 |
103 ngx_resolver_t * | |
4225
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
104 ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n) |
1649 | 105 { |
4295
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
106 ngx_str_t s; |
4225
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
107 ngx_url_t u; |
4684
f5c2c9d656f9
When "resolver" is configured with a domain name, only the first
Ruslan Ermilov <ru@nginx.com>
parents:
4683
diff
changeset
|
108 ngx_uint_t i, j; |
1649 | 109 ngx_resolver_t *r; |
1906 | 110 ngx_pool_cleanup_t *cln; |
1649 | 111 ngx_udp_connection_t *uc; |
112 | |
1913
c0f873458e2b
use cf->cycle->new_log because at merge stage cf->pool->log is old log
Igor Sysoev <igor@sysoev.ru>
parents:
1906
diff
changeset
|
113 cln = ngx_pool_cleanup_add(cf->pool, 0); |
1906 | 114 if (cln == NULL) { |
115 return NULL; | |
116 } | |
117 | |
118 cln->handler = ngx_resolver_cleanup; | |
119 | |
1913
c0f873458e2b
use cf->cycle->new_log because at merge stage cf->pool->log is old log
Igor Sysoev <igor@sysoev.ru>
parents:
1906
diff
changeset
|
120 r = ngx_calloc(sizeof(ngx_resolver_t), cf->log); |
1649 | 121 if (r == NULL) { |
122 return NULL; | |
123 } | |
124 | |
1906 | 125 cln->data = r; |
126 | |
1913
c0f873458e2b
use cf->cycle->new_log because at merge stage cf->pool->log is old log
Igor Sysoev <igor@sysoev.ru>
parents:
1906
diff
changeset
|
127 r->event = ngx_calloc(sizeof(ngx_event_t), cf->log); |
1649 | 128 if (r->event == NULL) { |
129 return NULL; | |
130 } | |
131 | |
1687 | 132 ngx_rbtree_init(&r->name_rbtree, &r->name_sentinel, |
133 ngx_resolver_rbtree_insert_value); | |
134 | |
135 ngx_rbtree_init(&r->addr_rbtree, &r->addr_sentinel, | |
136 ngx_rbtree_insert_value); | |
1649 | 137 |
1685 | 138 ngx_queue_init(&r->name_resend_queue); |
139 ngx_queue_init(&r->addr_resend_queue); | |
140 | |
141 ngx_queue_init(&r->name_expire_queue); | |
142 ngx_queue_init(&r->addr_expire_queue); | |
1649 | 143 |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
144 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
145 ngx_rbtree_init(&r->addr6_rbtree, &r->addr6_sentinel, |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
146 ngx_resolver_rbtree_insert_addr6_value); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
147 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
148 ngx_queue_init(&r->addr6_resend_queue); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
149 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
150 ngx_queue_init(&r->addr6_expire_queue); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
151 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
152 |
1649 | 153 r->event->handler = ngx_resolver_resend_handler; |
154 r->event->data = r; | |
2785
d478379e51ac
*) refactor error_log processing: listen socket log might inherit built-in
Igor Sysoev <igor@sysoev.ru>
parents:
2490
diff
changeset
|
155 r->event->log = &cf->cycle->new_log; |
1649 | 156 r->ident = -1; |
157 | |
158 r->resend_timeout = 5; | |
159 r->expire = 30; | |
4295
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
160 r->valid = 0; |
1649 | 161 |
2785
d478379e51ac
*) refactor error_log processing: listen socket log might inherit built-in
Igor Sysoev <igor@sysoev.ru>
parents:
2490
diff
changeset
|
162 r->log = &cf->cycle->new_log; |
3763
beca53d6ab3c
decrease resolver errors level to error
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
163 r->log_level = NGX_LOG_ERR; |
1649 | 164 |
4784
dd63abf20ba7
Resolver: fixed possible memory leak in ngx_resolver_create().
Maxim Dounin <mdounin@mdounin.ru>
parents:
4684
diff
changeset
|
165 if (n) { |
dd63abf20ba7
Resolver: fixed possible memory leak in ngx_resolver_create().
Maxim Dounin <mdounin@mdounin.ru>
parents:
4684
diff
changeset
|
166 if (ngx_array_init(&r->udp_connections, cf->pool, n, |
dd63abf20ba7
Resolver: fixed possible memory leak in ngx_resolver_create().
Maxim Dounin <mdounin@mdounin.ru>
parents:
4684
diff
changeset
|
167 sizeof(ngx_udp_connection_t)) |
dd63abf20ba7
Resolver: fixed possible memory leak in ngx_resolver_create().
Maxim Dounin <mdounin@mdounin.ru>
parents:
4684
diff
changeset
|
168 != NGX_OK) |
dd63abf20ba7
Resolver: fixed possible memory leak in ngx_resolver_create().
Maxim Dounin <mdounin@mdounin.ru>
parents:
4684
diff
changeset
|
169 { |
dd63abf20ba7
Resolver: fixed possible memory leak in ngx_resolver_create().
Maxim Dounin <mdounin@mdounin.ru>
parents:
4684
diff
changeset
|
170 return NULL; |
dd63abf20ba7
Resolver: fixed possible memory leak in ngx_resolver_create().
Maxim Dounin <mdounin@mdounin.ru>
parents:
4684
diff
changeset
|
171 } |
dd63abf20ba7
Resolver: fixed possible memory leak in ngx_resolver_create().
Maxim Dounin <mdounin@mdounin.ru>
parents:
4684
diff
changeset
|
172 } |
dd63abf20ba7
Resolver: fixed possible memory leak in ngx_resolver_create().
Maxim Dounin <mdounin@mdounin.ru>
parents:
4684
diff
changeset
|
173 |
4225
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
174 for (i = 0; i < n; i++) { |
4295
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
175 if (ngx_strncmp(names[i].data, "valid=", 6) == 0) { |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
176 s.len = names[i].len - 6; |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
177 s.data = names[i].data + 6; |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
178 |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
179 r->valid = ngx_parse_time(&s, 1); |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
180 |
4474 | 181 if (r->valid == (time_t) NGX_ERROR) { |
4295
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
182 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
183 "invalid parameter: %V", &names[i]); |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
184 return NULL; |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
185 } |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
186 |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
187 continue; |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
188 } |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
189 |
4225
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
190 ngx_memzero(&u, sizeof(ngx_url_t)); |
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
191 |
4671
af9342747669
Support for IPv6 literals and an optional port in resolver.
Ruslan Ermilov <ru@nginx.com>
parents:
4653
diff
changeset
|
192 u.url = names[i]; |
af9342747669
Support for IPv6 literals and an optional port in resolver.
Ruslan Ermilov <ru@nginx.com>
parents:
4653
diff
changeset
|
193 u.default_port = 53; |
af9342747669
Support for IPv6 literals and an optional port in resolver.
Ruslan Ermilov <ru@nginx.com>
parents:
4653
diff
changeset
|
194 |
af9342747669
Support for IPv6 literals and an optional port in resolver.
Ruslan Ermilov <ru@nginx.com>
parents:
4653
diff
changeset
|
195 if (ngx_parse_url(cf->pool, &u) != NGX_OK) { |
4643
bc5f881323b8
Fixed potential null pointer dereference in ngx_resolver_create().
Ruslan Ermilov <ru@nginx.com>
parents:
4619
diff
changeset
|
196 if (u.err) { |
bc5f881323b8
Fixed potential null pointer dereference in ngx_resolver_create().
Ruslan Ermilov <ru@nginx.com>
parents:
4619
diff
changeset
|
197 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
bc5f881323b8
Fixed potential null pointer dereference in ngx_resolver_create().
Ruslan Ermilov <ru@nginx.com>
parents:
4619
diff
changeset
|
198 "%s in resolver \"%V\"", |
4671
af9342747669
Support for IPv6 literals and an optional port in resolver.
Ruslan Ermilov <ru@nginx.com>
parents:
4653
diff
changeset
|
199 u.err, &u.url); |
4643
bc5f881323b8
Fixed potential null pointer dereference in ngx_resolver_create().
Ruslan Ermilov <ru@nginx.com>
parents:
4619
diff
changeset
|
200 } |
bc5f881323b8
Fixed potential null pointer dereference in ngx_resolver_create().
Ruslan Ermilov <ru@nginx.com>
parents:
4619
diff
changeset
|
201 |
4225
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
202 return NULL; |
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
203 } |
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
204 |
4684
f5c2c9d656f9
When "resolver" is configured with a domain name, only the first
Ruslan Ermilov <ru@nginx.com>
parents:
4683
diff
changeset
|
205 uc = ngx_array_push_n(&r->udp_connections, u.naddrs); |
1683
1e0b028055ec
allow to use IP addresses without defined resolver
Igor Sysoev <igor@sysoev.ru>
parents:
1679
diff
changeset
|
206 if (uc == NULL) { |
1e0b028055ec
allow to use IP addresses without defined resolver
Igor Sysoev <igor@sysoev.ru>
parents:
1679
diff
changeset
|
207 return NULL; |
1e0b028055ec
allow to use IP addresses without defined resolver
Igor Sysoev <igor@sysoev.ru>
parents:
1679
diff
changeset
|
208 } |
1e0b028055ec
allow to use IP addresses without defined resolver
Igor Sysoev <igor@sysoev.ru>
parents:
1679
diff
changeset
|
209 |
4684
f5c2c9d656f9
When "resolver" is configured with a domain name, only the first
Ruslan Ermilov <ru@nginx.com>
parents:
4683
diff
changeset
|
210 ngx_memzero(uc, u.naddrs * sizeof(ngx_udp_connection_t)); |
f5c2c9d656f9
When "resolver" is configured with a domain name, only the first
Ruslan Ermilov <ru@nginx.com>
parents:
4683
diff
changeset
|
211 |
f5c2c9d656f9
When "resolver" is configured with a domain name, only the first
Ruslan Ermilov <ru@nginx.com>
parents:
4683
diff
changeset
|
212 for (j = 0; j < u.naddrs; j++) { |
f5c2c9d656f9
When "resolver" is configured with a domain name, only the first
Ruslan Ermilov <ru@nginx.com>
parents:
4683
diff
changeset
|
213 uc[j].sockaddr = u.addrs[j].sockaddr; |
f5c2c9d656f9
When "resolver" is configured with a domain name, only the first
Ruslan Ermilov <ru@nginx.com>
parents:
4683
diff
changeset
|
214 uc[j].socklen = u.addrs[j].socklen; |
f5c2c9d656f9
When "resolver" is configured with a domain name, only the first
Ruslan Ermilov <ru@nginx.com>
parents:
4683
diff
changeset
|
215 uc[j].server = u.addrs[j].name; |
f5c2c9d656f9
When "resolver" is configured with a domain name, only the first
Ruslan Ermilov <ru@nginx.com>
parents:
4683
diff
changeset
|
216 } |
1683
1e0b028055ec
allow to use IP addresses without defined resolver
Igor Sysoev <igor@sysoev.ru>
parents:
1679
diff
changeset
|
217 } |
1649 | 218 |
219 return r; | |
220 } | |
221 | |
222 | |
1906 | 223 static void |
224 ngx_resolver_cleanup(void *data) | |
225 { | |
226 ngx_resolver_t *r = data; | |
227 | |
4225
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
228 ngx_uint_t i; |
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
229 ngx_udp_connection_t *uc; |
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
230 |
1906 | 231 if (r) { |
232 ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, | |
233 "cleanup resolver"); | |
234 | |
235 ngx_resolver_cleanup_tree(r, &r->name_rbtree); | |
236 | |
237 ngx_resolver_cleanup_tree(r, &r->addr_rbtree); | |
238 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
239 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
240 ngx_resolver_cleanup_tree(r, &r->addr6_rbtree); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
241 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
242 |
1906 | 243 if (r->event) { |
244 ngx_free(r->event); | |
245 } | |
246 | |
4225
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
247 |
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
248 uc = r->udp_connections.elts; |
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
249 |
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
250 for (i = 0; i < r->udp_connections.nelts; i++) { |
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
251 if (uc[i].connection) { |
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
252 ngx_close_connection(uc[i].connection); |
1906 | 253 } |
254 } | |
255 | |
256 ngx_free(r); | |
257 } | |
258 } | |
259 | |
260 | |
261 static void | |
262 ngx_resolver_cleanup_tree(ngx_resolver_t *r, ngx_rbtree_t *tree) | |
263 { | |
264 ngx_resolver_ctx_t *ctx, *next; | |
265 ngx_resolver_node_t *rn; | |
266 | |
267 while (tree->root != tree->sentinel) { | |
268 | |
269 rn = (ngx_resolver_node_t *) ngx_rbtree_min(tree->root, tree->sentinel); | |
270 | |
271 ngx_queue_remove(&rn->queue); | |
272 | |
273 for (ctx = rn->waiting; ctx; ctx = next) { | |
2006
b52cb9bf2064
style fix: remove tabs and trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
1969
diff
changeset
|
274 next = ctx->next; |
1906 | 275 |
276 if (ctx->event) { | |
277 ngx_resolver_free(r, ctx->event); | |
278 } | |
279 | |
280 ngx_resolver_free(r, ctx); | |
281 } | |
282 | |
283 ngx_rbtree_delete(tree, &rn->node); | |
284 | |
285 ngx_resolver_free_node(r, rn); | |
286 } | |
287 } | |
288 | |
289 | |
1649 | 290 ngx_resolver_ctx_t * |
291 ngx_resolve_start(ngx_resolver_t *r, ngx_resolver_ctx_t *temp) | |
292 { | |
293 in_addr_t addr; | |
294 ngx_resolver_ctx_t *ctx; | |
295 | |
296 if (temp) { | |
297 addr = ngx_inet_addr(temp->name.data, temp->name.len); | |
298 | |
299 if (addr != INADDR_NONE) { | |
300 temp->resolver = r; | |
301 temp->state = NGX_OK; | |
302 temp->naddrs = 1; | |
303 temp->addrs = &temp->addr; | |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
304 temp->addr.sockaddr = (struct sockaddr *) &temp->sin; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
305 temp->addr.socklen = sizeof(struct sockaddr_in); |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
306 ngx_memzero(&temp->sin, sizeof(struct sockaddr_in)); |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
307 temp->sin.sin_family = AF_INET; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
308 temp->sin.sin_addr.s_addr = addr; |
1649 | 309 temp->quick = 1; |
310 | |
311 return temp; | |
312 } | |
313 } | |
314 | |
4225
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
315 if (r->udp_connections.nelts == 0) { |
1683
1e0b028055ec
allow to use IP addresses without defined resolver
Igor Sysoev <igor@sysoev.ru>
parents:
1679
diff
changeset
|
316 return NGX_NO_RESOLVER; |
1e0b028055ec
allow to use IP addresses without defined resolver
Igor Sysoev <igor@sysoev.ru>
parents:
1679
diff
changeset
|
317 } |
1e0b028055ec
allow to use IP addresses without defined resolver
Igor Sysoev <igor@sysoev.ru>
parents:
1679
diff
changeset
|
318 |
1649 | 319 ctx = ngx_resolver_calloc(r, sizeof(ngx_resolver_ctx_t)); |
320 | |
321 if (ctx) { | |
322 ctx->resolver = r; | |
323 } | |
324 | |
325 return ctx; | |
326 } | |
327 | |
328 | |
329 ngx_int_t | |
330 ngx_resolve_name(ngx_resolver_ctx_t *ctx) | |
331 { | |
332 ngx_int_t rc; | |
333 ngx_resolver_t *r; | |
334 | |
335 r = ctx->resolver; | |
336 | |
337 ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, | |
338 "resolve: \"%V\"", &ctx->name); | |
339 | |
340 if (ctx->quick) { | |
341 ctx->handler(ctx); | |
342 return NGX_OK; | |
343 } | |
344 | |
345 /* lock name mutex */ | |
346 | |
347 rc = ngx_resolve_name_locked(r, ctx); | |
348 | |
349 if (rc == NGX_OK) { | |
350 return NGX_OK; | |
351 } | |
352 | |
353 /* unlock name mutex */ | |
354 | |
355 if (rc == NGX_AGAIN) { | |
356 return NGX_OK; | |
357 } | |
358 | |
1904
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
359 /* NGX_ERROR */ |
1649 | 360 |
361 if (ctx->event) { | |
1904
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
362 ngx_resolver_free(r, ctx->event); |
1649 | 363 } |
364 | |
1904
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
365 ngx_resolver_free(r, ctx); |
1649 | 366 |
367 return NGX_ERROR; | |
368 } | |
369 | |
370 | |
371 void | |
372 ngx_resolve_name_done(ngx_resolver_ctx_t *ctx) | |
373 { | |
374 uint32_t hash; | |
375 ngx_resolver_t *r; | |
376 ngx_resolver_ctx_t *w, **p; | |
377 ngx_resolver_node_t *rn; | |
378 | |
379 r = ctx->resolver; | |
380 | |
381 ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, | |
382 "resolve name done: %i", ctx->state); | |
383 | |
384 if (ctx->quick) { | |
385 return; | |
386 } | |
387 | |
388 if (ctx->event && ctx->event->timer_set) { | |
389 ngx_del_timer(ctx->event); | |
390 } | |
391 | |
392 /* lock name mutex */ | |
393 | |
394 if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) { | |
395 | |
396 hash = ngx_crc32_short(ctx->name.data, ctx->name.len); | |
397 | |
398 rn = ngx_resolver_lookup_name(r, &ctx->name, hash); | |
399 | |
400 if (rn) { | |
401 p = &rn->waiting; | |
402 w = rn->waiting; | |
403 | |
404 while (w) { | |
405 if (w == ctx) { | |
406 *p = w->next; | |
407 | |
408 goto done; | |
409 } | |
410 | |
411 p = &w->next; | |
412 w = w->next; | |
413 } | |
414 } | |
415 | |
416 ngx_log_error(NGX_LOG_ALERT, r->log, 0, | |
417 "could not cancel %V resolving", &ctx->name); | |
418 } | |
419 | |
420 done: | |
421 | |
422 ngx_resolver_expire(r, &r->name_rbtree, &r->name_expire_queue); | |
423 | |
424 /* unlock name mutex */ | |
425 | |
1904
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
426 /* lock alloc mutex */ |
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
427 |
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
428 if (ctx->event) { |
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
429 ngx_resolver_free_locked(r, ctx->event); |
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
430 } |
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
431 |
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
432 ngx_resolver_free_locked(r, ctx); |
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
433 |
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
434 /* unlock alloc mutex */ |
1649 | 435 } |
436 | |
437 | |
438 /* NGX_RESOLVE_A only */ | |
439 | |
440 static ngx_int_t | |
441 ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx) | |
442 { | |
443 uint32_t hash; | |
1961
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
444 ngx_int_t rc; |
1649 | 445 ngx_uint_t naddrs; |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
446 ngx_addr_t *addrs; |
1649 | 447 ngx_resolver_ctx_t *next; |
448 ngx_resolver_node_t *rn; | |
449 | |
450 hash = ngx_crc32_short(ctx->name.data, ctx->name.len); | |
451 | |
452 rn = ngx_resolver_lookup_name(r, &ctx->name, hash); | |
453 | |
454 if (rn) { | |
455 | |
456 if (rn->valid >= ngx_time()) { | |
457 | |
458 ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, "resolve cached"); | |
459 | |
460 ngx_queue_remove(&rn->queue); | |
461 | |
462 rn->expire = ngx_time() + r->expire; | |
463 | |
464 ngx_queue_insert_head(&r->name_expire_queue, &rn->queue); | |
465 | |
466 naddrs = rn->naddrs; | |
467 | |
468 if (naddrs) { | |
469 | |
470 /* NGX_RESOLVE_A answer */ | |
471 | |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
472 if (naddrs == 1) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
473 addrs = NULL; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
474 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
475 } else { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
476 addrs = ngx_resolver_export(r, rn->u.addrs, naddrs, 1); |
1649 | 477 if (addrs == NULL) { |
478 return NGX_ERROR; | |
479 } | |
480 } | |
481 | |
482 ctx->next = rn->waiting; | |
483 rn->waiting = NULL; | |
484 | |
485 /* unlock name mutex */ | |
486 | |
487 do { | |
488 ctx->state = NGX_OK; | |
489 ctx->naddrs = naddrs; | |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
490 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
491 if (addrs == NULL) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
492 ctx->addrs = &ctx->addr; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
493 ctx->addr.sockaddr = (struct sockaddr *) &ctx->sin; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
494 ctx->addr.socklen = sizeof(struct sockaddr_in); |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
495 ngx_memzero(&ctx->sin, sizeof(struct sockaddr_in)); |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
496 ctx->sin.sin_family = AF_INET; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
497 ctx->sin.sin_addr.s_addr = rn->u.addr; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
498 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
499 } else { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
500 ctx->addrs = addrs; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
501 } |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
502 |
1649 | 503 next = ctx->next; |
504 | |
505 ctx->handler(ctx); | |
506 | |
507 ctx = next; | |
508 } while (ctx); | |
509 | |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
510 if (addrs != NULL) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
511 ngx_resolver_free(r, addrs->sockaddr); |
1649 | 512 ngx_resolver_free(r, addrs); |
513 } | |
514 | |
515 return NGX_OK; | |
516 } | |
517 | |
518 /* NGX_RESOLVE_CNAME */ | |
519 | |
1969 | 520 if (ctx->recursion++ < NGX_RESOLVER_MAX_RECURSION) { |
521 | |
522 ctx->name.len = rn->cnlen; | |
523 ctx->name.data = rn->u.cname; | |
524 | |
525 return ngx_resolve_name_locked(r, ctx); | |
526 } | |
527 | |
528 ctx->next = rn->waiting; | |
529 rn->waiting = NULL; | |
530 | |
531 /* unlock name mutex */ | |
532 | |
533 do { | |
534 ctx->state = NGX_RESOLVE_NXDOMAIN; | |
535 next = ctx->next; | |
536 | |
537 ctx->handler(ctx); | |
538 | |
539 ctx = next; | |
540 } while (ctx); | |
541 | |
542 return NGX_OK; | |
1649 | 543 } |
544 | |
545 if (rn->waiting) { | |
546 | |
547 ctx->next = rn->waiting; | |
548 rn->waiting = ctx; | |
3297 | 549 ctx->state = NGX_AGAIN; |
1649 | 550 |
551 return NGX_AGAIN; | |
552 } | |
553 | |
554 ngx_queue_remove(&rn->queue); | |
555 | |
556 /* lock alloc mutex */ | |
557 | |
4619
3171ec7d0d05
Resolver: protection from duplicate responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4610
diff
changeset
|
558 if (rn->query) { |
3171ec7d0d05
Resolver: protection from duplicate responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4610
diff
changeset
|
559 ngx_resolver_free_locked(r, rn->query); |
3171ec7d0d05
Resolver: protection from duplicate responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4610
diff
changeset
|
560 rn->query = NULL; |
3171ec7d0d05
Resolver: protection from duplicate responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4610
diff
changeset
|
561 } |
1649 | 562 |
563 if (rn->cnlen) { | |
564 ngx_resolver_free_locked(r, rn->u.cname); | |
565 } | |
566 | |
567 if (rn->naddrs > 1) { | |
568 ngx_resolver_free_locked(r, rn->u.addrs); | |
569 } | |
570 | |
571 /* unlock alloc mutex */ | |
572 | |
573 } else { | |
574 | |
575 rn = ngx_resolver_alloc(r, sizeof(ngx_resolver_node_t)); | |
576 if (rn == NULL) { | |
577 return NGX_ERROR; | |
578 } | |
579 | |
580 rn->name = ngx_resolver_dup(r, ctx->name.data, ctx->name.len); | |
581 if (rn->name == NULL) { | |
582 ngx_resolver_free(r, rn); | |
583 return NGX_ERROR; | |
584 } | |
585 | |
586 rn->node.key = hash; | |
587 rn->nlen = (u_short) ctx->name.len; | |
1960
1609b3c3d604
fix memory leak on resolver query send failure
Igor Sysoev <igor@sysoev.ru>
parents:
1914
diff
changeset
|
588 rn->query = NULL; |
1649 | 589 |
590 ngx_rbtree_insert(&r->name_rbtree, &rn->node); | |
591 } | |
592 | |
1961
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
593 rc = ngx_resolver_create_name_query(rn, ctx); |
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
594 |
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
595 if (rc == NGX_ERROR) { |
1649 | 596 goto failed; |
597 } | |
598 | |
1961
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
599 if (rc == NGX_DECLINED) { |
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
600 ngx_rbtree_delete(&r->name_rbtree, &rn->node); |
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
601 |
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
602 ngx_resolver_free(r, rn->query); |
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
603 ngx_resolver_free(r, rn->name); |
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
604 ngx_resolver_free(r, rn); |
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
605 |
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
606 ctx->state = NGX_RESOLVE_NXDOMAIN; |
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
607 ctx->handler(ctx); |
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
608 |
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
609 return NGX_OK; |
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
610 } |
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
611 |
1649 | 612 if (ngx_resolver_send_query(r, rn) != NGX_OK) { |
613 goto failed; | |
614 } | |
615 | |
616 if (ctx->event == NULL) { | |
617 ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t)); | |
618 if (ctx->event == NULL) { | |
619 goto failed; | |
620 } | |
621 | |
622 ctx->event->handler = ngx_resolver_timeout_handler; | |
623 ctx->event->data = ctx; | |
624 ctx->event->log = r->log; | |
625 ctx->ident = -1; | |
626 | |
627 ngx_add_timer(ctx->event, ctx->timeout); | |
628 } | |
629 | |
630 if (ngx_queue_empty(&r->name_resend_queue)) { | |
631 ngx_add_timer(r->event, (ngx_msec_t) (r->resend_timeout * 1000)); | |
632 } | |
633 | |
634 rn->expire = ngx_time() + r->resend_timeout; | |
635 | |
636 ngx_queue_insert_head(&r->name_resend_queue, &rn->queue); | |
637 | |
638 rn->cnlen = 0; | |
639 rn->naddrs = 0; | |
640 rn->valid = 0; | |
641 rn->waiting = ctx; | |
642 | |
643 ctx->state = NGX_AGAIN; | |
644 | |
645 return NGX_AGAIN; | |
646 | |
647 failed: | |
648 | |
649 ngx_rbtree_delete(&r->name_rbtree, &rn->node); | |
650 | |
1960
1609b3c3d604
fix memory leak on resolver query send failure
Igor Sysoev <igor@sysoev.ru>
parents:
1914
diff
changeset
|
651 if (rn->query) { |
1609b3c3d604
fix memory leak on resolver query send failure
Igor Sysoev <igor@sysoev.ru>
parents:
1914
diff
changeset
|
652 ngx_resolver_free(r, rn->query); |
1609b3c3d604
fix memory leak on resolver query send failure
Igor Sysoev <igor@sysoev.ru>
parents:
1914
diff
changeset
|
653 } |
1609b3c3d604
fix memory leak on resolver query send failure
Igor Sysoev <igor@sysoev.ru>
parents:
1914
diff
changeset
|
654 |
1649 | 655 ngx_resolver_free(r, rn->name); |
656 | |
657 ngx_resolver_free(r, rn); | |
658 | |
659 return NGX_ERROR; | |
660 } | |
583 | 661 |
662 | |
663 ngx_int_t | |
1649 | 664 ngx_resolve_addr(ngx_resolver_ctx_t *ctx) |
665 { | |
2484
cf3cd450049c
store name pointer in variable allocated on stack
Igor Sysoev <igor@sysoev.ru>
parents:
2483
diff
changeset
|
666 u_char *name; |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
667 in_addr_t addr; |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
668 ngx_queue_t *resend_queue, *expire_queue; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
669 ngx_rbtree_t *tree; |
1649 | 670 ngx_resolver_t *r; |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
671 struct sockaddr_in *sin; |
1649 | 672 ngx_resolver_node_t *rn; |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
673 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
674 uint32_t hash; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
675 struct sockaddr_in6 *sin6; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
676 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
677 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
678 #if (NGX_SUPPRESS_WARN) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
679 addr = 0; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
680 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
681 hash = 0; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
682 sin6 = NULL; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
683 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
684 #endif |
1649 | 685 |
686 r = ctx->resolver; | |
687 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
688 switch (ctx->addr.sockaddr->sa_family) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
689 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
690 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
691 case AF_INET6: |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
692 sin6 = (struct sockaddr_in6 *) ctx->addr.sockaddr; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
693 hash = ngx_crc32_short(sin6->sin6_addr.s6_addr, 16); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
694 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
695 /* lock addr mutex */ |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
696 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
697 rn = ngx_resolver_lookup_addr6(r, &sin6->sin6_addr, hash); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
698 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
699 tree = &r->addr6_rbtree; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
700 resend_queue = &r->addr6_resend_queue; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
701 expire_queue = &r->addr6_expire_queue; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
702 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
703 break; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
704 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
705 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
706 default: /* AF_INET */ |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
707 sin = (struct sockaddr_in *) ctx->addr.sockaddr; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
708 addr = ntohl(sin->sin_addr.s_addr); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
709 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
710 /* lock addr mutex */ |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
711 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
712 rn = ngx_resolver_lookup_addr(r, addr); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
713 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
714 tree = &r->addr_rbtree; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
715 resend_queue = &r->addr_resend_queue; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
716 expire_queue = &r->addr_expire_queue; |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
717 } |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
718 |
1649 | 719 if (rn) { |
720 | |
721 if (rn->valid >= ngx_time()) { | |
722 | |
723 ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, "resolve cached"); | |
724 | |
725 ngx_queue_remove(&rn->queue); | |
726 | |
727 rn->expire = ngx_time() + r->expire; | |
728 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
729 ngx_queue_insert_head(expire_queue, &rn->queue); |
1649 | 730 |
2484
cf3cd450049c
store name pointer in variable allocated on stack
Igor Sysoev <igor@sysoev.ru>
parents:
2483
diff
changeset
|
731 name = ngx_resolver_dup(r, rn->name, rn->nlen); |
cf3cd450049c
store name pointer in variable allocated on stack
Igor Sysoev <igor@sysoev.ru>
parents:
2483
diff
changeset
|
732 if (name == NULL) { |
1649 | 733 goto failed; |
734 } | |
735 | |
2484
cf3cd450049c
store name pointer in variable allocated on stack
Igor Sysoev <igor@sysoev.ru>
parents:
2483
diff
changeset
|
736 ctx->name.len = rn->nlen; |
cf3cd450049c
store name pointer in variable allocated on stack
Igor Sysoev <igor@sysoev.ru>
parents:
2483
diff
changeset
|
737 ctx->name.data = name; |
cf3cd450049c
store name pointer in variable allocated on stack
Igor Sysoev <igor@sysoev.ru>
parents:
2483
diff
changeset
|
738 |
1649 | 739 /* unlock addr mutex */ |
740 | |
741 ctx->state = NGX_OK; | |
742 | |
743 ctx->handler(ctx); | |
744 | |
2484
cf3cd450049c
store name pointer in variable allocated on stack
Igor Sysoev <igor@sysoev.ru>
parents:
2483
diff
changeset
|
745 ngx_resolver_free(r, name); |
1649 | 746 |
747 return NGX_OK; | |
748 } | |
749 | |
750 if (rn->waiting) { | |
751 | |
752 ctx->next = rn->waiting; | |
753 rn->waiting = ctx; | |
3297 | 754 ctx->state = NGX_AGAIN; |
1649 | 755 |
2487
9b4dce95c744
fix return code, this fixes segfault when two or more
Igor Sysoev <igor@sysoev.ru>
parents:
2486
diff
changeset
|
756 /* unlock addr mutex */ |
9b4dce95c744
fix return code, this fixes segfault when two or more
Igor Sysoev <igor@sysoev.ru>
parents:
2486
diff
changeset
|
757 |
9b4dce95c744
fix return code, this fixes segfault when two or more
Igor Sysoev <igor@sysoev.ru>
parents:
2486
diff
changeset
|
758 return NGX_OK; |
1649 | 759 } |
760 | |
761 ngx_queue_remove(&rn->queue); | |
762 | |
763 ngx_resolver_free(r, rn->query); | |
1960
1609b3c3d604
fix memory leak on resolver query send failure
Igor Sysoev <igor@sysoev.ru>
parents:
1914
diff
changeset
|
764 rn->query = NULL; |
1649 | 765 |
766 } else { | |
767 rn = ngx_resolver_alloc(r, sizeof(ngx_resolver_node_t)); | |
768 if (rn == NULL) { | |
769 goto failed; | |
770 } | |
771 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
772 switch (ctx->addr.sockaddr->sa_family) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
773 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
774 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
775 case AF_INET6: |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
776 rn->addr6 = sin6->sin6_addr; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
777 rn->node.key = hash; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
778 break; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
779 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
780 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
781 default: /* AF_INET */ |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
782 rn->node.key = addr; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
783 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
784 |
1960
1609b3c3d604
fix memory leak on resolver query send failure
Igor Sysoev <igor@sysoev.ru>
parents:
1914
diff
changeset
|
785 rn->query = NULL; |
1649 | 786 |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
787 ngx_rbtree_insert(tree, &rn->node); |
1649 | 788 } |
789 | |
790 if (ngx_resolver_create_addr_query(rn, ctx) != NGX_OK) { | |
791 goto failed; | |
792 } | |
793 | |
794 if (ngx_resolver_send_query(r, rn) != NGX_OK) { | |
795 goto failed; | |
796 } | |
797 | |
798 ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t)); | |
799 if (ctx->event == NULL) { | |
800 goto failed; | |
801 } | |
802 | |
803 ctx->event->handler = ngx_resolver_timeout_handler; | |
804 ctx->event->data = ctx; | |
805 ctx->event->log = r->log; | |
806 ctx->ident = -1; | |
807 | |
808 ngx_add_timer(ctx->event, ctx->timeout); | |
809 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
810 if (ngx_queue_empty(resend_queue)) { |
1649 | 811 ngx_add_timer(r->event, (ngx_msec_t) (r->resend_timeout * 1000)); |
812 } | |
813 | |
814 rn->expire = ngx_time() + r->resend_timeout; | |
815 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
816 ngx_queue_insert_head(resend_queue, &rn->queue); |
1649 | 817 |
818 rn->cnlen = 0; | |
819 rn->naddrs = 0; | |
820 rn->name = NULL; | |
821 rn->nlen = 0; | |
822 rn->valid = 0; | |
823 rn->waiting = ctx; | |
824 | |
825 /* unlock addr mutex */ | |
826 | |
827 ctx->state = NGX_AGAIN; | |
828 | |
829 return NGX_OK; | |
830 | |
831 failed: | |
832 | |
833 if (rn) { | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
834 ngx_rbtree_delete(tree, &rn->node); |
1649 | 835 |
1960
1609b3c3d604
fix memory leak on resolver query send failure
Igor Sysoev <igor@sysoev.ru>
parents:
1914
diff
changeset
|
836 if (rn->query) { |
1609b3c3d604
fix memory leak on resolver query send failure
Igor Sysoev <igor@sysoev.ru>
parents:
1914
diff
changeset
|
837 ngx_resolver_free(r, rn->query); |
1609b3c3d604
fix memory leak on resolver query send failure
Igor Sysoev <igor@sysoev.ru>
parents:
1914
diff
changeset
|
838 } |
1609b3c3d604
fix memory leak on resolver query send failure
Igor Sysoev <igor@sysoev.ru>
parents:
1914
diff
changeset
|
839 |
1649 | 840 ngx_resolver_free(r, rn); |
841 } | |
842 | |
843 /* unlock addr mutex */ | |
844 | |
845 if (ctx->event) { | |
1904
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
846 ngx_resolver_free(r, ctx->event); |
1649 | 847 } |
848 | |
1904
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
849 ngx_resolver_free(r, ctx); |
1649 | 850 |
851 return NGX_ERROR; | |
852 } | |
853 | |
854 | |
855 void | |
856 ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx) | |
857 { | |
858 in_addr_t addr; | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
859 ngx_queue_t *expire_queue; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
860 ngx_rbtree_t *tree; |
1649 | 861 ngx_resolver_t *r; |
862 ngx_resolver_ctx_t *w, **p; | |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
863 struct sockaddr_in *sin; |
1649 | 864 ngx_resolver_node_t *rn; |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
865 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
866 uint32_t hash; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
867 struct sockaddr_in6 *sin6; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
868 #endif |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
869 |
1649 | 870 r = ctx->resolver; |
871 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
872 switch (ctx->addr.sockaddr->sa_family) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
873 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
874 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
875 case AF_INET6: |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
876 tree = &r->addr6_rbtree; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
877 expire_queue = &r->addr6_expire_queue; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
878 break; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
879 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
880 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
881 default: /* AF_INET */ |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
882 tree = &r->addr_rbtree; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
883 expire_queue = &r->addr_expire_queue; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
884 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
885 |
1649 | 886 ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, |
887 "resolve addr done: %i", ctx->state); | |
888 | |
889 if (ctx->event && ctx->event->timer_set) { | |
890 ngx_del_timer(ctx->event); | |
891 } | |
892 | |
893 /* lock addr mutex */ | |
894 | |
895 if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) { | |
896 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
897 switch (ctx->addr.sockaddr->sa_family) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
898 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
899 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
900 case AF_INET6: |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
901 sin6 = (struct sockaddr_in6 *) ctx->addr.sockaddr; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
902 hash = ngx_crc32_short(sin6->sin6_addr.s6_addr, 16); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
903 rn = ngx_resolver_lookup_addr6(r, &sin6->sin6_addr, hash); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
904 break; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
905 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
906 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
907 default: /* AF_INET */ |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
908 sin = (struct sockaddr_in *) ctx->addr.sockaddr; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
909 addr = ntohl(sin->sin_addr.s_addr); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
910 rn = ngx_resolver_lookup_addr(r, addr); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
911 } |
1649 | 912 |
913 if (rn) { | |
914 p = &rn->waiting; | |
915 w = rn->waiting; | |
916 | |
917 while (w) { | |
918 if (w == ctx) { | |
919 *p = w->next; | |
920 | |
921 goto done; | |
922 } | |
923 | |
924 p = &w->next; | |
925 w = w->next; | |
926 } | |
927 } | |
928 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
929 { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
930 u_char text[NGX_SOCKADDR_STRLEN]; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
931 ngx_str_t addrtext; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
932 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
933 addrtext.data = text; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
934 addrtext.len = ngx_sock_ntop(ctx->addr.sockaddr, ctx->addr.socklen, |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
935 text, NGX_SOCKADDR_STRLEN, 0); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
936 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
937 ngx_log_error(NGX_LOG_ALERT, r->log, 0, |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
938 "could not cancel %V resolving", &addrtext); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
939 } |
1649 | 940 } |
941 | |
942 done: | |
943 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
944 ngx_resolver_expire(r, tree, expire_queue); |
1649 | 945 |
946 /* unlock addr mutex */ | |
947 | |
1904
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
948 /* lock alloc mutex */ |
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
949 |
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
950 if (ctx->event) { |
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
951 ngx_resolver_free_locked(r, ctx->event); |
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
952 } |
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
953 |
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
954 ngx_resolver_free_locked(r, ctx); |
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
955 |
538f06aa8118
fix memory leaks, use unlocked ngx_resolver_free() for seldom failed cases
Igor Sysoev <igor@sysoev.ru>
parents:
1903
diff
changeset
|
956 /* unlock alloc mutex */ |
1649 | 957 } |
958 | |
959 | |
960 static void | |
961 ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue) | |
962 { | |
963 time_t now; | |
964 ngx_uint_t i; | |
965 ngx_queue_t *q; | |
966 ngx_resolver_node_t *rn; | |
967 | |
968 ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver expire"); | |
969 | |
970 now = ngx_time(); | |
971 | |
972 for (i = 0; i < 2; i++) { | |
973 if (ngx_queue_empty(queue)) { | |
974 return; | |
975 } | |
976 | |
977 q = ngx_queue_last(queue); | |
978 | |
979 rn = ngx_queue_data(q, ngx_resolver_node_t, queue); | |
980 | |
981 if (now <= rn->expire) { | |
982 return; | |
983 } | |
984 | |
1774 | 985 ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0, |
986 "resolver expire \"%*s\"", (size_t) rn->nlen, rn->name); | |
1649 | 987 |
988 ngx_queue_remove(q); | |
989 | |
990 ngx_rbtree_delete(tree, &rn->node); | |
991 | |
992 ngx_resolver_free_node(r, rn); | |
993 } | |
994 } | |
995 | |
996 | |
997 static ngx_int_t | |
998 ngx_resolver_send_query(ngx_resolver_t *r, ngx_resolver_node_t *rn) | |
999 { | |
1000 ssize_t n; | |
1001 ngx_udp_connection_t *uc; | |
1002 | |
4225
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
1003 uc = r->udp_connections.elts; |
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
1004 |
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
1005 uc = &uc[r->last_connection++]; |
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
1006 if (r->last_connection == r->udp_connections.nelts) { |
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
1007 r->last_connection = 0; |
016352c19049
Support of several servers in the "resolver" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3902
diff
changeset
|
1008 } |
1649 | 1009 |
1010 if (uc->connection == NULL) { | |
4496
be6c250b827b
Fixed null pointer dereference in resolver (ticket #91).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4474
diff
changeset
|
1011 |
be6c250b827b
Fixed null pointer dereference in resolver (ticket #91).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4474
diff
changeset
|
1012 uc->log = *r->log; |
be6c250b827b
Fixed null pointer dereference in resolver (ticket #91).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4474
diff
changeset
|
1013 uc->log.handler = ngx_resolver_log_error; |
be6c250b827b
Fixed null pointer dereference in resolver (ticket #91).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4474
diff
changeset
|
1014 uc->log.data = uc; |
be6c250b827b
Fixed null pointer dereference in resolver (ticket #91).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4474
diff
changeset
|
1015 uc->log.action = "resolving"; |
be6c250b827b
Fixed null pointer dereference in resolver (ticket #91).
Maxim Dounin <mdounin@mdounin.ru>
parents:
4474
diff
changeset
|
1016 |
1649 | 1017 if (ngx_udp_connect(uc) != NGX_OK) { |
1018 return NGX_ERROR; | |
1019 } | |
1020 | |
1021 uc->connection->data = r; | |
1022 uc->connection->read->handler = ngx_resolver_read_response; | |
1906 | 1023 uc->connection->read->resolver = 1; |
1649 | 1024 } |
1025 | |
1026 n = ngx_send(uc->connection, rn->query, rn->qlen); | |
1027 | |
1028 if (n == -1) { | |
1029 return NGX_ERROR; | |
1030 } | |
1031 | |
1032 if ((size_t) n != (size_t) rn->qlen) { | |
3408
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
1033 ngx_log_error(NGX_LOG_CRIT, &uc->log, 0, "send() incomplete"); |
1649 | 1034 return NGX_ERROR; |
1035 } | |
1036 | |
1037 return NGX_OK; | |
1038 } | |
1039 | |
1040 | |
1041 static void | |
1042 ngx_resolver_resend_handler(ngx_event_t *ev) | |
1043 { | |
1044 time_t timer, atimer, ntimer; | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1045 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1046 time_t a6timer; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1047 #endif |
1649 | 1048 ngx_resolver_t *r; |
1049 | |
1050 r = ev->data; | |
1051 | |
1052 ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, | |
1053 "resolver resend handler"); | |
1054 | |
1055 /* lock name mutex */ | |
1056 | |
1057 ntimer = ngx_resolver_resend(r, &r->name_rbtree, &r->name_resend_queue); | |
1058 | |
1059 /* unlock name mutex */ | |
1060 | |
1061 /* lock addr mutex */ | |
1062 | |
1063 atimer = ngx_resolver_resend(r, &r->addr_rbtree, &r->addr_resend_queue); | |
1679
ca317d9b5c09
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
1649
diff
changeset
|
1064 |
1649 | 1065 /* unlock addr mutex */ |
1066 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1067 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1068 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1069 /* lock addr6 mutex */ |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1070 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1071 a6timer = ngx_resolver_resend(r, &r->addr6_rbtree, &r->addr6_resend_queue); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1072 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1073 /* unlock addr6 mutex */ |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1074 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1075 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1076 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1077 timer = ntimer; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1078 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1079 if (timer == 0) { |
1649 | 1080 timer = atimer; |
1081 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1082 } else if (atimer) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1083 timer = ngx_min(timer, atimer); |
1649 | 1084 } |
1085 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1086 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1087 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1088 if (timer == 0) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1089 timer = a6timer; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1090 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1091 } else if (a6timer) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1092 timer = ngx_min(timer, a6timer); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1093 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1094 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1095 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1096 |
1649 | 1097 if (timer) { |
1098 ngx_add_timer(r->event, (ngx_msec_t) (timer * 1000)); | |
1099 } | |
1100 } | |
1101 | |
1102 | |
1103 static time_t | |
1104 ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue) | |
1105 { | |
1106 time_t now; | |
1107 ngx_queue_t *q; | |
1108 ngx_resolver_node_t *rn; | |
1109 | |
1110 now = ngx_time(); | |
1111 | |
1112 for ( ;; ) { | |
1113 if (ngx_queue_empty(queue)) { | |
1114 return 0; | |
1115 } | |
1116 | |
1117 q = ngx_queue_last(queue); | |
1118 | |
1119 rn = ngx_queue_data(q, ngx_resolver_node_t, queue); | |
1120 | |
1121 if (now < rn->expire) { | |
1122 return rn->expire - now; | |
1123 } | |
1124 | |
1774 | 1125 ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0, |
1126 "resolver resend \"%*s\" %p", | |
1127 (size_t) rn->nlen, rn->name, rn->waiting); | |
1649 | 1128 |
1129 ngx_queue_remove(q); | |
1130 | |
1131 if (rn->waiting) { | |
1132 | |
4683
84d8e60b65f0
Fixed crash in ngx_resolver_cleanup_tree().
Ruslan Ermilov <ru@nginx.com>
parents:
4671
diff
changeset
|
1133 (void) ngx_resolver_send_query(r, rn); |
84d8e60b65f0
Fixed crash in ngx_resolver_cleanup_tree().
Ruslan Ermilov <ru@nginx.com>
parents:
4671
diff
changeset
|
1134 |
84d8e60b65f0
Fixed crash in ngx_resolver_cleanup_tree().
Ruslan Ermilov <ru@nginx.com>
parents:
4671
diff
changeset
|
1135 rn->expire = now + r->resend_timeout; |
84d8e60b65f0
Fixed crash in ngx_resolver_cleanup_tree().
Ruslan Ermilov <ru@nginx.com>
parents:
4671
diff
changeset
|
1136 |
84d8e60b65f0
Fixed crash in ngx_resolver_cleanup_tree().
Ruslan Ermilov <ru@nginx.com>
parents:
4671
diff
changeset
|
1137 ngx_queue_insert_head(queue, q); |
1879
cf4ee321d195
do not delete failed DNS request if there are waiting clients
Igor Sysoev <igor@sysoev.ru>
parents:
1878
diff
changeset
|
1138 |
cf4ee321d195
do not delete failed DNS request if there are waiting clients
Igor Sysoev <igor@sysoev.ru>
parents:
1878
diff
changeset
|
1139 continue; |
1649 | 1140 } |
1141 | |
1142 ngx_rbtree_delete(tree, &rn->node); | |
1143 | |
1144 ngx_resolver_free_node(r, rn); | |
1145 } | |
1146 } | |
1147 | |
1148 | |
1149 static void | |
1150 ngx_resolver_read_response(ngx_event_t *rev) | |
1151 { | |
1152 ssize_t n; | |
1153 ngx_connection_t *c; | |
1154 u_char buf[NGX_RESOLVER_UDP_SIZE]; | |
1155 | |
1156 c = rev->data; | |
1157 | |
1158 do { | |
1689 | 1159 n = ngx_udp_recv(c, buf, NGX_RESOLVER_UDP_SIZE); |
1160 | |
1161 if (n < 0) { | |
1649 | 1162 return; |
1163 } | |
1164 | |
1165 ngx_resolver_process_response(c->data, buf, n); | |
1166 | |
1167 } while (rev->ready); | |
1168 } | |
1169 | |
1170 | |
1171 static void | |
1172 ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n) | |
1173 { | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1174 char *err; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1175 ngx_uint_t i, times, ident, qident, flags, code, nqs, nan, |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1176 qtype, qclass; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1177 ngx_queue_t *q; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1178 ngx_resolver_qs_t *qs; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1179 ngx_resolver_hdr_t *response; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1180 ngx_resolver_node_t *rn; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1181 |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1182 if (n < sizeof(ngx_resolver_hdr_t)) { |
1649 | 1183 goto short_response; |
1184 } | |
1185 | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1186 response = (ngx_resolver_hdr_t *) buf; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1187 |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1188 ident = (response->ident_hi << 8) + response->ident_lo; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1189 flags = (response->flags_hi << 8) + response->flags_lo; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1190 nqs = (response->nqs_hi << 8) + response->nqs_lo; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1191 nan = (response->nan_hi << 8) + response->nan_lo; |
1649 | 1192 |
1193 ngx_log_debug6(NGX_LOG_DEBUG_CORE, r->log, 0, | |
4653
134ccdf44647
Resolver: fixed format specification.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4643
diff
changeset
|
1194 "resolver DNS response %ui fl:%04Xui %ui/%ui/%ud/%ud", |
1649 | 1195 ident, flags, nqs, nan, |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1196 (response->nns_hi << 8) + response->nns_lo, |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1197 (response->nar_hi << 8) + response->nar_lo); |
1649 | 1198 |
5470
aebdca7e8f8f
Resolver: fixed response processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5469
diff
changeset
|
1199 /* response to a standard query */ |
aebdca7e8f8f
Resolver: fixed response processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5469
diff
changeset
|
1200 if ((flags & 0xf870) != 0x8000) { |
1649 | 1201 ngx_log_error(r->log_level, r->log, 0, |
1967
4a4b15c9c474
use correct ngx_sprintf() formats
Igor Sysoev <igor@sysoev.ru>
parents:
1966
diff
changeset
|
1202 "invalid DNS response %ui fl:%04Xui", ident, flags); |
1649 | 1203 return; |
1204 } | |
1205 | |
5470
aebdca7e8f8f
Resolver: fixed response processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5469
diff
changeset
|
1206 code = flags & 0xf; |
1649 | 1207 |
2282
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1208 if (code == NGX_RESOLVE_FORMERR) { |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1209 |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1210 times = 0; |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1211 |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1212 for (q = ngx_queue_head(&r->name_resend_queue); |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1213 q != ngx_queue_sentinel(&r->name_resend_queue) || times++ < 100; |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1214 q = ngx_queue_next(q)) |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1215 { |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1216 rn = ngx_queue_data(q, ngx_resolver_node_t, queue); |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1217 qident = (rn->query[0] << 8) + rn->query[1]; |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1218 |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1219 if (qident == ident) { |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1220 ngx_log_error(r->log_level, r->log, 0, |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1221 "DNS error (%ui: %s), query id:%ui, name:\"%*s\"", |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1222 code, ngx_resolver_strerror(code), ident, |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1223 rn->nlen, rn->name); |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1224 return; |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1225 } |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1226 } |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1227 |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1228 goto dns_error; |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1229 } |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1230 |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1231 if (code > NGX_RESOLVE_REFUSED) { |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1232 goto dns_error; |
1649 | 1233 } |
1234 | |
1235 if (nqs != 1) { | |
1236 err = "invalid number of questions in DNS response"; | |
1237 goto done; | |
1238 } | |
1239 | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1240 i = sizeof(ngx_resolver_hdr_t); |
1649 | 1241 |
1242 while (i < (ngx_uint_t) n) { | |
1243 if (buf[i] == '\0') { | |
1244 goto found; | |
1245 } | |
1246 | |
5470
aebdca7e8f8f
Resolver: fixed response processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5469
diff
changeset
|
1247 i += 1 + buf[i]; |
1649 | 1248 } |
1249 | |
1250 goto short_response; | |
1251 | |
1252 found: | |
1253 | |
5470
aebdca7e8f8f
Resolver: fixed response processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5469
diff
changeset
|
1254 if (i++ == sizeof(ngx_resolver_hdr_t)) { |
1649 | 1255 err = "zero-length domain name in DNS response"; |
1256 goto done; | |
1257 } | |
1258 | |
1259 if (i + sizeof(ngx_resolver_qs_t) + nan * (2 + sizeof(ngx_resolver_an_t)) | |
1260 > (ngx_uint_t) n) | |
1261 { | |
1262 goto short_response; | |
1263 } | |
1264 | |
1265 qs = (ngx_resolver_qs_t *) &buf[i]; | |
1266 | |
1267 qtype = (qs->type_hi << 8) + qs->type_lo; | |
1268 qclass = (qs->class_hi << 8) + qs->class_lo; | |
1269 | |
1270 ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0, | |
1967
4a4b15c9c474
use correct ngx_sprintf() formats
Igor Sysoev <igor@sysoev.ru>
parents:
1966
diff
changeset
|
1271 "resolver DNS response qt:%ui cl:%ui", qtype, qclass); |
1649 | 1272 |
1273 if (qclass != 1) { | |
1274 ngx_log_error(r->log_level, r->log, 0, | |
1967
4a4b15c9c474
use correct ngx_sprintf() formats
Igor Sysoev <igor@sysoev.ru>
parents:
1966
diff
changeset
|
1275 "unknown query class %ui in DNS response", qclass); |
1649 | 1276 return; |
1277 } | |
1278 | |
1279 switch (qtype) { | |
1280 | |
1281 case NGX_RESOLVE_A: | |
1282 | |
1283 ngx_resolver_process_a(r, buf, n, ident, code, nan, | |
1742
268b81386fe4
no answers in DNS response should be NXDOMAIN
Igor Sysoev <igor@sysoev.ru>
parents:
1741
diff
changeset
|
1284 i + sizeof(ngx_resolver_qs_t)); |
1649 | 1285 |
1286 break; | |
1287 | |
1288 case NGX_RESOLVE_PTR: | |
1289 | |
1742
268b81386fe4
no answers in DNS response should be NXDOMAIN
Igor Sysoev <igor@sysoev.ru>
parents:
1741
diff
changeset
|
1290 ngx_resolver_process_ptr(r, buf, n, ident, code, nan); |
1649 | 1291 |
1292 break; | |
1293 | |
1294 default: | |
1295 ngx_log_error(r->log_level, r->log, 0, | |
1967
4a4b15c9c474
use correct ngx_sprintf() formats
Igor Sysoev <igor@sysoev.ru>
parents:
1966
diff
changeset
|
1296 "unknown query type %ui in DNS response", qtype); |
1649 | 1297 return; |
1298 } | |
1299 | |
1300 return; | |
1301 | |
1302 short_response: | |
1303 | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1304 err = "short DNS response"; |
1649 | 1305 |
1306 done: | |
1307 | |
1308 ngx_log_error(r->log_level, r->log, 0, err); | |
1309 | |
1310 return; | |
2282
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1311 |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1312 dns_error: |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1313 |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1314 ngx_log_error(r->log_level, r->log, 0, |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1315 "DNS error (%ui: %s), query id:%ui", |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1316 code, ngx_resolver_strerror(code), ident); |
ec97eb9a8038
show name for a FORMERR DNS response
Igor Sysoev <igor@sysoev.ru>
parents:
2281
diff
changeset
|
1317 return; |
1649 | 1318 } |
1319 | |
1320 | |
1321 static void | |
1322 ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last, | |
1323 ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan, ngx_uint_t ans) | |
583 | 1324 { |
1649 | 1325 char *err; |
1326 u_char *cname; | |
1327 size_t len; | |
4295
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1328 int32_t ttl; |
1649 | 1329 uint32_t hash; |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1330 in_addr_t *addr; |
1649 | 1331 ngx_str_t name; |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1332 ngx_addr_t *addrs; |
5471
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1333 ngx_uint_t type, class, qident, naddrs, a, i, n, start; |
1649 | 1334 ngx_resolver_an_t *an; |
1335 ngx_resolver_ctx_t *ctx, *next; | |
1336 ngx_resolver_node_t *rn; | |
1337 | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1338 if (ngx_resolver_copy(r, &name, buf, |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1339 buf + sizeof(ngx_resolver_hdr_t), buf + last) |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1340 != NGX_OK) |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1341 { |
1649 | 1342 return; |
1343 } | |
1344 | |
1345 ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver qs:%V", &name); | |
1346 | |
1347 hash = ngx_crc32_short(name.data, name.len); | |
1348 | |
1349 /* lock name mutex */ | |
1350 | |
1351 rn = ngx_resolver_lookup_name(r, &name, hash); | |
1352 | |
1353 if (rn == NULL || rn->query == NULL) { | |
1354 ngx_log_error(r->log_level, r->log, 0, | |
1355 "unexpected response for %V", &name); | |
5471
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1356 ngx_resolver_free(r, name.data); |
1649 | 1357 goto failed; |
1358 } | |
1359 | |
1360 qident = (rn->query[0] << 8) + rn->query[1]; | |
1361 | |
1362 if (ident != qident) { | |
1363 ngx_log_error(r->log_level, r->log, 0, | |
1967
4a4b15c9c474
use correct ngx_sprintf() formats
Igor Sysoev <igor@sysoev.ru>
parents:
1966
diff
changeset
|
1364 "wrong ident %ui response for %V, expect %ui", |
1649 | 1365 ident, &name, qident); |
5471
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1366 ngx_resolver_free(r, name.data); |
1649 | 1367 goto failed; |
1368 } | |
1369 | |
3139 | 1370 ngx_resolver_free(r, name.data); |
1371 | |
1742
268b81386fe4
no answers in DNS response should be NXDOMAIN
Igor Sysoev <igor@sysoev.ru>
parents:
1741
diff
changeset
|
1372 if (code == 0 && nan == 0) { |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1373 code = NGX_RESOLVE_NXDOMAIN; |
1742
268b81386fe4
no answers in DNS response should be NXDOMAIN
Igor Sysoev <igor@sysoev.ru>
parents:
1741
diff
changeset
|
1374 } |
268b81386fe4
no answers in DNS response should be NXDOMAIN
Igor Sysoev <igor@sysoev.ru>
parents:
1741
diff
changeset
|
1375 |
1649 | 1376 if (code) { |
1377 next = rn->waiting; | |
1378 rn->waiting = NULL; | |
1379 | |
1380 ngx_queue_remove(&rn->queue); | |
1381 | |
1382 ngx_rbtree_delete(&r->name_rbtree, &rn->node); | |
1383 | |
1384 ngx_resolver_free_node(r, rn); | |
1385 | |
1386 /* unlock name mutex */ | |
1387 | |
1388 while (next) { | |
5474
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1389 ctx = next; |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1390 ctx->state = code; |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1391 next = ctx->next; |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1392 |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1393 ctx->handler(ctx); |
1649 | 1394 } |
1395 | |
1396 return; | |
1397 } | |
1398 | |
1399 i = ans; | |
1400 naddrs = 0; | |
1401 cname = NULL; | |
4296
783fd9c38d98
Silenced a warning for some compilers.
Ruslan Ermilov <ru@nginx.com>
parents:
4295
diff
changeset
|
1402 ttl = 0; |
1649 | 1403 |
1404 for (a = 0; a < nan; a++) { | |
1405 | |
1406 start = i; | |
1407 | |
1408 while (i < last) { | |
1409 | |
1410 if (buf[i] & 0xc0) { | |
1411 i += 2; | |
1412 goto found; | |
1413 } | |
1414 | |
1415 if (buf[i] == 0) { | |
1416 i++; | |
1417 goto test_length; | |
1418 } | |
1419 | |
1420 i += 1 + buf[i]; | |
1421 } | |
1422 | |
1423 goto short_response; | |
1424 | |
1425 test_length: | |
1426 | |
1427 if (i - start < 2) { | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1428 err = "invalid name in DNS response"; |
1649 | 1429 goto invalid; |
1430 } | |
1431 | |
1432 found: | |
1433 | |
1434 if (i + sizeof(ngx_resolver_an_t) >= last) { | |
1435 goto short_response; | |
1436 } | |
1437 | |
1438 an = (ngx_resolver_an_t *) &buf[i]; | |
1439 | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1440 type = (an->type_hi << 8) + an->type_lo; |
5471
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1441 class = (an->class_hi << 8) + an->class_lo; |
1649 | 1442 len = (an->len_hi << 8) + an->len_lo; |
4295
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1443 ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16) |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1444 + (an->ttl[2] << 8) + (an->ttl[3]); |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1445 |
5471
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1446 if (class != 1) { |
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1447 ngx_log_error(r->log_level, r->log, 0, |
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1448 "unexpected RR class %ui", class); |
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1449 goto failed; |
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1450 } |
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1451 |
4295
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1452 if (ttl < 0) { |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1453 ttl = 0; |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1454 } |
1649 | 1455 |
5471
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1456 i += sizeof(ngx_resolver_an_t); |
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1457 |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1458 switch (type) { |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1459 |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1460 case NGX_RESOLVE_A: |
1649 | 1461 |
5471
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1462 if (len != 4) { |
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1463 err = "invalid A record in DNS response"; |
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1464 goto invalid; |
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1465 } |
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1466 |
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1467 if (i + 4 > last) { |
1649 | 1468 goto short_response; |
1469 } | |
1470 | |
1471 naddrs++; | |
1472 | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1473 break; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1474 |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1475 case NGX_RESOLVE_CNAME: |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1476 |
5471
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1477 cname = &buf[i]; |
1965 | 1478 |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1479 break; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1480 |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1481 case NGX_RESOLVE_DNAME: |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1482 |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1483 break; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1484 |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1485 default: |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1486 |
1966 | 1487 ngx_log_error(r->log_level, r->log, 0, |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1488 "unexpected RR type %ui", type); |
1649 | 1489 } |
5471
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1490 |
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1491 i += len; |
1649 | 1492 } |
1493 | |
4295
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1494 ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0, |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1495 "resolver naddrs:%ui cname:%p ttl:%d", |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1496 naddrs, cname, ttl); |
1649 | 1497 |
1498 if (naddrs) { | |
1499 | |
1500 if (naddrs == 1) { | |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1501 addr = &rn->u.addr; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1502 rn->naddrs = 1; |
1649 | 1503 |
1504 } else { | |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1505 addr = ngx_resolver_alloc(r, naddrs * sizeof(in_addr_t)); |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1506 if (addr == NULL) { |
5471
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1507 goto failed; |
1649 | 1508 } |
1509 | |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1510 rn->u.addrs = addr; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1511 rn->naddrs = (u_short) naddrs; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1512 } |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1513 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1514 n = 0; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1515 i = ans; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1516 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1517 for (a = 0; a < nan; a++) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1518 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1519 for ( ;; ) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1520 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1521 if (buf[i] & 0xc0) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1522 i += 2; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1523 break; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1524 } |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1525 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1526 if (buf[i] == 0) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1527 i++; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1528 break; |
1649 | 1529 } |
1530 | |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1531 i += 1 + buf[i]; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1532 } |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1533 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1534 an = (ngx_resolver_an_t *) &buf[i]; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1535 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1536 type = (an->type_hi << 8) + an->type_lo; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1537 len = (an->len_hi << 8) + an->len_lo; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1538 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1539 i += sizeof(ngx_resolver_an_t); |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1540 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1541 if (type == NGX_RESOLVE_A) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1542 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1543 addr[n] = htonl((buf[i] << 24) + (buf[i + 1] << 16) |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1544 + (buf[i + 2] << 8) + (buf[i + 3])); |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1545 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1546 if (++n == naddrs) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1547 break; |
1649 | 1548 } |
1549 } | |
1550 | |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1551 i += len; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1552 } |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1553 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1554 if (naddrs == 1) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1555 addrs = NULL; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1556 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1557 } else { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1558 addrs = ngx_resolver_export(r, rn->u.addrs, naddrs, 0); |
1649 | 1559 if (addrs == NULL) { |
5471
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1560 goto failed; |
1649 | 1561 } |
1562 } | |
1563 | |
1564 ngx_queue_remove(&rn->queue); | |
1565 | |
4295
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1566 rn->valid = ngx_time() + (r->valid ? r->valid : ttl); |
1649 | 1567 rn->expire = ngx_time() + r->expire; |
1568 | |
1569 ngx_queue_insert_head(&r->name_expire_queue, &rn->queue); | |
1570 | |
1571 next = rn->waiting; | |
1572 rn->waiting = NULL; | |
1573 | |
1574 /* unlock name mutex */ | |
1575 | |
1576 while (next) { | |
5474
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1577 ctx = next; |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1578 ctx->state = NGX_OK; |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1579 ctx->naddrs = naddrs; |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1580 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1581 if (addrs == NULL) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1582 ctx->addrs = &ctx->addr; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1583 ctx->addr.sockaddr = (struct sockaddr *) &ctx->sin; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1584 ctx->addr.socklen = sizeof(struct sockaddr_in); |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1585 ngx_memzero(&ctx->sin, sizeof(struct sockaddr_in)); |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1586 ctx->sin.sin_family = AF_INET; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1587 ctx->sin.sin_addr.s_addr = rn->u.addr; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1588 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1589 } else { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1590 ctx->addrs = addrs; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1591 } |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1592 |
5474
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1593 next = ctx->next; |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1594 |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1595 ctx->handler(ctx); |
1649 | 1596 } |
1597 | |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1598 if (addrs != NULL) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
1599 ngx_resolver_free(r, addrs->sockaddr); |
1649 | 1600 ngx_resolver_free(r, addrs); |
1601 } | |
1602 | |
4619
3171ec7d0d05
Resolver: protection from duplicate responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4610
diff
changeset
|
1603 ngx_resolver_free(r, rn->query); |
3171ec7d0d05
Resolver: protection from duplicate responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4610
diff
changeset
|
1604 rn->query = NULL; |
3171ec7d0d05
Resolver: protection from duplicate responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4610
diff
changeset
|
1605 |
1649 | 1606 return; |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1607 } |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1608 |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1609 if (cname) { |
1649 | 1610 |
1611 /* CNAME only */ | |
1612 | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1613 if (ngx_resolver_copy(r, &name, buf, cname, buf + last) != NGX_OK) { |
5471
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1614 goto failed; |
1649 | 1615 } |
1616 | |
1617 ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, | |
1618 "resolver cname:\"%V\"", &name); | |
1619 | |
1741
0829024c924d
fix segfault if response will have CNAME only
Igor Sysoev <igor@sysoev.ru>
parents:
1689
diff
changeset
|
1620 ngx_queue_remove(&rn->queue); |
0829024c924d
fix segfault if response will have CNAME only
Igor Sysoev <igor@sysoev.ru>
parents:
1689
diff
changeset
|
1621 |
1649 | 1622 rn->cnlen = (u_short) name.len; |
1623 rn->u.cname = name.data; | |
4295
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1624 |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1625 rn->valid = ngx_time() + (r->valid ? r->valid : ttl); |
1649 | 1626 rn->expire = ngx_time() + r->expire; |
1627 | |
1628 ngx_queue_insert_head(&r->name_expire_queue, &rn->queue); | |
1629 | |
1630 ctx = rn->waiting; | |
1631 rn->waiting = NULL; | |
1632 | |
1633 if (ctx) { | |
1634 ctx->name = name; | |
1635 | |
1636 (void) ngx_resolve_name_locked(r, ctx); | |
1637 } | |
1638 | |
4619
3171ec7d0d05
Resolver: protection from duplicate responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4610
diff
changeset
|
1639 ngx_resolver_free(r, rn->query); |
3171ec7d0d05
Resolver: protection from duplicate responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4610
diff
changeset
|
1640 rn->query = NULL; |
3171ec7d0d05
Resolver: protection from duplicate responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4610
diff
changeset
|
1641 |
5471
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1642 /* unlock name mutex */ |
9c96782d9d05
Resolver: fixes in A processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5470
diff
changeset
|
1643 |
1649 | 1644 return; |
1645 } | |
1646 | |
1647 ngx_log_error(r->log_level, r->log, 0, | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1648 "no A or CNAME types in DNS response"); |
1649 | 1649 return; |
1650 | |
1651 short_response: | |
1652 | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1653 err = "short DNS response"; |
1649 | 1654 |
1655 invalid: | |
1656 | |
1657 /* unlock name mutex */ | |
1658 | |
1659 ngx_log_error(r->log_level, r->log, 0, err); | |
1660 | |
1661 return; | |
1662 | |
1663 failed: | |
1664 | |
1665 /* unlock name mutex */ | |
1666 | |
1667 return; | |
1668 } | |
1669 | |
1670 | |
1671 static void | |
1672 ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n, | |
1742
268b81386fe4
no answers in DNS response should be NXDOMAIN
Igor Sysoev <igor@sysoev.ru>
parents:
1741
diff
changeset
|
1673 ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan) |
1649 | 1674 { |
1675 char *err; | |
1676 size_t len; | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1677 u_char text[NGX_SOCKADDR_STRLEN]; |
1649 | 1678 in_addr_t addr; |
4295
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1679 int32_t ttl; |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1680 ngx_int_t octet; |
1649 | 1681 ngx_str_t name; |
5472
ab493c60d9ff
Resolver: fixes in PTR processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5471
diff
changeset
|
1682 ngx_uint_t i, mask, qident, class; |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1683 ngx_queue_t *expire_queue; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1684 ngx_rbtree_t *tree; |
1649 | 1685 ngx_resolver_an_t *an; |
1686 ngx_resolver_ctx_t *ctx, *next; | |
1687 ngx_resolver_node_t *rn; | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1688 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1689 uint32_t hash; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1690 ngx_int_t digit; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1691 struct in6_addr addr6; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1692 #endif |
1649 | 1693 |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1694 if (ngx_resolver_copy(r, NULL, buf, |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1695 buf + sizeof(ngx_resolver_hdr_t), buf + n) |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1696 != NGX_OK) |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1697 { |
5472
ab493c60d9ff
Resolver: fixes in PTR processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5471
diff
changeset
|
1698 return; |
1649 | 1699 } |
1700 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1701 /* AF_INET */ |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1702 |
1649 | 1703 addr = 0; |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1704 i = sizeof(ngx_resolver_hdr_t); |
1649 | 1705 |
1706 for (mask = 0; mask < 32; mask += 8) { | |
1707 len = buf[i++]; | |
1708 | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1709 octet = ngx_atoi(&buf[i], len); |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1710 if (octet == NGX_ERROR || octet > 255) { |
1649 | 1711 goto invalid_in_addr_arpa; |
1712 } | |
1713 | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1714 addr += octet << mask; |
1649 | 1715 i += len; |
1716 } | |
1717 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1718 if (ngx_strcmp(&buf[i], "\7in-addr\4arpa") == 0) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1719 i += sizeof("\7in-addr\4arpa"); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1720 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1721 /* lock addr mutex */ |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1722 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1723 rn = ngx_resolver_lookup_addr(r, addr); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1724 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1725 tree = &r->addr_rbtree; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1726 expire_queue = &r->addr_expire_queue; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1727 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1728 addr = htonl(addr); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1729 name.len = ngx_inet_ntop(AF_INET, &addr, text, NGX_SOCKADDR_STRLEN); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1730 name.data = text; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1731 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1732 goto valid; |
1649 | 1733 } |
1734 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1735 invalid_in_addr_arpa: |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1736 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1737 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1738 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1739 i = sizeof(ngx_resolver_hdr_t); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1740 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1741 for (octet = 15; octet >= 0; octet--) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1742 if (buf[i++] != '\1') { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1743 goto invalid_ip6_arpa; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1744 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1745 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1746 digit = ngx_hextoi(&buf[i++], 1); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1747 if (digit == NGX_ERROR) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1748 goto invalid_ip6_arpa; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1749 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1750 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1751 addr6.s6_addr[octet] = (u_char) digit; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1752 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1753 if (buf[i++] != '\1') { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1754 goto invalid_ip6_arpa; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1755 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1756 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1757 digit = ngx_hextoi(&buf[i++], 1); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1758 if (digit == NGX_ERROR) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1759 goto invalid_ip6_arpa; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1760 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1761 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1762 addr6.s6_addr[octet] += (u_char) (digit * 16); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1763 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1764 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1765 if (ngx_strcmp(&buf[i], "\3ip6\4arpa") == 0) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1766 i += sizeof("\3ip6\4arpa"); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1767 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1768 /* lock addr mutex */ |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1769 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1770 hash = ngx_crc32_short(addr6.s6_addr, 16); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1771 rn = ngx_resolver_lookup_addr6(r, &addr6, hash); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1772 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1773 tree = &r->addr6_rbtree; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1774 expire_queue = &r->addr6_expire_queue; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1775 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1776 name.len = ngx_inet6_ntop(addr6.s6_addr, text, NGX_SOCKADDR_STRLEN); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1777 name.data = text; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1778 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1779 goto valid; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1780 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1781 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1782 invalid_ip6_arpa: |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1783 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1784 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1785 ngx_log_error(r->log_level, r->log, 0, |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1786 "invalid in-addr.arpa or ip6.arpa name in DNS response"); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1787 return; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1788 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1789 valid: |
1649 | 1790 |
1791 if (rn == NULL || rn->query == NULL) { | |
1792 ngx_log_error(r->log_level, r->log, 0, | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1793 "unexpected response for %V", &name); |
1649 | 1794 goto failed; |
1795 } | |
1796 | |
1797 qident = (rn->query[0] << 8) + rn->query[1]; | |
1798 | |
1799 if (ident != qident) { | |
1800 ngx_log_error(r->log_level, r->log, 0, | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1801 "wrong ident %ui response for %V, expect %ui", |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1802 ident, &name, qident); |
1649 | 1803 goto failed; |
1804 } | |
1805 | |
1742
268b81386fe4
no answers in DNS response should be NXDOMAIN
Igor Sysoev <igor@sysoev.ru>
parents:
1741
diff
changeset
|
1806 if (code == 0 && nan == 0) { |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1807 code = NGX_RESOLVE_NXDOMAIN; |
1742
268b81386fe4
no answers in DNS response should be NXDOMAIN
Igor Sysoev <igor@sysoev.ru>
parents:
1741
diff
changeset
|
1808 } |
268b81386fe4
no answers in DNS response should be NXDOMAIN
Igor Sysoev <igor@sysoev.ru>
parents:
1741
diff
changeset
|
1809 |
1649 | 1810 if (code) { |
1811 next = rn->waiting; | |
1812 rn->waiting = NULL; | |
1813 | |
1814 ngx_queue_remove(&rn->queue); | |
1815 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1816 ngx_rbtree_delete(tree, &rn->node); |
1649 | 1817 |
1818 ngx_resolver_free_node(r, rn); | |
1819 | |
1820 /* unlock addr mutex */ | |
1821 | |
1822 while (next) { | |
5474
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1823 ctx = next; |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1824 ctx->state = code; |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1825 next = ctx->next; |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1826 |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1827 ctx->handler(ctx); |
1649 | 1828 } |
1829 | |
1830 return; | |
1831 } | |
1832 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1833 i += sizeof(ngx_resolver_qs_t); |
1649 | 1834 |
5472
ab493c60d9ff
Resolver: fixes in PTR processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5471
diff
changeset
|
1835 if (i + 2 + sizeof(ngx_resolver_an_t) >= n) { |
1649 | 1836 goto short_response; |
1837 } | |
1838 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1839 /* compression pointer to *.arpa */ |
1649 | 1840 |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1841 if (buf[i] != 0xc0 || buf[i + 1] != sizeof(ngx_resolver_hdr_t)) { |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1842 err = "invalid in-addr.arpa or ip6.arpa name in DNS response"; |
1649 | 1843 goto invalid; |
1844 } | |
1845 | |
1846 an = (ngx_resolver_an_t *) &buf[i + 2]; | |
1847 | |
5472
ab493c60d9ff
Resolver: fixes in PTR processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5471
diff
changeset
|
1848 class = (an->class_hi << 8) + an->class_lo; |
1649 | 1849 len = (an->len_hi << 8) + an->len_lo; |
4295
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1850 ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16) |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1851 + (an->ttl[2] << 8) + (an->ttl[3]); |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1852 |
5472
ab493c60d9ff
Resolver: fixes in PTR processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5471
diff
changeset
|
1853 if (class != 1) { |
ab493c60d9ff
Resolver: fixes in PTR processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5471
diff
changeset
|
1854 ngx_log_error(r->log_level, r->log, 0, |
ab493c60d9ff
Resolver: fixes in PTR processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5471
diff
changeset
|
1855 "unexpected RR class %ui", class); |
ab493c60d9ff
Resolver: fixes in PTR processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5471
diff
changeset
|
1856 goto failed; |
ab493c60d9ff
Resolver: fixes in PTR processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5471
diff
changeset
|
1857 } |
ab493c60d9ff
Resolver: fixes in PTR processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5471
diff
changeset
|
1858 |
4295
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1859 if (ttl < 0) { |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1860 ttl = 0; |
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1861 } |
1649 | 1862 |
1863 ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0, | |
3902
159b58f9c0bd
fix building by gcc 4.6 without --with-debug
Igor Sysoev <igor@sysoev.ru>
parents:
3763
diff
changeset
|
1864 "resolver qt:%ui cl:%ui len:%uz", |
159b58f9c0bd
fix building by gcc 4.6 without --with-debug
Igor Sysoev <igor@sysoev.ru>
parents:
3763
diff
changeset
|
1865 (an->type_hi << 8) + an->type_lo, |
5472
ab493c60d9ff
Resolver: fixes in PTR processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5471
diff
changeset
|
1866 class, len); |
1649 | 1867 |
1868 i += 2 + sizeof(ngx_resolver_an_t); | |
1869 | |
5469
b2fc466a11a7
Resolver: removed unnecessary casts.
Ruslan Ermilov <ru@nginx.com>
parents:
5468
diff
changeset
|
1870 if (i + len > n) { |
1649 | 1871 goto short_response; |
1872 } | |
1873 | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
1874 if (ngx_resolver_copy(r, &name, buf, buf + i, buf + n) != NGX_OK) { |
5472
ab493c60d9ff
Resolver: fixes in PTR processing.
Ruslan Ermilov <ru@nginx.com>
parents:
5471
diff
changeset
|
1875 goto failed; |
1649 | 1876 } |
1877 | |
1878 ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver an:%V", &name); | |
1879 | |
2486
8de5dc3e7001
use length of uncompressed name
Igor Sysoev <igor@sysoev.ru>
parents:
2484
diff
changeset
|
1880 if (name.len != (size_t) rn->nlen |
8de5dc3e7001
use length of uncompressed name
Igor Sysoev <igor@sysoev.ru>
parents:
2484
diff
changeset
|
1881 || ngx_strncmp(name.data, rn->name, name.len) != 0) |
1649 | 1882 { |
2482
30ec8c5ac75b
fix reverse resolving cache: it stored zero length names
Igor Sysoev <igor@sysoev.ru>
parents:
2314
diff
changeset
|
1883 if (rn->nlen) { |
30ec8c5ac75b
fix reverse resolving cache: it stored zero length names
Igor Sysoev <igor@sysoev.ru>
parents:
2314
diff
changeset
|
1884 ngx_resolver_free(r, rn->name); |
30ec8c5ac75b
fix reverse resolving cache: it stored zero length names
Igor Sysoev <igor@sysoev.ru>
parents:
2314
diff
changeset
|
1885 } |
30ec8c5ac75b
fix reverse resolving cache: it stored zero length names
Igor Sysoev <igor@sysoev.ru>
parents:
2314
diff
changeset
|
1886 |
2490
1c87647b7ca5
fix building by msvc, introduced in r2487
Igor Sysoev <igor@sysoev.ru>
parents:
2487
diff
changeset
|
1887 rn->nlen = (u_short) name.len; |
1649 | 1888 rn->name = name.data; |
1889 | |
2486
8de5dc3e7001
use length of uncompressed name
Igor Sysoev <igor@sysoev.ru>
parents:
2484
diff
changeset
|
1890 name.data = ngx_resolver_dup(r, rn->name, name.len); |
1649 | 1891 if (name.data == NULL) { |
1892 goto failed; | |
1893 } | |
1894 } | |
1895 | |
1896 ngx_queue_remove(&rn->queue); | |
1897 | |
4295
05031fce7ce8
Now nginx uses TTL of a DNS response when calculating cache validity.
Ruslan Ermilov <ru@nginx.com>
parents:
4267
diff
changeset
|
1898 rn->valid = ngx_time() + (r->valid ? r->valid : ttl); |
1649 | 1899 rn->expire = ngx_time() + r->expire; |
1900 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
1901 ngx_queue_insert_head(expire_queue, &rn->queue); |
1649 | 1902 |
1903 next = rn->waiting; | |
1904 rn->waiting = NULL; | |
1905 | |
1906 /* unlock addr mutex */ | |
1907 | |
1908 while (next) { | |
5474
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1909 ctx = next; |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1910 ctx->state = NGX_OK; |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1911 ctx->name = name; |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1912 next = ctx->next; |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1913 |
b43b02bb54db
Resolver: fixed indentation.
Ruslan Ermilov <ru@nginx.com>
parents:
5472
diff
changeset
|
1914 ctx->handler(ctx); |
1649 | 1915 } |
1916 | |
1917 ngx_resolver_free(r, name.data); | |
1918 | |
1919 return; | |
1920 | |
1921 short_response: | |
1922 | |
1923 err = "short DNS response"; | |
1924 | |
1925 invalid: | |
1926 | |
1927 /* unlock addr mutex */ | |
1928 | |
1929 ngx_log_error(r->log_level, r->log, 0, err); | |
1930 | |
1931 return; | |
1932 | |
1933 failed: | |
1934 | |
1935 /* unlock addr mutex */ | |
1936 | |
1937 return; | |
1938 } | |
1939 | |
1940 | |
1941 static ngx_resolver_node_t * | |
1942 ngx_resolver_lookup_name(ngx_resolver_t *r, ngx_str_t *name, uint32_t hash) | |
1943 { | |
1944 ngx_int_t rc; | |
1945 ngx_rbtree_node_t *node, *sentinel; | |
1946 ngx_resolver_node_t *rn; | |
1947 | |
1948 node = r->name_rbtree.root; | |
1949 sentinel = r->name_rbtree.sentinel; | |
1950 | |
1951 while (node != sentinel) { | |
1952 | |
1953 if (hash < node->key) { | |
1954 node = node->left; | |
1955 continue; | |
1956 } | |
1957 | |
1958 if (hash > node->key) { | |
1959 node = node->right; | |
1960 continue; | |
1961 } | |
1962 | |
1963 /* hash == node->key */ | |
1964 | |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4496
diff
changeset
|
1965 rn = (ngx_resolver_node_t *) node; |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4496
diff
changeset
|
1966 |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4496
diff
changeset
|
1967 rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen); |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4496
diff
changeset
|
1968 |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4496
diff
changeset
|
1969 if (rc == 0) { |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4496
diff
changeset
|
1970 return rn; |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4496
diff
changeset
|
1971 } |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4496
diff
changeset
|
1972 |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4496
diff
changeset
|
1973 node = (rc < 0) ? node->left : node->right; |
1649 | 1974 } |
1975 | |
1976 /* not found */ | |
1977 | |
1978 return NULL; | |
1979 } | |
1980 | |
1981 | |
1982 static ngx_resolver_node_t * | |
1983 ngx_resolver_lookup_addr(ngx_resolver_t *r, in_addr_t addr) | |
1984 { | |
1985 ngx_rbtree_node_t *node, *sentinel; | |
1986 | |
1987 node = r->addr_rbtree.root; | |
1988 sentinel = r->addr_rbtree.sentinel; | |
1989 | |
1990 while (node != sentinel) { | |
1991 | |
1992 if (addr < node->key) { | |
1993 node = node->left; | |
1994 continue; | |
1995 } | |
1996 | |
1997 if (addr > node->key) { | |
1998 node = node->right; | |
1999 continue; | |
2000 } | |
2001 | |
2002 /* addr == node->key */ | |
2003 | |
2004 return (ngx_resolver_node_t *) node; | |
2005 } | |
2006 | |
2007 /* not found */ | |
2008 | |
2009 return NULL; | |
2010 } | |
2011 | |
2012 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2013 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2014 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2015 static ngx_resolver_node_t * |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2016 ngx_resolver_lookup_addr6(ngx_resolver_t *r, struct in6_addr *addr, |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2017 uint32_t hash) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2018 { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2019 ngx_int_t rc; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2020 ngx_rbtree_node_t *node, *sentinel; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2021 ngx_resolver_node_t *rn; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2022 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2023 node = r->addr6_rbtree.root; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2024 sentinel = r->addr6_rbtree.sentinel; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2025 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2026 while (node != sentinel) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2027 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2028 if (hash < node->key) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2029 node = node->left; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2030 continue; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2031 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2032 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2033 if (hash > node->key) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2034 node = node->right; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2035 continue; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2036 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2037 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2038 /* hash == node->key */ |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2039 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2040 rn = (ngx_resolver_node_t *) node; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2041 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2042 rc = ngx_memcmp(addr, &rn->addr6, 16); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2043 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2044 if (rc == 0) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2045 return rn; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2046 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2047 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2048 node = (rc < 0) ? node->left : node->right; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2049 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2050 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2051 /* not found */ |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2052 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2053 return NULL; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2054 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2055 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2056 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2057 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2058 |
1649 | 2059 static void |
2060 ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t *temp, | |
2061 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) | |
2062 { | |
2063 ngx_rbtree_node_t **p; | |
2064 ngx_resolver_node_t *rn, *rn_temp; | |
2065 | |
2066 for ( ;; ) { | |
2067 | |
2068 if (node->key < temp->key) { | |
2069 | |
2070 p = &temp->left; | |
2071 | |
2072 } else if (node->key > temp->key) { | |
2073 | |
2074 p = &temp->right; | |
2075 | |
2076 } else { /* node->key == temp->key */ | |
2077 | |
2078 rn = (ngx_resolver_node_t *) node; | |
2079 rn_temp = (ngx_resolver_node_t *) temp; | |
2080 | |
3143
ab6258e18099
fix resolver cache rbtree comparison
Igor Sysoev <igor@sysoev.ru>
parents:
3139
diff
changeset
|
2081 p = (ngx_memn2cmp(rn->name, rn_temp->name, rn->nlen, rn_temp->nlen) |
ab6258e18099
fix resolver cache rbtree comparison
Igor Sysoev <igor@sysoev.ru>
parents:
3139
diff
changeset
|
2082 < 0) ? &temp->left : &temp->right; |
1649 | 2083 } |
2084 | |
2085 if (*p == sentinel) { | |
2086 break; | |
2087 } | |
2088 | |
2089 temp = *p; | |
2090 } | |
2091 | |
2092 *p = node; | |
2093 node->parent = temp; | |
2094 node->left = sentinel; | |
2095 node->right = sentinel; | |
2096 ngx_rbt_red(node); | |
2097 } | |
2098 | |
2099 | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2100 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2101 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2102 static void |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2103 ngx_resolver_rbtree_insert_addr6_value(ngx_rbtree_node_t *temp, |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2104 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2105 { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2106 ngx_rbtree_node_t **p; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2107 ngx_resolver_node_t *rn, *rn_temp; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2108 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2109 for ( ;; ) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2110 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2111 if (node->key < temp->key) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2112 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2113 p = &temp->left; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2114 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2115 } else if (node->key > temp->key) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2116 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2117 p = &temp->right; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2118 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2119 } else { /* node->key == temp->key */ |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2120 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2121 rn = (ngx_resolver_node_t *) node; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2122 rn_temp = (ngx_resolver_node_t *) temp; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2123 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2124 p = (ngx_memcmp(&rn->addr6, &rn_temp->addr6, 16) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2125 < 0) ? &temp->left : &temp->right; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2126 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2127 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2128 if (*p == sentinel) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2129 break; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2130 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2131 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2132 temp = *p; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2133 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2134 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2135 *p = node; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2136 node->parent = temp; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2137 node->left = sentinel; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2138 node->right = sentinel; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2139 ngx_rbt_red(node); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2140 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2141 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2142 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2143 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2144 |
1649 | 2145 static ngx_int_t |
2146 ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx) | |
2147 { | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
2148 u_char *p, *s; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
2149 size_t len, nlen; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
2150 ngx_uint_t ident; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
2151 ngx_resolver_qs_t *qs; |
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
2152 ngx_resolver_hdr_t *query; |
1649 | 2153 |
3306
61bdaac6c668
fix resolving an empty name (".")
Igor Sysoev <igor@sysoev.ru>
parents:
3299
diff
changeset
|
2154 nlen = ctx->name.len ? (1 + ctx->name.len + 1) : 1; |
61bdaac6c668
fix resolving an empty name (".")
Igor Sysoev <igor@sysoev.ru>
parents:
3299
diff
changeset
|
2155 |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
2156 len = sizeof(ngx_resolver_hdr_t) + nlen + sizeof(ngx_resolver_qs_t); |
1649 | 2157 |
3307
34e99a97fbd6
use ngx_resolver_alloc() instead of ngx_resolver_calloc()
Igor Sysoev <igor@sysoev.ru>
parents:
3306
diff
changeset
|
2158 p = ngx_resolver_alloc(ctx->resolver, len); |
1649 | 2159 if (p == NULL) { |
2160 return NGX_ERROR; | |
2161 } | |
2162 | |
2163 rn->qlen = (u_short) len; | |
2164 rn->query = p; | |
2165 | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
2166 query = (ngx_resolver_hdr_t *) p; |
1649 | 2167 |
2168 ident = ngx_random(); | |
2169 | |
2170 ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->resolver->log, 0, | |
2171 "resolve: \"%V\" %i", &ctx->name, ident & 0xffff); | |
2172 | |
2173 query->ident_hi = (u_char) ((ident >> 8) & 0xff); | |
2174 query->ident_lo = (u_char) (ident & 0xff); | |
2175 | |
2176 /* recursion query */ | |
2177 query->flags_hi = 1; query->flags_lo = 0; | |
2178 | |
2179 /* one question */ | |
2180 query->nqs_hi = 0; query->nqs_lo = 1; | |
2181 query->nan_hi = 0; query->nan_lo = 0; | |
2182 query->nns_hi = 0; query->nns_lo = 0; | |
2183 query->nar_hi = 0; query->nar_lo = 0; | |
2184 | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
2185 p += sizeof(ngx_resolver_hdr_t) + nlen; |
1649 | 2186 |
2187 qs = (ngx_resolver_qs_t *) p; | |
2188 | |
2189 /* query type */ | |
2190 qs->type_hi = 0; qs->type_lo = (u_char) ctx->type; | |
2191 | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
2192 /* IN query class */ |
1649 | 2193 qs->class_hi = 0; qs->class_lo = 1; |
2194 | |
2195 /* convert "www.example.com" to "\3www\7example\3com\0" */ | |
2196 | |
2197 len = 0; | |
2198 p--; | |
2199 *p-- = '\0'; | |
2200 | |
4610
778d2cc03e22
Fixed segmentation fault in ngx_resolver_create_name_query().
Ruslan Ermilov <ru@nginx.com>
parents:
4556
diff
changeset
|
2201 if (ctx->name.len == 0) { |
778d2cc03e22
Fixed segmentation fault in ngx_resolver_create_name_query().
Ruslan Ermilov <ru@nginx.com>
parents:
4556
diff
changeset
|
2202 return NGX_DECLINED; |
778d2cc03e22
Fixed segmentation fault in ngx_resolver_create_name_query().
Ruslan Ermilov <ru@nginx.com>
parents:
4556
diff
changeset
|
2203 } |
778d2cc03e22
Fixed segmentation fault in ngx_resolver_create_name_query().
Ruslan Ermilov <ru@nginx.com>
parents:
4556
diff
changeset
|
2204 |
1649 | 2205 for (s = ctx->name.data + ctx->name.len - 1; s >= ctx->name.data; s--) { |
2206 if (*s != '.') { | |
2207 *p = *s; | |
2208 len++; | |
2209 | |
2210 } else { | |
4556
1bddc91e78d6
Resolver: added missing sanity checking when creating name queries.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4497
diff
changeset
|
2211 if (len == 0 || len > 255) { |
1961
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
2212 return NGX_DECLINED; |
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
2213 } |
99b9feacccb4
return NXDOMAIN for ".." in host name
Igor Sysoev <igor@sysoev.ru>
parents:
1960
diff
changeset
|
2214 |
1649 | 2215 *p = (u_char) len; |
2216 len = 0; | |
2217 } | |
2218 | |
2219 p--; | |
2220 } | |
2221 | |
4556
1bddc91e78d6
Resolver: added missing sanity checking when creating name queries.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4497
diff
changeset
|
2222 if (len == 0 || len > 255) { |
1bddc91e78d6
Resolver: added missing sanity checking when creating name queries.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4497
diff
changeset
|
2223 return NGX_DECLINED; |
1bddc91e78d6
Resolver: added missing sanity checking when creating name queries.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4497
diff
changeset
|
2224 } |
1bddc91e78d6
Resolver: added missing sanity checking when creating name queries.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4497
diff
changeset
|
2225 |
1649 | 2226 *p = (u_char) len; |
2227 | |
2228 return NGX_OK; | |
2229 } | |
2230 | |
2231 | |
2232 static ngx_int_t | |
2233 ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx) | |
2234 { | |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2235 u_char *p, *d; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2236 size_t len; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2237 in_addr_t addr; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2238 ngx_int_t n; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2239 ngx_uint_t ident; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2240 ngx_resolver_hdr_t *query; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2241 struct sockaddr_in *sin; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2242 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2243 struct sockaddr_in6 *sin6; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2244 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2245 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2246 switch (ctx->addr.sockaddr->sa_family) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2247 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2248 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2249 case AF_INET6: |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2250 len = sizeof(ngx_resolver_hdr_t) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2251 + 64 + sizeof(".ip6.arpa.") - 1 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2252 + sizeof(ngx_resolver_qs_t); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2253 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2254 break; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2255 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2256 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2257 default: /* AF_INET */ |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2258 len = sizeof(ngx_resolver_hdr_t) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2259 + sizeof(".255.255.255.255.in-addr.arpa.") - 1 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2260 + sizeof(ngx_resolver_qs_t); |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2261 } |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
2262 |
3307
34e99a97fbd6
use ngx_resolver_alloc() instead of ngx_resolver_calloc()
Igor Sysoev <igor@sysoev.ru>
parents:
3306
diff
changeset
|
2263 p = ngx_resolver_alloc(ctx->resolver, len); |
1649 | 2264 if (p == NULL) { |
2265 return NGX_ERROR; | |
2266 } | |
2267 | |
2268 rn->query = p; | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
2269 query = (ngx_resolver_hdr_t *) p; |
1649 | 2270 |
2271 ident = ngx_random(); | |
2272 | |
2273 query->ident_hi = (u_char) ((ident >> 8) & 0xff); | |
2274 query->ident_lo = (u_char) (ident & 0xff); | |
2275 | |
2276 /* recursion query */ | |
2277 query->flags_hi = 1; query->flags_lo = 0; | |
2278 | |
2279 /* one question */ | |
2280 query->nqs_hi = 0; query->nqs_lo = 1; | |
2281 query->nan_hi = 0; query->nan_lo = 0; | |
2282 query->nns_hi = 0; query->nns_lo = 0; | |
2283 query->nar_hi = 0; query->nar_lo = 0; | |
2284 | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
2285 p += sizeof(ngx_resolver_hdr_t); |
1649 | 2286 |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2287 switch (ctx->addr.sockaddr->sa_family) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2288 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2289 #if (NGX_HAVE_INET6) |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2290 case AF_INET6: |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2291 sin6 = (struct sockaddr_in6 *) ctx->addr.sockaddr; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2292 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2293 for (n = 15; n >= 0; n--) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2294 p = ngx_sprintf(p, "\1%xd\1%xd", |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2295 sin6->sin6_addr.s6_addr[n] & 0xf, |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2296 (sin6->sin6_addr.s6_addr[n] >> 4) & 0xf); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2297 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2298 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2299 p = ngx_cpymem(p, "\3ip6\4arpa\0", 10); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2300 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2301 break; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2302 #endif |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2303 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2304 default: /* AF_INET */ |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2305 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2306 sin = (struct sockaddr_in *) ctx->addr.sockaddr; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2307 addr = ntohl(sin->sin_addr.s_addr); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2308 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2309 for (n = 0; n < 32; n += 8) { |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2310 d = ngx_sprintf(&p[1], "%ud", (addr >> n) & 0xff); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2311 *p = (u_char) (d - &p[1]); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2312 p = d; |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2313 } |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2314 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2315 p = ngx_cpymem(p, "\7in-addr\4arpa\0", 14); |
1649 | 2316 } |
2317 | |
5468
5c410d6ca7dd
Resolver: improved code readability.
Ruslan Ermilov <ru@nginx.com>
parents:
5360
diff
changeset
|
2318 /* query type "PTR", IN query class */ |
5476
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2319 p = ngx_cpymem(p, "\0\14\0\1", 4); |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2320 |
950c9ed3e66f
Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov <ru@nginx.com>
parents:
5475
diff
changeset
|
2321 rn->qlen = (u_short) (p - rn->query); |
1649 | 2322 |
2323 return NGX_OK; | |
2324 } | |
2325 | |
2326 | |
2327 static ngx_int_t | |
2328 ngx_resolver_copy(ngx_resolver_t *r, ngx_str_t *name, u_char *buf, u_char *src, | |
2329 u_char *last) | |
2330 { | |
2331 char *err; | |
2332 u_char *p, *dst; | |
2333 ssize_t len; | |
2334 ngx_uint_t i, n; | |
2335 | |
2336 p = src; | |
2337 len = -1; | |
2338 | |
2339 /* | |
2340 * compression pointers allow to create endless loop, so we set limit; | |
2341 * 128 pointers should be enough to store 255-byte name | |
2342 */ | |
2343 | |
2344 for (i = 0; i < 128; i++) { | |
2345 n = *p++; | |
2346 | |
2347 if (n == 0) { | |
2348 goto done; | |
2349 } | |
2350 | |
2351 if (n & 0xc0) { | |
2314
52987a023486
fix compression pointer for big (>255) DNS responses
Igor Sysoev <igor@sysoev.ru>
parents:
2282
diff
changeset
|
2352 n = ((n & 0x3f) << 8) + *p; |
1649 | 2353 p = &buf[n]; |
2354 | |
2355 } else { | |
2356 len += 1 + n; | |
2357 p = &p[n]; | |
2358 } | |
2359 | |
2360 if (p >= last) { | |
2361 err = "name is out of response"; | |
2362 goto invalid; | |
2363 } | |
2364 } | |
2365 | |
2366 err = "compression pointers loop"; | |
2367 | |
2368 invalid: | |
2369 | |
2370 ngx_log_error(r->log_level, r->log, 0, err); | |
2371 | |
2372 return NGX_ERROR; | |
2373 | |
2374 done: | |
2375 | |
2376 if (name == NULL) { | |
583 | 2377 return NGX_OK; |
2378 } | |
2379 | |
3298
847ab5a32307
fix "PTR ." case in address resolver
Igor Sysoev <igor@sysoev.ru>
parents:
3297
diff
changeset
|
2380 if (len == -1) { |
847ab5a32307
fix "PTR ." case in address resolver
Igor Sysoev <igor@sysoev.ru>
parents:
3297
diff
changeset
|
2381 name->len = 0; |
847ab5a32307
fix "PTR ." case in address resolver
Igor Sysoev <igor@sysoev.ru>
parents:
3297
diff
changeset
|
2382 name->data = NULL; |
847ab5a32307
fix "PTR ." case in address resolver
Igor Sysoev <igor@sysoev.ru>
parents:
3297
diff
changeset
|
2383 return NGX_OK; |
847ab5a32307
fix "PTR ." case in address resolver
Igor Sysoev <igor@sysoev.ru>
parents:
3297
diff
changeset
|
2384 } |
847ab5a32307
fix "PTR ." case in address resolver
Igor Sysoev <igor@sysoev.ru>
parents:
3297
diff
changeset
|
2385 |
1649 | 2386 dst = ngx_resolver_alloc(r, len); |
2387 if (dst == NULL) { | |
2388 return NGX_ERROR; | |
2389 } | |
2390 | |
2391 name->data = dst; | |
2392 | |
2393 n = *src++; | |
2394 | |
2395 for ( ;; ) { | |
4267
768212ca0745
Fixed compression pointer processing in DNS response greater than 255 bytes.
Igor Sysoev <igor@sysoev.ru>
parents:
4225
diff
changeset
|
2396 if (n & 0xc0) { |
768212ca0745
Fixed compression pointer processing in DNS response greater than 255 bytes.
Igor Sysoev <igor@sysoev.ru>
parents:
4225
diff
changeset
|
2397 n = ((n & 0x3f) << 8) + *src; |
768212ca0745
Fixed compression pointer processing in DNS response greater than 255 bytes.
Igor Sysoev <igor@sysoev.ru>
parents:
4225
diff
changeset
|
2398 src = &buf[n]; |
768212ca0745
Fixed compression pointer processing in DNS response greater than 255 bytes.
Igor Sysoev <igor@sysoev.ru>
parents:
4225
diff
changeset
|
2399 |
768212ca0745
Fixed compression pointer processing in DNS response greater than 255 bytes.
Igor Sysoev <igor@sysoev.ru>
parents:
4225
diff
changeset
|
2400 n = *src++; |
768212ca0745
Fixed compression pointer processing in DNS response greater than 255 bytes.
Igor Sysoev <igor@sysoev.ru>
parents:
4225
diff
changeset
|
2401 |
768212ca0745
Fixed compression pointer processing in DNS response greater than 255 bytes.
Igor Sysoev <igor@sysoev.ru>
parents:
4225
diff
changeset
|
2402 } else { |
1649 | 2403 ngx_memcpy(dst, src, n); |
2404 dst += n; | |
2405 src += n; | |
2406 | |
2407 n = *src++; | |
2408 | |
2409 if (n != 0) { | |
2410 *dst++ = '.'; | |
2411 } | |
2412 } | |
2413 | |
2414 if (n == 0) { | |
2415 name->len = dst - name->data; | |
2416 return NGX_OK; | |
2417 } | |
2418 } | |
2419 } | |
2420 | |
2421 | |
2422 static void | |
2423 ngx_resolver_timeout_handler(ngx_event_t *ev) | |
2424 { | |
2425 ngx_resolver_ctx_t *ctx; | |
2426 | |
2427 ctx = ev->data; | |
2428 | |
2429 ctx->state = NGX_RESOLVE_TIMEDOUT; | |
2430 | |
2431 ctx->handler(ctx); | |
2432 } | |
2433 | |
2434 | |
2435 static void | |
2436 ngx_resolver_free_node(ngx_resolver_t *r, ngx_resolver_node_t *rn) | |
2437 { | |
2438 /* lock alloc mutex */ | |
2439 | |
2440 if (rn->query) { | |
2441 ngx_resolver_free_locked(r, rn->query); | |
2442 } | |
2443 | |
2444 if (rn->name) { | |
2445 ngx_resolver_free_locked(r, rn->name); | |
2446 } | |
2447 | |
2448 if (rn->cnlen) { | |
2449 ngx_resolver_free_locked(r, rn->u.cname); | |
2450 } | |
2451 | |
2452 if (rn->naddrs > 1) { | |
2453 ngx_resolver_free_locked(r, rn->u.addrs); | |
2454 } | |
2455 | |
2456 ngx_resolver_free_locked(r, rn); | |
2457 | |
2458 /* unlock alloc mutex */ | |
2459 } | |
2460 | |
2461 | |
2462 static void * | |
2463 ngx_resolver_alloc(ngx_resolver_t *r, size_t size) | |
2464 { | |
2465 u_char *p; | |
2466 | |
2467 /* lock alloc mutex */ | |
2468 | |
2469 p = ngx_alloc(size, r->log); | |
2470 | |
2471 /* unlock alloc mutex */ | |
2472 | |
2473 return p; | |
2474 } | |
2475 | |
2476 | |
1903 | 2477 static void * |
1649 | 2478 ngx_resolver_calloc(ngx_resolver_t *r, size_t size) |
2479 { | |
2480 u_char *p; | |
2481 | |
2482 p = ngx_resolver_alloc(r, size); | |
2483 | |
2484 if (p) { | |
2485 ngx_memzero(p, size); | |
2486 } | |
2487 | |
2488 return p; | |
2489 } | |
2490 | |
2491 | |
2492 static void | |
2493 ngx_resolver_free(ngx_resolver_t *r, void *p) | |
2494 { | |
2495 /* lock alloc mutex */ | |
2496 | |
2497 ngx_free(p); | |
2498 | |
2499 /* unlock alloc mutex */ | |
2500 } | |
2501 | |
2502 | |
2503 static void | |
2504 ngx_resolver_free_locked(ngx_resolver_t *r, void *p) | |
2505 { | |
2506 ngx_free(p); | |
2507 } | |
2508 | |
2509 | |
2510 static void * | |
2511 ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size) | |
2512 { | |
2513 void *dst; | |
2514 | |
2515 dst = ngx_resolver_alloc(r, size); | |
2516 | |
2517 if (dst == NULL) { | |
2518 return dst; | |
2519 } | |
2520 | |
2521 ngx_memcpy(dst, src, size); | |
2522 | |
2523 return dst; | |
2524 } | |
2525 | |
2526 | |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2527 static ngx_addr_t * |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2528 ngx_resolver_export(ngx_resolver_t *r, in_addr_t *src, ngx_uint_t n, |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2529 ngx_uint_t rotate) |
4871
c85cefbdaafe
Resolver: cached addresses are returned with random rotation now.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4784
diff
changeset
|
2530 { |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2531 ngx_addr_t *dst; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2532 ngx_uint_t i, j; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2533 struct sockaddr_in *sin; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2534 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2535 dst = ngx_resolver_calloc(r, n * sizeof(ngx_addr_t)); |
4892
063ac68d89dc
Resolver: added missing memory allocation error handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4871
diff
changeset
|
2536 if (dst == NULL) { |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2537 return NULL; |
4892
063ac68d89dc
Resolver: added missing memory allocation error handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4871
diff
changeset
|
2538 } |
063ac68d89dc
Resolver: added missing memory allocation error handling.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4871
diff
changeset
|
2539 |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2540 sin = ngx_resolver_calloc(r, n * sizeof(struct sockaddr_in)); |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2541 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2542 if (sin == NULL) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2543 ngx_resolver_free(r, dst); |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2544 return NULL; |
4871
c85cefbdaafe
Resolver: cached addresses are returned with random rotation now.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4784
diff
changeset
|
2545 } |
c85cefbdaafe
Resolver: cached addresses are returned with random rotation now.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4784
diff
changeset
|
2546 |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2547 j = rotate ? ngx_random() % n : 0; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2548 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2549 for (i = 0; i < n; i++) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2550 dst[i].sockaddr = (struct sockaddr *) &sin[i]; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2551 dst[i].socklen = sizeof(struct sockaddr_in); |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2552 sin[i].sin_family = AF_INET; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2553 sin[i].sin_addr.s_addr = src[j++]; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2554 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2555 if (j == n) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2556 j = 0; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2557 } |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5474
diff
changeset
|
2558 } |
4871
c85cefbdaafe
Resolver: cached addresses are returned with random rotation now.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4784
diff
changeset
|
2559 |
c85cefbdaafe
Resolver: cached addresses are returned with random rotation now.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4784
diff
changeset
|
2560 return dst; |
c85cefbdaafe
Resolver: cached addresses are returned with random rotation now.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4784
diff
changeset
|
2561 } |
c85cefbdaafe
Resolver: cached addresses are returned with random rotation now.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4784
diff
changeset
|
2562 |
c85cefbdaafe
Resolver: cached addresses are returned with random rotation now.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4784
diff
changeset
|
2563 |
1649 | 2564 char * |
2565 ngx_resolver_strerror(ngx_int_t err) | |
2566 { | |
2567 static char *errors[] = { | |
2568 "Format error", /* FORMERR */ | |
2569 "Server failure", /* SERVFAIL */ | |
2570 "Host not found", /* NXDOMAIN */ | |
2571 "Unimplemented", /* NOTIMP */ | |
2572 "Operation refused" /* REFUSED */ | |
2573 }; | |
2574 | |
2575 if (err > 0 && err < 6) { | |
2576 return errors[err - 1]; | |
2577 } | |
2578 | |
2579 if (err == NGX_RESOLVE_TIMEDOUT) { | |
2580 return "Operation timed out"; | |
2581 } | |
2582 | |
2583 return "Unknown error"; | |
2584 } | |
2585 | |
2586 | |
3408
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2587 static u_char * |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2588 ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len) |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2589 { |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2590 u_char *p; |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2591 ngx_udp_connection_t *uc; |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2592 |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2593 p = buf; |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2594 |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2595 if (log->action) { |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2596 p = ngx_snprintf(buf, len, " while %s", log->action); |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2597 len -= p - buf; |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2598 } |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2599 |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2600 uc = log->data; |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2601 |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2602 if (uc) { |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2603 p = ngx_snprintf(p, len, ", resolver: %V", &uc->server); |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2604 } |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2605 |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2606 return p; |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2607 } |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2608 |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2609 |
1649 | 2610 ngx_int_t |
2611 ngx_udp_connect(ngx_udp_connection_t *uc) | |
2612 { | |
2613 int rc; | |
2614 ngx_int_t event; | |
2615 ngx_event_t *rev, *wev; | |
2616 ngx_socket_t s; | |
2617 ngx_connection_t *c; | |
2618 | |
4671
af9342747669
Support for IPv6 literals and an optional port in resolver.
Ruslan Ermilov <ru@nginx.com>
parents:
4653
diff
changeset
|
2619 s = ngx_socket(uc->sockaddr->sa_family, SOCK_DGRAM, 0); |
583 | 2620 |
3408
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2621 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &uc->log, 0, "UDP socket %d", s); |
583 | 2622 |
5360
3d2d3e1cf427
Win32: MinGW GCC compatibility.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4892
diff
changeset
|
2623 if (s == (ngx_socket_t) -1) { |
3408
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2624 ngx_log_error(NGX_LOG_ALERT, &uc->log, ngx_socket_errno, |
583 | 2625 ngx_socket_n " failed"); |
2626 return NGX_ERROR; | |
2627 } | |
2628 | |
3408
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2629 c = ngx_get_connection(s, &uc->log); |
583 | 2630 |
2631 if (c == NULL) { | |
2632 if (ngx_close_socket(s) == -1) { | |
3408
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2633 ngx_log_error(NGX_LOG_ALERT, &uc->log, ngx_socket_errno, |
583 | 2634 ngx_close_socket_n "failed"); |
2635 } | |
2636 | |
2637 return NGX_ERROR; | |
2638 } | |
2639 | |
1649 | 2640 if (ngx_nonblocking(s) == -1) { |
3408
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2641 ngx_log_error(NGX_LOG_ALERT, &uc->log, ngx_socket_errno, |
1649 | 2642 ngx_nonblocking_n " failed"); |
2643 | |
2644 ngx_free_connection(c); | |
2645 | |
2646 if (ngx_close_socket(s) == -1) { | |
3408
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2647 ngx_log_error(NGX_LOG_ALERT, &uc->log, ngx_socket_errno, |
1649 | 2648 ngx_close_socket_n " failed"); |
2649 } | |
2650 | |
2651 return NGX_ERROR; | |
2652 } | |
2653 | |
583 | 2654 rev = c->read; |
2655 wev = c->write; | |
2656 | |
3408
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2657 rev->log = &uc->log; |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2658 wev->log = &uc->log; |
1649 | 2659 |
2660 uc->connection = c; | |
583 | 2661 |
2662 c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); | |
2663 | |
2664 #if (NGX_THREADS) | |
1649 | 2665 |
2666 /* TODO: lock event when call completion handler */ | |
2667 | |
2668 rev->lock = &c->lock; | |
2669 wev->lock = &c->lock; | |
583 | 2670 rev->own_lock = &c->lock; |
2671 wev->own_lock = &c->lock; | |
1649 | 2672 |
583 | 2673 #endif |
2674 | |
3408
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2675 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, &uc->log, 0, |
1649 | 2676 "connect to %V, fd:%d #%d", &uc->server, s, c->number); |
2677 | |
2678 rc = connect(s, uc->sockaddr, uc->socklen); | |
2679 | |
2680 /* TODO: aio, iocp */ | |
583 | 2681 |
2682 if (rc == -1) { | |
3408
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2683 ngx_log_error(NGX_LOG_CRIT, &uc->log, ngx_socket_errno, |
71193a456616
add context to a resolver log
Igor Sysoev <igor@sysoev.ru>
parents:
3376
diff
changeset
|
2684 "connect() failed"); |
583 | 2685 |
2686 return NGX_ERROR; | |
2687 } | |
2688 | |
1649 | 2689 /* UDP sockets are always ready to write */ |
2690 wev->ready = 1; | |
2691 | |
2692 if (ngx_add_event) { | |
2693 | |
2694 event = (ngx_event_flags & NGX_USE_CLEAR_EVENT) ? | |
2695 /* kqueue, epoll */ NGX_CLEAR_EVENT: | |
2696 /* select, poll, /dev/poll */ NGX_LEVEL_EVENT; | |
2697 /* eventport event type has no meaning: oneshot only */ | |
2698 | |
2699 if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) { | |
2700 return NGX_ERROR; | |
2701 } | |
2702 | |
2703 } else { | |
2704 /* rtsig */ | |
2705 | |
583 | 2706 if (ngx_add_conn(c) == NGX_ERROR) { |
2707 return NGX_ERROR; | |
2708 } | |
2709 } | |
2710 | |
2711 return NGX_OK; | |
2712 } |