diff options
author | Ruslan Ermilov <ru@nginx.com> | 2022-07-12 20:44:02 +0300 |
---|---|---|
committer | Ruslan Ermilov <ru@nginx.com> | 2022-07-12 20:44:02 +0300 |
commit | 5178da4f94fbae1daec2800bc7fd74cd2923c5bd (patch) | |
tree | ea337fd6aa7ec84d1926123fe56d468ef43815ee | |
parent | ea46b22dfb56137afc7463bc0383e52ff27c7905 (diff) |
The "ipv4=" parameter of the "resolver" directive.
When set to "off", only IPv6 addresses will be resolved, and no
A queries are ever sent (ticket #2196).
-rw-r--r-- | src/core/ngx_resolver.c | 65 | ||||
-rw-r--r-- | src/core/ngx_resolver.h | 4 |
2 files changed, 54 insertions, 15 deletions
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c index b3947f5fd..36bd46df6 100644 --- a/src/core/ngx_resolver.c +++ b/src/core/ngx_resolver.c @@ -157,6 +157,8 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n) cln->handler = ngx_resolver_cleanup; cln->data = r; + r->ipv4 = 1; + ngx_rbtree_init(&r->name_rbtree, &r->name_sentinel, ngx_resolver_rbtree_insert_value); @@ -225,6 +227,23 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n) } #if (NGX_HAVE_INET6) + if (ngx_strncmp(names[i].data, "ipv4=", 5) == 0) { + + if (ngx_strcmp(&names[i].data[5], "on") == 0) { + r->ipv4 = 1; + + } else if (ngx_strcmp(&names[i].data[5], "off") == 0) { + r->ipv4 = 0; + + } else { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid parameter: %V", &names[i]); + return NULL; + } + + continue; + } + if (ngx_strncmp(names[i].data, "ipv6=", 5) == 0) { if (ngx_strcmp(&names[i].data[5], "on") == 0) { @@ -273,6 +292,14 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n) } } +#if (NGX_HAVE_INET6) + if (r->ipv4 + r->ipv6 == 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"ipv4\" and \"ipv6\" cannot both be \"off\""); + return NULL; + } +#endif + if (n && r->connections.nelts == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "no name servers defined"); return NULL; @@ -836,7 +863,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx, r->last_connection = 0; } - rn->naddrs = (u_short) -1; + rn->naddrs = r->ipv4 ? (u_short) -1 : 0; rn->tcp = 0; #if (NGX_HAVE_INET6) rn->naddrs6 = r->ipv6 ? (u_short) -1 : 0; @@ -1263,7 +1290,7 @@ ngx_resolver_send_query(ngx_resolver_t *r, ngx_resolver_node_t *rn) rec->log.action = "resolving"; } - if (rn->naddrs == (u_short) -1) { + if (rn->query && rn->naddrs == (u_short) -1) { rc = rn->tcp ? ngx_resolver_send_tcp_query(r, rec, rn->query, rn->qlen) : ngx_resolver_send_udp_query(r, rec, rn->query, rn->qlen); @@ -1765,10 +1792,13 @@ ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n, q = ngx_queue_next(q)) { rn = ngx_queue_data(q, ngx_resolver_node_t, queue); - qident = (rn->query[0] << 8) + rn->query[1]; - if (qident == ident) { - goto dns_error_name; + if (rn->query) { + qident = (rn->query[0] << 8) + rn->query[1]; + + if (qident == ident) { + goto dns_error_name; + } } #if (NGX_HAVE_INET6) @@ -3645,7 +3675,7 @@ ngx_resolver_create_name_query(ngx_resolver_t *r, ngx_resolver_node_t *rn, len = sizeof(ngx_resolver_hdr_t) + nlen + sizeof(ngx_resolver_qs_t); #if (NGX_HAVE_INET6) - p = ngx_resolver_alloc(r, r->ipv6 ? len * 2 : len); + p = ngx_resolver_alloc(r, len * (r->ipv4 + r->ipv6)); #else p = ngx_resolver_alloc(r, len); #endif @@ -3654,23 +3684,28 @@ ngx_resolver_create_name_query(ngx_resolver_t *r, ngx_resolver_node_t *rn, } rn->qlen = (u_short) len; - rn->query = p; + + if (r->ipv4) { + rn->query = p; + } #if (NGX_HAVE_INET6) if (r->ipv6) { - rn->query6 = p + len; + rn->query6 = r->ipv4 ? (p + len) : p; } #endif query = (ngx_resolver_hdr_t *) p; - ident = ngx_random(); + if (r->ipv4) { + ident = ngx_random(); - ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0, - "resolve: \"%V\" A %i", name, ident & 0xffff); + ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0, + "resolve: \"%V\" A %i", name, ident & 0xffff); - query->ident_hi = (u_char) ((ident >> 8) & 0xff); - query->ident_lo = (u_char) (ident & 0xff); + query->ident_hi = (u_char) ((ident >> 8) & 0xff); + query->ident_lo = (u_char) (ident & 0xff); + } /* recursion query */ query->flags_hi = 1; query->flags_lo = 0; @@ -3731,7 +3766,9 @@ ngx_resolver_create_name_query(ngx_resolver_t *r, ngx_resolver_node_t *rn, p = rn->query6; - ngx_memcpy(p, rn->query, rn->qlen); + if (r->ipv4) { + ngx_memcpy(p, rn->query, rn->qlen); + } query = (ngx_resolver_hdr_t *) p; diff --git a/src/core/ngx_resolver.h b/src/core/ngx_resolver.h index 0bd392189..06026b77d 100644 --- a/src/core/ngx_resolver.h +++ b/src/core/ngx_resolver.h @@ -175,8 +175,10 @@ struct ngx_resolver_s { ngx_queue_t srv_expire_queue; ngx_queue_t addr_expire_queue; + unsigned ipv4:1; + #if (NGX_HAVE_INET6) - ngx_uint_t ipv6; /* unsigned ipv6:1; */ + unsigned ipv6:1; ngx_rbtree_t addr6_rbtree; ngx_rbtree_node_t addr6_sentinel; ngx_queue_t addr6_resend_queue; |