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