comparison src/core/ngx_resolver.c @ 8055:2a77754cd9fe

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).
author Ruslan Ermilov <ru@nginx.com>
date Tue, 12 Jul 2022 21:44:02 +0400
parents aa28c802409f
children 0422365794f7
comparison
equal deleted inserted replaced
8054:cac164d0807e 8055:2a77754cd9fe
155 } 155 }
156 156
157 cln->handler = ngx_resolver_cleanup; 157 cln->handler = ngx_resolver_cleanup;
158 cln->data = r; 158 cln->data = r;
159 159
160 r->ipv4 = 1;
161
160 ngx_rbtree_init(&r->name_rbtree, &r->name_sentinel, 162 ngx_rbtree_init(&r->name_rbtree, &r->name_sentinel,
161 ngx_resolver_rbtree_insert_value); 163 ngx_resolver_rbtree_insert_value);
162 164
163 ngx_rbtree_init(&r->srv_rbtree, &r->srv_sentinel, 165 ngx_rbtree_init(&r->srv_rbtree, &r->srv_sentinel,
164 ngx_resolver_rbtree_insert_value); 166 ngx_resolver_rbtree_insert_value);
223 225
224 continue; 226 continue;
225 } 227 }
226 228
227 #if (NGX_HAVE_INET6) 229 #if (NGX_HAVE_INET6)
230 if (ngx_strncmp(names[i].data, "ipv4=", 5) == 0) {
231
232 if (ngx_strcmp(&names[i].data[5], "on") == 0) {
233 r->ipv4 = 1;
234
235 } else if (ngx_strcmp(&names[i].data[5], "off") == 0) {
236 r->ipv4 = 0;
237
238 } else {
239 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
240 "invalid parameter: %V", &names[i]);
241 return NULL;
242 }
243
244 continue;
245 }
246
228 if (ngx_strncmp(names[i].data, "ipv6=", 5) == 0) { 247 if (ngx_strncmp(names[i].data, "ipv6=", 5) == 0) {
229 248
230 if (ngx_strcmp(&names[i].data[5], "on") == 0) { 249 if (ngx_strcmp(&names[i].data[5], "on") == 0) {
231 r->ipv6 = 1; 250 r->ipv6 = 1;
232 251
270 rec[j].socklen = u.addrs[j].socklen; 289 rec[j].socklen = u.addrs[j].socklen;
271 rec[j].server = u.addrs[j].name; 290 rec[j].server = u.addrs[j].name;
272 rec[j].resolver = r; 291 rec[j].resolver = r;
273 } 292 }
274 } 293 }
294
295 #if (NGX_HAVE_INET6)
296 if (r->ipv4 + r->ipv6 == 0) {
297 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
298 "\"ipv4\" and \"ipv6\" cannot both be \"off\"");
299 return NULL;
300 }
301 #endif
275 302
276 if (n && r->connections.nelts == 0) { 303 if (n && r->connections.nelts == 0) {
277 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "no name servers defined"); 304 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "no name servers defined");
278 return NULL; 305 return NULL;
279 } 306 }
834 rn->last_connection = r->last_connection++; 861 rn->last_connection = r->last_connection++;
835 if (r->last_connection == r->connections.nelts) { 862 if (r->last_connection == r->connections.nelts) {
836 r->last_connection = 0; 863 r->last_connection = 0;
837 } 864 }
838 865
839 rn->naddrs = (u_short) -1; 866 rn->naddrs = r->ipv4 ? (u_short) -1 : 0;
840 rn->tcp = 0; 867 rn->tcp = 0;
841 #if (NGX_HAVE_INET6) 868 #if (NGX_HAVE_INET6)
842 rn->naddrs6 = r->ipv6 ? (u_short) -1 : 0; 869 rn->naddrs6 = r->ipv6 ? (u_short) -1 : 0;
843 rn->tcp6 = 0; 870 rn->tcp6 = 0;
844 #endif 871 #endif
1261 rec->log.handler = ngx_resolver_log_error; 1288 rec->log.handler = ngx_resolver_log_error;
1262 rec->log.data = rec; 1289 rec->log.data = rec;
1263 rec->log.action = "resolving"; 1290 rec->log.action = "resolving";
1264 } 1291 }
1265 1292
1266 if (rn->naddrs == (u_short) -1) { 1293 if (rn->query && rn->naddrs == (u_short) -1) {
1267 rc = rn->tcp ? ngx_resolver_send_tcp_query(r, rec, rn->query, rn->qlen) 1294 rc = rn->tcp ? ngx_resolver_send_tcp_query(r, rec, rn->query, rn->qlen)
1268 : ngx_resolver_send_udp_query(r, rec, rn->query, rn->qlen); 1295 : ngx_resolver_send_udp_query(r, rec, rn->query, rn->qlen);
1269 1296
1270 if (rc != NGX_OK) { 1297 if (rc != NGX_OK) {
1271 return rc; 1298 return rc;
1763 for (q = ngx_queue_head(&r->name_resend_queue); 1790 for (q = ngx_queue_head(&r->name_resend_queue);
1764 q != ngx_queue_sentinel(&r->name_resend_queue) && times++ < 100; 1791 q != ngx_queue_sentinel(&r->name_resend_queue) && times++ < 100;
1765 q = ngx_queue_next(q)) 1792 q = ngx_queue_next(q))
1766 { 1793 {
1767 rn = ngx_queue_data(q, ngx_resolver_node_t, queue); 1794 rn = ngx_queue_data(q, ngx_resolver_node_t, queue);
1768 qident = (rn->query[0] << 8) + rn->query[1]; 1795
1769 1796 if (rn->query) {
1770 if (qident == ident) { 1797 qident = (rn->query[0] << 8) + rn->query[1];
1771 goto dns_error_name; 1798
1799 if (qident == ident) {
1800 goto dns_error_name;
1801 }
1772 } 1802 }
1773 1803
1774 #if (NGX_HAVE_INET6) 1804 #if (NGX_HAVE_INET6)
1775 if (rn->query6) { 1805 if (rn->query6) {
1776 qident6 = (rn->query6[0] << 8) + rn->query6[1]; 1806 qident6 = (rn->query6[0] << 8) + rn->query6[1];
3643 nlen = name->len ? (1 + name->len + 1) : 1; 3673 nlen = name->len ? (1 + name->len + 1) : 1;
3644 3674
3645 len = sizeof(ngx_resolver_hdr_t) + nlen + sizeof(ngx_resolver_qs_t); 3675 len = sizeof(ngx_resolver_hdr_t) + nlen + sizeof(ngx_resolver_qs_t);
3646 3676
3647 #if (NGX_HAVE_INET6) 3677 #if (NGX_HAVE_INET6)
3648 p = ngx_resolver_alloc(r, r->ipv6 ? len * 2 : len); 3678 p = ngx_resolver_alloc(r, len * (r->ipv4 + r->ipv6));
3649 #else 3679 #else
3650 p = ngx_resolver_alloc(r, len); 3680 p = ngx_resolver_alloc(r, len);
3651 #endif 3681 #endif
3652 if (p == NULL) { 3682 if (p == NULL) {
3653 return NGX_ERROR; 3683 return NGX_ERROR;
3654 } 3684 }
3655 3685
3656 rn->qlen = (u_short) len; 3686 rn->qlen = (u_short) len;
3657 rn->query = p; 3687
3688 if (r->ipv4) {
3689 rn->query = p;
3690 }
3658 3691
3659 #if (NGX_HAVE_INET6) 3692 #if (NGX_HAVE_INET6)
3660 if (r->ipv6) { 3693 if (r->ipv6) {
3661 rn->query6 = p + len; 3694 rn->query6 = r->ipv4 ? (p + len) : p;
3662 } 3695 }
3663 #endif 3696 #endif
3664 3697
3665 query = (ngx_resolver_hdr_t *) p; 3698 query = (ngx_resolver_hdr_t *) p;
3666 3699
3667 ident = ngx_random(); 3700 if (r->ipv4) {
3668 3701 ident = ngx_random();
3669 ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0, 3702
3670 "resolve: \"%V\" A %i", name, ident & 0xffff); 3703 ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
3671 3704 "resolve: \"%V\" A %i", name, ident & 0xffff);
3672 query->ident_hi = (u_char) ((ident >> 8) & 0xff); 3705
3673 query->ident_lo = (u_char) (ident & 0xff); 3706 query->ident_hi = (u_char) ((ident >> 8) & 0xff);
3707 query->ident_lo = (u_char) (ident & 0xff);
3708 }
3674 3709
3675 /* recursion query */ 3710 /* recursion query */
3676 query->flags_hi = 1; query->flags_lo = 0; 3711 query->flags_hi = 1; query->flags_lo = 0;
3677 3712
3678 /* one question */ 3713 /* one question */
3729 return NGX_OK; 3764 return NGX_OK;
3730 } 3765 }
3731 3766
3732 p = rn->query6; 3767 p = rn->query6;
3733 3768
3734 ngx_memcpy(p, rn->query, rn->qlen); 3769 if (r->ipv4) {
3770 ngx_memcpy(p, rn->query, rn->qlen);
3771 }
3735 3772
3736 query = (ngx_resolver_hdr_t *) p; 3773 query = (ngx_resolver_hdr_t *) p;
3737 3774
3738 ident = ngx_random(); 3775 ident = ngx_random();
3739 3776