1 // Copyright (c) 2011 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_QUERY_H_ 6 #define NET_DNS_DNS_QUERY_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <memory> 12 #include <string> 13 14 #include "base/macros.h" 15 #include "base/memory/ref_counted.h" 16 #include "base/strings/string_piece.h" 17 #include "net/base/net_export.h" 18 19 namespace base { 20 class BigEndianReader; 21 } // namespace base 22 23 namespace net { 24 25 class OptRecordRdata; 26 27 namespace dns_protocol { 28 struct Header; 29 } // namespace dns_protocol 30 31 class IOBufferWithSize; 32 33 // Represents on-the-wire DNS query message as an object. 34 class NET_EXPORT_PRIVATE DnsQuery { 35 public: 36 enum class PaddingStrategy { 37 // Query will not be padded. Recommended strategy when query will not be 38 // encrypted. 39 NONE, 40 41 // Query will be padded to the next multiple of 128 octets. Recommended 42 // strategy (per RFC 8467) when query will be encrypted, e.g. through 43 // DNS-over-HTTPS. 44 BLOCK_LENGTH_128, 45 }; 46 47 // Constructs a query message from |qname| which *MUST* be in a valid 48 // DNS name format, and |qtype|. The qclass is set to IN. 49 // If |opt_rdata| is not null, an OPT record will be added to the "Additional" 50 // section of the query. 51 DnsQuery(uint16_t id, 52 const base::StringPiece& qname, 53 uint16_t qtype, 54 const OptRecordRdata* opt_rdata = nullptr, 55 PaddingStrategy padding_strategy = PaddingStrategy::NONE); 56 57 // Constructs an empty query from a raw packet in |buffer|. If the raw packet 58 // represents a valid DNS query in the wire format (RFC 1035), Parse() will 59 // populate the empty query. 60 explicit DnsQuery(scoped_refptr<IOBufferWithSize> buffer); 61 62 // Copies are constructed with an independent cloned, not mirrored, buffer. 63 DnsQuery(const DnsQuery& query); 64 DnsQuery& operator=(const DnsQuery& query); 65 66 ~DnsQuery(); 67 68 // Clones |this| verbatim, with ID field of the header set to |id|. 69 std::unique_ptr<DnsQuery> CloneWithNewId(uint16_t id) const; 70 71 // Returns true and populates the query if the internally stored raw packet 72 // can be parsed. This should only be called when DnsQuery is constructed from 73 // the raw buffer. 74 // |valid_bytes| indicates the number of initialized bytes in the raw buffer. 75 // E.g. if the buffer holds a packet received from the network, the buffer may 76 // be allocated with the maximum size of a UDP packet, but |valid_bytes| 77 // indicates the number of bytes actually received from the network. If the 78 // parsing requires reading more than the number of initialized bytes, this 79 // method fails and returns false. 80 bool Parse(size_t valid_bytes); 81 82 // DnsQuery field accessors. 83 uint16_t id() const; 84 base::StringPiece qname() const; 85 uint16_t qtype() const; 86 87 // Returns the Question section of the query. Used when matching the 88 // response. 89 base::StringPiece question() const; 90 91 // Returns the size of the question section. 92 size_t question_size() const; 93 94 // IOBuffer accessor to be used for writing out the query. The buffer has 95 // the same byte layout as the DNS query wire format. io_buffer()96 IOBufferWithSize* io_buffer() const { return io_buffer_.get(); } 97 98 void set_flags(uint16_t flags); 99 100 private: 101 DnsQuery(const DnsQuery& orig, uint16_t id); 102 void CopyFrom(const DnsQuery& orig); 103 104 bool ReadHeader(base::BigEndianReader* reader, dns_protocol::Header* out); 105 // After read, |out| is in the DNS format, e.g. 106 // "\x03""www""\x08""chromium""\x03""com""\x00". Use DNSDomainToString to 107 // convert to the dotted format "www.chromium.com" with no trailing dot. 108 bool ReadName(base::BigEndianReader* reader, std::string* out); 109 110 // Size of the DNS name (*NOT* hostname) we are trying to resolve; used 111 // to calculate offsets. 112 size_t qname_size_ = 0; 113 114 // Contains query bytes to be consumed by higher level Write() call. 115 scoped_refptr<IOBufferWithSize> io_buffer_; 116 117 // Pointer to the dns header section. 118 dns_protocol::Header* header_ = nullptr; 119 }; 120 121 } // namespace net 122 123 #endif // NET_DNS_DNS_QUERY_H_ 124