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 {
PropertiesProperties52     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 
device_name()123   const std::string& device_name() const { return device_name_; }
type()124   const std::string& type() const { return type_; }
serial()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 
set_properties(const Properties & props)158   void set_properties(const Properties& props) { properties_ = props; }
properties()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 
mutable_store()182   PropertyStore* mutable_store() { return &store_; }
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