| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/dns/dns_response.h" | 5 #include "net/dns/dns_response.h" |
| 6 | 6 |
| 7 #include "base/sys_byteorder.h" | 7 #include "base/sys_byteorder.h" |
| 8 #include "net/base/big_endian.h" | 8 #include "net/base/big_endian.h" |
| 9 #include "net/base/dns_util.h" |
| 9 #include "net/base/io_buffer.h" | 10 #include "net/base/io_buffer.h" |
| 10 #include "net/base/net_errors.h" | 11 #include "net/base/net_errors.h" |
| 11 #include "net/dns/dns_protocol.h" | 12 #include "net/dns/dns_protocol.h" |
| 12 #include "net/dns/dns_query.h" | 13 #include "net/dns/dns_query.h" |
| 13 | 14 |
| 14 namespace net { | 15 namespace net { |
| 15 | 16 |
| 16 DnsResourceRecord::DnsResourceRecord() { | 17 DnsResourceRecord::DnsResourceRecord() { |
| 17 } | 18 } |
| 18 | 19 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 | 126 |
| 126 DnsResponse::DnsResponse() | 127 DnsResponse::DnsResponse() |
| 127 : io_buffer_(new IOBufferWithSize(dns_protocol::kMaxUDPSize + 1)) { | 128 : io_buffer_(new IOBufferWithSize(dns_protocol::kMaxUDPSize + 1)) { |
| 128 } | 129 } |
| 129 | 130 |
| 130 DnsResponse::DnsResponse(const void* data, | 131 DnsResponse::DnsResponse(const void* data, |
| 131 size_t length, | 132 size_t length, |
| 132 size_t answer_offset) | 133 size_t answer_offset) |
| 133 : io_buffer_(new IOBufferWithSize(length)), | 134 : io_buffer_(new IOBufferWithSize(length)), |
| 134 parser_(io_buffer_->data(), length, answer_offset) { | 135 parser_(io_buffer_->data(), length, answer_offset) { |
| 136 DCHECK(data); |
| 135 memcpy(io_buffer_->data(), data, length); | 137 memcpy(io_buffer_->data(), data, length); |
| 136 } | 138 } |
| 137 | 139 |
| 138 DnsResponse::~DnsResponse() { | 140 DnsResponse::~DnsResponse() { |
| 139 } | 141 } |
| 140 | 142 |
| 141 bool DnsResponse::InitParse(int nbytes, const DnsQuery& query) { | 143 bool DnsResponse::InitParse(int nbytes, const DnsQuery& query) { |
| 142 // Response includes query, it should be at least that size. | 144 // Response includes query, it should be at least that size. |
| 143 if (nbytes < query.io_buffer()->size() || nbytes > dns_protocol::kMaxUDPSize) | 145 if (nbytes < query.io_buffer()->size() || nbytes > dns_protocol::kMaxUDPSize) |
| 144 return false; | 146 return false; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 159 return false; | 161 return false; |
| 160 } | 162 } |
| 161 | 163 |
| 162 // Construct the parser. | 164 // Construct the parser. |
| 163 parser_ = DnsRecordParser(io_buffer_->data(), | 165 parser_ = DnsRecordParser(io_buffer_->data(), |
| 164 nbytes, | 166 nbytes, |
| 165 hdr_size + question.size()); | 167 hdr_size + question.size()); |
| 166 return true; | 168 return true; |
| 167 } | 169 } |
| 168 | 170 |
| 169 uint8 DnsResponse::flags0() const { | 171 bool DnsResponse::IsValid() const { |
| 170 return header()->flags[0]; | 172 return parser_.IsValid(); |
| 171 } | 173 } |
| 172 | 174 |
| 173 uint8 DnsResponse::flags1() const { | 175 uint16 DnsResponse::flags() const { |
| 174 return header()->flags[1] & ~(dns_protocol::kRcodeMask); | 176 DCHECK(parser_.IsValid()); |
| 177 return ntohs(header()->flags) & ~(dns_protocol::kRcodeMask); |
| 175 } | 178 } |
| 176 | 179 |
| 177 uint8 DnsResponse::rcode() const { | 180 uint8 DnsResponse::rcode() const { |
| 178 return header()->flags[1] & dns_protocol::kRcodeMask; | 181 DCHECK(parser_.IsValid()); |
| 182 return ntohs(header()->flags) & dns_protocol::kRcodeMask; |
| 179 } | 183 } |
| 180 | 184 |
| 181 int DnsResponse::answer_count() const { | 185 int DnsResponse::answer_count() const { |
| 186 DCHECK(parser_.IsValid()); |
| 182 return ntohs(header()->ancount); | 187 return ntohs(header()->ancount); |
| 183 } | 188 } |
| 184 | 189 |
| 190 base::StringPiece DnsResponse::qname() const { |
| 191 DCHECK(parser_.IsValid()); |
| 192 // The response is HEADER QNAME QTYPE QCLASS ANSWER. |
| 193 // |parser_| is positioned at the beginning of ANSWER, so the end of QNAME is |
| 194 // two uint16s before it. |
| 195 const size_t hdr_size = sizeof(dns_protocol::Header); |
| 196 const size_t qname_size = parser_.GetOffset() - 2 * sizeof(uint16) - hdr_size; |
| 197 return base::StringPiece(io_buffer_->data() + hdr_size, qname_size); |
| 198 } |
| 199 |
| 200 uint16 DnsResponse::qtype() const { |
| 201 DCHECK(parser_.IsValid()); |
| 202 // QTYPE starts where QNAME ends. |
| 203 const size_t type_offset = parser_.GetOffset() - 2 * sizeof(uint16); |
| 204 uint16 type; |
| 205 ReadBigEndian<uint16>(io_buffer_->data() + type_offset, &type); |
| 206 return type; |
| 207 } |
| 208 |
| 209 std::string DnsResponse::GetDottedName() const { |
| 210 return DNSDomainToString(qname()); |
| 211 } |
| 212 |
| 185 DnsRecordParser DnsResponse::Parser() const { | 213 DnsRecordParser DnsResponse::Parser() const { |
| 186 DCHECK(parser_.IsValid()); | 214 DCHECK(parser_.IsValid()); |
| 215 // Return a copy of the parser. |
| 187 return parser_; | 216 return parser_; |
| 188 } | 217 } |
| 189 | 218 |
| 190 const dns_protocol::Header* DnsResponse::header() const { | 219 const dns_protocol::Header* DnsResponse::header() const { |
| 191 return reinterpret_cast<const dns_protocol::Header*>(io_buffer_->data()); | 220 return reinterpret_cast<const dns_protocol::Header*>(io_buffer_->data()); |
| 192 } | 221 } |
| 193 | 222 |
| 194 } // namespace net | 223 } // namespace net |
| OLD | NEW |