Mercurial > hg > nginx
comparison src/core/ngx_resolver.c @ 6371:33c4d319f08f
Resolver: improved PTR response processing.
The previous code only parsed the first answer, without checking its
type, and required a compressed RR name.
The new code checks the RR type, supports responses with multiple
answers, and doesn't require the RR name to be compressed.
This has a side effect in limited support of CNAME. If a response
includes both CNAME and PTR RRs, like when recursion is enabled on
the server, PTR RR is handled.
Full CNAME support in PTR response is not implemented in this change.
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Thu, 17 Dec 2015 17:21:16 +0300 |
parents | 8c8739bdd3f1 |
children | a6a5bacf6b74 |
comparison
equal
deleted
inserted
replaced
6370:8c8739bdd3f1 | 6371:33c4d319f08f |
---|---|
2399 u_char text[NGX_SOCKADDR_STRLEN]; | 2399 u_char text[NGX_SOCKADDR_STRLEN]; |
2400 in_addr_t addr; | 2400 in_addr_t addr; |
2401 int32_t ttl; | 2401 int32_t ttl; |
2402 ngx_int_t octet; | 2402 ngx_int_t octet; |
2403 ngx_str_t name; | 2403 ngx_str_t name; |
2404 ngx_uint_t i, mask, qident, class; | 2404 ngx_uint_t mask, type, class, qident, a, i, start; |
2405 ngx_queue_t *expire_queue; | 2405 ngx_queue_t *expire_queue; |
2406 ngx_rbtree_t *tree; | 2406 ngx_rbtree_t *tree; |
2407 ngx_resolver_an_t *an; | 2407 ngx_resolver_an_t *an; |
2408 ngx_resolver_ctx_t *ctx, *next; | 2408 ngx_resolver_ctx_t *ctx, *next; |
2409 ngx_resolver_node_t *rn; | 2409 ngx_resolver_node_t *rn; |
2552 return; | 2552 return; |
2553 } | 2553 } |
2554 | 2554 |
2555 i += sizeof(ngx_resolver_qs_t); | 2555 i += sizeof(ngx_resolver_qs_t); |
2556 | 2556 |
2557 if (i + 2 + sizeof(ngx_resolver_an_t) >= n) { | 2557 for (a = 0; a < nan; a++) { |
2558 | |
2559 start = i; | |
2560 | |
2561 while (i < n) { | |
2562 | |
2563 if (buf[i] & 0xc0) { | |
2564 i += 2; | |
2565 goto found; | |
2566 } | |
2567 | |
2568 if (buf[i] == 0) { | |
2569 i++; | |
2570 goto test_length; | |
2571 } | |
2572 | |
2573 i += 1 + buf[i]; | |
2574 } | |
2575 | |
2558 goto short_response; | 2576 goto short_response; |
2559 } | 2577 |
2560 | 2578 test_length: |
2561 /* compression pointer to *.arpa */ | 2579 |
2562 | 2580 if (i - start < 2) { |
2563 if (buf[i] != 0xc0 || buf[i + 1] != sizeof(ngx_resolver_hdr_t)) { | 2581 err = "invalid name in DNS response"; |
2564 err = "invalid in-addr.arpa or ip6.arpa name in DNS response"; | 2582 goto invalid; |
2565 goto invalid; | 2583 } |
2566 } | 2584 |
2567 | 2585 found: |
2568 an = (ngx_resolver_an_t *) &buf[i + 2]; | 2586 |
2569 | 2587 if (i + sizeof(ngx_resolver_an_t) >= n) { |
2570 class = (an->class_hi << 8) + an->class_lo; | 2588 goto short_response; |
2571 len = (an->len_hi << 8) + an->len_lo; | 2589 } |
2572 ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16) | 2590 |
2573 + (an->ttl[2] << 8) + (an->ttl[3]); | 2591 an = (ngx_resolver_an_t *) &buf[i]; |
2574 | 2592 |
2575 if (class != 1) { | 2593 type = (an->type_hi << 8) + an->type_lo; |
2576 ngx_log_error(r->log_level, r->log, 0, | 2594 class = (an->class_hi << 8) + an->class_lo; |
2577 "unexpected RR class %ui", class); | 2595 len = (an->len_hi << 8) + an->len_lo; |
2578 goto failed; | 2596 ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16) |
2579 } | 2597 + (an->ttl[2] << 8) + (an->ttl[3]); |
2580 | 2598 |
2581 if (ttl < 0) { | 2599 if (class != 1) { |
2582 ttl = 0; | 2600 ngx_log_error(r->log_level, r->log, 0, |
2583 } | 2601 "unexpected RR class %ui", class); |
2584 | 2602 goto failed; |
2585 ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0, | 2603 } |
2586 "resolver qt:%ui cl:%ui len:%uz", | 2604 |
2587 (an->type_hi << 8) + an->type_lo, | 2605 if (ttl < 0) { |
2588 class, len); | 2606 ttl = 0; |
2589 | 2607 } |
2590 i += 2 + sizeof(ngx_resolver_an_t); | 2608 |
2591 | 2609 ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0, |
2592 if (i + len > n) { | 2610 "resolver qt:%ui cl:%ui len:%uz", |
2593 goto short_response; | 2611 type, class, len); |
2594 } | 2612 |
2613 i += sizeof(ngx_resolver_an_t); | |
2614 | |
2615 switch (type) { | |
2616 | |
2617 case NGX_RESOLVE_PTR: | |
2618 | |
2619 goto ptr; | |
2620 | |
2621 case NGX_RESOLVE_CNAME: | |
2622 | |
2623 break; | |
2624 | |
2625 default: | |
2626 | |
2627 ngx_log_error(r->log_level, r->log, 0, | |
2628 "unexpected RR type %ui", type); | |
2629 } | |
2630 | |
2631 i += len; | |
2632 } | |
2633 | |
2634 /* unlock addr mutex */ | |
2635 | |
2636 ngx_log_error(r->log_level, r->log, 0, | |
2637 "no PTR type in DNS response"); | |
2638 return; | |
2639 | |
2640 ptr: | |
2595 | 2641 |
2596 if (ngx_resolver_copy(r, &name, buf, buf + i, buf + n) != NGX_OK) { | 2642 if (ngx_resolver_copy(r, &name, buf, buf + i, buf + n) != NGX_OK) { |
2597 goto failed; | 2643 goto failed; |
2598 } | 2644 } |
2599 | 2645 |