OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 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/observer_list.h" | |
15 #include "net/base/io_buffer.h" | |
16 #include "net/base/ip_endpoint.h" | |
17 #include "net/dns/mdns_cache.h" | |
18 #include "net/dns/mdns_client.h" | |
19 #include "net/udp/datagram_server_socket.h" | |
20 #include "net/udp/udp_server_socket.h" | |
21 #include "net/udp/udp_socket.h" | |
22 | |
23 | |
24 namespace net { | |
25 | |
26 class MDnsListenerImpl; | |
27 | |
28 // A connection to the network for multicast DNS clients. It reads data into | |
29 // DnsResponse objects and alerts the delegate that a packet has been received. | |
30 class MDnsConnection { | |
31 public: | |
32 class Delegate { | |
33 public: | |
34 // Handle an mDNS packet buffered in |response| with a size of |bytes_read|. | |
35 virtual void HandlePacket(DnsResponse* response, int bytes_read) = 0; | |
36 virtual void OnConnectionError(int error) = 0; | |
37 virtual ~Delegate() {} | |
38 }; | |
39 | |
40 // Start the connection. Will begin alerting the delegate of packets. | |
41 // Returns a net error code. | |
42 virtual int Init() = 0; | |
43 | |
44 // Send a packet on both ipv4 and ipv6. Returns a net error code. | |
45 virtual int Send(IOBuffer* buffer, unsigned size) = 0; | |
46 virtual ~MDnsConnection() {} | |
47 }; | |
48 | |
49 class MDnsConnectionFactory { | |
50 public: | |
51 virtual scoped_ptr<MDnsConnection> CreateConnection( | |
52 MDnsConnection::Delegate* delegate) = 0; | |
53 | |
54 virtual ~MDnsConnectionFactory() {} | |
55 }; | |
56 | |
57 class MDnsClientImpl : public MDnsClient { | |
58 public: | |
59 // The core object exists while the MDnsClient is listening for MDnsPackets, | |
60 // and is deleted whenever the number of references for listening reachers | |
szym
2013/06/10 21:58:29
nit: "reaches"
Suggest: "whenever the number of l
Noam Samuel
2013/06/11 20:35:03
Done.
| |
61 // zero. The message loop may hold weak pointers to it in order to ensure | |
62 // tasks scheduled on it are not delivered after it is destroyed. | |
szym
2013/06/10 21:58:29
The last sentence does not seem to be adding much.
Noam Samuel
2013/06/11 20:35:03
Done.
| |
63 class Core : public base::SupportsWeakPtr<Core>, MDnsConnection::Delegate { | |
64 public: | |
65 Core(MDnsClientImpl* client, | |
66 MDnsConnectionFactory* connection_factory); | |
67 virtual ~Core(); | |
68 | |
69 // Initialize the core. Returns true on success. | |
70 bool Init(); | |
71 | |
72 // Send a query with a specific rrtype and name. Returns true on success. | |
73 bool SendQuery(uint16 rrtype, std::string name); | |
74 | |
75 // Add/remove a listener to the list of listener. May cause network traffic | |
76 // if listener is active. | |
77 void AddListener(MDnsListenerImpl* listener); | |
78 void RemoveListener(MDnsListenerImpl* listener); | |
79 | |
80 // Query the cache for records of a specific type and name. | |
81 void QueryCache(uint16 rrtype, const std::string& name, | |
82 std::vector<const RecordParsed*>* records) const; | |
83 | |
84 // Parse the response and alert relevant listeners. | |
85 virtual void HandlePacket(DnsResponse* response, int bytes_read) OVERRIDE; | |
86 | |
87 virtual void OnConnectionError(int error) OVERRIDE; | |
88 | |
89 private: | |
90 typedef std::pair<uint16, std::string> ListenerKey; | |
91 typedef std::map<ListenerKey, ObserverList<MDnsListenerImpl>* > | |
92 ListenerMap; | |
93 | |
94 // Alert listeners of an update to the cache. | |
95 void AlertListeners(MDnsUpdateType update_type, | |
96 const ListenerKey& key, const RecordParsed* record); | |
97 | |
98 // Schedule a cleanup to a specific time, cancelling other cleanups. | |
99 void ScheduleCleanup(base::Time cleanup); | |
100 | |
101 // Clean up the cache and schedule a new cleanup. | |
102 void DoCleanup(); | |
103 | |
104 // Callback for when a record is removed from the cache. | |
105 void OnRecordRemoved(const RecordParsed* record); | |
106 | |
107 ListenerMap listeners_; | |
108 | |
109 MDnsClientImpl* client_; | |
110 MDnsCache cache_; | |
111 | |
112 base::CancelableCallback<void()> cleanup_callback_; | |
113 base::Time scheduled_cleanup_; | |
114 | |
115 scoped_ptr<MDnsConnection> connection_; | |
116 | |
117 DISALLOW_COPY_AND_ASSIGN(Core); | |
118 }; | |
119 | |
120 MDnsClientImpl(); | |
121 | |
122 // Used only for testing. Lets users of this class decouple it from time | |
123 // dependence and network dependence. | |
124 explicit MDnsClientImpl(MDnsConnectionFactory* connection_factory); | |
szym
2013/06/10 21:58:29
I suggest always passing the factory into the cons
Noam Samuel
2013/06/11 20:35:03
Done.
| |
125 virtual ~MDnsClientImpl(); | |
126 | |
127 // MDnsClient implementation: | |
128 virtual scoped_ptr<MDnsListener> CreateListener( | |
129 uint16 rrtype, | |
130 const std::string& name, | |
131 MDnsListener::Delegate* delegate) OVERRIDE; | |
132 | |
133 virtual scoped_ptr<MDnsTransaction> CreateTransaction( | |
134 uint16 rrtype, | |
135 const std::string& name, | |
136 int flags, | |
137 const MDnsTransaction::ResultCallback& callback) OVERRIDE; | |
138 | |
139 | |
140 // Functions for testing only. | |
141 bool IsListeningForTests(); | |
142 | |
143 bool AddListenRef(); | |
144 void SubtractListenRef(); | |
145 | |
146 Core* core() { return core_.get(); } | |
147 | |
148 private: | |
149 void Shutdown(); | |
150 | |
151 scoped_ptr<Core> core_; | |
152 int listen_refs_; | |
153 | |
154 // Since we can either own or not own the connection_factory, use a scoped_ptr | |
155 // and a ptr. | |
156 scoped_ptr<MDnsConnectionFactory> connection_factory_owned_; | |
157 MDnsConnectionFactory* connection_factory_; | |
szym
2013/06/10 21:58:29
I suggest it should always own it. Whenever a situ
Noam Samuel
2013/06/11 20:35:03
Done.
| |
158 | |
159 DISALLOW_COPY_AND_ASSIGN(MDnsClientImpl); | |
160 }; | |
161 | |
162 class MDnsListenerImpl : public MDnsListener, | |
163 public base::SupportsWeakPtr<MDnsListenerImpl> { | |
164 public: | |
165 MDnsListenerImpl(uint16 rrtype, | |
166 const std::string& name, | |
167 MDnsListener::Delegate* delegate, | |
168 MDnsClientImpl* client); | |
169 | |
170 virtual ~MDnsListenerImpl(); | |
171 | |
172 // MDnsListener implementation: | |
173 virtual bool Start() OVERRIDE; | |
174 | |
175 virtual const std::string& GetName() const OVERRIDE; | |
176 | |
177 virtual uint16 GetType() const OVERRIDE; | |
178 | |
179 MDnsListener::Delegate* delegate() { return delegate_; } | |
180 | |
181 // Alert the delegate of a record update. | |
182 void AlertDelegate(MDnsUpdateType update_type, | |
183 const RecordParsed* record_parsed); | |
184 private: | |
185 uint16 rrtype_; | |
186 std::string name_; | |
187 MDnsClientImpl* client_; | |
188 MDnsListener::Delegate* delegate_; | |
189 | |
190 bool started_; | |
191 DISALLOW_COPY_AND_ASSIGN(MDnsListenerImpl); | |
192 }; | |
193 | |
194 class MDnsTransactionImpl : public base::SupportsWeakPtr<MDnsTransactionImpl>, | |
195 public MDnsTransaction, | |
196 public MDnsListener::Delegate { | |
197 public: | |
198 MDnsTransactionImpl(uint16 rrtype, | |
199 const std::string& name, | |
200 int flags, | |
201 const MDnsTransaction::ResultCallback& callback, | |
202 MDnsClientImpl* client); | |
203 virtual ~MDnsTransactionImpl(); | |
204 | |
205 // MDnsTransaction implementation: | |
206 virtual bool Start() OVERRIDE; | |
207 | |
208 virtual const std::string& GetName() const OVERRIDE; | |
209 virtual uint16 GetType() const OVERRIDE; | |
210 | |
211 // MDnsListener::Delegate implementation: | |
212 virtual void OnRecordUpdate(MDnsUpdateType update, | |
213 const RecordParsed* record) OVERRIDE; | |
214 virtual void OnNsecRecord(const std::string& name, unsigned type) OVERRIDE; | |
215 | |
216 virtual void OnCachePurged() OVERRIDE; | |
217 | |
218 bool is_active() { return !callback_.is_null(); } | |
219 | |
220 void Reset(); | |
221 | |
222 private: | |
223 // Trigger the callback and reset all related variables. | |
224 void TriggerCallback(MDnsTransactionResult result, | |
225 const RecordParsed* record); | |
226 | |
227 // Internal callback for when a cache record is found. | |
228 void CacheRecordFound(const RecordParsed* record); | |
229 | |
230 // Signal the transactionis over and release all related resources. | |
231 void SignalTransactionOver(); | |
232 | |
233 uint16 rrtype_; | |
234 std::string name_; | |
235 MDnsTransaction::ResultCallback callback_; | |
236 | |
237 scoped_ptr<MDnsListener> listener_; | |
238 base::CancelableCallback<void()> timeout_; | |
239 | |
240 MDnsClientImpl* client_; | |
241 | |
242 bool started_; | |
243 int flags_; | |
244 | |
245 DISALLOW_COPY_AND_ASSIGN(MDnsTransactionImpl); | |
246 }; | |
247 | |
248 // This implementation of MDnsConnection handles connecting to both IPv4 and | |
249 // IPv6. | |
250 class MDnsConnectionImpl : public MDnsConnection { | |
251 public: | |
252 explicit MDnsConnectionImpl(MDnsConnection::Delegate* delegate); | |
253 MDnsConnectionImpl(DatagramServerSocket* socket_ipv4, | |
254 DatagramServerSocket* socket_ipv6, | |
255 MDnsConnection::Delegate* delegate); | |
256 | |
257 virtual ~MDnsConnectionImpl(); | |
258 | |
259 virtual int Init() OVERRIDE; | |
260 virtual int Send(IOBuffer* buffer, unsigned size) OVERRIDE; | |
261 | |
262 private: | |
263 class SocketHandler { | |
264 public: | |
265 // Pass the socket in. Used for testing. | |
266 SocketHandler(DatagramServerSocket* socket, MDnsConnectionImpl* connection, | |
267 const IPEndPoint& multicast_addr); | |
268 SocketHandler(MDnsConnectionImpl* connection, | |
269 const IPEndPoint& multicast_addr); | |
270 ~SocketHandler(); | |
271 int DoLoop(int rv); | |
272 int Start(); | |
273 | |
274 int Send(IOBuffer* buffer, unsigned size); | |
275 | |
276 private: | |
277 int BindSocket(); | |
278 void OnDatagramReceived(int rv); | |
279 | |
280 // Callback for when sending a query has finished. | |
281 void SendDone(int sent); | |
282 | |
283 scoped_ptr<DatagramServerSocket> socket_owned_; | |
284 DatagramServerSocket* socket_; | |
285 | |
286 MDnsConnectionImpl* connection_; | |
287 IPEndPoint recv_addr_; | |
288 scoped_ptr<DnsResponse> response_; | |
289 IPEndPoint multicast_addr_; | |
290 }; | |
291 | |
292 // Callback for handling a datagram being recieved on either ipv4 or ipv6. | |
szym
2013/06/10 21:58:29
nit: "received"
Noam Samuel
2013/06/11 20:35:03
Done.
| |
293 // Responsible for ensuring we request another packet from the network. | |
szym
2013/06/10 21:58:29
This sentence is obsolete.
Noam Samuel
2013/06/11 20:35:03
Done.
| |
294 void OnDatagramReceived(DatagramServerSocket* socket, | |
295 DnsResponse* response, | |
296 IPEndPoint* recv_addr, | |
297 int bytes_read); | |
298 | |
299 void OnError(SocketHandler* loop, int error); | |
300 | |
301 IPEndPoint GetIPEndPoint(const char* address, int port); | |
302 | |
303 SocketHandler socket_handler_ipv4_; | |
304 SocketHandler socket_handler_ipv6_; | |
305 | |
306 MDnsConnection::Delegate* delegate_; | |
307 | |
308 DISALLOW_COPY_AND_ASSIGN(MDnsConnectionImpl); | |
309 }; | |
310 | |
311 class MDnsConnectionImplFactory : public MDnsConnectionFactory { | |
312 public: | |
313 MDnsConnectionImplFactory(); | |
314 virtual ~MDnsConnectionImplFactory(); | |
315 | |
316 virtual scoped_ptr<MDnsConnection> CreateConnection( | |
317 MDnsConnection::Delegate* delegate) OVERRIDE; | |
318 | |
319 private: | |
320 DISALLOW_COPY_AND_ASSIGN(MDnsConnectionImplFactory); | |
321 }; | |
322 | |
323 } | |
324 #endif // NET_DNS_MDNS_CLIENT_IMPL_H_ | |
OLD | NEW |