xref: /aosp_15_r20/external/cronet/net/dns/mdns_client.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 #ifndef NET_DNS_MDNS_CLIENT_H_
6 #define NET_DNS_MDNS_CLIENT_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 
15 #include "base/functional/callback.h"
16 #include "base/time/time.h"
17 #include "net/base/ip_endpoint.h"
18 #include "net/base/net_export.h"
19 #include "net/dns/dns_query.h"
20 #include "net/dns/dns_response.h"
21 #include "net/dns/record_parsed.h"
22 
23 namespace net {
24 
25 class DatagramServerSocket;
26 class NetLog;
27 class RecordParsed;
28 
29 // Represents a one-time record lookup. A transaction takes one
30 // associated callback (see |MDnsClient::CreateTransaction|) and calls it
31 // whenever a matching record has been found, either from the cache or
32 // by querying the network (it may choose to query either or both based on its
33 // creation flags, see MDnsTransactionFlags). Network-based transactions will
34 // time out after a reasonable number of seconds.
35 class NET_EXPORT MDnsTransaction {
36  public:
37   static const base::TimeDelta kTransactionTimeout;
38 
39   // Used to signify what type of result the transaction has received.
40   enum Result {
41     // Passed whenever a record is found.
42     RESULT_RECORD,
43     // The transaction is done. Applies to non-single-valued transactions. Is
44     // called when the transaction has finished (this is the last call to the
45     // callback).
46     RESULT_DONE,
47     // No results have been found. Applies to single-valued transactions. Is
48     // called when the transaction has finished without finding any results.
49     // For transactions that use the network, this happens when a timeout
50     // occurs, for transactions that are cache-only, this happens when no
51     // results are in the cache.
52     RESULT_NO_RESULTS,
53     // Called when an NSec record is read for this transaction's
54     // query. This means there cannot possibly be a record of the type
55     // and name for this transaction.
56     RESULT_NSEC
57   };
58 
59   // Used when creating an MDnsTransaction.
60   enum Flags {
61     // Transaction should return only one result, and stop listening after it.
62     // Note that single result transactions will signal when their timeout is
63     // reached, whereas multi-result transactions will not.
64     SINGLE_RESULT = 1 << 0,
65     // Query the cache or the network. May both be used. One must be present.
66     QUERY_CACHE = 1 << 1,
67     QUERY_NETWORK = 1 << 2,
68     // TODO(noamsml): Add flag for flushing cache when feature is implemented
69     // Mask of all possible flags on MDnsTransaction.
70     FLAG_MASK = (1 << 3) - 1,
71   };
72 
73   typedef base::RepeatingCallback<void(Result, const RecordParsed*)>
74       ResultCallback;
75 
76   // Destroying the transaction cancels it.
77   virtual ~MDnsTransaction() = default;
78 
79   // Start the transaction. Return true on success. Cache-based transactions
80   // will execute the callback synchronously.
81   virtual bool Start() = 0;
82 
83   // Get the host or service name for the transaction.
84   virtual const std::string& GetName() const = 0;
85 
86   // Get the type for this transaction (SRV, TXT, A, AAA, etc)
87   virtual uint16_t GetType() const = 0;
88 };
89 
90 // A listener listens for updates regarding a specific record or set of records.
91 // Created by the MDnsClient (see |MDnsClient::CreateListener|) and used to keep
92 // track of listeners.
93 //
94 // TODO([email protected]): Consider moving this inside MDnsClient to better
95 // organize the namespace and avoid confusion with
96 // net::HostResolver::MdnsListener.
97 class NET_EXPORT MDnsListener {
98  public:
99   // Used in the MDnsListener delegate to signify what type of change has been
100   // made to a record.
101   enum UpdateType {
102     RECORD_ADDED,
103     RECORD_CHANGED,
104     RECORD_REMOVED
105   };
106 
107   class Delegate {
108    public:
109     virtual ~Delegate() = default;
110 
111     // Called when a record is added, removed or updated.
112     virtual void OnRecordUpdate(UpdateType update,
113                                 const RecordParsed* record) = 0;
114 
115     // Called when a record is marked nonexistent by an NSEC record.
116     virtual void OnNsecRecord(const std::string& name, unsigned type) = 0;
117 
118     // Called when the cache is purged (due, for example, ot the network
119     // disconnecting).
120     virtual void OnCachePurged() = 0;
121   };
122 
123   // Destroying the listener stops listening.
124   virtual ~MDnsListener() = default;
125 
126   // Start the listener. Return true on success.
127   virtual bool Start() = 0;
128 
129   // Actively refresh any received records.
130   virtual void SetActiveRefresh(bool active_refresh) = 0;
131 
132   // Get the host or service name for this query.
133   // Return an empty string for no name.
134   virtual const std::string& GetName() const = 0;
135 
136   // Get the type for this query (SRV, TXT, A, AAA, etc)
137   virtual uint16_t GetType() const = 0;
138 };
139 
140 // Creates bound datagram sockets ready to use by MDnsClient.
141 class NET_EXPORT MDnsSocketFactory {
142  public:
143   virtual ~MDnsSocketFactory() = default;
144   virtual void CreateSockets(
145       std::vector<std::unique_ptr<DatagramServerSocket>>* sockets) = 0;
146 
147   static std::unique_ptr<MDnsSocketFactory> CreateDefault();
148 };
149 
150 // Listens for Multicast DNS on the local network. You can access information
151 // regarding multicast DNS either by creating an |MDnsListener| to be notified
152 // of new records, or by creating an |MDnsTransaction| to look up the value of a
153 // specific records. When all listeners and active transactions are destroyed,
154 // the client stops listening on the network and destroys the cache.
155 class NET_EXPORT MDnsClient {
156  public:
157   virtual ~MDnsClient() = default;
158 
159   // Create listener object for RRType |rrtype| and name |name|.
160   virtual std::unique_ptr<MDnsListener> CreateListener(
161       uint16_t rrtype,
162       const std::string& name,
163       MDnsListener::Delegate* delegate) = 0;
164 
165   // Create a transaction that can be used to query either the MDns cache, the
166   // network, or both for records of type |rrtype| and name |name|. |flags| is
167   // defined by MDnsTransactionFlags.
168   virtual std::unique_ptr<MDnsTransaction> CreateTransaction(
169       uint16_t rrtype,
170       const std::string& name,
171       int flags,
172       const MDnsTransaction::ResultCallback& callback) = 0;
173 
174   virtual int StartListening(MDnsSocketFactory* factory) = 0;
175 
176   // Do not call this inside callbacks from related MDnsListener and
177   // MDnsTransaction objects.
178   virtual void StopListening() = 0;
179   virtual bool IsListening() const = 0;
180 
181   // Create the default MDnsClient
182   static std::unique_ptr<MDnsClient> CreateDefault();
183 };
184 
185 // Gets the endpoint for the multicast group a socket should join to receive
186 // MDNS messages. Such sockets should also bind to the endpoint from
187 // GetMDnsReceiveEndPoint().
188 //
189 // This is also the endpoint messages should be sent to to send MDNS messages.
190 NET_EXPORT IPEndPoint GetMDnsGroupEndPoint(AddressFamily address_family);
191 
192 // Gets the endpoint sockets should be bound to to receive MDNS messages. Such
193 // sockets should also join the multicast group from GetMDnsGroupEndPoint().
194 NET_EXPORT IPEndPoint GetMDnsReceiveEndPoint(AddressFamily address_family);
195 
196 typedef std::vector<std::pair<uint32_t, AddressFamily>>
197     InterfaceIndexFamilyList;
198 // Returns pairs of interface and address family to bind. Current
199 // implementation returns unique list of all available interfaces.
200 NET_EXPORT InterfaceIndexFamilyList GetMDnsInterfacesToBind();
201 
202 // Create sockets, binds socket to MDns endpoint, and sets multicast interface
203 // and joins multicast group on for |interface_index|.
204 // Returns NULL if failed.
205 NET_EXPORT std::unique_ptr<DatagramServerSocket> CreateAndBindMDnsSocket(
206     AddressFamily address_family,
207     uint32_t interface_index,
208     NetLog* net_log);
209 
210 }  // namespace net
211 
212 #endif  // NET_DNS_MDNS_CLIENT_H_
213