Chromecast: adds class to help record complex histograms.
[chromium-blink-merge.git] / net / dns / mdns_client_impl.h
blobb6f8b934c9352ee9066a6586379dee9f37138a04
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_
8 #include <map>
9 #include <string>
10 #include <utility>
11 #include <vector>
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"
24 namespace net {
26 class MDnsSocketFactoryImpl : public MDnsSocketFactory {
27 public:
28 MDnsSocketFactoryImpl() {};
29 virtual ~MDnsSocketFactoryImpl() {};
31 virtual void CreateSockets(
32 ScopedVector<DatagramServerSocket>* sockets) override;
34 private:
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 {
41 public:
42 class Delegate {
43 public:
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);
57 private:
58 class SocketHandler {
59 public:
60 SocketHandler(scoped_ptr<DatagramServerSocket> socket,
61 MDnsConnection* connection);
62 ~SocketHandler();
64 int Start();
65 void Send(const scoped_refptr<IOBuffer>& buffer, unsigned size);
67 private:
68 int DoLoop(int rv);
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,
88 int bytes_read);
90 void PostOnError(SocketHandler* loop, int rv);
91 void OnError(int rv);
93 // Only socket handlers which successfully bound and started are kept.
94 ScopedVector<SocketHandler> socket_handlers_;
96 Delegate* delegate_;
98 base::WeakPtrFactory<MDnsConnection> weak_ptr_factory_;
100 DISALLOW_COPY_AND_ASSIGN(MDnsConnection);
103 class MDnsListenerImpl;
105 class NET_EXPORT_PRIVATE MDnsClientImpl : public MDnsClient {
106 public:
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 {
112 public:
113 explicit Core(MDnsClientImpl* client);
114 virtual ~Core();
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;
135 private:
136 typedef std::pair<std::string, uint16> ListenerKey;
137 typedef std::map<ListenerKey, ObserverList<MDnsListenerImpl>* >
138 ListenerMap;
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.
148 void DoCleanup();
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
156 // list if is empty.
157 void CleanupObserverList(const ListenerKey& key);
159 ListenerMap listeners_;
161 MDnsClientImpl* client_;
162 MDnsCache cache_;
164 base::CancelableClosure cleanup_callback_;
165 base::Time scheduled_cleanup_;
167 scoped_ptr<MDnsConnection> connection_;
169 DISALLOW_COPY_AND_ASSIGN(Core);
172 MDnsClientImpl();
173 virtual ~MDnsClientImpl();
175 // MDnsClient implementation:
176 virtual scoped_ptr<MDnsListener> CreateListener(
177 uint16 rrtype,
178 const std::string& name,
179 MDnsListener::Delegate* delegate) override;
181 virtual scoped_ptr<MDnsTransaction> CreateTransaction(
182 uint16 rrtype,
183 const std::string& name,
184 int flags,
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(); }
193 private:
194 scoped_ptr<Core> core_;
196 DISALLOW_COPY_AND_ASSIGN(MDnsClientImpl);
199 class MDnsListenerImpl : public MDnsListener,
200 public base::SupportsWeakPtr<MDnsListenerImpl> {
201 public:
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();
228 private:
229 void ScheduleNextRefresh();
230 void DoRefresh();
232 uint16 rrtype_;
233 std::string name_;
234 MDnsClientImpl* client_;
235 MDnsListener::Delegate* delegate_;
237 base::Time last_update_;
238 uint32 ttl_;
239 bool started_;
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 {
249 public:
250 MDnsTransactionImpl(uint16 rrtype,
251 const std::string& name,
252 int flags,
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;
270 private:
271 bool is_active() { return !callback_.is_null(); }
273 void Reset();
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
286 // record read.
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();
294 uint16 rrtype_;
295 std::string name_;
296 MDnsTransaction::ResultCallback callback_;
298 scoped_ptr<MDnsListener> listener_;
299 base::CancelableCallback<void()> timeout_;
301 MDnsClientImpl* client_;
303 bool started_;
304 int flags_;
306 DISALLOW_COPY_AND_ASSIGN(MDnsTransactionImpl);
309 } // namespace net
310 #endif // NET_DNS_MDNS_CLIENT_IMPL_H_