IPv6 support in resolver
ToSHiC
toshic.toshic at gmail.com
Wed Jul 10 17:32:55 UTC 2013
commit f194edc7e351d3a487e9305935647f0587b65fca
Author: Anton Kortunov <toshic.toshic at gmail.com>
Date: Wed Jul 10 20:53:21 2013 +0400
IPv6 support in mail server
Client ip address is resolving to hostname even if it's IPv6 address.
Forward resolve of this hostname is processed according to socket
family.
diff --git a/src/mail/ngx_mail_smtp_handler.c
b/src/mail/ngx_mail_smtp_handler.c
index 2171423..481e4a4 100644
--- a/src/mail/ngx_mail_smtp_handler.c
+++ b/src/mail/ngx_mail_smtp_handler.c
@@ -56,6 +56,9 @@ void
ngx_mail_smtp_init_session(ngx_mail_session_t *s, ngx_connection_t *c)
{
struct sockaddr_in *sin;
+#if (NGX_HAVE_INET6)
+ struct sockaddr_in6 *sin6;
+#endif
ngx_resolver_ctx_t *ctx;
ngx_mail_core_srv_conf_t *cscf;
@@ -67,7 +70,11 @@ ngx_mail_smtp_init_session(ngx_mail_session_t *s,
ngx_connection_t *c)
return;
}
- if (c->sockaddr->sa_family != AF_INET) {
+ if (c->sockaddr->sa_family != AF_INET
+#if (NGX_HAVE_INET6)
+ && c->sockaddr->sa_family != AF_INET6
+#endif
+ ) {
s->host = smtp_tempunavail;
ngx_mail_smtp_greeting(s, c);
return;
@@ -81,11 +88,23 @@ ngx_mail_smtp_init_session(ngx_mail_session_t *s,
ngx_connection_t *c)
return;
}
- /* AF_INET only */
+ ctx->addr.family = c->sockaddr->sa_family;
- sin = (struct sockaddr_in *) c->sockaddr;
+ switch (c->sockaddr->sa_family) {
+
+ case AF_INET:
+ sin = (struct sockaddr_in *) c->sockaddr;
+ ctx->addr.u.v4 = sin->sin_addr.s_addr;
+ break;
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *) c->sockaddr;
+ ctx->addr.u.v6 = sin6->sin6_addr;
+ break;
+#endif
+ }
- ctx->addr = sin->sin_addr.s_addr;
ctx->handler = ngx_mail_smtp_resolve_addr_handler;
ctx->data = s;
ctx->timeout = cscf->resolver_timeout;
@@ -167,11 +186,23 @@ ngx_mail_smtp_resolve_name(ngx_event_t *rev)
}
ctx->name = s->host;
- ctx->type = NGX_RESOLVE_A;
ctx->handler = ngx_mail_smtp_resolve_name_handler;
ctx->data = s;
ctx->timeout = cscf->resolver_timeout;
+ switch (c->sockaddr->sa_family) {
+
+ case AF_INET:
+ ctx->type = NGX_RESOLVE_A;
+ break;
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ ctx->type = NGX_RESOLVE_AAAA_A;
+ break;
+#endif
+ }
+
if (ngx_resolve_name(ctx) != NGX_OK) {
ngx_mail_close_connection(c);
}
@@ -181,10 +212,13 @@ ngx_mail_smtp_resolve_name(ngx_event_t *rev)
static void
ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx)
{
- in_addr_t addr;
+ ngx_ipaddr_t addr;
ngx_uint_t i;
ngx_connection_t *c;
struct sockaddr_in *sin;
+#if (NGX_HAVE_INET6)
+ struct sockaddr_in6 *sin6;
+#endif
ngx_mail_session_t *s;
s = ctx->data;
@@ -205,23 +239,55 @@ ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t
*ctx)
} else {
- /* AF_INET only */
+ addr.family = c->sockaddr->sa_family;
- sin = (struct sockaddr_in *) c->sockaddr;
+ switch (c->sockaddr->sa_family) {
+
+ case AF_INET:
+ sin = (struct sockaddr_in *) c->sockaddr;
+ addr.u.v4 = sin->sin_addr.s_addr;
+ break;
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *) c->sockaddr;
+ addr.u.v6 = sin6->sin6_addr;
+ break;
+#endif
+ }
for (i = 0; i < ctx->naddrs; i++) {
- addr = ctx->addrs[i];
+#if (NGX_DEBUG)
+ {
+ u_char text[NGX_SOCKADDR_STRLEN];
+
+ ngx_inet_ntop(ctx->addrs[i].family, &ctx->addrs[i].u,
text, NGX_SOCKADDR_STRLEN);
+
+ ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
+ "name was resolved to %s", text);
+ }
+#endif
+
+ if (addr.family != ctx->addrs[i].family) {
+ continue;
+ }
- ngx_log_debug4(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "name was resolved to %ud.%ud.%ud.%ud",
- (ntohl(addr) >> 24) & 0xff,
- (ntohl(addr) >> 16) & 0xff,
- (ntohl(addr) >> 8) & 0xff,
- ntohl(addr) & 0xff);
+ switch (addr.family) {
- if (addr == sin->sin_addr.s_addr) {
- goto found;
+ case AF_INET:
+ if (addr.u.v4 == ctx->addrs[i].u.v4) {
+ goto found;
+ }
+ break;
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ if (!ngx_memcmp(&addr.u.v6, &ctx->addrs[i].u.v6,
sizeof(addr.u.v6))) {
+ goto found;
+ }
+ break;
+#endif
}
}
On Wed, Jul 10, 2013 at 9:30 PM, ToSHiC <toshic.toshic at gmail.com> wrote:
> commit 2bf37859004e3ff2b5dd9a11e1725153ca43ff32
> Author: Anton Kortunov <toshic.toshic at gmail.com>
> Date: Wed Jul 10 20:49:28 2013 +0400
>
> IPv6 support in http server upstreams
>
> Try to resolve upstream server name to IPv4 address first, then to
> IPv6.
>
> diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
> index 16e6602..df522f7 100644
> --- a/src/http/ngx_http_upstream.c
> +++ b/src/http/ngx_http_upstream.c
> @@ -638,7 +638,11 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
> }
>
> ctx->name = *host;
> +#if (NGX_HAVE_INET6)
> + ctx->type = NGX_RESOLVE_A_AAAA;
> +#else
> ctx->type = NGX_RESOLVE_A;
> +#endif
> ctx->handler = ngx_http_upstream_resolve_handler;
> ctx->data = r;
> ctx->timeout = clcf->resolver_timeout;
> @@ -912,16 +916,14 @@ ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t
> *ctx)
>
> #if (NGX_DEBUG)
> {
> - in_addr_t addr;
> + u_char text[NGX_SOCKADDR_STRLEN];
> ngx_uint_t i;
>
> - for (i = 0; i < ctx->naddrs; i++) {
> - addr = ntohl(ur->addrs[i]);
> + for (i = 0; i < ur->naddrs; i++) {
> + ngx_inet_ntop(ur->addrs[i].family, &ur->addrs[i].u, text,
> NGX_SOCKADDR_STRLEN);
>
> - ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
> - "name was resolved to %ud.%ud.%ud.%ud",
> - (addr >> 24) & 0xff, (addr >> 16) & 0xff,
> - (addr >> 8) & 0xff, addr & 0xff);
> + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
> + "name was resolved to %s", text);
> }
> }
> #endif
> diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
> index fd4e36b..9e88a9a 100644
> --- a/src/http/ngx_http_upstream.h
> +++ b/src/http/ngx_http_upstream.h
> @@ -254,7 +254,7 @@ typedef struct {
> ngx_uint_t no_port; /* unsigned no_port:1 */
>
> ngx_uint_t naddrs;
> - in_addr_t *addrs;
> + ngx_ipaddr_t *addrs;
>
> struct sockaddr *sockaddr;
> socklen_t socklen;
> diff --git a/src/http/ngx_http_upstream_round_robin.c
> b/src/http/ngx_http_upstream_round_robin.c
> index e0c6c58..cf9d6a0 100644
> --- a/src/http/ngx_http_upstream_round_robin.c
> +++ b/src/http/ngx_http_upstream_round_robin.c
> @@ -268,6 +268,9 @@
> ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
> size_t len;
> ngx_uint_t i, n;
> struct sockaddr_in *sin;
> +#if (NGX_HAVE_INET6)
> + struct sockaddr_in6 *sin6;
> +#endif
> ngx_http_upstream_rr_peers_t *peers;
> ngx_http_upstream_rr_peer_data_t *rrp;
>
> @@ -306,27 +309,52 @@
> ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
>
> for (i = 0; i < ur->naddrs; i++) {
>
> - len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1;
> + len = NGX_SOCKADDR_STRLEN;
>
> p = ngx_pnalloc(r->pool, len);
> if (p == NULL) {
> return NGX_ERROR;
> }
>
> - len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p,
> NGX_INET_ADDRSTRLEN);
> + len = ngx_inet_ntop(ur->addrs[i].family, &ur->addrs[i].u, p,
> NGX_SOCKADDR_STRLEN - sizeof(":65535") + 1);
> len = ngx_sprintf(&p[len], ":%d", ur->port) - p;
>
> - sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in));
> - if (sin == NULL) {
> + switch (ur->addrs[i].family) {
> +
> + case AF_INET:
> + sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in));
> + if (sin == NULL) {
> + return NGX_ERROR;
> + }
> +
> + sin->sin_family = AF_INET;
> + sin->sin_port = htons(ur->port);
> + sin->sin_addr.s_addr = ur->addrs[i].u.v4;
> +
> + peers->peer[i].sockaddr = (struct sockaddr *) sin;
> + peers->peer[i].socklen = sizeof(struct sockaddr_in);
> + break;
> +
> +#if (NGX_HAVE_INET6)
> + case AF_INET6:
> + sin6 = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in6));
> + if (sin6 == NULL) {
> + return NGX_ERROR;
> + }
> +
> + sin6->sin6_family = AF_INET6;
> + sin6->sin6_port = htons(ur->port);
> + sin6->sin6_addr = ur->addrs[i].u.v6;
> +
> + peers->peer[i].sockaddr = (struct sockaddr *) sin6;
> + peers->peer[i].socklen = sizeof(struct sockaddr_in6);
> + break;
> +#endif
> +
> + default:
> return NGX_ERROR;
> }
>
> - sin->sin_family = AF_INET;
> - sin->sin_port = htons(ur->port);
> - sin->sin_addr.s_addr = ur->addrs[i];
> -
> - peers->peer[i].sockaddr = (struct sockaddr *) sin;
> - peers->peer[i].socklen = sizeof(struct sockaddr_in);
> peers->peer[i].name.len = len;
> peers->peer[i].name.data = p;
> peers->peer[i].weight = 1;
>
>
>
> On Wed, Jul 10, 2013 at 9:29 PM, ToSHiC <toshic.toshic at gmail.com> wrote:
>
>> commit 524dd02549575cb9ad5e95444093f6b494dc59bc
>> Author: Anton Kortunov <toshic.toshic at gmail.com>
>> Date: Wed Jul 10 20:43:59 2013 +0400
>>
>> IPv6 reverse resolve support
>>
>> diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
>> index 567368b..06d46c1 100644
>> --- a/src/core/ngx_resolver.c
>> +++ b/src/core/ngx_resolver.c
>> @@ -71,7 +71,7 @@ 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);
>> -static void ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf,
>> size_t n,
>> +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,
>> ngx_str_t *name, uint32_t hash);
>> @@ -126,7 +126,7 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names,
>> ngx_uint_t n)
>> ngx_resolver_rbtree_insert_value);
>>
>> ngx_rbtree_init(&r->addr_rbtree, &r->addr_sentinel,
>> - ngx_rbtree_insert_value);
>> + ngx_resolver_rbtree_insert_value);
>>
>> ngx_queue_init(&r->name_resend_queue);
>> ngx_queue_init(&r->addr_resend_queue);
>> @@ -649,17 +649,40 @@ failed:
>> ngx_int_t
>> ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
>> {
>> + uint32_t hash;
>> u_char *name;
>> ngx_resolver_t *r;
>> ngx_resolver_node_t *rn;
>>
>> r = ctx->resolver;
>> + rn = NULL;
>> +
>> + hash = ctx->addr.family;
>> +
>> + switch(ctx->addr.family) {
>> +
>> + case AF_INET:
>> + ctx->addr.u.v4 = ntohl(ctx->addr.u.v4);
>> + ngx_crc32_update(&hash, (u_char *)&ctx->addr.u.v4,
>> sizeof(in_addr_t));
>> +ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
>> + "resolve addr hash: %xd, addr:%xd, family: %d", hash,
>> ctx->addr.u.v4, ctx->addr.family);
>> + break;
>> +
>> +#if (NGX_HAVE_INET6)
>> + case AF_INET6:
>> + ngx_crc32_update(&hash, (u_char *)&ctx->addr.u.v6, sizeof(struct
>> in6_addr));
>> + break;
>> +#endif
>>
>> - ctx->addr = ntohl(ctx->addr);
>> + default:
>> + goto failed;
>> + }
>>
>> /* lock addr mutex */
>>
>> - rn = ngx_resolver_lookup_addr(r, ctx->addr);
>> + rn = ngx_resolver_lookup_addr(r, ctx->addr, hash);
>> + ngx_log_error(r->log_level, r->log, 0,
>> + "resolve: in resolve_addr searching, hash = %xd, rn =
>> %p", hash, rn);
>>
>> if (rn) {
>>
>> @@ -714,8 +737,10 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
>> goto failed;
>> }
>>
>> - rn->node.key = ctx->addr;
>> + rn->node.key = hash;
>> rn->query = NULL;
>> + rn->qtype = ctx->type;
>> + rn->u.addr = ctx->addr;
>>
>> ngx_rbtree_insert(&r->addr_rbtree, &rn->node);
>> }
>> @@ -788,10 +813,11 @@ failed:
>> void
>> ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
>> {
>> - in_addr_t addr;
>> + uint32_t hash;
>> ngx_resolver_t *r;
>> ngx_resolver_ctx_t *w, **p;
>> ngx_resolver_node_t *rn;
>> + u_char text[NGX_SOCKADDR_STRLEN];
>>
>> r = ctx->resolver;
>>
>> @@ -806,7 +832,25 @@ ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
>>
>> if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
>>
>> - rn = ngx_resolver_lookup_addr(r, ctx->addr);
>> + hash = ctx->addr.family;
>> +
>> + switch(ctx->addr.family) {
>> +
>> + case AF_INET:
>> + ngx_crc32_update(&hash, (u_char *)&ctx->addr.u.v4,
>> sizeof(in_addr_t));
>> + break;
>> +
>> +#if (NGX_HAVE_INET6)
>> + case AF_INET6:
>> + ngx_crc32_update(&hash, (u_char *)&ctx->addr.u.v6,
>> sizeof(struct in6_addr));
>> + break;
>> +#endif
>> +
>> + default:
>> + goto failed;
>> + }
>> +
>> + rn = ngx_resolver_lookup_addr(r, ctx->addr, hash);
>>
>> if (rn) {
>> p = &rn->waiting;
>> @@ -824,12 +868,12 @@ ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
>> }
>> }
>>
>> - addr = ntohl(ctx->addr);
>> +failed:
>> +
>> + ngx_inet_ntop(ctx->addr.family, &ctx->addr.u, text,
>> NGX_SOCKADDR_STRLEN);
>>
>> 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);
>> + "could not cancel %s resolving", text);
>> }
>>
>> done:
>> @@ -1582,13 +1626,14 @@ failed:
>> }
>>
>>
>> -static void
>> +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)
>> {
>> - char *err;
>> + char *err = NULL;
>> + uint32_t hash = 0;
>> size_t len;
>> - in_addr_t addr;
>> + ngx_ipaddr_t addr;
>> int32_t ttl;
>> ngx_int_t digit;
>> ngx_str_t name;
>> @@ -1596,12 +1641,16 @@ ngx_resolver_process_ptr(ngx_resolver_t *r,
>> u_char *buf, size_t n,
>> ngx_resolver_an_t *an;
>> ngx_resolver_ctx_t *ctx, *next;
>> ngx_resolver_node_t *rn;
>> + u_char text[NGX_SOCKADDR_STRLEN];
>>
>> if (ngx_resolver_copy(r, NULL, buf, &buf[12], &buf[n]) != NGX_OK) {
>> goto invalid_in_addr_arpa;
>> }
>>
>> - addr = 0;
>> + ngx_memzero(&addr, sizeof(ngx_ipaddr_t));
>> +
>> + /* Try to parse request as in-addr.arpa */
>> + addr.family = AF_INET;
>> i = 12;
>>
>> for (mask = 0; mask < 32; mask += 8) {
>> @@ -1612,7 +1661,7 @@ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char
>> *buf, size_t n,
>> goto invalid_in_addr_arpa;
>> }
>>
>> - addr += digit << mask;
>> + addr.u.v4 += digit << mask;
>> i += len;
>> }
>>
>> @@ -1620,15 +1669,79 @@ ngx_resolver_process_ptr(ngx_resolver_t *r,
>> u_char *buf, size_t n,
>> goto invalid_in_addr_arpa;
>> }
>>
>> + i += sizeof("\7in-addr\4arpa") + sizeof(ngx_resolver_qs_t);
>> +
>> + goto found;
>> +
>> +invalid_in_addr_arpa:
>> +
>> +#if (NGX_HAVE_INET6)
>> + /* Try to parse request as ip6.arpa */
>> + addr.family = AF_INET6;
>> + i = 12;
>> +
>> + for (len = 15; len < 16; len--) {
>> + if (buf[i++] != 1)
>> + goto invalid_arpa;
>> +
>> + digit = ngx_hextoi(&buf[i++], 1);
>> + if (digit == NGX_ERROR || digit > 16) {
>> + goto invalid_arpa;
>> + }
>> +
>> + addr.u.v6.s6_addr[len] = digit;
>> +
>> + if (buf[i++] != 1)
>> + goto invalid_arpa;
>> +
>> +
>> + digit = ngx_hextoi(&buf[i++], 1);
>> + if (digit == NGX_ERROR || digit > 16) {
>> + goto invalid_arpa;
>> + }
>> +
>> + addr.u.v6.s6_addr[len] += digit << 4;
>> + }
>> +
>> + if (ngx_strcmp(&buf[i], "\3ip6\4arpa") != 0) {
>> + goto invalid_arpa;
>> + }
>> +
>> + i += sizeof("\3ip6\4arpa") + sizeof(ngx_resolver_qs_t);
>> +
>> +#else /* NGX_HAVE_INET6 */
>> + goto invalid_arpa;
>> +#endif
>> +
>> +found:
>> +
>> /* lock addr mutex */
>>
>> - rn = ngx_resolver_lookup_addr(r, addr);
>> + hash = addr.family;
>> +
>> + switch(addr.family) {
>> +
>> + case AF_INET:
>> + ngx_crc32_update(&hash, (u_char *)&addr.u.v4, sizeof(in_addr_t));
>> + break;
>> +
>> +#if (NGX_HAVE_INET6)
>> + case AF_INET6:
>> + ngx_crc32_update(&hash, (u_char *)&addr.u.v6, sizeof(struct
>> in6_addr));
>> + break;
>> +#endif
>> +
>> + default:
>> + goto invalid;
>> + }
>> +
>> + rn = ngx_resolver_lookup_addr(r, addr, hash);
>> +
>> + ngx_inet_ntop(addr.family, &addr.u, text, NGX_SOCKADDR_STRLEN);
>>
>> if (rn == NULL || rn->query == NULL) {
>> ngx_log_error(r->log_level, r->log, 0,
>> - "unexpected response for %ud.%ud.%ud.%ud",
>> - (addr >> 24) & 0xff, (addr >> 16) & 0xff,
>> - (addr >> 8) & 0xff, addr & 0xff);
>> + "unexpected response for %s", text);
>> goto failed;
>> }
>>
>> @@ -1636,12 +1749,15 @@ ngx_resolver_process_ptr(ngx_resolver_t *r,
>> u_char *buf, size_t n,
>>
>> if (ident != qident) {
>> ngx_log_error(r->log_level, r->log, 0,
>> - "wrong ident %ui response for %ud.%ud.%ud.%ud,
>> expect %ui",
>> - ident, (addr >> 24) & 0xff, (addr >> 16) & 0xff,
>> - (addr >> 8) & 0xff, addr & 0xff, qident);
>> + "wrong ident %ui response for %s, expect %ui",
>> + ident, text, qident);
>> goto failed;
>> }
>>
>> + ngx_log_error(r->log_level, r->log, 0,
>> + "code: %d, nan: %d",
>> + code, nan);
>> +
>> if (code == 0 && nan == 0) {
>> code = 3; /* NXDOMAIN */
>> }
>> @@ -1669,8 +1785,6 @@ ngx_resolver_process_ptr(ngx_resolver_t *r, u_char
>> *buf, size_t n,
>> return;
>> }
>>
>> - i += sizeof("\7in-addr\4arpa") + sizeof(ngx_resolver_qs_t);
>> -
>> if (i + 2 + sizeof(ngx_resolver_an_t) > (ngx_uint_t) n) {
>> goto short_response;
>> }
>> @@ -1750,10 +1864,10 @@ ngx_resolver_process_ptr(ngx_resolver_t *r,
>> u_char *buf, size_t n,
>>
>> return;
>> -invalid_in_addr_arpa:
>> +invalid_arpa:
>>
>> ngx_log_error(r->log_level, r->log, 0,
>> - "invalid in-addr.arpa name in DNS response");
>> + "invalid in-addr.arpa or ip6.arpa name in DNS
>> response");
>> return;
>>
>> short_response:
>> @@ -1818,28 +1932,54 @@ ngx_resolver_lookup_name(ngx_resolver_t *r,
>> ngx_str_t *name, uint32_t hash)
>>
>>
>> static ngx_resolver_node_t *
>> -ngx_resolver_lookup_addr(ngx_resolver_t *r, in_addr_t addr)
>> +ngx_resolver_lookup_addr(ngx_resolver_t *r, ngx_ipaddr_t addr, uint32_t
>> hash)
>> {
>> + ngx_int_t rc;
>> ngx_rbtree_node_t *node, *sentinel;
>> + ngx_resolver_node_t *rn;
>>
>> node = r->addr_rbtree.root;
>> sentinel = r->addr_rbtree.sentinel;
>>
>> while (node != sentinel) {
>>
>> - if (addr < node->key) {
>> + if (hash < node->key) {
>> node = node->left;
>> continue;
>> }
>>
>> - if (addr > node->key) {
>> + if (hash > node->key) {
>> node = node->right;
>> continue;
>> }
>>
>> - /* addr == node->key */
>> + /* hash == node->key */
>> +
>> + rn = (ngx_resolver_node_t *) node;
>> +
>> + rc = addr.family - rn->u.addr.family;
>> +
>> + if (rc == 0) {
>> +
>> + switch (addr.family) {
>> + case AF_INET:
>> + rc = ngx_memn2cmp((u_char *)&addr.u.v4, (u_char
>> *)&rn->u.addr.u.v4, sizeof(in_addr_t), sizeof(in_addr_t));
>> + break;
>> +
>> +#if (NGX_HAVE_INET6)
>> + case AF_INET6:
>> + rc = ngx_memn2cmp((u_char *)&addr.u.v6, (u_char
>> *)&rn->u.addr.u.v6, sizeof(struct in6_addr), sizeof(struct in6_addr));
>> + break;
>> +#endif
>> + }
>> +
>> + if (rc == 0) {
>> + return rn;
>> + }
>>
>> - return (ngx_resolver_node_t *) node;
>> + }
>> +
>> + node = (rc < 0) ? node->left : node->right;
>> }
>>
>> /* not found */
>> @@ -1854,6 +1994,7 @@ ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t
>> *temp,
>> {
>> ngx_rbtree_node_t **p;
>> ngx_resolver_node_t *rn, *rn_temp;
>> + ngx_int_t rc;
>>
>> for ( ;; ) {
>>
>> @@ -1870,8 +2011,29 @@ ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t
>> *temp,
>> rn = (ngx_resolver_node_t *) node;
>> rn_temp = (ngx_resolver_node_t *) temp;
>>
>> - p = (ngx_memn2cmp(rn->name, rn_temp->name, rn->nlen,
>> rn_temp->nlen)
>> - < 0) ? &temp->left : &temp->right;
>> + if (rn->qtype == NGX_RESOLVE_PTR) {
>> + rc = rn->u.addr.family - rn_temp->u.addr.family;
>> +
>> + if (rc == 0) {
>> +
>> + switch (rn->u.addr.family) {
>> + case AF_INET:
>> + rc = ngx_memn2cmp((u_char *)&rn->u.addr.u.v4,
>> (u_char *)&rn_temp->u.addr.u.v4, sizeof(in_addr_t), sizeof(in_addr_t));
>> + break;
>> +
>> + #if (NGX_HAVE_INET6)
>> + case AF_INET6:
>> + rc = ngx_memn2cmp((u_char *)&rn->u.addr.u.v6,
>> (u_char *)&rn_temp->u.addr.u.v6, sizeof(struct in6_addr), sizeof(struct
>> in6_addr));
>> + break;
>> + #endif
>> + }
>> + }
>> +
>> + } else {
>> + rc = ngx_memn2cmp(rn->name, rn_temp->name, rn->nlen,
>> rn_temp->nlen);
>> + }
>> +
>> + p = (rc < 0) ? &temp->left : &temp->right;
>> }
>>
>> if (*p == sentinel) {
>> @@ -1989,8 +2151,6 @@ ngx_resolver_create_name_query(ngx_resolver_node_t
>> *rn, ngx_resolver_ctx_t *ctx)
>> }
>>
>>
>> -/* AF_INET only */
>> -
>> static ngx_int_t
>> ngx_resolver_create_addr_query(ngx_resolver_node_t *rn,
>> ngx_resolver_ctx_t *ctx)
>> {
>> @@ -2001,7 +2161,7 @@ ngx_resolver_create_addr_query(ngx_resolver_node_t
>> *rn, ngx_resolver_ctx_t *ctx)
>> ngx_resolver_query_t *query;
>>
>> len = sizeof(ngx_resolver_query_t)
>> - + sizeof(".255.255.255.255.in-addr.arpa.") - 1
>> + + NGX_PTR_QUERY_LEN
>> + sizeof(ngx_resolver_qs_t);
>>
>> p = ngx_resolver_alloc(ctx->resolver, len);
>> @@ -2028,18 +2188,50 @@
>> ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t
>> *ctx)
>> p += sizeof(ngx_resolver_query_t);
>>
>> - for (n = 0; n < 32; n += 8) {
>> - d = ngx_sprintf(&p[1], "%ud", (ctx->addr >> n) & 0xff);
>> - *p = (u_char) (d - &p[1]);
>> - p = d;
>> + switch (ctx->addr.family) {
>> +
>> + case AF_INET:
>> + for (n = 0; n < 32; n += 8) {
>> + d = ngx_sprintf(&p[1], "%ud", (ctx->addr.u.v4 >> n) & 0xff);
>> + *p = (u_char) (d - &p[1]);
>> + p = d;
>> + }
>> +
>> + /* query type "PTR", IP query class */
>> + ngx_memcpy(p, "\7in-addr\4arpa\0\0\14\0\1", 18);
>> +
>> + rn->qlen = (u_short)
>> + (p + sizeof("\7in-addr\4arpa") +
>> sizeof(ngx_resolver_qs_t)
>> + - rn->query);
>> +
>> + break;
>> +
>> +#if (NGX_HAVE_INET6)
>> + case AF_INET6:
>> + for (n = 15; n >= 0; n--) {
>> + p = ngx_sprintf(p, "\1%xd\1%xd",
>> + (ctx->addr.u.v6.s6_addr[n]) & 0xf,
>> + (ctx->addr.u.v6.s6_addr[n] >> 4) & 0xf);
>> +
>> + }
>> +
>> + /* query type "PTR", IP query class */
>> + ngx_memcpy(p, "\3ip6\4arpa\0\0\14\0\1", 18);
>> +
>> + rn->qlen = (u_short)
>> + (p + sizeof("\3ip6\4arpa") +
>> sizeof(ngx_resolver_qs_t)
>> + - rn->query);
>> +
>> + break;
>> +#endif
>> +
>> + default:
>> + return NGX_ERROR;
>> }
>>
>> - /* query type "PTR", IP query class */
>> - ngx_memcpy(p, "\7in-addr\4arpa\0\0\14\0\1", 18);
>> +ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->resolver->log, 0,
>> + "resolve: query %s, ident %i", (rn->query+12), ident &
>> 0xffff);
>>
>> - rn->qlen = (u_short)
>> - (p + sizeof("\7in-addr\4arpa") +
>> sizeof(ngx_resolver_qs_t)
>> - - rn->query);
>>
>> return NGX_OK;
>> }
>> diff --git a/src/core/ngx_resolver.h b/src/core/ngx_resolver.h
>> index d2a4606..a45b244 100644
>> --- a/src/core/ngx_resolver.h
>> +++ b/src/core/ngx_resolver.h
>> @@ -41,6 +41,11 @@
>>
>> #define NGX_RESOLVER_MAX_RECURSION 50
>>
>> +#if (NGX_HAVE_INET6)
>> +#define NGX_PTR_QUERY_LEN
>> (sizeof(".f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.ip6.arpa.")
>> - 1)
>> +#else
>> +#define NGX_PTR_QUERY_LEN (sizeof(".255.255.255.255.in-addr.arpa.") -
>> 1)
>> +#endif
>>
>> typedef struct {
>> ngx_connection_t *connection;
>>
>>
>>
>> On Wed, Jul 10, 2013 at 9:24 PM, ToSHiC <toshic.toshic at gmail.com> wrote:
>>
>>> commit 8670b164784032b2911b3c34ac31ef52ddba5b60
>>> Author: Anton Kortunov <toshic.toshic at gmail.com>
>>> Date: Wed Jul 10 19:53:06 2013 +0400
>>>
>>> IPv6 support in resolver for forward requests
>>>
>>> To resolve name into IPv6 address use NGX_RESOLVE_AAAA,
>>> NGX_RESOLVE_A_AAAA or NGX_RESOLVE_AAAA_A record type instead of
>>> NGX_RESOLVE_A
>>>
>>> diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
>>> index d59d0c4..567368b 100644
>>> --- a/src/core/ngx_resolver.c
>>> +++ b/src/core/ngx_resolver.c
>>> @@ -76,7 +76,7 @@ static void ngx_resolver_process_ptr(ngx_resolver_t
>>> *r, u_char *buf, size_t n,
>>> static ngx_resolver_node_t *ngx_resolver_lookup_name(ngx_resolver_t *r,
>>> ngx_str_t *name, uint32_t hash);
>>> static ngx_resolver_node_t *ngx_resolver_lookup_addr(ngx_resolver_t *r,
>>> - in_addr_t addr);
>>> + ngx_ipaddr_t addr, uint32_t hash);
>>> static void ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t *temp,
>>> ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
>>> static ngx_int_t ngx_resolver_copy(ngx_resolver_t *r, ngx_str_t *name,
>>> @@ -88,7 +88,7 @@ static void *ngx_resolver_calloc(ngx_resolver_t *r,
>>> size_t size);
>>> 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 in_addr_t *ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src,
>>> +static ngx_ipaddr_t *ngx_resolver_rotate(ngx_resolver_t *r,
>>> ngx_ipaddr_t *src,
>>> ngx_uint_t n);
>>> static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf,
>>> size_t len);
>>>
>>> @@ -270,13 +270,27 @@ ngx_resolver_cleanup_tree(ngx_resolver_t *r,
>>> ngx_rbtree_t *tree)
>>> ngx_resolver_ctx_t *
>>> ngx_resolve_start(ngx_resolver_t *r, ngx_resolver_ctx_t *temp)
>>> {
>>> - in_addr_t addr;
>>> + ngx_ipaddr_t addr;
>>> ngx_resolver_ctx_t *ctx;
>>>
>>> if (temp) {
>>> - addr = ngx_inet_addr(temp->name.data, temp->name.len);
>>> + addr.family = 0;
>>>
>>> - if (addr != INADDR_NONE) {
>>> +
>>> + addr.u.v4 = ngx_inet_addr(temp->name.data, temp->name.len);
>>> +
>>> + if (addr.u.v4 != INADDR_NONE) {
>>> +
>>> + addr.family = AF_INET;
>>> +
>>> +#if (NGX_HAVE_INET6)
>>> + } else if (ngx_inet6_addr(temp->name.data, temp->name.len,
>>> addr.u.v6.s6_addr) == NGX_OK) {
>>> +
>>> + addr.family = AF_INET6;
>>> +#endif
>>> + }
>>> +
>>> + if (addr.family) {
>>> temp->resolver = r;
>>> temp->state = NGX_OK;
>>> temp->naddrs = 1;
>>> @@ -417,7 +431,7 @@ static ngx_int_t
>>> ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
>>> {
>>> uint32_t hash;
>>> - in_addr_t addr, *addrs;
>>> + ngx_ipaddr_t addr, *addrs;
>>> ngx_int_t rc;
>>> ngx_uint_t naddrs;
>>> ngx_resolver_ctx_t *next;
>>> @@ -429,7 +443,11 @@ ngx_resolve_name_locked(ngx_resolver_t *r,
>>> ngx_resolver_ctx_t *ctx)
>>>
>>> if (rn) {
>>>
>>> - if (rn->valid >= ngx_time()) {
>>> + if (rn->valid >= ngx_time()
>>> +#if (NGX_HAVE_INET6)
>>> + && rn->qtype != NGX_RESOLVE_RETRY
>>> +#endif
>>> + ) {
>>>
>>> ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, "resolve
>>> cached");
>>>
>>> @@ -446,7 +464,6 @@ ngx_resolve_name_locked(ngx_resolver_t *r,
>>> ngx_resolver_ctx_t *ctx)
>>> /* NGX_RESOLVE_A answer */
>>>
>>> if (naddrs != 1) {
>>> - addr = 0;
>>> addrs = ngx_resolver_rotate(r, rn->u.addrs, naddrs);
>>> if (addrs == NULL) {
>>> return NGX_ERROR;
>>> @@ -506,6 +523,8 @@ ngx_resolve_name_locked(ngx_resolver_t *r,
>>> ngx_resolver_ctx_t *ctx)
>>> } while (ctx);
>>>
>>> return NGX_OK;
>>> + } else {
>>> + rn->qtype = ctx->type;
>>> }
>>>
>>> if (rn->waiting) {
>>> @@ -552,6 +571,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r,
>>> ngx_resolver_ctx_t *ctx)
>>> rn->node.key = hash;
>>> rn->nlen = (u_short) ctx->name.len;
>>> rn->query = NULL;
>>> + rn->qtype = ctx->type;
>>>
>>> ngx_rbtree_insert(&r->name_rbtree, &rn->node);
>>> }
>>> @@ -1130,6 +1150,9 @@ found:
>>> switch (qtype) {
>>>
>>> case NGX_RESOLVE_A:
>>> +#if (NGX_HAVE_INET6)
>>> + case NGX_RESOLVE_AAAA:
>>> +#endif
>>>
>>> ngx_resolver_process_a(r, buf, n, ident, code, nan,
>>> i + sizeof(ngx_resolver_qs_t));
>>> @@ -1178,7 +1201,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char
>>> *buf, size_t last,
>>> size_t len;
>>> int32_t ttl;
>>> uint32_t hash;
>>> - in_addr_t addr, *addrs;
>>> + ngx_ipaddr_t addr, *addrs;
>>> ngx_str_t name;
>>> ngx_uint_t qtype, qident, naddrs, a, i, n, start;
>>> ngx_resolver_an_t *an;
>>> @@ -1212,12 +1235,57 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char
>>> *buf, size_t last,
>>> goto failed;
>>> }
>>>
>>> - ngx_resolver_free(r, name.data);
>>> -
>>> if (code == 0 && nan == 0) {
>>> +
>>> +#if (NGX_HAVE_INET6)
>>> + /*
>>> + * If it was required dual type v4|v6 resolv create one more request
>>> + */
>>> + if (rn->qtype == NGX_RESOLVE_A_AAAA
>>> + || rn->qtype == NGX_RESOLVE_AAAA_A) {
>>> +
>>> + ngx_queue_remove(&rn->queue);
>>> +
>>> + rn->valid = ngx_time() + (r->valid ? r->valid : ttl);
>>> + rn->expire = ngx_time() + r->expire;
>>> +
>>> + ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
>>> +
>>> + ctx = rn->waiting;
>>> + rn->waiting = NULL;
>>> +
>>> + if (ctx) {
>>> + ctx->name = name;
>>> +
>>> + switch (rn->qtype) {
>>> +
>>> + case NGX_RESOLVE_A_AAAA:
>>> + ctx->type = NGX_RESOLVE_AAAA;
>>> + break;
>>> +
>>> + case NGX_RESOLVE_AAAA_A:
>>> + ctx->type = NGX_RESOLVE_A;
>>> + break;
>>> + }
>>> +
>>> + ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
>>> + "restarting request for name %V, with
>>> type %ud",
>>> + &name, ctx->type);
>>> +
>>> + rn->qtype = NGX_RESOLVE_RETRY;
>>> +
>>> + (void) ngx_resolve_name_locked(r, ctx);
>>> + }
>>> +
>>> + return;
>>> + }
>>> +#endif
>>> +
>>> code = 3; /* NXDOMAIN */
>>> }
>>>
>>> + ngx_resolver_free(r, name.data);
>>> +
>>> if (code) {
>>> next = rn->waiting;
>>> rn->waiting = NULL;
>>> @@ -1243,7 +1311,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char
>>> *buf, size_t last,
>>>
>>> i = ans;
>>> naddrs = 0;
>>> - addr = 0;
>>> + addr.family = 0;
>>> addrs = NULL;
>>> cname = NULL;
>>> qtype = 0;
>>> @@ -1302,13 +1370,30 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char
>>> *buf, size_t last,
>>> goto short_response;
>>> }
>>>
>>> - addr = htonl((buf[i] << 24) + (buf[i + 1] << 16)
>>> + addr.family = AF_INET;
>>> + addr.u.v4 = htonl((buf[i] << 24) + (buf[i + 1] << 16)
>>> + (buf[i + 2] << 8) + (buf[i + 3]));
>>>
>>> naddrs++;
>>>
>>> i += len;
>>>
>>> +#if (NGX_HAVE_INET6)
>>> + } else if (qtype == NGX_RESOLVE_AAAA) {
>>> +
>>> + i += sizeof(ngx_resolver_an_t);
>>> +
>>> + if (i + len > last) {
>>> + goto short_response;
>>> + }
>>> +
>>> + addr.family = AF_INET6;
>>> + ngx_memcpy(&addr.u.v6.s6_addr, &buf[i], 16);
>>> +
>>> + naddrs++;
>>> +
>>> + i += len;
>>> +#endif
>>> } else if (qtype == NGX_RESOLVE_CNAME) {
>>> cname = &buf[i] + sizeof(ngx_resolver_an_t);
>>> i += sizeof(ngx_resolver_an_t) + len;
>>> @@ -1333,7 +1418,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char
>>> *buf, size_t last,
>>>
>>> } else {
>>>
>>> - addrs = ngx_resolver_alloc(r, naddrs * sizeof(in_addr_t));
>>> + addrs = ngx_resolver_alloc(r, naddrs *
>>> sizeof(ngx_ipaddr_t));
>>> if (addrs == NULL) {
>>> return;
>>> }
>>> @@ -1369,12 +1454,23 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char
>>> *buf, size_t last,
>>>
>>> if (qtype == NGX_RESOLVE_A) {
>>>
>>> - addrs[n++] = htonl((buf[i] << 24) + (buf[i + 1] <<
>>> 16)
>>> + addrs[n].family = AF_INET;
>>> + addrs[n++].u.v4 = htonl((buf[i] << 24) + (buf[i +
>>> 1] << 16)
>>> + (buf[i + 2] << 8) + (buf[i +
>>> 3]));
>>>
>>> if (n == naddrs) {
>>> break;
>>> }
>>> +#if (NGX_HAVE_INET6)
>>> + } else if (qtype == NGX_RESOLVE_AAAA) {
>>> +
>>> + addrs[n].family = AF_INET6;
>>> + ngx_memcpy(&addrs[n++].u.v6.s6_addr, &buf[i], 16);
>>> +
>>> + if (n == naddrs) {
>>> + break;
>>> + }
>>> +#endif
>>> }
>>>
>>> i += len;
>>> @@ -1383,7 +1479,7 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char
>>> *buf, size_t last,
>>> rn->u.addrs = addrs;
>>>
>>> addrs = ngx_resolver_dup(r, rn->u.addrs,
>>> - naddrs * sizeof(in_addr_t));
>>> + naddrs * sizeof(ngx_ipaddr_t));
>>> if (addrs == NULL) {
>>> return;
>>> }
>>> @@ -1838,7 +1934,20 @@
>>> ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t
>>> *ctx)
>>> qs = (ngx_resolver_qs_t *) p;
>>>
>>> /* query type */
>>> - qs->type_hi = 0; qs->type_lo = (u_char) ctx->type;
>>> + qs->type_hi = 0; qs->type_lo = (u_char) rn->qtype;
>>> +
>>> +#if (NGX_HAVE_INET6)
>>> + switch (rn->qtype) {
>>> +
>>> + case NGX_RESOLVE_A_AAAA:
>>> + qs->type_lo = NGX_RESOLVE_A;
>>> + break;
>>> +
>>> + case NGX_RESOLVE_AAAA_A:
>>> + qs->type_lo = NGX_RESOLVE_AAAA;
>>> + break;
>>> + }
>>> +#endif
>>>
>>> /* IP query class */
>>> qs->class_hi = 0; qs->class_lo = 1;
>>> @@ -2136,13 +2245,13 @@ ngx_resolver_dup(ngx_resolver_t *r, void *src,
>>> size_t size)
>>> }
>>>
>>>
>>> -static in_addr_t *
>>> -ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src, ngx_uint_t n)
>>> +static ngx_ipaddr_t *
>>> +ngx_resolver_rotate(ngx_resolver_t *r, ngx_ipaddr_t *src, ngx_uint_t n)
>>> {
>>> void *dst, *p;
>>> ngx_uint_t j;
>>>
>>> - dst = ngx_resolver_alloc(r, n * sizeof(in_addr_t));
>>> + dst = ngx_resolver_alloc(r, n * sizeof(ngx_ipaddr_t));
>>>
>>> if (dst == NULL) {
>>> return dst;
>>> @@ -2151,12 +2260,12 @@ ngx_resolver_rotate(ngx_resolver_t *r,
>>> in_addr_t *src, ngx_uint_t n)
>>> j = ngx_random() % n;
>>>
>>> if (j == 0) {
>>> - ngx_memcpy(dst, src, n * sizeof(in_addr_t));
>>> + ngx_memcpy(dst, src, n * sizeof(ngx_ipaddr_t));
>>> return dst;
>>> }
>>>
>>> - p = ngx_cpymem(dst, &src[j], (n - j) * sizeof(in_addr_t));
>>> - ngx_memcpy(p, src, j * sizeof(in_addr_t));
>>> + p = ngx_cpymem(dst, &src[j], (n - j) * sizeof(ngx_ipaddr_t));
>>> + ngx_memcpy(p, src, j * sizeof(ngx_ipaddr_t));
>>>
>>> return dst;
>>> }
>>> diff --git a/src/core/ngx_resolver.h b/src/core/ngx_resolver.h
>>> index 6fd81fe..d2a4606 100644
>>> --- a/src/core/ngx_resolver.h
>>> +++ b/src/core/ngx_resolver.h
>>> @@ -67,10 +67,11 @@ typedef struct {
>>> u_short qlen;
>>>
>>> u_char *query;
>>> + ngx_int_t qtype;
>>>
>>> union {
>>> - in_addr_t addr;
>>> - in_addr_t *addrs;
>>> + ngx_ipaddr_t addr;
>>> + ngx_ipaddr_t *addrs;
>>> u_char *cname;
>>> } u;
>>>
>>> @@ -130,8 +131,8 @@ struct ngx_resolver_ctx_s {
>>> ngx_str_t name;
>>>
>>> ngx_uint_t naddrs;
>>> - in_addr_t *addrs;
>>> - in_addr_t addr;
>>> + ngx_ipaddr_t *addrs;
>>> + ngx_ipaddr_t addr;
>>>
>>> ngx_resolver_handler_pt handler;
>>> void *data;
>>>
>>>
>>>
>>> On Wed, Jul 10, 2013 at 9:17 PM, ToSHiC <toshic.toshic at gmail.com> wrote:
>>>
>>>> commit 482bd2a0b6240a2b26409b9c7924ad01c814f293
>>>> Author: Anton Kortunov <toshic.toshic at gmail.com>
>>>> Date: Wed Jul 10 13:21:27 2013 +0400
>>>>
>>>> Added NGX_RESOLVE_* constants
>>>>
>>>> Module developers can decide how to resolve hosts relating to IPv6:
>>>>
>>>> NGX_RESOLVE_AAAA - try to resolve only to IPv6 address
>>>> NGX_RESOLVE_AAAA_A - IPv6 is preferred (recommended by standards)
>>>> NGX_RESOLVE_A_AAAA - IPv4 is preferred (better strategy nowadays)
>>>>
>>>> diff --git a/src/core/ngx_resolver.h b/src/core/ngx_resolver.h
>>>> index ae34ca5..6fd81fe 100644
>>>> --- a/src/core/ngx_resolver.h
>>>> +++ b/src/core/ngx_resolver.h
>>>> @@ -20,6 +20,15 @@
>>>> #define NGX_RESOLVE_TXT 16
>>>> #define NGX_RESOLVE_DNAME 39
>>>>
>>>> +#if (NGX_HAVE_INET6)
>>>> +
>>>> +#define NGX_RESOLVE_AAAA 28
>>>> +#define NGX_RESOLVE_A_AAAA 1000
>>>> +#define NGX_RESOLVE_AAAA_A 1001
>>>> +#define NGX_RESOLVE_RETRY 1002
>>>> +
>>>> +#endif
>>>> +
>>>> #define NGX_RESOLVE_FORMERR 1
>>>> #define NGX_RESOLVE_SERVFAIL 2
>>>> #define NGX_RESOLVE_NXDOMAIN 3
>>>>
>>>>
>>>>
>>>> On Wed, Jul 10, 2013 at 9:17 PM, ToSHiC <toshic.toshic at gmail.com>wrote:
>>>>
>>>>> Hello,
>>>>>
>>>>> I've split this big patch into several small patches, taking into
>>>>> account your comments. I'll send each part in separate email. Here is the
>>>>> first one.
>>>>>
>>>>> commit 597d09e7ae9247c5466b18aa2ef3f5892e61b708
>>>>> Author: Anton Kortunov <toshic.toshic at gmail.com>
>>>>> Date: Wed Jul 10 13:14:52 2013 +0400
>>>>>
>>>>> Added new structure ngx_ipaddr_t
>>>>>
>>>>> This structure contains family field
>>>>> and the union of ipv4/ipv6 structures in_addr_t and in6_addr.
>>>>>
>>>>> diff --git a/src/core/ngx_inet.h b/src/core/ngx_inet.h
>>>>> index 6a5a368..077ed34 100644
>>>>> --- a/src/core/ngx_inet.h
>>>>> +++ b/src/core/ngx_inet.h
>>>>> @@ -68,6 +68,16 @@ typedef struct {
>>>>>
>>>>>
>>>>> typedef struct {
>>>>> + ngx_uint_t family;
>>>>> + union {
>>>>> + in_addr_t v4;
>>>>> +#if (NGX_HAVE_INET6)
>>>>> + struct in6_addr v6;
>>>>> +#endif
>>>>> + } u;
>>>>> +} ngx_ipaddr_t;
>>>>> +
>>>>> +typedef struct {
>>>>> struct sockaddr *sockaddr;
>>>>> socklen_t socklen;
>>>>> ngx_str_t name;
>>>>>
>>>>>
>>>>>
>>>>> On Mon, Jun 17, 2013 at 7:30 PM, Maxim Dounin <mdounin at mdounin.ru>wrote:
>>>>>
>>>>>> Hello!
>>>>>>
>>>>>> On Fri, Jun 14, 2013 at 09:44:46PM +0400, ToSHiC wrote:
>>>>>>
>>>>>> > Hello,
>>>>>> >
>>>>>> > We needed this feature in our company, I found that it is in
>>>>>> milestones of
>>>>>> > version 1.5 but doesn't exist yet. So I've implemented it based in
>>>>>> 1.3 code
>>>>>> > and merged in current 1.5 code. When I wrote this code I mostly
>>>>>> cared about
>>>>>> > minimum intrusion into other parts of nginx.
>>>>>> >
>>>>>> > IPv6 fallback logic is not a straightforward implementation of
>>>>>> suggested by
>>>>>> > RFC. RFC states that IPv6 resolving have priority over IPv4, and
>>>>>> it's not
>>>>>> > very good for Internet we have currently. With this patch you can
>>>>>> specify
>>>>>> > priority, and in upstream and mail modules I've set IPv4 as
>>>>>> preferred
>>>>>> > address family.
>>>>>> >
>>>>>> > Patch is pretty big and I hope it'll not break mailing list or mail
>>>>>> clients.
>>>>>>
>>>>>> You may want to try to split the patch into smaller patches to
>>>>>> simplify review. See also some hints here:
>>>>>>
>>>>>> http://nginx.org/en/docs/contributing_changes.html
>>>>>>
>>>>>> Some quick comments below.
>>>>>>
>>>>>> [...]
>>>>>>
>>>>>> > - addr = ntohl(ctx->addr);
>>>>>> > +failed:
>>>>>> > +
>>>>>> > + //addr = ntohl(ctx->addr);
>>>>>> > + inet_ntop(ctx->addr.family, &ctx->addr.u, text,
>>>>>> > NGX_SOCKADDR_STRLEN);
>>>>>> >
>>>>>> > 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);
>>>>>> > + "could not cancel %s resolving", text);
>>>>>>
>>>>>> 1. Don't use inet_ntop(), there is ngx_sock_ntop() instead.
>>>>>>
>>>>>> 2. Don't use C++ style ("//") comments.
>>>>>>
>>>>>> 3. If some data is only needed for debug logging, keep relevant
>>>>>> calculations under #if (NGX_DEBUG).
>>>>>>
>>>>>> [...]
>>>>>>
>>>>>> > @@ -334,6 +362,7 @@
>>>>>> > ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
>>>>>> > peers->peer[i].current_weight = 0;
>>>>>> > peers->peer[i].max_fails = 1;
>>>>>> > peers->peer[i].fail_timeout = 10;
>>>>>> > +
>>>>>> > }
>>>>>> > }
>>>>>> >
>>>>>>
>>>>>> Please avoid unrelated changes.
>>>>>>
>>>>>> [...]
>>>>>>
>>>>>> --
>>>>>> Maxim Dounin
>>>>>> http://nginx.org/en/donation.html
>>>>>>
>>>>>> _______________________________________________
>>>>>> nginx-devel mailing list
>>>>>> nginx-devel at nginx.org
>>>>>> http://mailman.nginx.org/mailman/listinfo/nginx-devel
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20130710/e05754ea/attachment-0001.html>
More information about the nginx-devel
mailing list