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