blob: 7e8a7f7fdc28bfb46e89066e6e63e3683e37794c [file] [log] [blame]
Jason Jeremy Imana21be272020-10-21 17:53:45 +09001// Copyright 2020 The Chromium OS 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 PATCHPANEL_DNS_DNS_QUERY_H_
6#define PATCHPANEL_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
18#include "patchpanel/dns/net_export.h"
19
20namespace base {
21class BigEndianReader;
22} // namespace base
23
24namespace patchpanel {
25
26namespace dns_protocol {
27struct Header;
28} // namespace dns_protocol
29
30class IOBufferWithSize;
31
32// Represents on-the-wire DNS query message as an object.
33class NET_EXPORT_PRIVATE DnsQuery {
34 public:
35 // Constructs an empty query from a raw packet in |buffer|. If the raw packet
36 // represents a valid DNS query in the wire format (RFC 1035), Parse() will
37 // populate the empty query.
38 explicit DnsQuery(scoped_refptr<IOBufferWithSize> buffer);
39
40 ~DnsQuery();
41
42 // Returns true and populates the query if the internally stored raw packet
43 // can be parsed. This should only be called when DnsQuery is constructed from
44 // the raw buffer.
45 // |valid_bytes| indicates the number of initialized bytes in the raw buffer.
46 // E.g. if the buffer holds a packet received from the network, the buffer may
47 // be allocated with the maximum size of a UDP packet, but |valid_bytes|
48 // indicates the number of bytes actually received from the network. If the
49 // parsing requires reading more than the number of initialized bytes, this
50 // method fails and returns false.
51 bool Parse(size_t valid_bytes);
52
53 // DnsQuery field accessors.
54 uint16_t id() const;
55 base::StringPiece qname() const;
56 uint16_t qtype() const;
57
58 // Returns the Question section of the query. Used when matching the
59 // response.
60 base::StringPiece question() const;
61
62 // Returns the size of the question section.
63 size_t question_size() const;
64
65 // IOBuffer accessor to be used for writing out the query. The buffer has
66 // the same byte layout as the DNS query wire format.
67 IOBufferWithSize* io_buffer() const { return io_buffer_.get(); }
68
69 private:
70 bool ReadHeader(base::BigEndianReader* reader, dns_protocol::Header* out);
71 // After read, |out| is in the DNS format, e.g.
72 // "\x03""www""\x08""chromium""\x03""com""\x00". Use DNSDomainToString to
73 // convert to the dotted format "www.chromium.com" with no trailing dot.
74 bool ReadName(base::BigEndianReader* reader, std::string* out);
75
76 // Size of the DNS name (*NOT* hostname) we are trying to resolve; used
77 // to calculate offsets.
78 size_t qname_size_ = 0;
79
80 // Contains query bytes to be consumed by higher level Write() call.
81 scoped_refptr<IOBufferWithSize> io_buffer_;
82
83 // Pointer to the dns header section.
84 dns_protocol::Header* header_ = nullptr;
85};
86
87} // namespace patchpanel
88
89#endif // PATCHPANEL_DNS_DNS_QUERY_H_