[nginx] Resolver: implemented IPv6 address to name resolving.
Ruslan Ermilov
ru at nginx.com
Fri Dec 13 16:54:48 UTC 2013
details: http://hg.nginx.org/nginx/rev/950c9ed3e66f
branches:
changeset: 5476:950c9ed3e66f
user: Ruslan Ermilov <ru at 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
More information about the nginx-devel
mailing list