Home | History | Annotate | Download | only in shill
      1 //
      2 // Copyright (C) 2012 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #ifndef SHILL_IPCONFIG_H_
     18 #define SHILL_IPCONFIG_H_
     19 
     20 #include <memory>
     21 #include <string>
     22 #include <sys/time.h>
     23 #include <vector>
     24 
     25 #include <base/callback.h>
     26 #include <base/memory/ref_counted.h>
     27 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
     28 
     29 #include "shill/net/ip_address.h"
     30 #include "shill/property_store.h"
     31 #include "shill/refptr_types.h"
     32 #include "shill/routing_table_entry.h"
     33 
     34 namespace shill {
     35 class ControlInterface;
     36 class Error;
     37 class IPConfigAdaptorInterface;
     38 class StaticIPParameters;
     39 class Time;
     40 
     41 // IPConfig superclass. Individual IP configuration types will inherit from this
     42 // class.
     43 class IPConfig : public base::RefCounted<IPConfig> {
     44  public:
     45   struct Route {
     46     std::string host;
     47     std::string netmask;
     48     std::string gateway;
     49   };
     50 
     51   struct Properties {
     52     Properties() : address_family(IPAddress::kFamilyUnknown),
     53                    subnet_prefix(0),
     54                    delegated_prefix_length(0),
     55                    user_traffic_only(false),
     56                    default_route(true),
     57                    blackhole_ipv6(false),
     58                    mtu(kUndefinedMTU),
     59                    lease_duration_seconds(0) {}
     60 
     61     IPAddress::Family address_family;
     62     std::string address;
     63     int32_t subnet_prefix;
     64     std::string broadcast_address;
     65     std::vector<std::string> dns_servers;
     66     std::string domain_name;
     67     std::string accepted_hostname;
     68     std::vector<std::string> domain_search;
     69     std::string gateway;
     70     std::string method;
     71     std::string peer_address;
     72     // IPv6 prefix delegated from a DHCPv6 server.
     73     std::string delegated_prefix;
     74     int32_t delegated_prefix_length;
     75     // Set the flag when a secondary routing table should be used for less
     76     // privileged user traffic which alone would be sent to the VPN client. A
     77     // primary routing table will be used for traffic from privileged processes
     78     // which will bypass VPN.
     79     bool user_traffic_only;
     80     // Set the flag to true when the interface should be set as the default
     81     // route.
     82     bool default_route;
     83     // A list of IP blocks in CIDR format that should be excluded from VPN.
     84     std::vector<std::string> exclusion_list;
     85     bool blackhole_ipv6;
     86     int32_t mtu;
     87     std::vector<Route> routes;
     88     // Vendor encapsulated option string gained from DHCP.
     89     ByteArray vendor_encapsulated_options;
     90     // Web Proxy Auto Discovery (WPAD) URL gained from DHCP.
     91     std::string web_proxy_auto_discovery;
     92     // Length of time the lease was granted.
     93     uint32_t lease_duration_seconds;
     94   };
     95 
     96   enum Method {
     97     kMethodUnknown,
     98     kMethodPPP,
     99     kMethodStatic,
    100     kMethodDHCP
    101   };
    102 
    103   enum ReleaseReason {
    104     kReleaseReasonDisconnect,
    105     kReleaseReasonStaticIP
    106   };
    107 
    108   typedef base::Callback<void(const IPConfigRefPtr&, bool)> UpdateCallback;
    109   typedef base::Callback<void(const IPConfigRefPtr&)> Callback;
    110 
    111   // Define a default and a minimum viable MTU value.
    112   static const int kDefaultMTU;
    113   static const int kMinIPv4MTU;
    114   static const int kMinIPv6MTU;
    115   static const int kUndefinedMTU;
    116 
    117   IPConfig(ControlInterface* control_interface, const std::string& device_name);
    118   IPConfig(ControlInterface* control_interface,
    119            const std::string& device_name,
    120            const std::string& type);
    121   virtual ~IPConfig();
    122 
    123   const std::string& device_name() const { return device_name_; }
    124   const std::string& type() const { return type_; }
    125   uint serial() const { return serial_; }
    126 
    127   std::string GetRpcIdentifier();
    128 
    129   // Registers a callback that's executed every time the configuration
    130   // properties are acquired. Takes ownership of |callback|.  Pass NULL
    131   // to remove a callback. The callback's first argument is a pointer to this IP
    132   // configuration instance allowing clients to more easily manage multiple IP
    133   // configurations. The callback's second argument is a boolean indicating
    134   // whether or not a DHCP lease was acquired from the server.
    135   void RegisterUpdateCallback(const UpdateCallback& callback);
    136 
    137   // Registers a callback that's executed every time the configuration
    138   // properties fail to be acquired. Takes ownership of |callback|.  Pass NULL
    139   // to remove a callback. The callback's argument is a pointer to this IP
    140   // configuration instance allowing clients to more easily manage multiple IP
    141   // configurations.
    142   void RegisterFailureCallback(const Callback& callback);
    143 
    144   // Registers a callback that's executed every time the Refresh method
    145   // on the ipconfig is called.  Takes ownership of |callback|. Pass NULL
    146   // to remove a callback. The callback's argument is a pointer to this IP
    147   // configuration instance allowing clients to more easily manage multiple IP
    148   // configurations.
    149   void RegisterRefreshCallback(const Callback& callback);
    150 
    151   // Registers a callback that's executed every time the the lease exipres
    152   // and the IPConfig is about to perform a restart to attempt to regain it.
    153   // Takes ownership of |callback|. Pass NULL  to remove a callback. The
    154   // callback's argument is a pointer to this IP configuration instance
    155   // allowing clients to more easily manage multiple IP configurations.
    156   void RegisterExpireCallback(const Callback& callback);
    157 
    158   void set_properties(const Properties& props) { properties_ = props; }
    159   virtual const Properties& properties() const { return properties_; }
    160 
    161   // Update DNS servers setting for this ipconfig, this allows Chrome
    162   // to retrieve the new DNS servers.
    163   virtual void UpdateDNSServers(const std::vector<std::string>& dns_servers);
    164 
    165   // Reset the IPConfig properties to their default values.
    166   virtual void ResetProperties();
    167 
    168   // Request, renew and release IP configuration. Return true on success, false
    169   // otherwise. The default implementation always returns false indicating a
    170   // failure.  ReleaseIP is advisory: if we are no longer connected, it is not
    171   // possible to properly vacate the lease on the remote server.  Also,
    172   // depending on the configuration of the specific IPConfig subclass, we may
    173   // end up holding on to the lease so we can resume to the network lease
    174   // faster.
    175   virtual bool RequestIP();
    176   virtual bool RenewIP();
    177   virtual bool ReleaseIP(ReleaseReason reason);
    178 
    179   // Refresh IP configuration.  Called by the DBus Adaptor "Refresh" call.
    180   void Refresh(Error* error);
    181 
    182   PropertyStore* mutable_store() { return &store_; }
    183   const PropertyStore& store() const { return store_; }
    184   void ApplyStaticIPParameters(StaticIPParameters* static_ip_parameters);
    185 
    186   // Restore the fields of |properties_| to their original values before
    187   // static IP parameters were previously applied.
    188   void RestoreSavedIPParameters(StaticIPParameters* static_ip_parameters);
    189 
    190   // Updates |current_lease_expiration_time_| by adding |new_lease_duration| to
    191   // the current time.
    192   virtual void UpdateLeaseExpirationTime(uint32_t new_lease_duration);
    193 
    194   // Resets |current_lease_expiration_time_| to its default value.
    195   virtual void ResetLeaseExpirationTime();
    196 
    197   // Returns the time left (in seconds) till the current DHCP lease is to be
    198   // renewed in |time_left|. Returns false if an error occurs (i.e. current
    199   // lease has already expired or no current DHCP lease), true otherwise.
    200   bool TimeToLeaseExpiry(uint32_t* time_left);
    201 
    202  protected:
    203   // Inform RPC listeners of changes to our properties. MAY emit
    204   // changes even on unchanged properties.
    205   virtual void EmitChanges();
    206 
    207   // Updates the IP configuration properties and notifies registered listeners
    208   // about the event.
    209   virtual void UpdateProperties(const Properties& properties,
    210                                 bool new_lease_acquired);
    211 
    212   // Notifies registered listeners that the configuration process has failed.
    213   virtual void NotifyFailure();
    214 
    215   // Notifies registered listeners that the lease has expired.
    216   virtual void NotifyExpiry();
    217 
    218  private:
    219   friend class IPConfigAdaptorInterface;
    220   friend class IPConfigTest;
    221   friend class ConnectionTest;
    222 
    223   FRIEND_TEST(DeviceTest, AcquireIPConfigWithoutSelectedService);
    224   FRIEND_TEST(DeviceTest, AcquireIPConfigWithSelectedService);
    225   FRIEND_TEST(DeviceTest, DestroyIPConfig);
    226   FRIEND_TEST(DeviceTest, IsConnectedViaTether);
    227   FRIEND_TEST(DeviceTest, OnIPConfigExpired);
    228   FRIEND_TEST(IPConfigTest, UpdateCallback);
    229   FRIEND_TEST(IPConfigTest, UpdateProperties);
    230   FRIEND_TEST(IPConfigTest, UpdateLeaseExpirationTime);
    231   FRIEND_TEST(IPConfigTest, TimeToLeaseExpiry_NoDHCPLease);
    232   FRIEND_TEST(IPConfigTest, TimeToLeaseExpiry_CurrentLeaseExpired);
    233   FRIEND_TEST(IPConfigTest, TimeToLeaseExpiry_Success);
    234   FRIEND_TEST(ResolverTest, Empty);
    235   FRIEND_TEST(ResolverTest, NonEmpty);
    236   FRIEND_TEST(RoutingTableTest, ConfigureRoutes);
    237   FRIEND_TEST(RoutingTableTest, RouteAddDelete);
    238   FRIEND_TEST(RoutingTableTest, RouteDeleteForeign);
    239 
    240   static const char kType[];
    241 
    242   void Init();
    243 
    244   static uint global_serial_;
    245   PropertyStore store_;
    246   const std::string device_name_;
    247   const std::string type_;
    248   const uint serial_;
    249   std::unique_ptr<IPConfigAdaptorInterface> adaptor_;
    250   Properties properties_;
    251   UpdateCallback update_callback_;
    252   Callback failure_callback_;
    253   Callback refresh_callback_;
    254   Callback expire_callback_;
    255   struct timeval current_lease_expiration_time_;
    256   Time* time_;
    257 
    258   DISALLOW_COPY_AND_ASSIGN(IPConfig);
    259 };
    260 
    261 }  // namespace shill
    262 
    263 #endif  // SHILL_IPCONFIG_H_
    264