xref: /aosp_15_r20/external/cronet/net/dns/record_parsed.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/dns/record_parsed.h"
6 
7 #include <utility>
8 
9 #include "base/logging.h"
10 #include "base/memory/ptr_util.h"
11 #include "net/dns/dns_response.h"
12 #include "net/dns/https_record_rdata.h"
13 #include "net/dns/opt_record_rdata.h"
14 #include "net/dns/record_rdata.h"
15 
16 namespace net {
17 
RecordParsed(const std::string & name,uint16_t type,uint16_t klass,uint32_t ttl,std::unique_ptr<const RecordRdata> rdata,base::Time time_created)18 RecordParsed::RecordParsed(const std::string& name,
19                            uint16_t type,
20                            uint16_t klass,
21                            uint32_t ttl,
22                            std::unique_ptr<const RecordRdata> rdata,
23                            base::Time time_created)
24     : name_(name),
25       type_(type),
26       klass_(klass),
27       ttl_(ttl),
28       rdata_(std::move(rdata)),
29       time_created_(time_created) {}
30 
31 RecordParsed::~RecordParsed() = default;
32 
33 // static
CreateFrom(DnsRecordParser * parser,base::Time time_created)34 std::unique_ptr<const RecordParsed> RecordParsed::CreateFrom(
35     DnsRecordParser* parser,
36     base::Time time_created) {
37   DnsResourceRecord record;
38   std::unique_ptr<const RecordRdata> rdata;
39 
40   if (!parser->ReadRecord(&record))
41     return nullptr;
42 
43   bool unrecognized_type = false;
44   switch (record.type) {
45     case ARecordRdata::kType:
46       rdata = ARecordRdata::Create(record.rdata, *parser);
47       break;
48     case AAAARecordRdata::kType:
49       rdata = AAAARecordRdata::Create(record.rdata, *parser);
50       break;
51     case CnameRecordRdata::kType:
52       rdata = CnameRecordRdata::Create(record.rdata, *parser);
53       break;
54     case PtrRecordRdata::kType:
55       rdata = PtrRecordRdata::Create(record.rdata, *parser);
56       break;
57     case SrvRecordRdata::kType:
58       rdata = SrvRecordRdata::Create(record.rdata, *parser);
59       break;
60     case TxtRecordRdata::kType:
61       rdata = TxtRecordRdata::Create(record.rdata, *parser);
62       break;
63     case NsecRecordRdata::kType:
64       rdata = NsecRecordRdata::Create(record.rdata, *parser);
65       break;
66     case OptRecordRdata::kType:
67       rdata = OptRecordRdata::Create(record.rdata);
68       break;
69     case HttpsRecordRdata::kType:
70       rdata = HttpsRecordRdata::Parse(record.rdata);
71       break;
72     default:
73       DVLOG(1) << "Unknown RData type for received record: " << record.type;
74       rdata = nullptr;
75       unrecognized_type = true;
76       break;
77   }
78 
79   // If a recognized type has a malformed rdata, consider the whole record
80   // malformed.
81   if (!rdata.get() && !unrecognized_type)
82     return nullptr;
83 
84   return base::WrapUnique(new RecordParsed(record.name, record.type,
85                                            record.klass, record.ttl,
86                                            std::move(rdata), time_created));
87 }
88 
IsEqual(const RecordParsed * other,bool is_mdns) const89 bool RecordParsed::IsEqual(const RecordParsed* other, bool is_mdns) const {
90   DCHECK(other);
91   uint16_t klass = klass_;
92   uint16_t other_klass = other->klass_;
93 
94   if (is_mdns) {
95     klass &= dns_protocol::kMDnsClassMask;
96     other_klass &= dns_protocol::kMDnsClassMask;
97   }
98 
99   return name_ == other->name_ && klass == other_klass &&
100          type_ == other->type_ && !!rdata_ == !!other->rdata_ &&
101          (!rdata_ || rdata_->IsEqual(other->rdata_.get()));
102 }
103 
104 }  // namespace net
105