OLD | NEW |
| (Empty) |
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 Core(); | |
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 MDnsCache cache_; | |
161 | |
162 base::CancelableClosure cleanup_callback_; | |
163 base::Time scheduled_cleanup_; | |
164 | |
165 scoped_ptr<MDnsConnection> connection_; | |
166 | |
167 DISALLOW_COPY_AND_ASSIGN(Core); | |
168 }; | |
169 | |
170 MDnsClientImpl(); | |
171 ~MDnsClientImpl() override; | |
172 | |
173 // MDnsClient implementation: | |
174 scoped_ptr<MDnsListener> CreateListener( | |
175 uint16 rrtype, | |
176 const std::string& name, | |
177 MDnsListener::Delegate* delegate) override; | |
178 | |
179 scoped_ptr<MDnsTransaction> CreateTransaction( | |
180 uint16 rrtype, | |
181 const std::string& name, | |
182 int flags, | |
183 const MDnsTransaction::ResultCallback& callback) override; | |
184 | |
185 bool StartListening(MDnsSocketFactory* socket_factory) override; | |
186 void StopListening() override; | |
187 bool IsListening() const override; | |
188 | |
189 Core* core() { return core_.get(); } | |
190 | |
191 private: | |
192 scoped_ptr<Core> core_; | |
193 | |
194 DISALLOW_COPY_AND_ASSIGN(MDnsClientImpl); | |
195 }; | |
196 | |
197 class MDnsListenerImpl : public MDnsListener, | |
198 public base::SupportsWeakPtr<MDnsListenerImpl> { | |
199 public: | |
200 MDnsListenerImpl(uint16 rrtype, | |
201 const std::string& name, | |
202 MDnsListener::Delegate* delegate, | |
203 MDnsClientImpl* client); | |
204 | |
205 ~MDnsListenerImpl() override; | |
206 | |
207 // MDnsListener implementation: | |
208 bool Start() override; | |
209 | |
210 // Actively refresh any received records. | |
211 void SetActiveRefresh(bool active_refresh) override; | |
212 | |
213 const std::string& GetName() const override; | |
214 | |
215 uint16 GetType() const override; | |
216 | |
217 MDnsListener::Delegate* delegate() { return delegate_; } | |
218 | |
219 // Alert the delegate of a record update. | |
220 void HandleRecordUpdate(MDnsCache::UpdateType update_type, | |
221 const RecordParsed* record_parsed); | |
222 | |
223 // Alert the delegate of the existence of an Nsec record. | |
224 void AlertNsecRecord(); | |
225 | |
226 private: | |
227 void ScheduleNextRefresh(); | |
228 void DoRefresh(); | |
229 | |
230 uint16 rrtype_; | |
231 std::string name_; | |
232 MDnsClientImpl* client_; | |
233 MDnsListener::Delegate* delegate_; | |
234 | |
235 base::Time last_update_; | |
236 uint32 ttl_; | |
237 bool started_; | |
238 bool active_refresh_; | |
239 | |
240 base::CancelableClosure next_refresh_; | |
241 DISALLOW_COPY_AND_ASSIGN(MDnsListenerImpl); | |
242 }; | |
243 | |
244 class MDnsTransactionImpl : public base::SupportsWeakPtr<MDnsTransactionImpl>, | |
245 public MDnsTransaction, | |
246 public MDnsListener::Delegate { | |
247 public: | |
248 MDnsTransactionImpl(uint16 rrtype, | |
249 const std::string& name, | |
250 int flags, | |
251 const MDnsTransaction::ResultCallback& callback, | |
252 MDnsClientImpl* client); | |
253 ~MDnsTransactionImpl() override; | |
254 | |
255 // MDnsTransaction implementation: | |
256 bool Start() override; | |
257 | |
258 const std::string& GetName() const override; | |
259 uint16 GetType() const override; | |
260 | |
261 // MDnsListener::Delegate implementation: | |
262 void OnRecordUpdate(MDnsListener::UpdateType update, | |
263 const RecordParsed* record) override; | |
264 void OnNsecRecord(const std::string& name, unsigned type) override; | |
265 | |
266 void OnCachePurged() override; | |
267 | |
268 private: | |
269 bool is_active() { return !callback_.is_null(); } | |
270 | |
271 void Reset(); | |
272 | |
273 // Trigger the callback and reset all related variables. | |
274 void TriggerCallback(MDnsTransaction::Result result, | |
275 const RecordParsed* record); | |
276 | |
277 // Internal callback for when a cache record is found. | |
278 void CacheRecordFound(const RecordParsed* record); | |
279 | |
280 // Signal the transactionis over and release all related resources. | |
281 void SignalTransactionOver(); | |
282 | |
283 // Reads records from the cache and calls the callback for every | |
284 // record read. | |
285 void ServeRecordsFromCache(); | |
286 | |
287 // Send a query to the network and set up a timeout to time out the | |
288 // transaction. Returns false if it fails to start listening on the network | |
289 // or if it fails to send a query. | |
290 bool QueryAndListen(); | |
291 | |
292 uint16 rrtype_; | |
293 std::string name_; | |
294 MDnsTransaction::ResultCallback callback_; | |
295 | |
296 scoped_ptr<MDnsListener> listener_; | |
297 base::CancelableCallback<void()> timeout_; | |
298 | |
299 MDnsClientImpl* client_; | |
300 | |
301 bool started_; | |
302 int flags_; | |
303 | |
304 DISALLOW_COPY_AND_ASSIGN(MDnsTransactionImpl); | |
305 }; | |
306 | |
307 } // namespace net | |
308 #endif // NET_DNS_MDNS_CLIENT_IMPL_H_ | |
OLD | NEW |