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 #include "shill/ipconfig.h"
     18 
     19 #include <sys/time.h>
     20 
     21 #include <limits>
     22 
     23 #if defined(__ANDROID__)
     24 #include <dbus/service_constants.h>
     25 #else
     26 #include <chromeos/dbus/service_constants.h>
     27 #endif  // __ANDROID__
     28 
     29 #include "shill/adaptor_interfaces.h"
     30 #include "shill/control_interface.h"
     31 #include "shill/error.h"
     32 #include "shill/logging.h"
     33 #include "shill/net/shill_time.h"
     34 #include "shill/static_ip_parameters.h"
     35 
     36 using base::Callback;
     37 using std::string;
     38 
     39 namespace shill {
     40 
     41 namespace Logging {
     42 static auto kModuleLogScope = ScopeLogger::kInet;
     43 static string ObjectID(IPConfig* i) { return i->GetRpcIdentifier(); }
     44 }
     45 
     46 namespace {
     47 
     48 const time_t kDefaultLeaseExpirationTime = std::numeric_limits<long>::max();
     49 
     50 }  // namespace
     51 
     52 // static
     53 const int IPConfig::kDefaultMTU = 1500;
     54 const int IPConfig::kMinIPv4MTU = 576;
     55 const int IPConfig::kMinIPv6MTU = 1280;
     56 const int IPConfig::kUndefinedMTU = 0;
     57 const char IPConfig::kType[] = "ip";
     58 
     59 // static
     60 uint IPConfig::global_serial_ = 0;
     61 
     62 IPConfig::IPConfig(ControlInterface* control_interface,
     63                    const std::string& device_name)
     64     : device_name_(device_name),
     65       type_(kType),
     66       serial_(global_serial_++),
     67       adaptor_(control_interface->CreateIPConfigAdaptor(this)) {
     68   Init();
     69 }
     70 
     71 IPConfig::IPConfig(ControlInterface* control_interface,
     72                    const std::string& device_name,
     73                    const std::string& type)
     74     : device_name_(device_name),
     75       type_(type),
     76       serial_(global_serial_++),
     77       adaptor_(control_interface->CreateIPConfigAdaptor(this)) {
     78   Init();
     79 }
     80 
     81 void IPConfig::Init() {
     82   store_.RegisterConstString(kAddressProperty, &properties_.address);
     83   store_.RegisterConstString(kBroadcastProperty,
     84                              &properties_.broadcast_address);
     85   store_.RegisterConstString(kDomainNameProperty, &properties_.domain_name);
     86   store_.RegisterConstString(kAcceptedHostnameProperty,
     87                              &properties_.accepted_hostname);
     88   store_.RegisterConstString(kGatewayProperty, &properties_.gateway);
     89   store_.RegisterConstString(kMethodProperty, &properties_.method);
     90   store_.RegisterConstInt32(kMtuProperty, &properties_.mtu);
     91   store_.RegisterConstStrings(kNameServersProperty, &properties_.dns_servers);
     92   store_.RegisterConstString(kPeerAddressProperty, &properties_.peer_address);
     93   store_.RegisterConstInt32(kPrefixlenProperty, &properties_.subnet_prefix);
     94   store_.RegisterConstStrings(kSearchDomainsProperty,
     95                               &properties_.domain_search);
     96   store_.RegisterConstByteArray(kVendorEncapsulatedOptionsProperty,
     97                                 &properties_.vendor_encapsulated_options);
     98   store_.RegisterConstString(kWebProxyAutoDiscoveryUrlProperty,
     99                              &properties_.web_proxy_auto_discovery);
    100   store_.RegisterConstString(kDelegatedPrefixProperty,
    101                              &properties_.delegated_prefix);
    102   store_.RegisterConstInt32(kDelegatedPrefixLengthProperty,
    103                             &properties_.delegated_prefix_length);
    104   store_.RegisterConstUint32(kLeaseDurationSecondsProperty,
    105                              &properties_.lease_duration_seconds);
    106   time_ = Time::GetInstance();
    107   current_lease_expiration_time_ = {kDefaultLeaseExpirationTime, 0};
    108   SLOG(this, 2) << __func__ << " device: " << device_name();
    109 }
    110 
    111 IPConfig::~IPConfig() {
    112   SLOG(this, 2) << __func__ << " device: " << device_name();
    113 }
    114 
    115 string IPConfig::GetRpcIdentifier() {
    116   return adaptor_->GetRpcIdentifier();
    117 }
    118 
    119 bool IPConfig::RequestIP() {
    120   return false;
    121 }
    122 
    123 bool IPConfig::RenewIP() {
    124   return false;
    125 }
    126 
    127 bool IPConfig::ReleaseIP(ReleaseReason reason) {
    128   return false;
    129 }
    130 
    131 void IPConfig::Refresh(Error* /*error*/) {
    132   if (!refresh_callback_.is_null()) {
    133     refresh_callback_.Run(this);
    134   }
    135   RenewIP();
    136 }
    137 
    138 void IPConfig::ApplyStaticIPParameters(
    139     StaticIPParameters* static_ip_parameters) {
    140   static_ip_parameters->ApplyTo(&properties_);
    141   EmitChanges();
    142 }
    143 
    144 void IPConfig::RestoreSavedIPParameters(
    145     StaticIPParameters* static_ip_parameters) {
    146   static_ip_parameters->RestoreTo(&properties_);
    147   EmitChanges();
    148 }
    149 
    150 void IPConfig::UpdateLeaseExpirationTime(uint32_t new_lease_duration) {
    151   struct timeval new_expiration_time;
    152   time_->GetTimeBoottime(&new_expiration_time);
    153   new_expiration_time.tv_sec += new_lease_duration;
    154   current_lease_expiration_time_ = new_expiration_time;
    155 }
    156 
    157 void IPConfig::ResetLeaseExpirationTime() {
    158   current_lease_expiration_time_ = {kDefaultLeaseExpirationTime, 0};
    159 }
    160 
    161 bool IPConfig::TimeToLeaseExpiry(uint32_t* time_left) {
    162   if (current_lease_expiration_time_.tv_sec == kDefaultLeaseExpirationTime) {
    163     SLOG(this, 2) << __func__ << ": No current DHCP lease";
    164     return false;
    165   }
    166   struct timeval now;
    167   time_->GetTimeBoottime(&now);
    168   if (now.tv_sec > current_lease_expiration_time_.tv_sec) {
    169     SLOG(this, 2) << __func__ << ": Current DHCP lease has already expired";
    170     return false;
    171   }
    172   *time_left = current_lease_expiration_time_.tv_sec - now.tv_sec;
    173   return true;
    174 }
    175 
    176 void IPConfig::UpdateProperties(const Properties& properties,
    177                                 bool new_lease_acquired) {
    178   // Take a reference of this instance to make sure we don't get destroyed in
    179   // the middle of this call. (The |update_callback_| may cause a reference
    180   // to be dropped. See, e.g., EthernetService::Disconnect and
    181   // Ethernet::DropConnection.)
    182   IPConfigRefPtr me = this;
    183 
    184   properties_ = properties;
    185 
    186   if (!update_callback_.is_null()) {
    187     update_callback_.Run(this, new_lease_acquired);
    188   }
    189   EmitChanges();
    190 }
    191 
    192 void IPConfig::UpdateDNSServers(const std::vector<std::string>& dns_servers) {
    193   properties_.dns_servers = dns_servers;
    194   EmitChanges();
    195 }
    196 
    197 void IPConfig::NotifyFailure() {
    198   // Take a reference of this instance to make sure we don't get destroyed in
    199   // the middle of this call. (The |update_callback_| may cause a reference
    200   // to be dropped. See, e.g., EthernetService::Disconnect and
    201   // Ethernet::DropConnection.)
    202   IPConfigRefPtr me = this;
    203 
    204   if (!failure_callback_.is_null()) {
    205     failure_callback_.Run(this);
    206   }
    207 }
    208 
    209 void IPConfig::NotifyExpiry() {
    210   if (!expire_callback_.is_null()) {
    211     expire_callback_.Run(this);
    212   }
    213 }
    214 
    215 void IPConfig::RegisterUpdateCallback(const UpdateCallback& callback) {
    216   update_callback_ = callback;
    217 }
    218 
    219 void IPConfig::RegisterFailureCallback(const Callback& callback) {
    220   failure_callback_ = callback;
    221 }
    222 
    223 void IPConfig::RegisterRefreshCallback(const Callback& callback) {
    224   refresh_callback_ = callback;
    225 }
    226 
    227 void IPConfig::RegisterExpireCallback(const Callback& callback) {
    228   expire_callback_ = callback;
    229 }
    230 
    231 void IPConfig::ResetProperties() {
    232   properties_ = Properties();
    233   EmitChanges();
    234 }
    235 
    236 void IPConfig::EmitChanges() {
    237   adaptor_->EmitStringChanged(kAddressProperty, properties_.address);
    238   adaptor_->EmitStringsChanged(kNameServersProperty, properties_.dns_servers);
    239 }
    240 
    241 }  // namespace shill
    242