You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
5.3 KiB
135 lines
5.3 KiB
// Copyright 2020 The Chromium 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 DISCOVERY_DNSSD_IMPL_DNS_DATA_GRAPH_H_
|
|
#define DISCOVERY_DNSSD_IMPL_DNS_DATA_GRAPH_H_
|
|
|
|
#include <functional>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
#include "absl/types/optional.h"
|
|
#include "discovery/dnssd/impl/constants.h"
|
|
#include "discovery/dnssd/public/dns_sd_instance_endpoint.h"
|
|
#include "discovery/mdns/mdns_record_changed_callback.h"
|
|
#include "discovery/mdns/mdns_records.h"
|
|
|
|
namespace openscreen {
|
|
namespace discovery {
|
|
|
|
/*
|
|
Per RFC 6763, the following mappings exist between the domains of the called
|
|
out mDNS records:
|
|
|
|
--------------
|
|
| PTR Record |
|
|
--------------
|
|
/\
|
|
/ \
|
|
/ \
|
|
/ \
|
|
/ \
|
|
-------------- --------------
|
|
| SRV Record | | TXT Record |
|
|
-------------- --------------
|
|
/\
|
|
/ \
|
|
/ \
|
|
/ \
|
|
/ \
|
|
/ \
|
|
-------------- ---------------
|
|
| A Record | | AAAA Record |
|
|
-------------- ---------------
|
|
|
|
Such that PTR records point to the domain of SRV and TXT records, and SRV
|
|
records point to the domain of A and AAAA records. Below, these 3 separate
|
|
sets are referred to as "Domain Groups".
|
|
|
|
Though it is frequently the case that each A or AAAA record will only be
|
|
pointed to by one SRV record domain, this is not a requirement for DNS-SD and
|
|
in the wild this case does come up. On the other hand, it is expected that
|
|
each PTR record domain will point to multiple SRV records.
|
|
|
|
To represent this data, a multigraph structure has been used.
|
|
- Each node of the graph represents a specific domain name
|
|
- Each edge represents a parent-child relationship, such that node A is a
|
|
parent of node B iff there exists some record x in A such that x points to
|
|
the domain represented by B.
|
|
In practice, it is expected that no more than one edge will ever exist
|
|
between two nodes. A multigraph is used despite this to simplify the code and
|
|
avoid a number of tricky edge cases (both literally and figuratively).
|
|
|
|
Note the following:
|
|
- This definition allows for cycles in the multigraph (which are unexpected
|
|
but allowed by the RFC).
|
|
- This definition allows for self loops (which are expected when a SRV record
|
|
points to address records with the same domain).
|
|
- The memory requirement for this graph is bounded due to a bound on the
|
|
number of tracked records in the mDNS layer as part of
|
|
discovery/mdns/mdns_querier.h.
|
|
*/
|
|
class DnsDataGraph {
|
|
public:
|
|
// The set of valid groups of domains, as called out in the hierarchy
|
|
// described above.
|
|
enum class DomainGroup { kNone = 0, kPtr, kSrvAndTxt, kAddress };
|
|
|
|
// Get the domain group associated with the provided object.
|
|
static DomainGroup GetDomainGroup(DnsType type);
|
|
static DomainGroup GetDomainGroup(const MdnsRecord record);
|
|
|
|
// Creates a new DnsDataGraph.
|
|
static std::unique_ptr<DnsDataGraph> Create(
|
|
NetworkInterfaceIndex network_index);
|
|
|
|
// Callback to use when a domain change occurs.
|
|
using DomainChangeCallback = std::function<void(DomainName)>;
|
|
|
|
virtual ~DnsDataGraph();
|
|
|
|
// Manually starts or stops tracking the provided domain. These methods should
|
|
// only be called for top-level PTR domains.
|
|
virtual void StartTracking(const DomainName& domain,
|
|
DomainChangeCallback on_start_tracking) = 0;
|
|
virtual void StopTracking(const DomainName& domain,
|
|
DomainChangeCallback on_stop_tracking) = 0;
|
|
|
|
// Attempts to create all DnsSdInstanceEndpoint objects with |name| associated
|
|
// with the provided |domain_group|. If all required data for one such
|
|
// endpoint has been received, and an error occurs while parsing this data,
|
|
// then an error is returned in place of that endpoint.
|
|
virtual std::vector<ErrorOr<DnsSdInstanceEndpoint>> CreateEndpoints(
|
|
DomainGroup domain_group,
|
|
const DomainName& name) const = 0;
|
|
|
|
// Modifies this entity with the provided DnsRecord. If called with a valid
|
|
// record type, the provided change will only be applied if the provided event
|
|
// is valid at the time of calling. The returned result will be an error if
|
|
// the change does not make sense from our current data state, and
|
|
// Error::None() otherwise. Valid record types with which this method can be
|
|
// called are PTR, SRV, TXT, A, and AAAA record types.
|
|
//
|
|
// TODO(issuetracker.google.com/157822423): Allow for duplicate records of
|
|
// non-PTR types.
|
|
virtual Error ApplyDataRecordChange(
|
|
MdnsRecord record,
|
|
RecordChangedEvent event,
|
|
DomainChangeCallback on_start_tracking,
|
|
DomainChangeCallback on_stop_tracking) = 0;
|
|
|
|
virtual size_t GetTrackedDomainCount() const = 0;
|
|
|
|
// Returns whether the provided domain is tracked or not. This may either be
|
|
// due to a direct call to StartTracking() or due to the result of a received
|
|
// record.
|
|
virtual bool IsTracked(const DomainName& name) const = 0;
|
|
};
|
|
|
|
} // namespace discovery
|
|
} // namespace openscreen
|
|
|
|
#endif // DISCOVERY_DNSSD_IMPL_DNS_DATA_GRAPH_H_
|