[nginx] Resolver: implemented IPv6 name to address resolving.
Ruslan Ermilov
ru at nginx.com
Fri Dec 13 16:54:49 UTC 2013
details: http://hg.nginx.org/nginx/rev/98876ce2a7fd
branches:
changeset: 5477:98876ce2a7fd
user: Ruslan Ermilov <ru at nginx.com>
date: Mon Dec 09 10:53:28 2013 +0400
description:
Resolver: implemented IPv6 name to address resolving.
diffstat:
src/core/ngx_resolver.c | 487 ++++++++++++++++++++++++++++----
src/core/ngx_resolver.h | 18 +-
src/event/ngx_event_openssl_stapling.c | 1 -
src/http/ngx_http_upstream.c | 1 -
src/mail/ngx_mail_smtp_handler.c | 1 -
5 files changed, 439 insertions(+), 69 deletions(-)
diffs (truncated from 897 to 300 lines):
diff -r 950c9ed3e66f -r 98876ce2a7fd src/core/ngx_resolver.c
--- a/src/core/ngx_resolver.c Fri Dec 06 14:30:28 2013 +0400
+++ b/src/core/ngx_resolver.c Mon Dec 09 10:53:28 2013 +0400
@@ -70,7 +70,8 @@ static void ngx_resolver_read_response(n
static void ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf,
size_t n);
static void ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t n,
- ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan, ngx_uint_t ans);
+ ngx_uint_t ident, ngx_uint_t code, ngx_uint_t qtype,
+ ngx_uint_t nan, ngx_uint_t ans);
static void ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan);
static ngx_resolver_node_t *ngx_resolver_lookup_name(ngx_resolver_t *r,
@@ -88,8 +89,8 @@ static void *ngx_resolver_calloc(ngx_res
static void ngx_resolver_free(ngx_resolver_t *r, void *p);
static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p);
static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size);
-static ngx_addr_t *ngx_resolver_export(ngx_resolver_t *r, in_addr_t *src,
- ngx_uint_t n, ngx_uint_t rotate);
+static ngx_addr_t *ngx_resolver_export(ngx_resolver_t *r,
+ ngx_resolver_node_t *rn, ngx_uint_t rotate);
static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len);
#if (NGX_HAVE_INET6)
@@ -435,8 +436,6 @@ done:
}
-/* NGX_RESOLVE_A only */
-
static ngx_int_t
ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
{
@@ -463,17 +462,18 @@ ngx_resolve_name_locked(ngx_resolver_t *
ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
- naddrs = rn->naddrs;
+ naddrs = (rn->naddrs == (u_short) -1) ? 0 : rn->naddrs;
+#if (NGX_HAVE_INET6)
+ naddrs += (rn->naddrs6 == (u_short) -1) ? 0 : rn->naddrs6;
+#endif
if (naddrs) {
- /* NGX_RESOLVE_A answer */
-
- if (naddrs == 1) {
+ if (naddrs == 1 && rn->naddrs == 1) {
addrs = NULL;
} else {
- addrs = ngx_resolver_export(r, rn->u.addrs, naddrs, 1);
+ addrs = ngx_resolver_export(r, rn, 1);
if (addrs == NULL) {
return NGX_ERROR;
}
@@ -558,16 +558,25 @@ ngx_resolve_name_locked(ngx_resolver_t *
if (rn->query) {
ngx_resolver_free_locked(r, rn->query);
rn->query = NULL;
+#if (NGX_HAVE_INET6)
+ rn->query6 = NULL;
+#endif
}
if (rn->cnlen) {
ngx_resolver_free_locked(r, rn->u.cname);
}
- if (rn->naddrs > 1) {
+ if (rn->naddrs > 1 && rn->naddrs != (u_short) -1) {
ngx_resolver_free_locked(r, rn->u.addrs);
}
+#if (NGX_HAVE_INET6)
+ if (rn->naddrs6 > 1 && rn->naddrs6 != (u_short) -1) {
+ ngx_resolver_free_locked(r, rn->u6.addrs6);
+ }
+#endif
+
/* unlock alloc mutex */
} else {
@@ -586,6 +595,9 @@ ngx_resolve_name_locked(ngx_resolver_t *
rn->node.key = hash;
rn->nlen = (u_short) ctx->name.len;
rn->query = NULL;
+#if (NGX_HAVE_INET6)
+ rn->query6 = NULL;
+#endif
ngx_rbtree_insert(&r->name_rbtree, &rn->node);
}
@@ -609,6 +621,11 @@ ngx_resolve_name_locked(ngx_resolver_t *
return NGX_OK;
}
+ rn->naddrs = (u_short) -1;
+#if (NGX_HAVE_INET6)
+ rn->naddrs6 = (u_short) -1;
+#endif
+
if (ngx_resolver_send_query(r, rn) != NGX_OK) {
goto failed;
}
@@ -635,8 +652,8 @@ ngx_resolve_name_locked(ngx_resolver_t *
ngx_queue_insert_head(&r->name_resend_queue, &rn->queue);
+ rn->code = 0;
rn->cnlen = 0;
- rn->naddrs = 0;
rn->valid = 0;
rn->waiting = ctx;
@@ -762,6 +779,9 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx
ngx_resolver_free(r, rn->query);
rn->query = NULL;
+#if (NGX_HAVE_INET6)
+ rn->query6 = NULL;
+#endif
} else {
rn = ngx_resolver_alloc(r, sizeof(ngx_resolver_node_t));
@@ -783,6 +803,9 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx
}
rn->query = NULL;
+#if (NGX_HAVE_INET6)
+ rn->query6 = NULL;
+#endif
ngx_rbtree_insert(tree, &rn->node);
}
@@ -791,6 +814,11 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx
goto failed;
}
+ rn->naddrs = (u_short) -1;
+#if (NGX_HAVE_INET6)
+ rn->naddrs6 = (u_short) -1;
+#endif
+
if (ngx_resolver_send_query(r, rn) != NGX_OK) {
goto failed;
}
@@ -815,8 +843,8 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx
ngx_queue_insert_head(resend_queue, &rn->queue);
+ rn->code = 0;
rn->cnlen = 0;
- rn->naddrs = 0;
rn->name = NULL;
rn->nlen = 0;
rn->valid = 0;
@@ -1023,16 +1051,33 @@ ngx_resolver_send_query(ngx_resolver_t *
uc->connection->read->resolver = 1;
}
- n = ngx_send(uc->connection, rn->query, rn->qlen);
-
- if (n == -1) {
- return NGX_ERROR;
+ if (rn->naddrs == (u_short) -1) {
+ n = ngx_send(uc->connection, rn->query, rn->qlen);
+
+ if (n == -1) {
+ return NGX_ERROR;
+ }
+
+ if ((size_t) n != (size_t) rn->qlen) {
+ ngx_log_error(NGX_LOG_CRIT, &uc->log, 0, "send() incomplete");
+ return NGX_ERROR;
+ }
}
- if ((size_t) n != (size_t) rn->qlen) {
- ngx_log_error(NGX_LOG_CRIT, &uc->log, 0, "send() incomplete");
- return NGX_ERROR;
+#if (NGX_HAVE_INET6)
+ if (rn->query6 && rn->naddrs6 == (u_short) -1) {
+ n = ngx_send(uc->connection, rn->query6, rn->qlen);
+
+ if (n == -1) {
+ return NGX_ERROR;
+ }
+
+ if ((size_t) n != (size_t) rn->qlen) {
+ ngx_log_error(NGX_LOG_CRIT, &uc->log, 0, "send() incomplete");
+ return NGX_ERROR;
+ }
}
+#endif
return NGX_OK;
}
@@ -1174,6 +1219,9 @@ ngx_resolver_process_response(ngx_resolv
char *err;
ngx_uint_t i, times, ident, qident, flags, code, nqs, nan,
qtype, qclass;
+#if (NGX_HAVE_INET6)
+ ngx_uint_t qident6;
+#endif
ngx_queue_t *q;
ngx_resolver_qs_t *qs;
ngx_resolver_hdr_t *response;
@@ -1217,12 +1265,18 @@ ngx_resolver_process_response(ngx_resolv
qident = (rn->query[0] << 8) + rn->query[1];
if (qident == ident) {
- ngx_log_error(r->log_level, r->log, 0,
- "DNS error (%ui: %s), query id:%ui, name:\"%*s\"",
- code, ngx_resolver_strerror(code), ident,
- rn->nlen, rn->name);
- return;
+ goto dns_error_name;
}
+
+#if (NGX_HAVE_INET6)
+ if (rn->query6) {
+ qident6 = (rn->query6[0] << 8) + rn->query6[1];
+
+ if (qident6 == ident) {
+ goto dns_error_name;
+ }
+ }
+#endif
}
goto dns_error;
@@ -1279,8 +1333,11 @@ found:
switch (qtype) {
case NGX_RESOLVE_A:
-
- ngx_resolver_process_a(r, buf, n, ident, code, nan,
+#if (NGX_HAVE_INET6)
+ case NGX_RESOLVE_AAAA:
+#endif
+
+ ngx_resolver_process_a(r, buf, n, ident, code, qtype, nan,
i + sizeof(ngx_resolver_qs_t));
break;
@@ -1309,6 +1366,14 @@ done:
return;
+dns_error_name:
+
+ ngx_log_error(r->log_level, r->log, 0,
+ "DNS error (%ui: %s), query id:%ui, name:\"%*s\"",
+ code, ngx_resolver_strerror(code), ident,
+ rn->nlen, rn->name);
+ return;
+
dns_error:
ngx_log_error(r->log_level, r->log, 0,
@@ -1320,7 +1385,8 @@ dns_error:
static void
ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
- ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan, ngx_uint_t ans)
+ ngx_uint_t ident, ngx_uint_t code, ngx_uint_t qtype,
+ ngx_uint_t nan, ngx_uint_t ans)
{
char *err;
u_char *cname;
@@ -1331,6 +1397,9 @@ ngx_resolver_process_a(ngx_resolver_t *r
ngx_str_t name;
ngx_addr_t *addrs;
ngx_uint_t type, class, qident, naddrs, a, i, n, start;
+#if (NGX_HAVE_INET6)
+ struct in6_addr *addr6;
+#endif
ngx_resolver_an_t *an;
ngx_resolver_ctx_t *ctx, *next;
ngx_resolver_node_t *rn;
@@ -1350,14 +1419,43 @@ ngx_resolver_process_a(ngx_resolver_t *r
rn = ngx_resolver_lookup_name(r, &name, hash);
- if (rn == NULL || rn->query == NULL) {
+ if (rn == NULL) {
ngx_log_error(r->log_level, r->log, 0,
"unexpected response for %V", &name);
ngx_resolver_free(r, name.data);
goto failed;
}
- qident = (rn->query[0] << 8) + rn->query[1];
+ switch (qtype) {
+
+#if (NGX_HAVE_INET6)
+ case NGX_RESOLVE_AAAA:
+
More information about the nginx-devel
mailing list