1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard
5*3f982cf4SFabien Sanglard #include "discovery/dnssd/impl/service_dispatcher.h"
6*3f982cf4SFabien Sanglard
7*3f982cf4SFabien Sanglard #include <utility>
8*3f982cf4SFabien Sanglard
9*3f982cf4SFabien Sanglard #include "discovery/common/config.h"
10*3f982cf4SFabien Sanglard #include "discovery/dnssd/impl/service_instance.h"
11*3f982cf4SFabien Sanglard #include "discovery/dnssd/public/dns_sd_instance.h"
12*3f982cf4SFabien Sanglard #include "discovery/mdns/public/mdns_service.h"
13*3f982cf4SFabien Sanglard #include "platform/api/serial_delete_ptr.h"
14*3f982cf4SFabien Sanglard #include "platform/api/task_runner.h"
15*3f982cf4SFabien Sanglard #include "util/trace_logging.h"
16*3f982cf4SFabien Sanglard
17*3f982cf4SFabien Sanglard namespace openscreen {
18*3f982cf4SFabien Sanglard namespace discovery {
19*3f982cf4SFabien Sanglard namespace {
20*3f982cf4SFabien Sanglard
ForAllQueriers(std::vector<std::unique_ptr<ServiceInstance>> * service_instances,std::function<void (DnsSdQuerier *)> action)21*3f982cf4SFabien Sanglard void ForAllQueriers(
22*3f982cf4SFabien Sanglard std::vector<std::unique_ptr<ServiceInstance>>* service_instances,
23*3f982cf4SFabien Sanglard std::function<void(DnsSdQuerier*)> action) {
24*3f982cf4SFabien Sanglard for (auto& service_instance : *service_instances) {
25*3f982cf4SFabien Sanglard auto* querier = service_instance->GetQuerier();
26*3f982cf4SFabien Sanglard OSP_CHECK(querier);
27*3f982cf4SFabien Sanglard
28*3f982cf4SFabien Sanglard action(querier);
29*3f982cf4SFabien Sanglard }
30*3f982cf4SFabien Sanglard }
31*3f982cf4SFabien Sanglard
ForAllPublishers(std::vector<std::unique_ptr<ServiceInstance>> * service_instances,std::function<Error (DnsSdPublisher *)> action,const char * operation)32*3f982cf4SFabien Sanglard Error ForAllPublishers(
33*3f982cf4SFabien Sanglard std::vector<std::unique_ptr<ServiceInstance>>* service_instances,
34*3f982cf4SFabien Sanglard std::function<Error(DnsSdPublisher*)> action,
35*3f982cf4SFabien Sanglard const char* operation) {
36*3f982cf4SFabien Sanglard Error result = Error::None();
37*3f982cf4SFabien Sanglard for (auto& service_instance : *service_instances) {
38*3f982cf4SFabien Sanglard auto* publisher = service_instance->GetPublisher();
39*3f982cf4SFabien Sanglard OSP_CHECK(publisher);
40*3f982cf4SFabien Sanglard
41*3f982cf4SFabien Sanglard TRACE_SCOPED(TraceCategory::kDiscovery, operation);
42*3f982cf4SFabien Sanglard Error inner_result = action(publisher);
43*3f982cf4SFabien Sanglard TRACE_SET_RESULT(inner_result);
44*3f982cf4SFabien Sanglard if (!inner_result.ok()) {
45*3f982cf4SFabien Sanglard result = std::move(inner_result);
46*3f982cf4SFabien Sanglard }
47*3f982cf4SFabien Sanglard }
48*3f982cf4SFabien Sanglard return result;
49*3f982cf4SFabien Sanglard }
50*3f982cf4SFabien Sanglard
51*3f982cf4SFabien Sanglard } // namespace
52*3f982cf4SFabien Sanglard
53*3f982cf4SFabien Sanglard // static
CreateDnsSdService(TaskRunner * task_runner,ReportingClient * reporting_client,const Config & config)54*3f982cf4SFabien Sanglard SerialDeletePtr<DnsSdService> CreateDnsSdService(
55*3f982cf4SFabien Sanglard TaskRunner* task_runner,
56*3f982cf4SFabien Sanglard ReportingClient* reporting_client,
57*3f982cf4SFabien Sanglard const Config& config) {
58*3f982cf4SFabien Sanglard return SerialDeletePtr<DnsSdService>(
59*3f982cf4SFabien Sanglard task_runner,
60*3f982cf4SFabien Sanglard new ServiceDispatcher(task_runner, reporting_client, config));
61*3f982cf4SFabien Sanglard }
62*3f982cf4SFabien Sanglard
ServiceDispatcher(TaskRunner * task_runner,ReportingClient * reporting_client,const Config & config)63*3f982cf4SFabien Sanglard ServiceDispatcher::ServiceDispatcher(TaskRunner* task_runner,
64*3f982cf4SFabien Sanglard ReportingClient* reporting_client,
65*3f982cf4SFabien Sanglard const Config& config)
66*3f982cf4SFabien Sanglard : task_runner_(task_runner),
67*3f982cf4SFabien Sanglard publisher_(config.enable_publication ? this : nullptr),
68*3f982cf4SFabien Sanglard querier_(config.enable_querying ? this : nullptr) {
69*3f982cf4SFabien Sanglard OSP_DCHECK_GT(config.network_info.size(), 0);
70*3f982cf4SFabien Sanglard OSP_DCHECK(task_runner);
71*3f982cf4SFabien Sanglard
72*3f982cf4SFabien Sanglard service_instances_.reserve(config.network_info.size());
73*3f982cf4SFabien Sanglard for (const auto& network_info : config.network_info) {
74*3f982cf4SFabien Sanglard service_instances_.push_back(std::make_unique<ServiceInstance>(
75*3f982cf4SFabien Sanglard task_runner_, reporting_client, config, network_info));
76*3f982cf4SFabien Sanglard }
77*3f982cf4SFabien Sanglard }
78*3f982cf4SFabien Sanglard
~ServiceDispatcher()79*3f982cf4SFabien Sanglard ServiceDispatcher::~ServiceDispatcher() {
80*3f982cf4SFabien Sanglard OSP_DCHECK(task_runner_->IsRunningOnTaskRunner());
81*3f982cf4SFabien Sanglard }
82*3f982cf4SFabien Sanglard
83*3f982cf4SFabien Sanglard // DnsSdQuerier overrides.
StartQuery(const std::string & service,Callback * cb)84*3f982cf4SFabien Sanglard void ServiceDispatcher::StartQuery(const std::string& service, Callback* cb) {
85*3f982cf4SFabien Sanglard TRACE_DEFAULT_SCOPED(TraceCategory::kDiscovery);
86*3f982cf4SFabien Sanglard auto start_query = [&service, cb](DnsSdQuerier* querier) {
87*3f982cf4SFabien Sanglard querier->StartQuery(service, cb);
88*3f982cf4SFabien Sanglard };
89*3f982cf4SFabien Sanglard ForAllQueriers(&service_instances_, std::move(start_query));
90*3f982cf4SFabien Sanglard }
91*3f982cf4SFabien Sanglard
StopQuery(const std::string & service,Callback * cb)92*3f982cf4SFabien Sanglard void ServiceDispatcher::StopQuery(const std::string& service, Callback* cb) {
93*3f982cf4SFabien Sanglard TRACE_DEFAULT_SCOPED(TraceCategory::kDiscovery);
94*3f982cf4SFabien Sanglard auto stop_query = [&service, cb](DnsSdQuerier* querier) {
95*3f982cf4SFabien Sanglard querier->StopQuery(service, cb);
96*3f982cf4SFabien Sanglard };
97*3f982cf4SFabien Sanglard ForAllQueriers(&service_instances_, std::move(stop_query));
98*3f982cf4SFabien Sanglard }
99*3f982cf4SFabien Sanglard
ReinitializeQueries(const std::string & service)100*3f982cf4SFabien Sanglard void ServiceDispatcher::ReinitializeQueries(const std::string& service) {
101*3f982cf4SFabien Sanglard TRACE_DEFAULT_SCOPED(TraceCategory::kDiscovery);
102*3f982cf4SFabien Sanglard auto reinitialize_queries = [&service](DnsSdQuerier* querier) {
103*3f982cf4SFabien Sanglard querier->ReinitializeQueries(service);
104*3f982cf4SFabien Sanglard };
105*3f982cf4SFabien Sanglard ForAllQueriers(&service_instances_, std::move(reinitialize_queries));
106*3f982cf4SFabien Sanglard }
107*3f982cf4SFabien Sanglard
108*3f982cf4SFabien Sanglard // DnsSdPublisher overrides.
Register(const DnsSdInstance & instance,Client * client)109*3f982cf4SFabien Sanglard Error ServiceDispatcher::Register(const DnsSdInstance& instance,
110*3f982cf4SFabien Sanglard Client* client) {
111*3f982cf4SFabien Sanglard TRACE_DEFAULT_SCOPED(TraceCategory::kDiscovery);
112*3f982cf4SFabien Sanglard auto register_instance = [&instance, client](DnsSdPublisher* publisher) {
113*3f982cf4SFabien Sanglard return publisher->Register(instance, client);
114*3f982cf4SFabien Sanglard };
115*3f982cf4SFabien Sanglard return ForAllPublishers(&service_instances_, std::move(register_instance),
116*3f982cf4SFabien Sanglard "DNS-SD.Register");
117*3f982cf4SFabien Sanglard }
118*3f982cf4SFabien Sanglard
UpdateRegistration(const DnsSdInstance & instance)119*3f982cf4SFabien Sanglard Error ServiceDispatcher::UpdateRegistration(const DnsSdInstance& instance) {
120*3f982cf4SFabien Sanglard TRACE_DEFAULT_SCOPED(TraceCategory::kDiscovery);
121*3f982cf4SFabien Sanglard auto update_registration = [&instance](DnsSdPublisher* publisher) {
122*3f982cf4SFabien Sanglard return publisher->UpdateRegistration(instance);
123*3f982cf4SFabien Sanglard };
124*3f982cf4SFabien Sanglard return ForAllPublishers(&service_instances_, std::move(update_registration),
125*3f982cf4SFabien Sanglard "DNS-SD.UpdateRegistration");
126*3f982cf4SFabien Sanglard }
127*3f982cf4SFabien Sanglard
DeregisterAll(const std::string & service)128*3f982cf4SFabien Sanglard ErrorOr<int> ServiceDispatcher::DeregisterAll(const std::string& service) {
129*3f982cf4SFabien Sanglard TRACE_DEFAULT_SCOPED(TraceCategory::kDiscovery);
130*3f982cf4SFabien Sanglard int total = 0;
131*3f982cf4SFabien Sanglard Error failure = Error::None();
132*3f982cf4SFabien Sanglard for (auto& service_instance : service_instances_) {
133*3f982cf4SFabien Sanglard auto* publisher = service_instance->GetPublisher();
134*3f982cf4SFabien Sanglard OSP_CHECK(publisher);
135*3f982cf4SFabien Sanglard
136*3f982cf4SFabien Sanglard TRACE_SCOPED(TraceCategory::kDiscovery, "DNS-SD.DeregisterAll");
137*3f982cf4SFabien Sanglard auto result = publisher->DeregisterAll(service);
138*3f982cf4SFabien Sanglard if (result.is_error()) {
139*3f982cf4SFabien Sanglard TRACE_SET_RESULT(result.error());
140*3f982cf4SFabien Sanglard failure = std::move(result.error());
141*3f982cf4SFabien Sanglard } else {
142*3f982cf4SFabien Sanglard total += result.value();
143*3f982cf4SFabien Sanglard }
144*3f982cf4SFabien Sanglard }
145*3f982cf4SFabien Sanglard
146*3f982cf4SFabien Sanglard if (!failure.ok()) {
147*3f982cf4SFabien Sanglard return failure;
148*3f982cf4SFabien Sanglard } else {
149*3f982cf4SFabien Sanglard return total;
150*3f982cf4SFabien Sanglard }
151*3f982cf4SFabien Sanglard }
152*3f982cf4SFabien Sanglard
153*3f982cf4SFabien Sanglard } // namespace discovery
154*3f982cf4SFabien Sanglard } // namespace openscreen
155