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 bool Send(IOBuffer
* buffer
, unsigned size
);
60 SocketHandler(scoped_ptr
<DatagramServerSocket
> socket
,
61 MDnsConnection
* connection
);
65 int Send(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_
;
80 DISALLOW_COPY_AND_ASSIGN(SocketHandler
);
83 // Callback for handling a datagram being received on either ipv4 or ipv6.
84 void OnDatagramReceived(DnsResponse
* response
,
85 const IPEndPoint
& recv_addr
,
88 void OnError(SocketHandler
* loop
, int error
);
90 // Only socket handlers which successfully bound and started are kept.
91 ScopedVector
<SocketHandler
> socket_handlers_
;
95 DISALLOW_COPY_AND_ASSIGN(MDnsConnection
);
98 class MDnsListenerImpl
;
100 class NET_EXPORT_PRIVATE MDnsClientImpl
: public MDnsClient
{
102 // The core object exists while the MDnsClient is listening, and is deleted
103 // whenever the number of listeners reaches zero. The deletion happens
104 // asychronously, so destroying the last listener does not immediately
105 // invalidate the core.
106 class Core
: public base::SupportsWeakPtr
<Core
>, MDnsConnection::Delegate
{
108 explicit Core(MDnsClientImpl
* client
);
111 // Initialize the core. Returns true on success.
112 bool Init(MDnsSocketFactory
* socket_factory
);
114 // Send a query with a specific rrtype and name. Returns true on success.
115 bool SendQuery(uint16 rrtype
, std::string name
);
117 // Add/remove a listener to the list of listeners.
118 void AddListener(MDnsListenerImpl
* listener
);
119 void RemoveListener(MDnsListenerImpl
* listener
);
121 // Query the cache for records of a specific type and name.
122 void QueryCache(uint16 rrtype
, const std::string
& name
,
123 std::vector
<const RecordParsed
*>* records
) const;
125 // Parse the response and alert relevant listeners.
126 virtual void HandlePacket(DnsResponse
* response
, int bytes_read
) OVERRIDE
;
128 virtual void OnConnectionError(int error
) OVERRIDE
;
131 typedef std::pair
<std::string
, uint16
> ListenerKey
;
132 typedef std::map
<ListenerKey
, ObserverList
<MDnsListenerImpl
>* >
135 // Alert listeners of an update to the cache.
136 void AlertListeners(MDnsCache::UpdateType update_type
,
137 const ListenerKey
& key
, const RecordParsed
* record
);
139 // Schedule a cache cleanup to a specific time, cancelling other cleanups.
140 void ScheduleCleanup(base::Time cleanup
);
142 // Clean up the cache and schedule a new cleanup.
145 // Callback for when a record is removed from the cache.
146 void OnRecordRemoved(const RecordParsed
* record
);
148 void NotifyNsecRecord(const RecordParsed
* record
);
150 // Delete and erase the observer list for |key|. Only deletes the observer
152 void CleanupObserverList(const ListenerKey
& key
);
154 ListenerMap listeners_
;
156 MDnsClientImpl
* client_
;
159 base::CancelableClosure cleanup_callback_
;
160 base::Time scheduled_cleanup_
;
162 scoped_ptr
<MDnsConnection
> connection_
;
164 DISALLOW_COPY_AND_ASSIGN(Core
);
168 virtual ~MDnsClientImpl();
170 // MDnsClient implementation:
171 virtual scoped_ptr
<MDnsListener
> CreateListener(
173 const std::string
& name
,
174 MDnsListener::Delegate
* delegate
) OVERRIDE
;
176 virtual scoped_ptr
<MDnsTransaction
> CreateTransaction(
178 const std::string
& name
,
180 const MDnsTransaction::ResultCallback
& callback
) OVERRIDE
;
182 virtual bool StartListening(MDnsSocketFactory
* socket_factory
) OVERRIDE
;
183 virtual void StopListening() OVERRIDE
;
184 virtual bool IsListening() const OVERRIDE
;
186 Core
* core() { return core_
.get(); }
189 scoped_ptr
<Core
> core_
;
191 DISALLOW_COPY_AND_ASSIGN(MDnsClientImpl
);
194 class MDnsListenerImpl
: public MDnsListener
,
195 public base::SupportsWeakPtr
<MDnsListenerImpl
> {
197 MDnsListenerImpl(uint16 rrtype
,
198 const std::string
& name
,
199 MDnsListener::Delegate
* delegate
,
200 MDnsClientImpl
* client
);
202 virtual ~MDnsListenerImpl();
204 // MDnsListener implementation:
205 virtual bool Start() OVERRIDE
;
207 // Actively refresh any received records.
208 virtual void SetActiveRefresh(bool active_refresh
) OVERRIDE
;
210 virtual const std::string
& GetName() const OVERRIDE
;
212 virtual uint16
GetType() const OVERRIDE
;
214 MDnsListener::Delegate
* delegate() { return delegate_
; }
216 // Alert the delegate of a record update.
217 void HandleRecordUpdate(MDnsCache::UpdateType update_type
,
218 const RecordParsed
* record_parsed
);
220 // Alert the delegate of the existence of an Nsec record.
221 void AlertNsecRecord();
224 void ScheduleNextRefresh();
229 MDnsClientImpl
* client_
;
230 MDnsListener::Delegate
* delegate_
;
232 base::Time last_update_
;
235 bool active_refresh_
;
237 base::CancelableClosure next_refresh_
;
238 DISALLOW_COPY_AND_ASSIGN(MDnsListenerImpl
);
241 class MDnsTransactionImpl
: public base::SupportsWeakPtr
<MDnsTransactionImpl
>,
242 public MDnsTransaction
,
243 public MDnsListener::Delegate
{
245 MDnsTransactionImpl(uint16 rrtype
,
246 const std::string
& name
,
248 const MDnsTransaction::ResultCallback
& callback
,
249 MDnsClientImpl
* client
);
250 virtual ~MDnsTransactionImpl();
252 // MDnsTransaction implementation:
253 virtual bool Start() OVERRIDE
;
255 virtual const std::string
& GetName() const OVERRIDE
;
256 virtual uint16
GetType() const OVERRIDE
;
258 // MDnsListener::Delegate implementation:
259 virtual void OnRecordUpdate(MDnsListener::UpdateType update
,
260 const RecordParsed
* record
) OVERRIDE
;
261 virtual void OnNsecRecord(const std::string
& name
, unsigned type
) OVERRIDE
;
263 virtual void OnCachePurged() OVERRIDE
;
266 bool is_active() { return !callback_
.is_null(); }
270 // Trigger the callback and reset all related variables.
271 void TriggerCallback(MDnsTransaction::Result result
,
272 const RecordParsed
* record
);
274 // Internal callback for when a cache record is found.
275 void CacheRecordFound(const RecordParsed
* record
);
277 // Signal the transactionis over and release all related resources.
278 void SignalTransactionOver();
280 // Reads records from the cache and calls the callback for every
282 void ServeRecordsFromCache();
284 // Send a query to the network and set up a timeout to time out the
285 // transaction. Returns false if it fails to start listening on the network
286 // or if it fails to send a query.
287 bool QueryAndListen();
291 MDnsTransaction::ResultCallback callback_
;
293 scoped_ptr
<MDnsListener
> listener_
;
294 base::CancelableCallback
<void()> timeout_
;
296 MDnsClientImpl
* client_
;
301 DISALLOW_COPY_AND_ASSIGN(MDnsTransactionImpl
);
305 #endif // NET_DNS_MDNS_CLIENT_IMPL_H_