changeset 5470:aebdca7e8f8f

Resolver: fixed response processing. Stricten response header checks: ensure that reserved bits are zeroes, and that the opcode is "standard query". Fixed the "zero-length domain name in DNS response" condition.
author Ruslan Ermilov <ru@nginx.com>
date Fri, 06 Dec 2013 14:30:27 +0400
parents b2fc466a11a7
children 9c96782d9d05
files src/core/ngx_resolver.c
diffstat 1 files changed, 5 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -1022,7 +1022,6 @@ static void
 ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n)
 {
     char                 *err;
-    size_t                len;
     ngx_uint_t            i, times, ident, qident, flags, code, nqs, nan,
                           qtype, qclass;
     ngx_queue_t          *q;
@@ -1047,13 +1046,14 @@ ngx_resolver_process_response(ngx_resolv
                    (response->nns_hi << 8) + response->nns_lo,
                    (response->nar_hi << 8) + response->nar_lo);
 
-    if (!(flags & 0x8000)) {
+    /* response to a standard query */
+    if ((flags & 0xf870) != 0x8000) {
         ngx_log_error(r->log_level, r->log, 0,
                       "invalid DNS response %ui fl:%04Xui", ident, flags);
         return;
     }
 
-    code = flags & 0x7f;
+    code = flags & 0xf;
 
     if (code == NGX_RESOLVE_FORMERR) {
 
@@ -1094,15 +1094,14 @@ ngx_resolver_process_response(ngx_resolv
             goto found;
         }
 
-        len = buf[i];
-        i += 1 + len;
+        i += 1 + buf[i];
     }
 
     goto short_response;
 
 found:
 
-    if (i++ == 0) {
+    if (i++ == sizeof(ngx_resolver_hdr_t)) {
         err = "zero-length domain name in DNS response";
         goto done;
     }