1 // Copyright 2019 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/host_resolver_mdns_listener_impl.h"
6
7 #include "base/check_op.h"
8 #include "base/notreached.h"
9 #include "net/base/host_port_pair.h"
10 #include "net/dns/host_cache.h"
11 #include "net/dns/host_resolver_mdns_task.h"
12 #include "net/dns/public/mdns_listener_update_type.h"
13 #include "net/dns/record_parsed.h"
14
15 namespace net {
16
17 namespace {
18
ConvertUpdateType(net::MDnsListener::UpdateType type)19 MdnsListenerUpdateType ConvertUpdateType(net::MDnsListener::UpdateType type) {
20 switch (type) {
21 case net::MDnsListener::RECORD_ADDED:
22 return MdnsListenerUpdateType::kAdded;
23 case net::MDnsListener::RECORD_CHANGED:
24 return MdnsListenerUpdateType::kChanged;
25 case net::MDnsListener::RECORD_REMOVED:
26 return MdnsListenerUpdateType::kRemoved;
27 }
28 }
29
30 } // namespace
31
HostResolverMdnsListenerImpl(const HostPortPair & query_host,DnsQueryType query_type)32 HostResolverMdnsListenerImpl::HostResolverMdnsListenerImpl(
33 const HostPortPair& query_host,
34 DnsQueryType query_type)
35 : query_host_(query_host), query_type_(query_type) {
36 DCHECK_NE(DnsQueryType::UNSPECIFIED, query_type_);
37 }
38
~HostResolverMdnsListenerImpl()39 HostResolverMdnsListenerImpl::~HostResolverMdnsListenerImpl() {
40 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
41
42 // Destroy |inner_listener_| first to cancel listening and callbacks to |this|
43 // before anything else becomes invalid.
44 inner_listener_ = nullptr;
45 }
46
Start(Delegate * delegate)47 int HostResolverMdnsListenerImpl::Start(Delegate* delegate) {
48 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
49 DCHECK(delegate);
50
51 if (initialization_error_ != OK)
52 return initialization_error_;
53
54 DCHECK(inner_listener_);
55
56 delegate_ = delegate;
57 return inner_listener_->Start() ? OK : ERR_FAILED;
58 }
59
OnRecordUpdate(net::MDnsListener::UpdateType update,const RecordParsed * record)60 void HostResolverMdnsListenerImpl::OnRecordUpdate(
61 net::MDnsListener::UpdateType update,
62 const RecordParsed* record) {
63 DCHECK(delegate_);
64
65 HostCache::Entry parsed_entry =
66 HostResolverMdnsTask::ParseResult(OK, query_type_, record,
67 query_host_.host())
68 .CopyWithDefaultPort(query_host_.port());
69 if (parsed_entry.error() != OK) {
70 delegate_->OnUnhandledResult(ConvertUpdateType(update), query_type_);
71 return;
72 }
73
74 switch (query_type_) {
75 case DnsQueryType::UNSPECIFIED:
76 case DnsQueryType::HTTPS:
77 NOTREACHED();
78 break;
79 case DnsQueryType::A:
80 case DnsQueryType::AAAA:
81 DCHECK_EQ(1u, parsed_entry.ip_endpoints().size());
82 delegate_->OnAddressResult(ConvertUpdateType(update), query_type_,
83 parsed_entry.ip_endpoints().front());
84 break;
85 case DnsQueryType::TXT:
86 delegate_->OnTextResult(ConvertUpdateType(update), query_type_,
87 parsed_entry.text_records());
88 break;
89 case DnsQueryType::PTR:
90 case DnsQueryType::SRV:
91 DCHECK(!parsed_entry.hostnames().empty());
92 delegate_->OnHostnameResult(ConvertUpdateType(update), query_type_,
93 parsed_entry.hostnames().front());
94 break;
95 }
96 }
97
OnNsecRecord(const std::string & name,unsigned type)98 void HostResolverMdnsListenerImpl::OnNsecRecord(const std::string& name,
99 unsigned type) {
100 // Do nothing. HostResolver does not support listening for NSEC records.
101 }
102
OnCachePurged()103 void HostResolverMdnsListenerImpl::OnCachePurged() {
104 // Do nothing. HostResolver does not support listening for cache purges.
105 }
106
107 } // namespace net
108