diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c index 54ae2fc0e..d1beb5812 100644 --- a/src/core/ngx_resolver.c +++ b/src/core/ngx_resolver.c @@ -59,7 +59,7 @@ ngx_int_t ngx_udp_connect(ngx_udp_connection_t *uc); static void ngx_resolver_cleanup(void *data); static void ngx_resolver_cleanup_tree(ngx_resolver_t *r, ngx_rbtree_t *tree); static ngx_int_t ngx_resolve_name_locked(ngx_resolver_t *r, - ngx_resolver_ctx_t *ctx); + ngx_resolver_ctx_t *ctx, ngx_str_t *name); static void ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue); static ngx_int_t ngx_resolver_send_query(ngx_resolver_t *r, @@ -376,7 +376,7 @@ ngx_resolve_name(ngx_resolver_ctx_t *ctx) /* lock name mutex */ - rc = ngx_resolve_name_locked(r, ctx); + rc = ngx_resolve_name_locked(r, ctx, &ctx->name); if (rc == NGX_OK) { return NGX_OK; @@ -403,7 +403,6 @@ ngx_resolve_name(ngx_resolver_ctx_t *ctx) void ngx_resolve_name_done(ngx_resolver_ctx_t *ctx) { - uint32_t hash; ngx_resolver_t *r; ngx_resolver_ctx_t *w, **p; ngx_resolver_node_t *rn; @@ -425,9 +424,7 @@ ngx_resolve_name_done(ngx_resolver_ctx_t *ctx) if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) { - hash = ngx_crc32_short(ctx->name.data, ctx->name.len); - - rn = ngx_resolver_lookup_name(r, &ctx->name, hash); + rn = ctx->node; if (rn) { p = &rn->waiting; @@ -472,20 +469,22 @@ done: static ngx_int_t -ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx) +ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx, + ngx_str_t *name) { uint32_t hash; ngx_int_t rc; + ngx_str_t cname; ngx_uint_t naddrs; ngx_addr_t *addrs; ngx_resolver_ctx_t *next, *last; ngx_resolver_node_t *rn; - ngx_strlow(ctx->name.data, ctx->name.data, ctx->name.len); + ngx_strlow(name->data, name->data, name->len); - hash = ngx_crc32_short(ctx->name.data, ctx->name.len); + hash = ngx_crc32_short(name->data, name->len); - rn = ngx_resolver_lookup_name(r, &ctx->name, hash); + rn = ngx_resolver_lookup_name(r, name, hash); if (rn) { @@ -559,10 +558,10 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx) if (ctx->recursion++ < NGX_RESOLVER_MAX_RECURSION) { - ctx->name.len = rn->cnlen; - ctx->name.data = rn->u.cname; + cname.len = rn->cnlen; + cname.data = rn->u.cname; - return ngx_resolve_name_locked(r, ctx); + return ngx_resolve_name_locked(r, ctx, &cname); } last->next = rn->waiting; @@ -602,6 +601,11 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx) rn->waiting = ctx; ctx->state = NGX_AGAIN; + do { + ctx->node = rn; + ctx = ctx->next; + } while (ctx); + return NGX_AGAIN; } @@ -640,14 +644,14 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx) return NGX_ERROR; } - rn->name = ngx_resolver_dup(r, ctx->name.data, ctx->name.len); + rn->name = ngx_resolver_dup(r, name->data, name->len); if (rn->name == NULL) { ngx_resolver_free(r, rn); return NGX_ERROR; } rn->node.key = hash; - rn->nlen = (u_short) ctx->name.len; + rn->nlen = (u_short) name->len; rn->query = NULL; #if (NGX_HAVE_INET6) rn->query6 = NULL; @@ -656,7 +660,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx) ngx_rbtree_insert(&r->name_rbtree, &rn->node); } - rc = ngx_resolver_create_name_query(r, rn, &ctx->name); + rc = ngx_resolver_create_name_query(r, rn, name); if (rc == NGX_ERROR) { goto failed; @@ -720,6 +724,11 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx) ctx->state = NGX_AGAIN; + do { + ctx->node = rn; + ctx = ctx->next; + } while (ctx); + return NGX_AGAIN; failed: @@ -842,6 +851,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx) ctx->next = rn->waiting; rn->waiting = ctx; ctx->state = NGX_AGAIN; + ctx->node = rn; /* unlock addr mutex */ @@ -927,6 +937,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx) /* unlock addr mutex */ ctx->state = NGX_AGAIN; + ctx->node = rn; return NGX_OK; @@ -957,17 +968,11 @@ failed: void ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx) { - in_addr_t addr; ngx_queue_t *expire_queue; ngx_rbtree_t *tree; ngx_resolver_t *r; ngx_resolver_ctx_t *w, **p; - struct sockaddr_in *sin; ngx_resolver_node_t *rn; -#if (NGX_HAVE_INET6) - uint32_t hash; - struct sockaddr_in6 *sin6; -#endif r = ctx->resolver; @@ -996,21 +1001,7 @@ ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx) if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) { - switch (ctx->addr.sockaddr->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) ctx->addr.sockaddr; - hash = ngx_crc32_short(sin6->sin6_addr.s6_addr, 16); - rn = ngx_resolver_lookup_addr6(r, &sin6->sin6_addr, hash); - break; -#endif - - default: /* AF_INET */ - sin = (struct sockaddr_in *) ctx->addr.sockaddr; - addr = ntohl(sin->sin_addr.s_addr); - rn = ngx_resolver_lookup_addr(r, addr); - } + rn = ctx->node; if (rn) { p = &rn->waiting; @@ -2014,9 +2005,12 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last, rn->waiting = NULL; if (ctx) { - ctx->name = name; - (void) ngx_resolve_name_locked(r, ctx); + for (next = ctx; next; next = next->next) { + next->node = NULL; + } + + (void) ngx_resolve_name_locked(r, ctx, &name); } ngx_resolver_free(r, rn->query); diff --git a/src/core/ngx_resolver.h b/src/core/ngx_resolver.h index 22f249595..07fa25785 100644 --- a/src/core/ngx_resolver.h +++ b/src/core/ngx_resolver.h @@ -161,6 +161,8 @@ struct ngx_resolver_ctx_s { ngx_uint_t quick; /* unsigned quick:1; */ ngx_uint_t recursion; ngx_event_t *event; + + ngx_resolver_node_t *node; };