1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef NET_DNS_MDNS_CLIENT_IMPL_H_
6 #define NET_DNS_MDNS_CLIENT_IMPL_H_
13 #include "base/cancelable_callback.h"
14 #include "base/memory/scoped_vector.h"
15 #include "base/observer_list.h"
16 #include "net/base/io_buffer.h"
17 #include "net/base/ip_endpoint.h"
18 #include "net/dns/mdns_cache.h"
19 #include "net/dns/mdns_client.h"
20 #include "net/udp/datagram_server_socket.h"
21 #include "net/udp/udp_server_socket.h"
22 #include "net/udp/udp_socket.h"
26 class MDnsSocketFactoryImpl
: public MDnsSocketFactory
{
28 MDnsSocketFactoryImpl() {};
29 virtual ~MDnsSocketFactoryImpl() {};
31 virtual void CreateSockets(
32 ScopedVector
<DatagramServerSocket
>* sockets
) override
;
35 DISALLOW_COPY_AND_ASSIGN(MDnsSocketFactoryImpl
);
38 // A connection to the network for multicast DNS clients. It reads data into
39 // DnsResponse objects and alerts the delegate that a packet has been received.
40 class NET_EXPORT_PRIVATE MDnsConnection
{
44 // Handle an mDNS packet buffered in |response| with a size of |bytes_read|.
45 virtual void HandlePacket(DnsResponse
* response
, int bytes_read
) = 0;
46 virtual void OnConnectionError(int error
) = 0;
47 virtual ~Delegate() {}
50 explicit MDnsConnection(MDnsConnection::Delegate
* delegate
);
51 virtual ~MDnsConnection();
53 // Both methods return true if at least one of the socket handlers succeeded.
54 bool Init(MDnsSocketFactory
* socket_factory
);
55 void Send(const scoped_refptr
<IOBuffer
>& buffer
, unsigned size
);
60 SocketHandler(scoped_ptr
<DatagramServerSocket
> socket
,
61 MDnsConnection
* connection
);
65 void Send(const scoped_refptr
<IOBuffer
>& buffer
, unsigned size
);
69 void OnDatagramReceived(int rv
);
71 // Callback for when sending a query has finished.
72 void SendDone(int rv
);
74 scoped_ptr
<DatagramServerSocket
> socket_
;
75 MDnsConnection
* connection_
;
76 IPEndPoint recv_addr_
;
77 DnsResponse response_
;
78 IPEndPoint multicast_addr_
;
79 bool send_in_progress_
;
80 std::queue
<std::pair
<scoped_refptr
<IOBuffer
>, unsigned> > send_queue_
;
82 DISALLOW_COPY_AND_ASSIGN(SocketHandler
);
85 // Callback for handling a datagram being received on either ipv4 or ipv6.
86 void OnDatagramReceived(DnsResponse
* response
,
87 const IPEndPoint
& recv_addr
,
90 void PostOnError(SocketHandler
* loop
, int rv
);
93 // Only socket handlers which successfully bound and started are kept.
94 ScopedVector
<SocketHandler
> socket_handlers_
;
98 base::WeakPtrFactory
<MDnsConnection
> weak_ptr_factory_
;
100 DISALLOW_COPY_AND_ASSIGN(MDnsConnection
);
103 class MDnsListenerImpl
;
105 class NET_EXPORT_PRIVATE MDnsClientImpl
: public MDnsClient
{
107 // The core object exists while the MDnsClient is listening, and is deleted
108 // whenever the number of listeners reaches zero. The deletion happens
109 // asychronously, so destroying the last listener does not immediately
110 // invalidate the core.
111 class Core
: public base::SupportsWeakPtr
<Core
>, MDnsConnection::Delegate
{
113 explicit Core(MDnsClientImpl
* client
);
116 // Initialize the core. Returns true on success.
117 bool Init(MDnsSocketFactory
* socket_factory
);
119 // Send a query with a specific rrtype and name. Returns true on success.
120 bool SendQuery(uint16 rrtype
, std::string name
);
122 // Add/remove a listener to the list of listeners.
123 void AddListener(MDnsListenerImpl
* listener
);
124 void RemoveListener(MDnsListenerImpl
* listener
);
126 // Query the cache for records of a specific type and name.
127 void QueryCache(uint16 rrtype
, const std::string
& name
,
128 std::vector
<const RecordParsed
*>* records
) const;
130 // Parse the response and alert relevant listeners.
131 virtual void HandlePacket(DnsResponse
* response
, int bytes_read
) override
;
133 virtual void OnConnectionError(int error
) override
;
136 typedef std::pair
<std::string
, uint16
> ListenerKey
;
137 typedef std::map
<ListenerKey
, ObserverList
<MDnsListenerImpl
>* >
140 // Alert listeners of an update to the cache.
141 void AlertListeners(MDnsCache::UpdateType update_type
,
142 const ListenerKey
& key
, const RecordParsed
* record
);
144 // Schedule a cache cleanup to a specific time, cancelling other cleanups.
145 void ScheduleCleanup(base::Time cleanup
);
147 // Clean up the cache and schedule a new cleanup.
150 // Callback for when a record is removed from the cache.
151 void OnRecordRemoved(const RecordParsed
* record
);
153 void NotifyNsecRecord(const RecordParsed
* record
);
155 // Delete and erase the observer list for |key|. Only deletes the observer
157 void CleanupObserverList(const ListenerKey
& key
);
159 ListenerMap listeners_
;
161 MDnsClientImpl
* client_
;
164 base::CancelableClosure cleanup_callback_
;
165 base::Time scheduled_cleanup_
;
167 scoped_ptr
<MDnsConnection
> connection_
;
169 DISALLOW_COPY_AND_ASSIGN(Core
);
173 virtual ~MDnsClientImpl();
175 // MDnsClient implementation:
176 virtual scoped_ptr
<MDnsListener
> CreateListener(
178 const std::string
& name
,
179 MDnsListener::Delegate
* delegate
) override
;
181 virtual scoped_ptr
<MDnsTransaction
> CreateTransaction(
183 const std::string
& name
,
185 const MDnsTransaction::ResultCallback
& callback
) override
;
187 virtual bool StartListening(MDnsSocketFactory
* socket_factory
) override
;
188 virtual void StopListening() override
;
189 virtual bool IsListening() const override
;
191 Core
* core() { return core_
.get(); }
194 scoped_ptr
<Core
> core_
;
196 DISALLOW_COPY_AND_ASSIGN(MDnsClientImpl
);
199 class MDnsListenerImpl
: public MDnsListener
,
200 public base::SupportsWeakPtr
<MDnsListenerImpl
> {
202 MDnsListenerImpl(uint16 rrtype
,
203 const std::string
& name
,
204 MDnsListener::Delegate
* delegate
,
205 MDnsClientImpl
* client
);
207 virtual ~MDnsListenerImpl();
209 // MDnsListener implementation:
210 virtual bool Start() override
;
212 // Actively refresh any received records.
213 virtual void SetActiveRefresh(bool active_refresh
) override
;
215 virtual const std::string
& GetName() const override
;
217 virtual uint16
GetType() const override
;
219 MDnsListener::Delegate
* delegate() { return delegate_
; }
221 // Alert the delegate of a record update.
222 void HandleRecordUpdate(MDnsCache::UpdateType update_type
,
223 const RecordParsed
* record_parsed
);
225 // Alert the delegate of the existence of an Nsec record.
226 void AlertNsecRecord();
229 void ScheduleNextRefresh();
234 MDnsClientImpl
* client_
;
235 MDnsListener::Delegate
* delegate_
;
237 base::Time last_update_
;
240 bool active_refresh_
;
242 base::CancelableClosure next_refresh_
;
243 DISALLOW_COPY_AND_ASSIGN(MDnsListenerImpl
);
246 class MDnsTransactionImpl
: public base::SupportsWeakPtr
<MDnsTransactionImpl
>,
247 public MDnsTransaction
,
248 public MDnsListener::Delegate
{
250 MDnsTransactionImpl(uint16 rrtype
,
251 const std::string
& name
,
253 const MDnsTransaction::ResultCallback
& callback
,
254 MDnsClientImpl
* client
);
255 virtual ~MDnsTransactionImpl();
257 // MDnsTransaction implementation:
258 virtual bool Start() override
;
260 virtual const std::string
& GetName() const override
;
261 virtual uint16
GetType() const override
;
263 // MDnsListener::Delegate implementation:
264 virtual void OnRecordUpdate(MDnsListener::UpdateType update
,
265 const RecordParsed
* record
) override
;
266 virtual void OnNsecRecord(const std::string
& name
, unsigned type
) override
;
268 virtual void OnCachePurged() override
;
271 bool is_active() { return !callback_
.is_null(); }
275 // Trigger the callback and reset all related variables.
276 void TriggerCallback(MDnsTransaction::Result result
,
277 const RecordParsed
* record
);
279 // Internal callback for when a cache record is found.
280 void CacheRecordFound(const RecordParsed
* record
);
282 // Signal the transactionis over and release all related resources.
283 void SignalTransactionOver();
285 // Reads records from the cache and calls the callback for every
287 void ServeRecordsFromCache();
289 // Send a query to the network and set up a timeout to time out the
290 // transaction. Returns false if it fails to start listening on the network
291 // or if it fails to send a query.
292 bool QueryAndListen();
296 MDnsTransaction::ResultCallback callback_
;
298 scoped_ptr
<MDnsListener
> listener_
;
299 base::CancelableCallback
<void()> timeout_
;
301 MDnsClientImpl
* client_
;
306 DISALLOW_COPY_AND_ASSIGN(MDnsTransactionImpl
);
310 #endif // NET_DNS_MDNS_CLIENT_IMPL_H_