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 namespace net { |
| 24 |
| 25 // A connection to the network for multicast DNS clients. It reads data into |
| 26 // DnsResponse objects and alerts the delegate that a packet has been received. |
| 27 class MDnsConnection { |
| 28 public: |
| 29 class SocketFactory { |
| 30 public: |
| 31 virtual ~SocketFactory() {} |
| 32 |
| 33 virtual scoped_ptr<DatagramServerSocket> CreateSocket() = 0; |
| 34 |
| 35 static scoped_ptr<SocketFactory> CreateDefault(); |
| 36 }; |
| 37 |
| 38 class Delegate { |
| 39 public: |
| 40 // Handle an mDNS packet buffered in |response| with a size of |bytes_read|. |
| 41 virtual void HandlePacket(DnsResponse* response, int bytes_read) = 0; |
| 42 virtual void OnConnectionError(int error) = 0; |
| 43 virtual ~Delegate() {} |
| 44 }; |
| 45 |
| 46 explicit MDnsConnection(SocketFactory* socket_factory, |
| 47 MDnsConnection::Delegate* delegate); |
| 48 |
| 49 virtual ~MDnsConnection(); |
| 50 |
| 51 int Init(); |
| 52 int Send(IOBuffer* buffer, unsigned size); |
| 53 |
| 54 private: |
| 55 class SocketHandler { |
| 56 public: |
| 57 SocketHandler(MDnsConnection* connection, |
| 58 const IPEndPoint& multicast_addr, |
| 59 SocketFactory* socket_factory); |
| 60 ~SocketHandler(); |
| 61 int DoLoop(int rv); |
| 62 int Start(); |
| 63 |
| 64 int Send(IOBuffer* buffer, unsigned size); |
| 65 |
| 66 private: |
| 67 int BindSocket(); |
| 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 |
| 75 MDnsConnection* connection_; |
| 76 IPEndPoint recv_addr_; |
| 77 scoped_ptr<DnsResponse> response_; |
| 78 IPEndPoint multicast_addr_; |
| 79 }; |
| 80 |
| 81 // Callback for handling a datagram being received on either ipv4 or ipv6. |
| 82 void OnDatagramReceived(DnsResponse* response, |
| 83 const IPEndPoint& recv_addr, |
| 84 int bytes_read); |
| 85 |
| 86 void OnError(SocketHandler* loop, int error); |
| 87 |
| 88 IPEndPoint GetMDnsIPEndPoint(const char* address); |
| 89 |
| 90 SocketHandler socket_handler_ipv4_; |
| 91 SocketHandler socket_handler_ipv6_; |
| 92 |
| 93 Delegate* delegate_; |
| 94 |
| 95 DISALLOW_COPY_AND_ASSIGN(MDnsConnection); |
| 96 }; |
| 97 |
| 98 class MDnsListenerImpl; |
| 99 |
| 100 class MDnsClientImpl : public MDnsClient { |
| 101 public: |
| 102 // The core object exists while the MDnsClient is listening, and is |
| 103 // deleted whenever the number of listeners reaches zero. |
| 104 class Core : public base::SupportsWeakPtr<Core>, MDnsConnection::Delegate { |
| 105 public: |
| 106 Core(MDnsClientImpl* client, |
| 107 MDnsConnection::SocketFactory* socket_factory); |
| 108 virtual ~Core(); |
| 109 |
| 110 // Initialize the core. Returns true on success. |
| 111 bool Init(); |
| 112 |
| 113 // Send a query with a specific rrtype and name. Returns true on success. |
| 114 bool SendQuery(uint16 rrtype, std::string name); |
| 115 |
| 116 // Add/remove a listener to the list of listener. May cause network traffic |
| 117 // if listener is active. |
| 118 void AddListener(MDnsListenerImpl* listener); |
| 119 void RemoveListener(MDnsListenerImpl* listener); |
| 120 |
| 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; |
| 124 |
| 125 // Parse the response and alert relevant listeners. |
| 126 virtual void HandlePacket(DnsResponse* response, int bytes_read) OVERRIDE; |
| 127 |
| 128 virtual void OnConnectionError(int error) OVERRIDE; |
| 129 |
| 130 private: |
| 131 typedef std::pair<uint16, std::string> ListenerKey; |
| 132 typedef std::map<ListenerKey, ObserverList<MDnsListenerImpl>* > |
| 133 ListenerMap; |
| 134 |
| 135 // Alert listeners of an update to the cache. |
| 136 void AlertListeners(MDnsListener::UpdateType update_type, |
| 137 const ListenerKey& key, const RecordParsed* record); |
| 138 |
| 139 // Schedule a cache cleanup to a specific time, cancelling other cleanups. |
| 140 void ScheduleCleanup(base::Time cleanup); |
| 141 |
| 142 // Clean up the cache and schedule a new cleanup. |
| 143 void DoCleanup(); |
| 144 |
| 145 // Callback for when a record is removed from the cache. |
| 146 void OnRecordRemoved(const RecordParsed* record); |
| 147 |
| 148 ListenerMap listeners_; |
| 149 |
| 150 MDnsClientImpl* client_; |
| 151 MDnsCache cache_; |
| 152 |
| 153 base::CancelableCallback<void()> cleanup_callback_; |
| 154 base::Time scheduled_cleanup_; |
| 155 |
| 156 scoped_ptr<MDnsConnection> connection_; |
| 157 |
| 158 DISALLOW_COPY_AND_ASSIGN(Core); |
| 159 }; |
| 160 |
| 161 explicit MDnsClientImpl( |
| 162 scoped_ptr<MDnsConnection::SocketFactory> socket_factory_); |
| 163 virtual ~MDnsClientImpl(); |
| 164 |
| 165 // MDnsClient implementation: |
| 166 virtual scoped_ptr<MDnsListener> CreateListener( |
| 167 uint16 rrtype, |
| 168 const std::string& name, |
| 169 MDnsListener::Delegate* delegate) OVERRIDE; |
| 170 |
| 171 virtual scoped_ptr<MDnsTransaction> CreateTransaction( |
| 172 uint16 rrtype, |
| 173 const std::string& name, |
| 174 int flags, |
| 175 const MDnsTransaction::ResultCallback& callback) OVERRIDE; |
| 176 |
| 177 // Returns true when the client is listening for network packets. |
| 178 bool IsListeningForTests(); |
| 179 |
| 180 bool AddListenRef(); |
| 181 void SubtractListenRef(); |
| 182 |
| 183 Core* core() { return core_.get(); } |
| 184 |
| 185 private: |
| 186 // This method causes the client to stop listening for packets. The |
| 187 // call for it is deferred through the message loop after the last |
| 188 // listener is removed. If another listener is added after a |
| 189 // shutdown is scheduled but before it actually runs, the shutdown |
| 190 // will be canceled. |
| 191 void Shutdown(); |
| 192 |
| 193 scoped_ptr<Core> core_; |
| 194 int listen_refs_; |
| 195 |
| 196 scoped_ptr<MDnsConnection::SocketFactory> socket_factory_; |
| 197 |
| 198 DISALLOW_COPY_AND_ASSIGN(MDnsClientImpl); |
| 199 }; |
| 200 |
| 201 class MDnsListenerImpl : public MDnsListener, |
| 202 public base::SupportsWeakPtr<MDnsListenerImpl> { |
| 203 public: |
| 204 MDnsListenerImpl(uint16 rrtype, |
| 205 const std::string& name, |
| 206 MDnsListener::Delegate* delegate, |
| 207 MDnsClientImpl* client); |
| 208 |
| 209 virtual ~MDnsListenerImpl(); |
| 210 |
| 211 // MDnsListener implementation: |
| 212 virtual bool Start() OVERRIDE; |
| 213 |
| 214 virtual const std::string& GetName() const OVERRIDE; |
| 215 |
| 216 virtual uint16 GetType() const OVERRIDE; |
| 217 |
| 218 MDnsListener::Delegate* delegate() { return delegate_; } |
| 219 |
| 220 // Alert the delegate of a record update. |
| 221 void AlertDelegate(MDnsListener::UpdateType update_type, |
| 222 const RecordParsed* record_parsed); |
| 223 private: |
| 224 uint16 rrtype_; |
| 225 std::string name_; |
| 226 MDnsClientImpl* client_; |
| 227 MDnsListener::Delegate* delegate_; |
| 228 |
| 229 bool started_; |
| 230 DISALLOW_COPY_AND_ASSIGN(MDnsListenerImpl); |
| 231 }; |
| 232 |
| 233 class MDnsTransactionImpl : public base::SupportsWeakPtr<MDnsTransactionImpl>, |
| 234 public MDnsTransaction, |
| 235 public MDnsListener::Delegate { |
| 236 public: |
| 237 MDnsTransactionImpl(uint16 rrtype, |
| 238 const std::string& name, |
| 239 int flags, |
| 240 const MDnsTransaction::ResultCallback& callback, |
| 241 MDnsClientImpl* client); |
| 242 virtual ~MDnsTransactionImpl(); |
| 243 |
| 244 // MDnsTransaction implementation: |
| 245 virtual bool Start() OVERRIDE; |
| 246 |
| 247 virtual const std::string& GetName() const OVERRIDE; |
| 248 virtual uint16 GetType() const OVERRIDE; |
| 249 |
| 250 // MDnsListener::Delegate implementation: |
| 251 virtual void OnRecordUpdate(MDnsListener::UpdateType update, |
| 252 const RecordParsed* record) OVERRIDE; |
| 253 virtual void OnNsecRecord(const std::string& name, unsigned type) OVERRIDE; |
| 254 |
| 255 virtual void OnCachePurged() OVERRIDE; |
| 256 |
| 257 private: |
| 258 bool is_active() { return !callback_.is_null(); } |
| 259 |
| 260 void Reset(); |
| 261 |
| 262 // Trigger the callback and reset all related variables. |
| 263 void TriggerCallback(MDnsTransaction::Result result, |
| 264 const RecordParsed* record); |
| 265 |
| 266 // Internal callback for when a cache record is found. |
| 267 void CacheRecordFound(const RecordParsed* record); |
| 268 |
| 269 // Signal the transactionis over and release all related resources. |
| 270 void SignalTransactionOver(); |
| 271 |
| 272 uint16 rrtype_; |
| 273 std::string name_; |
| 274 MDnsTransaction::ResultCallback callback_; |
| 275 |
| 276 scoped_ptr<MDnsListener> listener_; |
| 277 base::CancelableCallback<void()> timeout_; |
| 278 |
| 279 MDnsClientImpl* client_; |
| 280 |
| 281 bool started_; |
| 282 int flags_; |
| 283 |
| 284 DISALLOW_COPY_AND_ASSIGN(MDnsTransactionImpl); |
| 285 }; |
| 286 |
| 287 } // namespace net |
| 288 #endif // NET_DNS_MDNS_CLIENT_IMPL_H_ |
OLD | NEW |