details: http://hg.nginx.org/nginx/rev/950c9ed3e66f branches: changeset: 5476:950c9ed3e66f user: Ruslan Ermilov <r...@nginx.com> date: Fri Dec 06 14:30:28 2013 +0400 description: Resolver: implemented IPv6 address to name resolving.
diffstat: src/core/ngx_resolver.c | 484 +++++++++++++++++++++++++++++++++++++++-------- src/core/ngx_resolver.h | 12 + 2 files changed, 407 insertions(+), 89 deletions(-) diffs (truncated from 757 to 300 lines): diff -r 07dd5bd222ac -r 950c9ed3e66f src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Fri Dec 06 14:30:27 2013 +0400 +++ b/src/core/ngx_resolver.c Fri Dec 06 14:30:28 2013 +0400 @@ -92,6 +92,13 @@ static ngx_addr_t *ngx_resolver_export(n ngx_uint_t n, 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) +static void ngx_resolver_rbtree_insert_addr6_value(ngx_rbtree_node_t *temp, + ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); +static ngx_resolver_node_t *ngx_resolver_lookup_addr6(ngx_resolver_t *r, + struct in6_addr *addr, uint32_t hash); +#endif + ngx_resolver_t * ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n) @@ -134,6 +141,15 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_ ngx_queue_init(&r->name_expire_queue); ngx_queue_init(&r->addr_expire_queue); +#if (NGX_HAVE_INET6) + ngx_rbtree_init(&r->addr6_rbtree, &r->addr6_sentinel, + ngx_resolver_rbtree_insert_addr6_value); + + ngx_queue_init(&r->addr6_resend_queue); + + ngx_queue_init(&r->addr6_expire_queue); +#endif + r->event->handler = ngx_resolver_resend_handler; r->event->data = r; r->event->log = &cf->cycle->new_log; @@ -220,6 +236,10 @@ ngx_resolver_cleanup(void *data) ngx_resolver_cleanup_tree(r, &r->addr_rbtree); +#if (NGX_HAVE_INET6) + ngx_resolver_cleanup_tree(r, &r->addr6_rbtree); +#endif + if (r->event) { ngx_free(r->event); } @@ -640,30 +660,62 @@ failed: } -/* AF_INET only */ - ngx_int_t ngx_resolve_addr(ngx_resolver_ctx_t *ctx) { u_char *name; in_addr_t addr; + ngx_queue_t *resend_queue, *expire_queue; + ngx_rbtree_t *tree; ngx_resolver_t *r; struct sockaddr_in *sin; ngx_resolver_node_t *rn; +#if (NGX_HAVE_INET6) + uint32_t hash; + struct sockaddr_in6 *sin6; +#endif + +#if (NGX_SUPPRESS_WARN) + addr = 0; +#if (NGX_HAVE_INET6) + hash = 0; + sin6 = NULL; +#endif +#endif r = ctx->resolver; - if (ctx->addr.sockaddr->sa_family != AF_INET) { - return NGX_ERROR; + 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); + + /* lock addr mutex */ + + rn = ngx_resolver_lookup_addr6(r, &sin6->sin6_addr, hash); + + tree = &r->addr6_rbtree; + resend_queue = &r->addr6_resend_queue; + expire_queue = &r->addr6_expire_queue; + + break; +#endif + + default: /* AF_INET */ + sin = (struct sockaddr_in *) ctx->addr.sockaddr; + addr = ntohl(sin->sin_addr.s_addr); + + /* lock addr mutex */ + + rn = ngx_resolver_lookup_addr(r, addr); + + tree = &r->addr_rbtree; + resend_queue = &r->addr_resend_queue; + expire_queue = &r->addr_expire_queue; } - sin = (struct sockaddr_in *) ctx->addr.sockaddr; - addr = ntohl(sin->sin_addr.s_addr); - - /* lock addr mutex */ - - rn = ngx_resolver_lookup_addr(r, addr); - if (rn) { if (rn->valid >= ngx_time()) { @@ -674,7 +726,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx rn->expire = ngx_time() + r->expire; - ngx_queue_insert_head(&r->addr_expire_queue, &rn->queue); + ngx_queue_insert_head(expire_queue, &rn->queue); name = ngx_resolver_dup(r, rn->name, rn->nlen); if (name == NULL) { @@ -717,10 +769,22 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx goto failed; } - rn->node.key = addr; + switch (ctx->addr.sockaddr->sa_family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + rn->addr6 = sin6->sin6_addr; + rn->node.key = hash; + break; +#endif + + default: /* AF_INET */ + rn->node.key = addr; + } + rn->query = NULL; - ngx_rbtree_insert(&r->addr_rbtree, &rn->node); + ngx_rbtree_insert(tree, &rn->node); } if (ngx_resolver_create_addr_query(rn, ctx) != NGX_OK) { @@ -743,13 +807,13 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx ngx_add_timer(ctx->event, ctx->timeout); - if (ngx_queue_empty(&r->addr_resend_queue)) { + if (ngx_queue_empty(resend_queue)) { ngx_add_timer(r->event, (ngx_msec_t) (r->resend_timeout * 1000)); } rn->expire = ngx_time() + r->resend_timeout; - ngx_queue_insert_head(&r->addr_resend_queue, &rn->queue); + ngx_queue_insert_head(resend_queue, &rn->queue); rn->cnlen = 0; rn->naddrs = 0; @@ -767,7 +831,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx failed: if (rn) { - ngx_rbtree_delete(&r->addr_rbtree, &rn->node); + ngx_rbtree_delete(tree, &rn->node); if (rn->query) { ngx_resolver_free(r, rn->query); @@ -788,26 +852,37 @@ failed: } -/* AF_INET only */ - 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 (ctx->addr.sockaddr->sa_family != AF_INET) { - return; +#if (NGX_HAVE_INET6) + uint32_t hash; + struct sockaddr_in6 *sin6; +#endif + + r = ctx->resolver; + + switch (ctx->addr.sockaddr->sa_family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + tree = &r->addr6_rbtree; + expire_queue = &r->addr6_expire_queue; + break; +#endif + + default: /* AF_INET */ + tree = &r->addr_rbtree; + expire_queue = &r->addr_expire_queue; } - sin = (struct sockaddr_in *) ctx->addr.sockaddr; - addr = ntohl(sin->sin_addr.s_addr); - - r = ctx->resolver; - ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolve addr done: %i", ctx->state); @@ -819,7 +894,21 @@ ngx_resolve_addr_done(ngx_resolver_ctx_t if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) { - rn = ngx_resolver_lookup_addr(r, addr); + 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); + } if (rn) { p = &rn->waiting; @@ -837,15 +926,22 @@ ngx_resolve_addr_done(ngx_resolver_ctx_t } } - ngx_log_error(NGX_LOG_ALERT, r->log, 0, - "could not cancel %ud.%ud.%ud.%ud resolving", - (addr >> 24) & 0xff, (addr >> 16) & 0xff, - (addr >> 8) & 0xff, addr & 0xff); + { + u_char text[NGX_SOCKADDR_STRLEN]; + ngx_str_t addrtext; + + addrtext.data = text; + addrtext.len = ngx_sock_ntop(ctx->addr.sockaddr, ctx->addr.socklen, + text, NGX_SOCKADDR_STRLEN, 0); + + ngx_log_error(NGX_LOG_ALERT, r->log, 0, + "could not cancel %V resolving", &addrtext); + } } done: - ngx_resolver_expire(r, &r->addr_rbtree, &r->addr_expire_queue); + ngx_resolver_expire(r, tree, expire_queue); /* unlock addr mutex */ @@ -946,6 +1042,9 @@ static void ngx_resolver_resend_handler(ngx_event_t *ev) { time_t timer, atimer, ntimer; +#if (NGX_HAVE_INET6) + time_t a6timer; +#endif ngx_resolver_t *r; r = ev->data; @@ -965,16 +1064,36 @@ ngx_resolver_resend_handler(ngx_event_t /* unlock addr mutex */ - if (ntimer == 0) { +#if (NGX_HAVE_INET6) + + /* lock addr6 mutex */ + + a6timer = ngx_resolver_resend(r, &r->addr6_rbtree, &r->addr6_resend_queue); + + /* unlock addr6 mutex */ + +#endif _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel