Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / dns / mdns_client_impl.h
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.
4
5 #ifndef NET_DNS_MDNS_CLIENT_IMPL_H_
6 #define NET_DNS_MDNS_CLIENT_IMPL_H_
7
8 #include <map>
9 #include <string>
10 #include <utility>
11 #include <vector>
12
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"
23
24 namespace net {
25
26 class MDnsSocketFactoryImpl : public MDnsSocketFactory {
27  public:
28   MDnsSocketFactoryImpl() {};
29   ~MDnsSocketFactoryImpl() override{};
30
31   void CreateSockets(ScopedVector<DatagramServerSocket>* sockets) override;
32
33  private:
34   DISALLOW_COPY_AND_ASSIGN(MDnsSocketFactoryImpl);
35 };
36
37 // A connection to the network for multicast DNS clients. It reads data into
38 // DnsResponse objects and alerts the delegate that a packet has been received.
39 class NET_EXPORT_PRIVATE MDnsConnection {
40  public:
41   class Delegate {
42    public:
43     // Handle an mDNS packet buffered in |response| with a size of |bytes_read|.
44     virtual void HandlePacket(DnsResponse* response, int bytes_read) = 0;
45     virtual void OnConnectionError(int error) = 0;
46     virtual ~Delegate() {}
47   };
48
49   explicit MDnsConnection(MDnsConnection::Delegate* delegate);
50   virtual ~MDnsConnection();
51
52   // Both methods return true if at least one of the socket handlers succeeded.
53   bool Init(MDnsSocketFactory* socket_factory);
54   void Send(const scoped_refptr<IOBuffer>& buffer, unsigned size);
55
56  private:
57   class SocketHandler {
58    public:
59     SocketHandler(scoped_ptr<DatagramServerSocket> socket,
60                   MDnsConnection* connection);
61     ~SocketHandler();
62
63     int Start();
64     void Send(const scoped_refptr<IOBuffer>& buffer, unsigned size);
65
66    private:
67     int DoLoop(int rv);
68     void OnDatagramReceived(int rv);
69
70     // Callback for when sending a query has finished.
71     void SendDone(int rv);
72
73     scoped_ptr<DatagramServerSocket> socket_;
74     MDnsConnection* connection_;
75     IPEndPoint recv_addr_;
76     DnsResponse response_;
77     IPEndPoint multicast_addr_;
78     bool send_in_progress_;
79     std::queue<std::pair<scoped_refptr<IOBuffer>, unsigned> > send_queue_;
80
81     DISALLOW_COPY_AND_ASSIGN(SocketHandler);
82   };
83
84   // Callback for handling a datagram being received on either ipv4 or ipv6.
85   void OnDatagramReceived(DnsResponse* response,
86                           const IPEndPoint& recv_addr,
87                           int bytes_read);
88
89   void PostOnError(SocketHandler* loop, int rv);
90   void OnError(int rv);
91
92   // Only socket handlers which successfully bound and started are kept.
93   ScopedVector<SocketHandler> socket_handlers_;
94
95   Delegate* delegate_;
96
97   base::WeakPtrFactory<MDnsConnection> weak_ptr_factory_;
98
99   DISALLOW_COPY_AND_ASSIGN(MDnsConnection);
100 };
101
102 class MDnsListenerImpl;
103
104 class NET_EXPORT_PRIVATE MDnsClientImpl : public MDnsClient {
105  public:
106   // The core object exists while the MDnsClient is listening, and is deleted
107   // whenever the number of listeners reaches zero. The deletion happens
108   // asychronously, so destroying the last listener does not immediately
109   // invalidate the core.
110   class Core : public base::SupportsWeakPtr<Core>, MDnsConnection::Delegate {
111    public:
112     explicit Core(MDnsClientImpl* client);
113     ~Core() override;
114
115     // Initialize the core. Returns true on success.
116     bool Init(MDnsSocketFactory* socket_factory);
117
118     // Send a query with a specific rrtype and name. Returns true on success.
119     bool SendQuery(uint16 rrtype, std::string name);
120
121     // Add/remove a listener to the list of listeners.
122     void AddListener(MDnsListenerImpl* listener);
123     void RemoveListener(MDnsListenerImpl* listener);
124
125     // Query the cache for records of a specific type and name.
126     void QueryCache(uint16 rrtype, const std::string& name,
127                     std::vector<const RecordParsed*>* records) const;
128
129     // Parse the response and alert relevant listeners.
130     void HandlePacket(DnsResponse* response, int bytes_read) override;
131
132     void OnConnectionError(int error) override;
133
134    private:
135     typedef std::pair<std::string, uint16> ListenerKey;
136     typedef std::map<ListenerKey, ObserverList<MDnsListenerImpl>* >
137     ListenerMap;
138
139     // Alert listeners of an update to the cache.
140     void AlertListeners(MDnsCache::UpdateType update_type,
141                         const ListenerKey& key, const RecordParsed* record);
142
143     // Schedule a cache cleanup to a specific time, cancelling other cleanups.
144     void ScheduleCleanup(base::Time cleanup);
145
146     // Clean up the cache and schedule a new cleanup.
147     void DoCleanup();
148
149     // Callback for when a record is removed from the cache.
150     void OnRecordRemoved(const RecordParsed* record);
151
152     void NotifyNsecRecord(const RecordParsed* record);
153
154     // Delete and erase the observer list for |key|. Only deletes the observer
155     // list if is empty.
156     void CleanupObserverList(const ListenerKey& key);
157
158     ListenerMap listeners_;
159
160     MDnsClientImpl* client_;
161     MDnsCache cache_;
162
163     base::CancelableClosure cleanup_callback_;
164     base::Time scheduled_cleanup_;
165
166     scoped_ptr<MDnsConnection> connection_;
167
168     DISALLOW_COPY_AND_ASSIGN(Core);
169   };
170
171   MDnsClientImpl();
172   ~MDnsClientImpl() override;
173
174   // MDnsClient implementation:
175   scoped_ptr<MDnsListener> CreateListener(
176       uint16 rrtype,
177       const std::string& name,
178       MDnsListener::Delegate* delegate) override;
179
180   scoped_ptr<MDnsTransaction> CreateTransaction(
181       uint16 rrtype,
182       const std::string& name,
183       int flags,
184       const MDnsTransaction::ResultCallback& callback) override;
185
186   bool StartListening(MDnsSocketFactory* socket_factory) override;
187   void StopListening() override;
188   bool IsListening() const override;
189
190   Core* core() { return core_.get(); }
191
192  private:
193   scoped_ptr<Core> core_;
194
195   DISALLOW_COPY_AND_ASSIGN(MDnsClientImpl);
196 };
197
198 class MDnsListenerImpl : public MDnsListener,
199                          public base::SupportsWeakPtr<MDnsListenerImpl> {
200  public:
201   MDnsListenerImpl(uint16 rrtype,
202                    const std::string& name,
203                    MDnsListener::Delegate* delegate,
204                    MDnsClientImpl* client);
205
206   ~MDnsListenerImpl() override;
207
208   // MDnsListener implementation:
209   bool Start() override;
210
211   // Actively refresh any received records.
212   void SetActiveRefresh(bool active_refresh) override;
213
214   const std::string& GetName() const override;
215
216   uint16 GetType() const override;
217
218   MDnsListener::Delegate* delegate() { return delegate_; }
219
220   // Alert the delegate of a record update.
221   void HandleRecordUpdate(MDnsCache::UpdateType update_type,
222                           const RecordParsed* record_parsed);
223
224   // Alert the delegate of the existence of an Nsec record.
225   void AlertNsecRecord();
226
227  private:
228   void ScheduleNextRefresh();
229   void DoRefresh();
230
231   uint16 rrtype_;
232   std::string name_;
233   MDnsClientImpl* client_;
234   MDnsListener::Delegate* delegate_;
235
236   base::Time last_update_;
237   uint32 ttl_;
238   bool started_;
239   bool active_refresh_;
240
241   base::CancelableClosure next_refresh_;
242   DISALLOW_COPY_AND_ASSIGN(MDnsListenerImpl);
243 };
244
245 class MDnsTransactionImpl : public base::SupportsWeakPtr<MDnsTransactionImpl>,
246                             public MDnsTransaction,
247                             public MDnsListener::Delegate {
248  public:
249   MDnsTransactionImpl(uint16 rrtype,
250                       const std::string& name,
251                       int flags,
252                       const MDnsTransaction::ResultCallback& callback,
253                       MDnsClientImpl* client);
254   ~MDnsTransactionImpl() override;
255
256   // MDnsTransaction implementation:
257   bool Start() override;
258
259   const std::string& GetName() const override;
260   uint16 GetType() const override;
261
262   // MDnsListener::Delegate implementation:
263   void OnRecordUpdate(MDnsListener::UpdateType update,
264                       const RecordParsed* record) override;
265   void OnNsecRecord(const std::string& name, unsigned type) override;
266
267   void OnCachePurged() override;
268
269  private:
270   bool is_active() { return !callback_.is_null(); }
271
272   void Reset();
273
274   // Trigger the callback and reset all related variables.
275   void TriggerCallback(MDnsTransaction::Result result,
276                        const RecordParsed* record);
277
278   // Internal callback for when a cache record is found.
279   void CacheRecordFound(const RecordParsed* record);
280
281   // Signal the transactionis over and release all related resources.
282   void SignalTransactionOver();
283
284   // Reads records from the cache and calls the callback for every
285   // record read.
286   void ServeRecordsFromCache();
287
288   // Send a query to the network and set up a timeout to time out the
289   // transaction. Returns false if it fails to start listening on the network
290   // or if it fails to send a query.
291   bool QueryAndListen();
292
293   uint16 rrtype_;
294   std::string name_;
295   MDnsTransaction::ResultCallback callback_;
296
297   scoped_ptr<MDnsListener> listener_;
298   base::CancelableCallback<void()> timeout_;
299
300   MDnsClientImpl* client_;
301
302   bool started_;
303   int flags_;
304
305   DISALLOW_COPY_AND_ASSIGN(MDnsTransactionImpl);
306 };
307
308 }  // namespace net
309 #endif  // NET_DNS_MDNS_CLIENT_IMPL_H_