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_
10 #include "base/basictypes.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/string_piece.h"
13 #include "base/time.h"
14 #include "net/base/net_export.h"
15 #include "net/base/net_util.h"
21 class IOBufferWithSize
;
23 namespace dns_protocol
{
27 // Parsed resource record.
28 struct NET_EXPORT_PRIVATE DnsResourceRecord
{
32 std::string name
; // in dotted form
36 base::StringPiece rdata
; // points to the original response buffer
39 // Iterator to walk over resource records of the DNS response packet.
40 class NET_EXPORT_PRIVATE DnsRecordParser
{
42 // Construct an uninitialized iterator.
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
);
49 // Returns |true| if initialized.
50 bool IsValid() const { return packet_
!= NULL
; }
52 // Returns |true| if no more bytes remain in the packet.
53 bool AtEnd() const { return cur_
== packet_
+ length_
; }
55 // Returns current offset into the packet.
56 size_t GetOffset() const { return cur_
- packet_
; }
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;
67 // Parses the next resource record into |record|. Returns true if succeeded.
68 bool ReadRecord(DnsResourceRecord
* record
);
73 // Current offset within the packet.
77 // Buffer-holder for the DNS response allowing easy access to the header fields
78 // and resource records. After reading into |io_buffer| must call InitParse to
79 // position the RR parser.
80 class NET_EXPORT_PRIVATE DnsResponse
{
82 // Possible results from ParseToAddressList.
85 DNS_MALFORMED_RESPONSE
, // DnsRecordParser failed before the end of
87 DNS_MALFORMED_CNAME
, // Could not parse CNAME out of RRDATA.
88 DNS_NAME_MISMATCH
, // Got an address but no ordered chain of CNAMEs
90 DNS_SIZE_MISMATCH
, // Got an address but size does not match.
91 DNS_CNAME_AFTER_ADDRESS
, // Found CNAME after an address record.
92 DNS_ADDRESS_TTL_MISMATCH
, // OBSOLETE. No longer used.
93 DNS_NO_ADDRESSES
, // OBSOLETE. No longer used.
94 // Only add new values here.
95 DNS_PARSE_RESULT_MAX
, // Bounding value for histograms.
98 // Constructs a response buffer large enough to store one byte more than
99 // largest possible response, to detect malformed responses.
102 // Constructs a response buffer of given length. Used for TCP transactions.
103 explicit DnsResponse(size_t length
);
105 // Constructs a response from |data|. Used for testing purposes only!
106 DnsResponse(const void* data
, size_t length
, size_t answer_offset
);
110 // Internal buffer accessor into which actual bytes of response will be
112 IOBufferWithSize
* io_buffer() { return io_buffer_
.get(); }
114 // Assuming the internal buffer holds |nbytes| bytes, returns true iff the
115 // packet matches the |query| id and question.
116 bool InitParse(int nbytes
, const DnsQuery
& query
);
118 // Returns true if response is valid, that is, after successful InitParse.
119 bool IsValid() const;
121 // All of the methods below are valid only if the response is valid.
123 // Accessors for the header.
124 uint16
flags() const; // excluding rcode
126 unsigned answer_count() const;
128 // Accessors to the question. The qname is unparsed.
129 base::StringPiece
qname() const;
130 uint16
qtype() const;
132 // Returns qname in dotted format.
133 std::string
GetDottedName() const;
135 // Returns an iterator to the resource records in the answer section.
136 // The iterator is valid only in the scope of the DnsResponse.
137 // This operation is idempotent.
138 DnsRecordParser
Parser() const;
140 // Extracts an AddressList from this response. Returns SUCCESS if succeeded.
141 // Otherwise returns a detailed error number.
142 Result
ParseToAddressList(AddressList
* addr_list
, base::TimeDelta
* ttl
) const;
145 // Convenience for header access.
146 const dns_protocol::Header
* header() const;
148 // Buffer into which response bytes are read.
149 scoped_refptr
<IOBufferWithSize
> io_buffer_
;
151 // Iterator constructed after InitParse positioned at the answer section.
152 // It is never updated afterwards, so can be used in accessors.
153 DnsRecordParser parser_
;
155 DISALLOW_COPY_AND_ASSIGN(DnsResponse
);
160 #endif // NET_DNS_DNS_RESPONSE_H_