Mercurial > hg > nginx
comparison src/core/ngx_resolver.c @ 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 |
comparison
equal
deleted
inserted
replaced
5469:b2fc466a11a7 | 5470:aebdca7e8f8f |
---|---|
1020 | 1020 |
1021 static void | 1021 static void |
1022 ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n) | 1022 ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n) |
1023 { | 1023 { |
1024 char *err; | 1024 char *err; |
1025 size_t len; | |
1026 ngx_uint_t i, times, ident, qident, flags, code, nqs, nan, | 1025 ngx_uint_t i, times, ident, qident, flags, code, nqs, nan, |
1027 qtype, qclass; | 1026 qtype, qclass; |
1028 ngx_queue_t *q; | 1027 ngx_queue_t *q; |
1029 ngx_resolver_qs_t *qs; | 1028 ngx_resolver_qs_t *qs; |
1030 ngx_resolver_hdr_t *response; | 1029 ngx_resolver_hdr_t *response; |
1045 "resolver DNS response %ui fl:%04Xui %ui/%ui/%ud/%ud", | 1044 "resolver DNS response %ui fl:%04Xui %ui/%ui/%ud/%ud", |
1046 ident, flags, nqs, nan, | 1045 ident, flags, nqs, nan, |
1047 (response->nns_hi << 8) + response->nns_lo, | 1046 (response->nns_hi << 8) + response->nns_lo, |
1048 (response->nar_hi << 8) + response->nar_lo); | 1047 (response->nar_hi << 8) + response->nar_lo); |
1049 | 1048 |
1050 if (!(flags & 0x8000)) { | 1049 /* response to a standard query */ |
1050 if ((flags & 0xf870) != 0x8000) { | |
1051 ngx_log_error(r->log_level, r->log, 0, | 1051 ngx_log_error(r->log_level, r->log, 0, |
1052 "invalid DNS response %ui fl:%04Xui", ident, flags); | 1052 "invalid DNS response %ui fl:%04Xui", ident, flags); |
1053 return; | 1053 return; |
1054 } | 1054 } |
1055 | 1055 |
1056 code = flags & 0x7f; | 1056 code = flags & 0xf; |
1057 | 1057 |
1058 if (code == NGX_RESOLVE_FORMERR) { | 1058 if (code == NGX_RESOLVE_FORMERR) { |
1059 | 1059 |
1060 times = 0; | 1060 times = 0; |
1061 | 1061 |
1092 while (i < (ngx_uint_t) n) { | 1092 while (i < (ngx_uint_t) n) { |
1093 if (buf[i] == '\0') { | 1093 if (buf[i] == '\0') { |
1094 goto found; | 1094 goto found; |
1095 } | 1095 } |
1096 | 1096 |
1097 len = buf[i]; | 1097 i += 1 + buf[i]; |
1098 i += 1 + len; | |
1099 } | 1098 } |
1100 | 1099 |
1101 goto short_response; | 1100 goto short_response; |
1102 | 1101 |
1103 found: | 1102 found: |
1104 | 1103 |
1105 if (i++ == 0) { | 1104 if (i++ == sizeof(ngx_resolver_hdr_t)) { |
1106 err = "zero-length domain name in DNS response"; | 1105 err = "zero-length domain name in DNS response"; |
1107 goto done; | 1106 goto done; |
1108 } | 1107 } |
1109 | 1108 |
1110 if (i + sizeof(ngx_resolver_qs_t) + nan * (2 + sizeof(ngx_resolver_an_t)) | 1109 if (i + sizeof(ngx_resolver_qs_t) + nan * (2 + sizeof(ngx_resolver_an_t)) |