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