1 // Copyright 2018 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 CHROME_BROWSER_CHROMEOS_SMB_CLIENT_DISCOVERY_NETWORK_SCANNER_H_ 6 #define CHROME_BROWSER_CHROMEOS_SMB_CLIENT_DISCOVERY_NETWORK_SCANNER_H_ 7 8 #include <map> 9 #include <vector> 10 11 #include "base/callback.h" 12 #include "base/memory/weak_ptr.h" 13 #include "chrome/browser/chromeos/smb_client/discovery/host_locator.h" 14 #include "net/base/ip_address.h" 15 16 namespace chromeos { 17 namespace smb_client { 18 19 // Holds the number of in-flight requests and the callback to call once all the 20 // HostLocators are finished. Also holds the hosts found from the HostLocators 21 // that have already returned. 22 struct RequestInfo { 23 uint32_t remaining_requests; 24 FindHostsCallback callback; 25 HostMap hosts_found; 26 27 RequestInfo(uint32_t remaining_requests, FindHostsCallback callback); 28 RequestInfo(RequestInfo&& other); 29 ~RequestInfo(); 30 31 DISALLOW_COPY_AND_ASSIGN(RequestInfo); 32 }; 33 34 // NetworkScanner discovers SMB hosts in the local network by querying 35 // registered HostLocators and aggregating their results. RegisterHostLocator is 36 // used to register HostLocators that are responsible for finding hosts. 37 // FindHostsInNetwork is called to get a list of discoverable hosts in the 38 // network. ResolveHost is used to get the IP address of a given host. 39 class NetworkScanner : public base::SupportsWeakPtr<NetworkScanner> { 40 public: 41 NetworkScanner(); 42 ~NetworkScanner(); 43 44 // Query the registered HostLocators and return all the hosts found. 45 // |callback| is called once all the HostLocators have responded with their 46 // results. If there are no locators, the callback is fired immediately with 47 // an empty result and success set to false. Once this call has returned, the 48 // hosts found are cached locally and are resolvable individually through 49 // ResolveHost(). 50 void FindHostsInNetwork(FindHostsCallback callback); 51 52 // Registeres a |locator| to be queried when FindHostsInNetwork() is called. 53 void RegisterHostLocator(std::unique_ptr<HostLocator> locator); 54 55 // Resolves |host| to an address using the cached results of 56 // FindHostsInNetwork(). FindHostsInNetwork() has to be called beforehand. If 57 // no address is found, this returns an invalid IPAddress. 58 net::IPAddress ResolveHost(const std::string& host) const; 59 60 private: 61 // Callback handler for HostLocator::FindHosts(). 62 void OnHostsFound(uint32_t request_id, bool success, const HostMap& host_map); 63 64 // Adds |host_map| hosts to current results. The host will not be added if the 65 // hostname already exists in results, and if the IP address does not match, 66 // it will be logged. 67 void AddHostsToResults(uint32_t request_id, const HostMap& host_map); 68 69 // Adds a new request to track and saves |callback| to be called when the 70 // request is finished. Returns the request id. 71 uint32_t AddNewRequest(FindHostsCallback callback); 72 73 // Called after a HostLocator returns with results and decrements the count of 74 // requests in RequestInfo for |request_id|. Fires the callback for if 75 // there are no more requests and deletes the corresponding RequestInfo. 76 void FireCallbackIfFinished(uint32_t request_id); 77 78 std::vector<std::unique_ptr<HostLocator>> locators_; 79 80 // Used for tracking in-flight requests to HostLocators. The key is the 81 // request id, and the value is the RequestInfo struct. 82 std::map<uint32_t, RequestInfo> requests_; 83 84 uint32_t next_request_id_ = 0; 85 86 // Hosts that are found from FindHostsInNetwork(). This is cached for name 87 // resolution when calling ResolveHost(). 88 HostMap found_hosts_; 89 90 // True if FindHostsInNetwork() has been called and returned results 91 // regardless if any hosts are found. 92 bool find_hosts_returned_ = false; 93 94 // True if FindHostsInNetwork() has been called and is waiting for 95 // FindHostsCallback to be invoked. This is to prevent multiple calls of 96 // FindHostsInNetwork() from concurrently executing. Used only for DCHECKing 97 // if FindHostsInNetwork() is already running. 98 bool running_ = false; 99 100 DISALLOW_COPY_AND_ASSIGN(NetworkScanner); 101 }; 102 103 } // namespace smb_client 104 } // namespace chromeos 105 106 #endif // CHROME_BROWSER_CHROMEOS_SMB_CLIENT_DISCOVERY_NETWORK_SCANNER_H_ 107