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