details: http://hg.nginx.org/nginx/rev/98876ce2a7fd branches: changeset: 5477:98876ce2a7fd user: Ruslan Ermilov <r...@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