Welcome! Log In Create A New Profile

Advanced

[nginx] Resolver: implemented IPv6 name to address resolving.

Ruslan Ermilov
December 13, 2013 01:30PM
details: http://hg.nginx.org/nginx/rev/98876ce2a7fd
branches:
changeset: 5477:98876ce2a7fd
user: Ruslan Ermilov <ru@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:
+

_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[nginx] Resolver: implemented IPv6 name to address resolving.

Ruslan Ermilov 758 December 13, 2013 01:30PM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 157
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready