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(MDnsListener::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::CancelableCallback
<void()> 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 virtual const std::string
& GetName() const OVERRIDE
;
209 virtual uint16
GetType() const OVERRIDE
;
211 MDnsListener::Delegate
* delegate() { return delegate_
; }
213 // Alert the delegate of a record update.
214 void AlertDelegate(MDnsListener::UpdateType update_type
,
215 const RecordParsed
* record_parsed
);
217 // Alert the delegate of the existence of an Nsec record.
218 void AlertNsecRecord();
223 MDnsClientImpl
* client_
;
224 MDnsListener::Delegate
* delegate_
;
227 DISALLOW_COPY_AND_ASSIGN(MDnsListenerImpl
);
230 class MDnsTransactionImpl
: public base::SupportsWeakPtr
<MDnsTransactionImpl
>,
231 public MDnsTransaction
,
232 public MDnsListener::Delegate
{
234 MDnsTransactionImpl(uint16 rrtype
,
235 const std::string
& name
,
237 const MDnsTransaction::ResultCallback
& callback
,
238 MDnsClientImpl
* client
);
239 virtual ~MDnsTransactionImpl();
241 // MDnsTransaction implementation:
242 virtual bool Start() OVERRIDE
;
244 virtual const std::string
& GetName() const OVERRIDE
;
245 virtual uint16
GetType() const OVERRIDE
;
247 // MDnsListener::Delegate implementation:
248 virtual void OnRecordUpdate(MDnsListener::UpdateType update
,
249 const RecordParsed
* record
) OVERRIDE
;
250 virtual void OnNsecRecord(const std::string
& name
, unsigned type
) OVERRIDE
;
252 virtual void OnCachePurged() OVERRIDE
;
255 bool is_active() { return !callback_
.is_null(); }
259 // Trigger the callback and reset all related variables.
260 void TriggerCallback(MDnsTransaction::Result result
,
261 const RecordParsed
* record
);
263 // Internal callback for when a cache record is found.
264 void CacheRecordFound(const RecordParsed
* record
);
266 // Signal the transactionis over and release all related resources.
267 void SignalTransactionOver();
269 // Reads records from the cache and calls the callback for every
271 void ServeRecordsFromCache();
273 // Send a query to the network and set up a timeout to time out the
274 // transaction. Returns false if it fails to start listening on the network
275 // or if it fails to send a query.
276 bool QueryAndListen();
280 MDnsTransaction::ResultCallback callback_
;
282 scoped_ptr
<MDnsListener
> listener_
;
283 base::CancelableCallback
<void()> timeout_
;
285 MDnsClientImpl
* client_
;
290 DISALLOW_COPY_AND_ASSIGN(MDnsTransactionImpl
);
294 #endif // NET_DNS_MDNS_CLIENT_IMPL_H_