xref: /aosp_15_r20/external/cronet/net/dns/mdns_client_impl.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef NET_DNS_MDNS_CLIENT_IMPL_H_
6*6777b538SAndroid Build Coastguard Worker #define NET_DNS_MDNS_CLIENT_IMPL_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include <map>
11*6777b538SAndroid Build Coastguard Worker #include <memory>
12*6777b538SAndroid Build Coastguard Worker #include <string>
13*6777b538SAndroid Build Coastguard Worker #include <utility>
14*6777b538SAndroid Build Coastguard Worker #include <vector>
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker #include "base/cancelable_callback.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/containers/queue.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/gtest_prod_util.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/observer_list.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
22*6777b538SAndroid Build Coastguard Worker #include "net/base/io_buffer.h"
23*6777b538SAndroid Build Coastguard Worker #include "net/base/ip_endpoint.h"
24*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h"
25*6777b538SAndroid Build Coastguard Worker #include "net/dns/mdns_cache.h"
26*6777b538SAndroid Build Coastguard Worker #include "net/dns/mdns_client.h"
27*6777b538SAndroid Build Coastguard Worker #include "net/socket/datagram_server_socket.h"
28*6777b538SAndroid Build Coastguard Worker #include "net/socket/udp_server_socket.h"
29*6777b538SAndroid Build Coastguard Worker #include "net/socket/udp_socket.h"
30*6777b538SAndroid Build Coastguard Worker 
31*6777b538SAndroid Build Coastguard Worker namespace base {
32*6777b538SAndroid Build Coastguard Worker class Clock;
33*6777b538SAndroid Build Coastguard Worker class OneShotTimer;
34*6777b538SAndroid Build Coastguard Worker }  // namespace base
35*6777b538SAndroid Build Coastguard Worker 
36*6777b538SAndroid Build Coastguard Worker namespace net {
37*6777b538SAndroid Build Coastguard Worker 
38*6777b538SAndroid Build Coastguard Worker class NetLog;
39*6777b538SAndroid Build Coastguard Worker 
40*6777b538SAndroid Build Coastguard Worker class MDnsSocketFactoryImpl : public MDnsSocketFactory {
41*6777b538SAndroid Build Coastguard Worker  public:
MDnsSocketFactoryImpl()42*6777b538SAndroid Build Coastguard Worker   MDnsSocketFactoryImpl() : net_log_(nullptr) {}
MDnsSocketFactoryImpl(NetLog * net_log)43*6777b538SAndroid Build Coastguard Worker   explicit MDnsSocketFactoryImpl(NetLog* net_log) : net_log_(net_log) {}
44*6777b538SAndroid Build Coastguard Worker 
45*6777b538SAndroid Build Coastguard Worker   MDnsSocketFactoryImpl(const MDnsSocketFactoryImpl&) = delete;
46*6777b538SAndroid Build Coastguard Worker   MDnsSocketFactoryImpl& operator=(const MDnsSocketFactoryImpl&) = delete;
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker   ~MDnsSocketFactoryImpl() override = default;
49*6777b538SAndroid Build Coastguard Worker 
50*6777b538SAndroid Build Coastguard Worker   void CreateSockets(
51*6777b538SAndroid Build Coastguard Worker       std::vector<std::unique_ptr<DatagramServerSocket>>* sockets) override;
52*6777b538SAndroid Build Coastguard Worker 
53*6777b538SAndroid Build Coastguard Worker  private:
54*6777b538SAndroid Build Coastguard Worker   const raw_ptr<NetLog> net_log_;
55*6777b538SAndroid Build Coastguard Worker };
56*6777b538SAndroid Build Coastguard Worker 
57*6777b538SAndroid Build Coastguard Worker // A connection to the network for multicast DNS clients. It reads data into
58*6777b538SAndroid Build Coastguard Worker // DnsResponse objects and alerts the delegate that a packet has been received.
59*6777b538SAndroid Build Coastguard Worker class NET_EXPORT_PRIVATE MDnsConnection {
60*6777b538SAndroid Build Coastguard Worker  public:
61*6777b538SAndroid Build Coastguard Worker   class Delegate {
62*6777b538SAndroid Build Coastguard Worker    public:
63*6777b538SAndroid Build Coastguard Worker     // Handle an mDNS packet buffered in |response| with a size of |bytes_read|.
64*6777b538SAndroid Build Coastguard Worker     virtual void HandlePacket(DnsResponse* response, int bytes_read) = 0;
65*6777b538SAndroid Build Coastguard Worker     virtual void OnConnectionError(int error) = 0;
66*6777b538SAndroid Build Coastguard Worker     virtual ~Delegate() = default;
67*6777b538SAndroid Build Coastguard Worker   };
68*6777b538SAndroid Build Coastguard Worker 
69*6777b538SAndroid Build Coastguard Worker   explicit MDnsConnection(MDnsConnection::Delegate* delegate);
70*6777b538SAndroid Build Coastguard Worker 
71*6777b538SAndroid Build Coastguard Worker   MDnsConnection(const MDnsConnection&) = delete;
72*6777b538SAndroid Build Coastguard Worker   MDnsConnection& operator=(const MDnsConnection&) = delete;
73*6777b538SAndroid Build Coastguard Worker 
74*6777b538SAndroid Build Coastguard Worker   virtual ~MDnsConnection();
75*6777b538SAndroid Build Coastguard Worker 
76*6777b538SAndroid Build Coastguard Worker   // Succeeds if at least one of the socket handlers succeeded.
77*6777b538SAndroid Build Coastguard Worker   int Init(MDnsSocketFactory* socket_factory);
78*6777b538SAndroid Build Coastguard Worker   void Send(const scoped_refptr<IOBuffer>& buffer, unsigned size);
79*6777b538SAndroid Build Coastguard Worker 
80*6777b538SAndroid Build Coastguard Worker  private:
81*6777b538SAndroid Build Coastguard Worker   class SocketHandler {
82*6777b538SAndroid Build Coastguard Worker    public:
83*6777b538SAndroid Build Coastguard Worker     SocketHandler(std::unique_ptr<DatagramServerSocket> socket,
84*6777b538SAndroid Build Coastguard Worker                   MDnsConnection* connection);
85*6777b538SAndroid Build Coastguard Worker 
86*6777b538SAndroid Build Coastguard Worker     SocketHandler(const SocketHandler&) = delete;
87*6777b538SAndroid Build Coastguard Worker     SocketHandler& operator=(const SocketHandler&) = delete;
88*6777b538SAndroid Build Coastguard Worker 
89*6777b538SAndroid Build Coastguard Worker     ~SocketHandler();
90*6777b538SAndroid Build Coastguard Worker 
91*6777b538SAndroid Build Coastguard Worker     int Start();
92*6777b538SAndroid Build Coastguard Worker     void Send(const scoped_refptr<IOBuffer>& buffer, unsigned size);
93*6777b538SAndroid Build Coastguard Worker 
94*6777b538SAndroid Build Coastguard Worker    private:
95*6777b538SAndroid Build Coastguard Worker     int DoLoop(int rv);
96*6777b538SAndroid Build Coastguard Worker     void OnDatagramReceived(int rv);
97*6777b538SAndroid Build Coastguard Worker 
98*6777b538SAndroid Build Coastguard Worker     // Callback for when sending a query has finished.
99*6777b538SAndroid Build Coastguard Worker     void SendDone(int rv);
100*6777b538SAndroid Build Coastguard Worker 
101*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<DatagramServerSocket> socket_;
102*6777b538SAndroid Build Coastguard Worker     raw_ptr<MDnsConnection> connection_;
103*6777b538SAndroid Build Coastguard Worker     IPEndPoint recv_addr_;
104*6777b538SAndroid Build Coastguard Worker     DnsResponse response_;
105*6777b538SAndroid Build Coastguard Worker     IPEndPoint multicast_addr_;
106*6777b538SAndroid Build Coastguard Worker     bool send_in_progress_ = false;
107*6777b538SAndroid Build Coastguard Worker     base::queue<std::pair<scoped_refptr<IOBuffer>, unsigned>> send_queue_;
108*6777b538SAndroid Build Coastguard Worker   };
109*6777b538SAndroid Build Coastguard Worker 
110*6777b538SAndroid Build Coastguard Worker   // Callback for handling a datagram being received on either ipv4 or ipv6.
111*6777b538SAndroid Build Coastguard Worker   void OnDatagramReceived(DnsResponse* response,
112*6777b538SAndroid Build Coastguard Worker                           const IPEndPoint& recv_addr,
113*6777b538SAndroid Build Coastguard Worker                           int bytes_read);
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker   void PostOnError(SocketHandler* loop, int rv);
116*6777b538SAndroid Build Coastguard Worker   void OnError(int rv);
117*6777b538SAndroid Build Coastguard Worker 
118*6777b538SAndroid Build Coastguard Worker   // Only socket handlers which successfully bound and started are kept.
119*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<SocketHandler>> socket_handlers_;
120*6777b538SAndroid Build Coastguard Worker 
121*6777b538SAndroid Build Coastguard Worker   raw_ptr<Delegate> delegate_;
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker   base::WeakPtrFactory<MDnsConnection> weak_ptr_factory_{this};
124*6777b538SAndroid Build Coastguard Worker };
125*6777b538SAndroid Build Coastguard Worker 
126*6777b538SAndroid Build Coastguard Worker class MDnsListenerImpl;
127*6777b538SAndroid Build Coastguard Worker 
128*6777b538SAndroid Build Coastguard Worker class NET_EXPORT_PRIVATE MDnsClientImpl : public MDnsClient {
129*6777b538SAndroid Build Coastguard Worker  public:
130*6777b538SAndroid Build Coastguard Worker   // The core object exists while the MDnsClient is listening, and is deleted
131*6777b538SAndroid Build Coastguard Worker   // whenever the number of listeners reaches zero. The deletion happens
132*6777b538SAndroid Build Coastguard Worker   // asychronously, so destroying the last listener does not immediately
133*6777b538SAndroid Build Coastguard Worker   // invalidate the core.
134*6777b538SAndroid Build Coastguard Worker   class Core : public base::SupportsWeakPtr<Core>, MDnsConnection::Delegate {
135*6777b538SAndroid Build Coastguard Worker    public:
136*6777b538SAndroid Build Coastguard Worker     Core(base::Clock* clock, base::OneShotTimer* timer);
137*6777b538SAndroid Build Coastguard Worker 
138*6777b538SAndroid Build Coastguard Worker     Core(const Core&) = delete;
139*6777b538SAndroid Build Coastguard Worker     Core& operator=(const Core&) = delete;
140*6777b538SAndroid Build Coastguard Worker 
141*6777b538SAndroid Build Coastguard Worker     ~Core() override;
142*6777b538SAndroid Build Coastguard Worker 
143*6777b538SAndroid Build Coastguard Worker     // Initialize the core.
144*6777b538SAndroid Build Coastguard Worker     int Init(MDnsSocketFactory* socket_factory);
145*6777b538SAndroid Build Coastguard Worker 
146*6777b538SAndroid Build Coastguard Worker     // Send a query with a specific rrtype and name. Returns true on success.
147*6777b538SAndroid Build Coastguard Worker     bool SendQuery(uint16_t rrtype, const std::string& name);
148*6777b538SAndroid Build Coastguard Worker 
149*6777b538SAndroid Build Coastguard Worker     // Add/remove a listener to the list of listeners.
150*6777b538SAndroid Build Coastguard Worker     void AddListener(MDnsListenerImpl* listener);
151*6777b538SAndroid Build Coastguard Worker     void RemoveListener(MDnsListenerImpl* listener);
152*6777b538SAndroid Build Coastguard Worker 
153*6777b538SAndroid Build Coastguard Worker     // Query the cache for records of a specific type and name.
154*6777b538SAndroid Build Coastguard Worker     void QueryCache(uint16_t rrtype,
155*6777b538SAndroid Build Coastguard Worker                     const std::string& name,
156*6777b538SAndroid Build Coastguard Worker                     std::vector<const RecordParsed*>* records) const;
157*6777b538SAndroid Build Coastguard Worker 
158*6777b538SAndroid Build Coastguard Worker     // Parse the response and alert relevant listeners.
159*6777b538SAndroid Build Coastguard Worker     void HandlePacket(DnsResponse* response, int bytes_read) override;
160*6777b538SAndroid Build Coastguard Worker 
161*6777b538SAndroid Build Coastguard Worker     void OnConnectionError(int error) override;
162*6777b538SAndroid Build Coastguard Worker 
cache_for_testing()163*6777b538SAndroid Build Coastguard Worker     MDnsCache* cache_for_testing() { return &cache_; }
164*6777b538SAndroid Build Coastguard Worker 
165*6777b538SAndroid Build Coastguard Worker    private:
166*6777b538SAndroid Build Coastguard Worker     FRIEND_TEST_ALL_PREFIXES(MDnsTest, CacheCleanupWithShortTTL);
167*6777b538SAndroid Build Coastguard Worker 
168*6777b538SAndroid Build Coastguard Worker     class ListenerKey {
169*6777b538SAndroid Build Coastguard Worker      public:
170*6777b538SAndroid Build Coastguard Worker       ListenerKey(const std::string& name, uint16_t type);
171*6777b538SAndroid Build Coastguard Worker       ListenerKey(const ListenerKey&) = default;
172*6777b538SAndroid Build Coastguard Worker       ListenerKey(ListenerKey&&) = default;
173*6777b538SAndroid Build Coastguard Worker       bool operator<(const ListenerKey& key) const;
name_lowercase()174*6777b538SAndroid Build Coastguard Worker       const std::string& name_lowercase() const { return name_lowercase_; }
type()175*6777b538SAndroid Build Coastguard Worker       uint16_t type() const { return type_; }
176*6777b538SAndroid Build Coastguard Worker 
177*6777b538SAndroid Build Coastguard Worker      private:
178*6777b538SAndroid Build Coastguard Worker       std::string name_lowercase_;
179*6777b538SAndroid Build Coastguard Worker       uint16_t type_;
180*6777b538SAndroid Build Coastguard Worker     };
181*6777b538SAndroid Build Coastguard Worker     typedef base::ObserverList<MDnsListenerImpl>::Unchecked ObserverListType;
182*6777b538SAndroid Build Coastguard Worker     typedef std::map<ListenerKey, std::unique_ptr<ObserverListType>>
183*6777b538SAndroid Build Coastguard Worker         ListenerMap;
184*6777b538SAndroid Build Coastguard Worker 
185*6777b538SAndroid Build Coastguard Worker     // Alert listeners of an update to the cache.
186*6777b538SAndroid Build Coastguard Worker     void AlertListeners(MDnsCache::UpdateType update_type,
187*6777b538SAndroid Build Coastguard Worker                         const ListenerKey& key, const RecordParsed* record);
188*6777b538SAndroid Build Coastguard Worker 
189*6777b538SAndroid Build Coastguard Worker     // Schedule a cache cleanup to a specific time, cancelling other cleanups.
190*6777b538SAndroid Build Coastguard Worker     void ScheduleCleanup(base::Time cleanup);
191*6777b538SAndroid Build Coastguard Worker 
192*6777b538SAndroid Build Coastguard Worker     // Clean up the cache and schedule a new cleanup.
193*6777b538SAndroid Build Coastguard Worker     void DoCleanup();
194*6777b538SAndroid Build Coastguard Worker 
195*6777b538SAndroid Build Coastguard Worker     // Callback for when a record is removed from the cache.
196*6777b538SAndroid Build Coastguard Worker     void OnRecordRemoved(const RecordParsed* record);
197*6777b538SAndroid Build Coastguard Worker 
198*6777b538SAndroid Build Coastguard Worker     void NotifyNsecRecord(const RecordParsed* record);
199*6777b538SAndroid Build Coastguard Worker 
200*6777b538SAndroid Build Coastguard Worker     // Delete and erase the observer list for |key|. Only deletes the observer
201*6777b538SAndroid Build Coastguard Worker     // list if is empty.
202*6777b538SAndroid Build Coastguard Worker     void CleanupObserverList(const ListenerKey& key);
203*6777b538SAndroid Build Coastguard Worker 
204*6777b538SAndroid Build Coastguard Worker     ListenerMap listeners_;
205*6777b538SAndroid Build Coastguard Worker 
206*6777b538SAndroid Build Coastguard Worker     MDnsCache cache_;
207*6777b538SAndroid Build Coastguard Worker 
208*6777b538SAndroid Build Coastguard Worker     raw_ptr<base::Clock> clock_;
209*6777b538SAndroid Build Coastguard Worker     raw_ptr<base::OneShotTimer> cleanup_timer_;
210*6777b538SAndroid Build Coastguard Worker     base::Time scheduled_cleanup_;
211*6777b538SAndroid Build Coastguard Worker 
212*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<MDnsConnection> connection_;
213*6777b538SAndroid Build Coastguard Worker   };
214*6777b538SAndroid Build Coastguard Worker 
215*6777b538SAndroid Build Coastguard Worker   MDnsClientImpl();
216*6777b538SAndroid Build Coastguard Worker 
217*6777b538SAndroid Build Coastguard Worker   // Test constructor, takes a mock clock and mock timer.
218*6777b538SAndroid Build Coastguard Worker   MDnsClientImpl(base::Clock* clock,
219*6777b538SAndroid Build Coastguard Worker                  std::unique_ptr<base::OneShotTimer> cleanup_timer);
220*6777b538SAndroid Build Coastguard Worker 
221*6777b538SAndroid Build Coastguard Worker   MDnsClientImpl(const MDnsClientImpl&) = delete;
222*6777b538SAndroid Build Coastguard Worker   MDnsClientImpl& operator=(const MDnsClientImpl&) = delete;
223*6777b538SAndroid Build Coastguard Worker 
224*6777b538SAndroid Build Coastguard Worker   ~MDnsClientImpl() override;
225*6777b538SAndroid Build Coastguard Worker 
226*6777b538SAndroid Build Coastguard Worker   // MDnsClient implementation:
227*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<MDnsListener> CreateListener(
228*6777b538SAndroid Build Coastguard Worker       uint16_t rrtype,
229*6777b538SAndroid Build Coastguard Worker       const std::string& name,
230*6777b538SAndroid Build Coastguard Worker       MDnsListener::Delegate* delegate) override;
231*6777b538SAndroid Build Coastguard Worker 
232*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<MDnsTransaction> CreateTransaction(
233*6777b538SAndroid Build Coastguard Worker       uint16_t rrtype,
234*6777b538SAndroid Build Coastguard Worker       const std::string& name,
235*6777b538SAndroid Build Coastguard Worker       int flags,
236*6777b538SAndroid Build Coastguard Worker       const MDnsTransaction::ResultCallback& callback) override;
237*6777b538SAndroid Build Coastguard Worker 
238*6777b538SAndroid Build Coastguard Worker   int StartListening(MDnsSocketFactory* socket_factory) override;
239*6777b538SAndroid Build Coastguard Worker   void StopListening() override;
240*6777b538SAndroid Build Coastguard Worker   bool IsListening() const override;
241*6777b538SAndroid Build Coastguard Worker 
core()242*6777b538SAndroid Build Coastguard Worker   Core* core() { return core_.get(); }
243*6777b538SAndroid Build Coastguard Worker 
244*6777b538SAndroid Build Coastguard Worker  private:
245*6777b538SAndroid Build Coastguard Worker   raw_ptr<base::Clock> clock_;
246*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<base::OneShotTimer> cleanup_timer_;
247*6777b538SAndroid Build Coastguard Worker 
248*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<Core> core_;
249*6777b538SAndroid Build Coastguard Worker };
250*6777b538SAndroid Build Coastguard Worker 
251*6777b538SAndroid Build Coastguard Worker class MDnsListenerImpl : public MDnsListener,
252*6777b538SAndroid Build Coastguard Worker                          public base::SupportsWeakPtr<MDnsListenerImpl> {
253*6777b538SAndroid Build Coastguard Worker  public:
254*6777b538SAndroid Build Coastguard Worker   MDnsListenerImpl(uint16_t rrtype,
255*6777b538SAndroid Build Coastguard Worker                    const std::string& name,
256*6777b538SAndroid Build Coastguard Worker                    base::Clock* clock,
257*6777b538SAndroid Build Coastguard Worker                    MDnsListener::Delegate* delegate,
258*6777b538SAndroid Build Coastguard Worker                    MDnsClientImpl* client);
259*6777b538SAndroid Build Coastguard Worker 
260*6777b538SAndroid Build Coastguard Worker   MDnsListenerImpl(const MDnsListenerImpl&) = delete;
261*6777b538SAndroid Build Coastguard Worker   MDnsListenerImpl& operator=(const MDnsListenerImpl&) = delete;
262*6777b538SAndroid Build Coastguard Worker 
263*6777b538SAndroid Build Coastguard Worker   ~MDnsListenerImpl() override;
264*6777b538SAndroid Build Coastguard Worker 
265*6777b538SAndroid Build Coastguard Worker   // MDnsListener implementation:
266*6777b538SAndroid Build Coastguard Worker   bool Start() override;
267*6777b538SAndroid Build Coastguard Worker 
268*6777b538SAndroid Build Coastguard Worker   // Actively refresh any received records.
269*6777b538SAndroid Build Coastguard Worker   void SetActiveRefresh(bool active_refresh) override;
270*6777b538SAndroid Build Coastguard Worker 
271*6777b538SAndroid Build Coastguard Worker   const std::string& GetName() const override;
272*6777b538SAndroid Build Coastguard Worker 
273*6777b538SAndroid Build Coastguard Worker   uint16_t GetType() const override;
274*6777b538SAndroid Build Coastguard Worker 
delegate()275*6777b538SAndroid Build Coastguard Worker   MDnsListener::Delegate* delegate() { return delegate_; }
276*6777b538SAndroid Build Coastguard Worker 
277*6777b538SAndroid Build Coastguard Worker   // Alert the delegate of a record update.
278*6777b538SAndroid Build Coastguard Worker   void HandleRecordUpdate(MDnsCache::UpdateType update_type,
279*6777b538SAndroid Build Coastguard Worker                           const RecordParsed* record_parsed);
280*6777b538SAndroid Build Coastguard Worker 
281*6777b538SAndroid Build Coastguard Worker   // Alert the delegate of the existence of an Nsec record.
282*6777b538SAndroid Build Coastguard Worker   void AlertNsecRecord();
283*6777b538SAndroid Build Coastguard Worker 
284*6777b538SAndroid Build Coastguard Worker  private:
285*6777b538SAndroid Build Coastguard Worker   void ScheduleNextRefresh();
286*6777b538SAndroid Build Coastguard Worker   void DoRefresh();
287*6777b538SAndroid Build Coastguard Worker 
288*6777b538SAndroid Build Coastguard Worker   uint16_t rrtype_;
289*6777b538SAndroid Build Coastguard Worker   std::string name_;
290*6777b538SAndroid Build Coastguard Worker   raw_ptr<base::Clock> clock_;
291*6777b538SAndroid Build Coastguard Worker   raw_ptr<MDnsClientImpl> client_;
292*6777b538SAndroid Build Coastguard Worker   raw_ptr<MDnsListener::Delegate> delegate_;
293*6777b538SAndroid Build Coastguard Worker 
294*6777b538SAndroid Build Coastguard Worker   base::Time last_update_;
295*6777b538SAndroid Build Coastguard Worker   uint32_t ttl_;
296*6777b538SAndroid Build Coastguard Worker   bool started_ = false;
297*6777b538SAndroid Build Coastguard Worker   bool active_refresh_ = false;
298*6777b538SAndroid Build Coastguard Worker 
299*6777b538SAndroid Build Coastguard Worker   base::CancelableRepeatingClosure next_refresh_;
300*6777b538SAndroid Build Coastguard Worker };
301*6777b538SAndroid Build Coastguard Worker 
302*6777b538SAndroid Build Coastguard Worker class MDnsTransactionImpl : public base::SupportsWeakPtr<MDnsTransactionImpl>,
303*6777b538SAndroid Build Coastguard Worker                             public MDnsTransaction,
304*6777b538SAndroid Build Coastguard Worker                             public MDnsListener::Delegate {
305*6777b538SAndroid Build Coastguard Worker  public:
306*6777b538SAndroid Build Coastguard Worker   MDnsTransactionImpl(uint16_t rrtype,
307*6777b538SAndroid Build Coastguard Worker                       const std::string& name,
308*6777b538SAndroid Build Coastguard Worker                       int flags,
309*6777b538SAndroid Build Coastguard Worker                       const MDnsTransaction::ResultCallback& callback,
310*6777b538SAndroid Build Coastguard Worker                       MDnsClientImpl* client);
311*6777b538SAndroid Build Coastguard Worker 
312*6777b538SAndroid Build Coastguard Worker   MDnsTransactionImpl(const MDnsTransactionImpl&) = delete;
313*6777b538SAndroid Build Coastguard Worker   MDnsTransactionImpl& operator=(const MDnsTransactionImpl&) = delete;
314*6777b538SAndroid Build Coastguard Worker 
315*6777b538SAndroid Build Coastguard Worker   ~MDnsTransactionImpl() override;
316*6777b538SAndroid Build Coastguard Worker 
317*6777b538SAndroid Build Coastguard Worker   // MDnsTransaction implementation:
318*6777b538SAndroid Build Coastguard Worker   bool Start() override;
319*6777b538SAndroid Build Coastguard Worker 
320*6777b538SAndroid Build Coastguard Worker   const std::string& GetName() const override;
321*6777b538SAndroid Build Coastguard Worker   uint16_t GetType() const override;
322*6777b538SAndroid Build Coastguard Worker 
323*6777b538SAndroid Build Coastguard Worker   // MDnsListener::Delegate implementation:
324*6777b538SAndroid Build Coastguard Worker   void OnRecordUpdate(MDnsListener::UpdateType update,
325*6777b538SAndroid Build Coastguard Worker                       const RecordParsed* record) override;
326*6777b538SAndroid Build Coastguard Worker   void OnNsecRecord(const std::string& name, unsigned type) override;
327*6777b538SAndroid Build Coastguard Worker 
328*6777b538SAndroid Build Coastguard Worker   void OnCachePurged() override;
329*6777b538SAndroid Build Coastguard Worker 
330*6777b538SAndroid Build Coastguard Worker  private:
is_active()331*6777b538SAndroid Build Coastguard Worker   bool is_active() { return !callback_.is_null(); }
332*6777b538SAndroid Build Coastguard Worker 
333*6777b538SAndroid Build Coastguard Worker   void Reset();
334*6777b538SAndroid Build Coastguard Worker 
335*6777b538SAndroid Build Coastguard Worker   // Trigger the callback and reset all related variables.
336*6777b538SAndroid Build Coastguard Worker   void TriggerCallback(MDnsTransaction::Result result,
337*6777b538SAndroid Build Coastguard Worker                        const RecordParsed* record);
338*6777b538SAndroid Build Coastguard Worker 
339*6777b538SAndroid Build Coastguard Worker   // Internal callback for when a cache record is found.
340*6777b538SAndroid Build Coastguard Worker   void CacheRecordFound(const RecordParsed* record);
341*6777b538SAndroid Build Coastguard Worker 
342*6777b538SAndroid Build Coastguard Worker   // Signal the transactionis over and release all related resources.
343*6777b538SAndroid Build Coastguard Worker   void SignalTransactionOver();
344*6777b538SAndroid Build Coastguard Worker 
345*6777b538SAndroid Build Coastguard Worker   // Reads records from the cache and calls the callback for every
346*6777b538SAndroid Build Coastguard Worker   // record read.
347*6777b538SAndroid Build Coastguard Worker   void ServeRecordsFromCache();
348*6777b538SAndroid Build Coastguard Worker 
349*6777b538SAndroid Build Coastguard Worker   // Send a query to the network and set up a timeout to time out the
350*6777b538SAndroid Build Coastguard Worker   // transaction. Returns false if it fails to start listening on the network
351*6777b538SAndroid Build Coastguard Worker   // or if it fails to send a query.
352*6777b538SAndroid Build Coastguard Worker   bool QueryAndListen();
353*6777b538SAndroid Build Coastguard Worker 
354*6777b538SAndroid Build Coastguard Worker   uint16_t rrtype_;
355*6777b538SAndroid Build Coastguard Worker   std::string name_;
356*6777b538SAndroid Build Coastguard Worker   MDnsTransaction::ResultCallback callback_;
357*6777b538SAndroid Build Coastguard Worker 
358*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<MDnsListener> listener_;
359*6777b538SAndroid Build Coastguard Worker   base::CancelableOnceCallback<void()> timeout_;
360*6777b538SAndroid Build Coastguard Worker 
361*6777b538SAndroid Build Coastguard Worker   raw_ptr<MDnsClientImpl> client_;
362*6777b538SAndroid Build Coastguard Worker 
363*6777b538SAndroid Build Coastguard Worker   bool started_ = false;
364*6777b538SAndroid Build Coastguard Worker   int flags_;
365*6777b538SAndroid Build Coastguard Worker };
366*6777b538SAndroid Build Coastguard Worker 
367*6777b538SAndroid Build Coastguard Worker }  // namespace net
368*6777b538SAndroid Build Coastguard Worker #endif  // NET_DNS_MDNS_CLIENT_IMPL_H_
369