Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / net / dns / dns_response.h
blob6e67b5dea97026d17f541dc5a3605ebb3e4b57ec
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
3 // found in the LICENSE file.
5 #ifndef NET_DNS_DNS_RESPONSE_H_
6 #define NET_DNS_DNS_RESPONSE_H_
8 #include <string>
10 #include "base/basictypes.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/strings/string_piece.h"
13 #include "base/time/time.h"
14 #include "net/base/net_export.h"
16 namespace net {
18 class AddressList;
19 class DnsQuery;
20 class IOBufferWithSize;
22 namespace dns_protocol {
23 struct Header;
26 // Parsed resource record.
27 struct NET_EXPORT_PRIVATE DnsResourceRecord {
28 DnsResourceRecord();
29 ~DnsResourceRecord();
31 std::string name; // in dotted form
32 uint16 type;
33 uint16 klass;
34 uint32 ttl;
35 base::StringPiece rdata; // points to the original response buffer
38 // Iterator to walk over resource records of the DNS response packet.
39 class NET_EXPORT_PRIVATE DnsRecordParser {
40 public:
41 // Construct an uninitialized iterator.
42 DnsRecordParser();
44 // Construct an iterator to process the |packet| of given |length|.
45 // |offset| points to the beginning of the answer section.
46 DnsRecordParser(const void* packet, size_t length, size_t offset);
48 // Returns |true| if initialized.
49 bool IsValid() const { return packet_ != NULL; }
51 // Returns |true| if no more bytes remain in the packet.
52 bool AtEnd() const { return cur_ == packet_ + length_; }
54 // Returns current offset into the packet.
55 size_t GetOffset() const { return cur_ - packet_; }
57 // Parses a (possibly compressed) DNS name from the packet starting at
58 // |pos|. Stores output (even partial) in |out| unless |out| is NULL. |out|
59 // is stored in the dotted form, e.g., "example.com". Returns number of bytes
60 // consumed or 0 on failure.
61 // This is exposed to allow parsing compressed names within RRDATA for TYPEs
62 // such as NS, CNAME, PTR, MX, SOA.
63 // See RFC 1035 section 4.1.4.
64 unsigned ReadName(const void* pos, std::string* out) const;
66 // Parses the next resource record into |record|. Returns true if succeeded.
67 bool ReadRecord(DnsResourceRecord* record);
69 // Skip a question section, returns true if succeeded.
70 bool SkipQuestion();
72 private:
73 const char* packet_;
74 size_t length_;
75 // Current offset within the packet.
76 const char* cur_;
79 // Buffer-holder for the DNS response allowing easy access to the header fields
80 // and resource records. After reading into |io_buffer| must call InitParse to
81 // position the RR parser.
82 class NET_EXPORT_PRIVATE DnsResponse {
83 public:
84 // Possible results from ParseToAddressList.
85 enum Result {
86 DNS_PARSE_OK = 0,
87 DNS_MALFORMED_RESPONSE, // DnsRecordParser failed before the end of
88 // packet.
89 DNS_MALFORMED_CNAME, // Could not parse CNAME out of RRDATA.
90 DNS_NAME_MISMATCH, // Got an address but no ordered chain of CNAMEs
91 // leads there.
92 DNS_SIZE_MISMATCH, // Got an address but size does not match.
93 DNS_CNAME_AFTER_ADDRESS, // Found CNAME after an address record.
94 DNS_ADDRESS_TTL_MISMATCH, // OBSOLETE. No longer used.
95 DNS_NO_ADDRESSES, // OBSOLETE. No longer used.
96 // Only add new values here.
97 DNS_PARSE_RESULT_MAX, // Bounding value for histograms.
100 // Constructs a response buffer large enough to store one byte more than
101 // largest possible response, to detect malformed responses.
102 DnsResponse();
104 // Constructs a response buffer of given length. Used for TCP transactions.
105 explicit DnsResponse(size_t length);
107 // Constructs a response from |data|. Used for testing purposes only!
108 DnsResponse(const void* data, size_t length, size_t answer_offset);
110 ~DnsResponse();
112 // Internal buffer accessor into which actual bytes of response will be
113 // read.
114 IOBufferWithSize* io_buffer() { return io_buffer_.get(); }
116 // Assuming the internal buffer holds |nbytes| bytes, returns true iff the
117 // packet matches the |query| id and question.
118 bool InitParse(int nbytes, const DnsQuery& query);
120 // Assuming the internal buffer holds |nbytes| bytes, initialize the parser
121 // without matching it against an existing query.
122 bool InitParseWithoutQuery(int nbytes);
124 // Returns true if response is valid, that is, after successful InitParse.
125 bool IsValid() const;
127 // All of the methods below are valid only if the response is valid.
129 // Accessors for the header.
130 uint16 flags() const; // excluding rcode
131 uint8 rcode() const;
133 unsigned answer_count() const;
134 unsigned additional_answer_count() const;
136 // Accessors to the question. The qname is unparsed.
137 base::StringPiece qname() const;
138 uint16 qtype() const;
140 // Returns qname in dotted format.
141 std::string GetDottedName() const;
143 // Returns an iterator to the resource records in the answer section.
144 // The iterator is valid only in the scope of the DnsResponse.
145 // This operation is idempotent.
146 DnsRecordParser Parser() const;
148 // Extracts an AddressList from this response. Returns SUCCESS if succeeded.
149 // Otherwise returns a detailed error number.
150 Result ParseToAddressList(AddressList* addr_list, base::TimeDelta* ttl) const;
152 private:
153 // Convenience for header access.
154 const dns_protocol::Header* header() const;
156 // Buffer into which response bytes are read.
157 scoped_refptr<IOBufferWithSize> io_buffer_;
159 // Iterator constructed after InitParse positioned at the answer section.
160 // It is never updated afterwards, so can be used in accessors.
161 DnsRecordParser parser_;
163 DISALLOW_COPY_AND_ASSIGN(DnsResponse);
166 } // namespace net
168 #endif // NET_DNS_DNS_RESPONSE_H_