blob: e5f2c10149e320a1903ecaf06f80c48ca3f33009 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GARNET_BIN_MDNS_SERVICE_PROBER_H_
#define GARNET_BIN_MDNS_SERVICE_PROBER_H_
#include <memory>
#include <string>
#include <lib/fit/function.h>
#include "garnet/bin/mdns/service/mdns_agent.h"
#include "lib/fxl/time/time_delta.h"
namespace mdns {
// Base class for |AddressProber| and |InstanceProber|.
//
// Probing involves repeatedly sending a probe message. The first probe message
// is sent after a random delta of 0 to 250ms. This prevents synchronized
// probing in case multiple devices are powered on simultaneously. Two more
// probe messages are sent at intervals of 250ms, and we'll wait up to 250ms
// for a response.
//
// A probe message consists of a question record asking for any type of
// resource matching the resource name in question. We're looking for specific
// records types, but the wildcard ANY type is used. The question is marked for
// unicast response. The message also includes our proposed record(s) in the
// authority section.
//
// If we see a matching response before we're done with the probe sequence,
// there's a conflict. If not, the probe has completed successfully.
class Prober : public MdnsAgent {
public:
using CompletionCallback = fit::function<void(bool)>;
// Creates a |Prober|. |type| is the resource type for which we're probing.
// Use |kA| for address types (A and AAAA).
Prober(MdnsAgent::Host* host, DnsType type, CompletionCallback callback);
~Prober() override;
// MdnsAgent overrides.
void Start(const std::string& host_full_name) final;
void ReceiveResource(const DnsResource& resource,
MdnsResourceSection section) final;
protected:
const std::string& host_full_name() { return host_full_name_; }
// Returns the name of the resource for which we're probing.
virtual const std::string& ResourceName() = 0;
// Sends the proposed resources.
virtual void SendProposedResources(MdnsResourceSection section) = 0;
private:
static const fxl::TimeDelta kMaxProbeInterval;
static constexpr uint32_t kMaxProbeAttemptCount = 3;
// Returns a time delta between 0 and |kMaxProbeInterval|.
fxl::TimeDelta InitialDelay();
// Waits for |delay| and either sends a probe message or signals success and
// calls |RemoveSelf|.
void Probe(fxl::TimeDelta delay);
DnsType type_;
CompletionCallback callback_;
std::string host_full_name_;
std::shared_ptr<DnsQuestion> question_;
uint32_t probe_attempt_count_ = 0;
};
} // namespace mdns
#endif // GARNET_BIN_MDNS_SERVICE_PROBER_H_