|  | // Copyright 2013 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef CHROME_BROWSER_PRINTING_CLOUD_PRINT_PRIVET_TRAFFIC_DETECTOR_H_ | 
|  | #define CHROME_BROWSER_PRINTING_CLOUD_PRINT_PRIVET_TRAFFIC_DETECTOR_H_ | 
|  |  | 
|  | #include "base/callback.h" | 
|  | #include "base/macros.h" | 
|  | #include "mojo/public/cpp/bindings/receiver.h" | 
|  | #include "mojo/public/cpp/bindings/remote.h" | 
|  | #include "net/base/ip_endpoint.h" | 
|  | #include "net/base/network_interfaces.h" | 
|  | #include "services/network/public/cpp/network_connection_tracker.h" | 
|  | #include "services/network/public/mojom/udp_socket.mojom.h" | 
|  |  | 
|  | namespace content { | 
|  | class BrowserContext; | 
|  | } | 
|  |  | 
|  | namespace cloud_print { | 
|  |  | 
|  | // Detects mDns traffic that looks like the "Privet" protocol. This can produce | 
|  | // false positives results, but the main task of the class is to avoid running a | 
|  | // full mDns listener if user doesn't have devices. | 
|  | // When potential "Privet" traffic has been detected, fire a callback and stop | 
|  | // listening for traffic. | 
|  | // When the network changes, restarts itself to start listening for traffic | 
|  | // again on the new network(s). | 
|  | // The class lives on the UI thread, with a helper that lives on the IO thread. | 
|  | class PrivetTrafficDetector | 
|  | : public network::NetworkConnectionTracker::NetworkConnectionObserver { | 
|  | public: | 
|  | // Called on the UI thread. | 
|  | PrivetTrafficDetector(content::BrowserContext* profile, | 
|  | base::RepeatingClosure on_traffic_detected); | 
|  | ~PrivetTrafficDetector() override; | 
|  |  | 
|  | // network::NetworkConnectionTracker::NetworkConnectionObserver: | 
|  | void OnConnectionChanged(network::mojom::ConnectionType type) override; | 
|  |  | 
|  | private: | 
|  | // Constructed by PrivetTrafficDetector on the UI thread. but lives on the IO | 
|  | // thread and destroyed on the IO thread. | 
|  | class Helper : public network::mojom::UDPSocketListener { | 
|  | public: | 
|  | Helper(content::BrowserContext* profile, | 
|  | base::RepeatingClosure on_traffic_detected); | 
|  | ~Helper() override; | 
|  |  | 
|  | // network::mojom::UDPSocketListener: | 
|  | void OnReceived(int32_t result, | 
|  | const base::Optional<net::IPEndPoint>& src_addr, | 
|  | base::Optional<base::span<const uint8_t>> data) override; | 
|  |  | 
|  | void HandleConnectionChanged(network::mojom::ConnectionType type); | 
|  | void ScheduleRestart(); | 
|  |  | 
|  | private: | 
|  | void Restart(net::NetworkInterfaceList networks); | 
|  | void Bind(); | 
|  | void OnBindComplete(net::IPEndPoint multicast_addr, | 
|  | int rv, | 
|  | const base::Optional<net::IPEndPoint>& ip_address); | 
|  | bool IsSourceAcceptable() const; | 
|  | bool IsPrivetPacket(base::span<const uint8_t> data) const; | 
|  | void OnJoinGroupComplete(int rv); | 
|  | void ResetConnection(); | 
|  |  | 
|  | // Initialized on the UI thread, but only accessed on the IO thread for the | 
|  | // purpose of passing it back to the UI thread. Safe because it is const. | 
|  | content::BrowserContext* const profile_; | 
|  |  | 
|  | // Initialized on the UI thread, but only accessed on the IO thread. | 
|  | base::RepeatingClosure on_traffic_detected_; | 
|  | int restart_attempts_; | 
|  |  | 
|  | // Only accessed on the IO thread. | 
|  | net::NetworkInterfaceList networks_; | 
|  | net::IPEndPoint recv_addr_; | 
|  | mojo::Remote<network::mojom::UDPSocket> socket_; | 
|  |  | 
|  | // Implementation of socket listener callback. | 
|  | // Initialized on the UI thread, but only accessed on the IO thread. | 
|  | mojo::Receiver<network::mojom::UDPSocketListener> listener_receiver_{this}; | 
|  |  | 
|  | base::WeakPtrFactory<Helper> weak_ptr_factory_{this}; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(Helper); | 
|  | }; | 
|  |  | 
|  | Helper* const helper_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(PrivetTrafficDetector); | 
|  | }; | 
|  |  | 
|  | }  // namespace cloud_print | 
|  |  | 
|  | #endif  // CHROME_BROWSER_PRINTING_CLOUD_PRINT_PRIVET_TRAFFIC_DETECTOR_H_ |