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