|  | // Copyright (c) 2020 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 QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_CONTROLLER_H_ | 
|  | #define QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_CONTROLLER_H_ | 
|  |  | 
|  | #include "quic/qbone/bonnet/tun_device.h" | 
|  | #include "quic/qbone/platform/netlink_interface.h" | 
|  | #include "quic/qbone/qbone_control.pb.h" | 
|  | #include "quic/qbone/qbone_control_stream.h" | 
|  |  | 
|  | namespace quic { | 
|  |  | 
|  | // TunDeviceController consumes control stream messages from a Qbone server | 
|  | // and applies the given updates to the TUN device. | 
|  | class TunDeviceController { | 
|  | public: | 
|  | // |ifname| is the interface name of the TUN device to be managed. This does | 
|  | // not take ownership of |netlink|. | 
|  | TunDeviceController(std::string ifname, bool setup_tun, | 
|  | NetlinkInterface* netlink) | 
|  | : ifname_(std::move(ifname)), setup_tun_(setup_tun), netlink_(netlink) {} | 
|  |  | 
|  | TunDeviceController(const TunDeviceController&) = delete; | 
|  | TunDeviceController& operator=(const TunDeviceController&) = delete; | 
|  |  | 
|  | TunDeviceController(TunDeviceController&&) = delete; | 
|  | TunDeviceController& operator=(TunDeviceController&&) = delete; | 
|  |  | 
|  | virtual ~TunDeviceController() = default; | 
|  |  | 
|  | // Updates the local address of the TUN device to be the first address in the | 
|  | // given |response.ip_range()|. | 
|  | virtual bool UpdateAddress(const IpRange& desired_range); | 
|  |  | 
|  | // Updates the set of routes that the TUN device will provide. All current | 
|  | // routes for the tunnel that do not exist in the |response| will be removed. | 
|  | virtual bool UpdateRoutes(const IpRange& desired_range, | 
|  | const std::vector<IpRange>& desired_routes); | 
|  |  | 
|  | // Same as UpdateRoutes, but will wait and retry up to the number of times | 
|  | // given by |retries| before giving up. This is an unpleasant workaround to | 
|  | // deal with older kernels that aren't always able to set a route with a | 
|  | // source address immediately after adding the address to the interface. | 
|  | // | 
|  | // TODO(b/179430548): Remove this once we've root-caused the underlying issue. | 
|  | virtual bool UpdateRoutesWithRetries( | 
|  | const IpRange& desired_range, | 
|  | const std::vector<IpRange>& desired_routes, | 
|  | int retries); | 
|  |  | 
|  | virtual void RegisterAddressUpdateCallback( | 
|  | const std::function<void(QuicIpAddress)>& cb); | 
|  |  | 
|  | virtual QuicIpAddress current_address(); | 
|  |  | 
|  | private: | 
|  | // Update the IP Rules, this should only be used by UpdateRoutes. | 
|  | bool UpdateRules(IpRange desired_range); | 
|  |  | 
|  | const std::string ifname_; | 
|  | const bool setup_tun_; | 
|  |  | 
|  | NetlinkInterface* netlink_; | 
|  |  | 
|  | QuicIpAddress current_address_; | 
|  |  | 
|  | std::vector<std::function<void(QuicIpAddress)>> address_update_cbs_; | 
|  | }; | 
|  |  | 
|  | }  // namespace quic | 
|  |  | 
|  | #endif  // QUICHE_QUIC_QBONE_BONNET_TUN_DEVICE_CONTROLLER_H_ |