| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 
|  | 2 // Use of this source code is governed by a BSD-style license that can be | 
|  | 3 // found in the LICENSE file. | 
|  | 4 | 
|  | 5 #include "chromeos/dbus/shill_third_party_vpn_driver_client.h" | 
|  | 6 | 
|  | 7 #include "base/bind.h" | 
|  | 8 #include "chromeos/dbus/shill_third_party_vpn_observer.h" | 
|  | 9 #include "dbus/bus.h" | 
|  | 10 #include "dbus/message.h" | 
|  | 11 #include "dbus/object_proxy.h" | 
|  | 12 #include "third_party/cros_system_api/dbus/service_constants.h" | 
|  | 13 | 
|  | 14 namespace chromeos { | 
|  | 15 | 
|  | 16 namespace { | 
|  | 17 | 
|  | 18 const char* kSetParametersKeyList[] = { | 
|  | 19     shill::kAddressParameterThirdPartyVpn, | 
|  | 20     shill::kBroadcastAddressParameterThirdPartyVpn, | 
|  | 21     shill::kGatewayParameterThirdPartyVpn, | 
|  | 22     shill::kBypassTunnelForIpParameterThirdPartyVpn, | 
|  | 23     shill::kSubnetPrefixParameterThirdPartyVpn, | 
|  | 24     shill::kMtuParameterThirdPartyVpn, | 
|  | 25     shill::kDomainSearchParameterThirdPartyVpn, | 
|  | 26     shill::kDnsServersParameterThirdPartyVpn}; | 
|  | 27 | 
|  | 28 // The ShillThirdPartyVpnDriverClient implementation. | 
|  | 29 class ShillThirdPartyVpnDriverClientImpl | 
|  | 30     : public ShillThirdPartyVpnDriverClient { | 
|  | 31  public: | 
|  | 32   ShillThirdPartyVpnDriverClientImpl(); | 
|  | 33   ~ShillThirdPartyVpnDriverClientImpl() override; | 
|  | 34 | 
|  | 35   // ShillThirdPartyVpnDriverClient overrides | 
|  | 36   void AddShillThirdPartyVpnObserver( | 
|  | 37       const std::string& object_path_value, | 
|  | 38       ShillThirdPartyVpnObserver* observer) override; | 
|  | 39 | 
|  | 40   void RemoveShillThirdPartyVpnObserver( | 
|  | 41       const std::string& object_path_value) override; | 
|  | 42 | 
|  | 43   void SetParameters( | 
|  | 44       const std::string& object_path_value, | 
|  | 45       const base::DictionaryValue& parameters, | 
|  | 46       const base::Closure& callback, | 
|  | 47       const ShillClientHelper::ErrorCallback& error_callback) override; | 
|  | 48 | 
|  | 49   void UpdateConnectionState( | 
|  | 50       const std::string& object_path_value, | 
|  | 51       const uint32_t connection_state, | 
|  | 52       const base::Closure& callback, | 
|  | 53       const ShillClientHelper::ErrorCallback& error_callback) override; | 
|  | 54 | 
|  | 55   void SendPacket( | 
|  | 56       const std::string& object_path_value, | 
|  | 57       const std::string& ip_packet, | 
|  | 58       const base::Closure& callback, | 
|  | 59       const ShillClientHelper::ErrorCallback& error_callback) override; | 
|  | 60 | 
|  | 61  protected: | 
|  | 62   void Init(dbus::Bus* bus) override { bus_ = bus; } | 
|  | 63 | 
|  | 64   ShillThirdPartyVpnDriverClient::TestInterface* GetTestInterface() override { | 
|  | 65     return nullptr; | 
|  | 66   } | 
|  | 67 | 
|  | 68  private: | 
|  | 69   class HelperInfo { | 
|  | 70    public: | 
|  | 71     explicit HelperInfo(dbus::ObjectProxy* object_proxy); | 
|  | 72 | 
|  | 73     ShillClientHelper* helper() { return &helper_; } | 
|  | 74     ShillThirdPartyVpnObserver* observer() { return observer_; } | 
|  | 75 | 
|  | 76     void set_observer(ShillThirdPartyVpnObserver* observer) { | 
|  | 77       observer_ = observer; | 
|  | 78     } | 
|  | 79 | 
|  | 80     base::WeakPtr<HelperInfo> GetWeakPtr() { | 
|  | 81       return weak_ptr_factory_.GetWeakPtr(); | 
|  | 82     } | 
|  | 83 | 
|  | 84    private: | 
|  | 85     ShillClientHelper helper_; | 
|  | 86     ShillThirdPartyVpnObserver* observer_; | 
|  | 87 | 
|  | 88     base::WeakPtrFactory<HelperInfo> weak_ptr_factory_; | 
|  | 89   }; | 
|  | 90   using HelperMap = std::map<std::string, HelperInfo*>; | 
|  | 91 | 
|  | 92   static void OnPacketReceived(base::WeakPtr<HelperInfo> helper_info, | 
|  | 93                                dbus::Signal* signal); | 
|  | 94   static void OnPlatformMessage(base::WeakPtr<HelperInfo> helper_info, | 
|  | 95                                 dbus::Signal* signal); | 
|  | 96   static void OnSignalConnected(const std::string& interface, | 
|  | 97                                 const std::string& signal, | 
|  | 98                                 bool success); | 
|  | 99 | 
|  | 100   // Returns or creates the corresponding ShillClientHelper for the | 
|  | 101   // |object_path_value|. | 
|  | 102   ShillClientHelper* GetHelper(const std::string& object_path_value); | 
|  | 103 | 
|  | 104   // Returns or creates the corresponding HelperInfo for the | 
|  | 105   // |object_path_value|. | 
|  | 106   HelperInfo* GetHelperInfo(const std::string& object_path_value); | 
|  | 107 | 
|  | 108   // Returns the corresponding HelperInfo for the |object_path| if exists, | 
|  | 109   // nullptr if not. | 
|  | 110   HelperInfo* FindHelperInfo(const dbus::ObjectPath& object_path); | 
|  | 111 | 
|  | 112   // Deletes the helper object corresponding to |object_path|. | 
|  | 113   void DeleteHelper(const dbus::ObjectPath& object_path); | 
|  | 114 | 
|  | 115   dbus::Bus* bus_; | 
|  | 116   HelperMap helpers_; | 
|  | 117   std::set<std::string> valid_keys_; | 
|  | 118 | 
|  | 119   DISALLOW_COPY_AND_ASSIGN(ShillThirdPartyVpnDriverClientImpl); | 
|  | 120 }; | 
|  | 121 | 
|  | 122 ShillThirdPartyVpnDriverClientImpl::HelperInfo::HelperInfo( | 
|  | 123     dbus::ObjectProxy* object_proxy) | 
|  | 124     : helper_(object_proxy), observer_(nullptr), weak_ptr_factory_(this) { | 
|  | 125 } | 
|  | 126 | 
|  | 127 ShillThirdPartyVpnDriverClientImpl::ShillThirdPartyVpnDriverClientImpl() | 
|  | 128     : bus_(nullptr) { | 
|  | 129   for (uint32_t i = 0; i < arraysize(kSetParametersKeyList); ++i) { | 
|  | 130     valid_keys_.insert(kSetParametersKeyList[i]); | 
|  | 131   } | 
|  | 132 } | 
|  | 133 | 
|  | 134 ShillThirdPartyVpnDriverClientImpl::~ShillThirdPartyVpnDriverClientImpl() { | 
|  | 135   for (auto& iter : helpers_) { | 
|  | 136     HelperInfo* helper_info = iter.second; | 
|  | 137     bus_->RemoveObjectProxy( | 
|  | 138         shill::kFlimflamServiceName, | 
|  | 139         helper_info->helper()->object_proxy()->object_path(), | 
|  | 140         base::Bind(&base::DoNothing)); | 
|  | 141     delete helper_info; | 
|  | 142   } | 
|  | 143 } | 
|  | 144 | 
|  | 145 void ShillThirdPartyVpnDriverClientImpl::AddShillThirdPartyVpnObserver( | 
|  | 146     const std::string& object_path_value, | 
|  | 147     ShillThirdPartyVpnObserver* observer) { | 
|  | 148   HelperInfo* helper_info = GetHelperInfo(object_path_value); | 
|  | 149   if (helper_info->observer()) { | 
|  | 150     LOG(ERROR) << "Observer exists for " << object_path_value; | 
|  | 151     return; | 
|  | 152   } | 
|  | 153 | 
|  | 154   // TODO(kaliamoorthi): Remove the const_cast. | 
|  | 155   helper_info->set_observer(observer); | 
|  | 156   dbus::ObjectProxy* proxy = | 
|  | 157       const_cast<dbus::ObjectProxy*>(helper_info->helper()->object_proxy()); | 
|  | 158 | 
|  | 159   proxy->ConnectToSignal( | 
|  | 160       shill::kFlimflamThirdPartyVpnInterface, shill::kOnPlatformMessageFunction, | 
|  | 161       base::Bind(&ShillThirdPartyVpnDriverClientImpl::OnPlatformMessage, | 
|  | 162                  helper_info->GetWeakPtr()), | 
|  | 163       base::Bind(&ShillThirdPartyVpnDriverClientImpl::OnSignalConnected)); | 
|  | 164 | 
|  | 165   proxy->ConnectToSignal( | 
|  | 166       shill::kFlimflamThirdPartyVpnInterface, shill::kOnPacketReceivedFunction, | 
|  | 167       base::Bind(&ShillThirdPartyVpnDriverClientImpl::OnPacketReceived, | 
|  | 168                  helper_info->GetWeakPtr()), | 
|  | 169       base::Bind(&ShillThirdPartyVpnDriverClientImpl::OnSignalConnected)); | 
|  | 170 } | 
|  | 171 | 
|  | 172 void ShillThirdPartyVpnDriverClientImpl::RemoveShillThirdPartyVpnObserver( | 
|  | 173     const std::string& object_path_value) { | 
|  | 174   HelperInfo* helper_info = FindHelperInfo(dbus::ObjectPath(object_path_value)); | 
|  | 175   if (!helper_info) { | 
|  | 176     LOG(ERROR) << "Unknown object_path_value " << object_path_value; | 
|  | 177     return; | 
|  | 178   } | 
|  | 179 | 
|  | 180   CHECK(helper_info->observer()); | 
|  | 181   helper_info->set_observer(nullptr); | 
|  | 182   DeleteHelper(dbus::ObjectPath(object_path_value)); | 
|  | 183 } | 
|  | 184 | 
|  | 185 void ShillThirdPartyVpnDriverClientImpl::DeleteHelper( | 
|  | 186     const dbus::ObjectPath& object_path) { | 
|  | 187   HelperInfo* helper_info = FindHelperInfo(dbus::ObjectPath(object_path)); | 
|  | 188   if (!helper_info) { | 
|  | 189     LOG(ERROR) << "Unknown object_path " << object_path.value(); | 
|  | 190     return; | 
|  | 191   } | 
|  | 192 | 
|  | 193   bus_->RemoveObjectProxy(shill::kFlimflamServiceName, object_path, | 
|  | 194                           base::Bind(&base::DoNothing)); | 
|  | 195   helpers_.erase(helpers_.find(object_path.value())); | 
|  | 196   delete helper_info; | 
|  | 197 } | 
|  | 198 | 
|  | 199 void ShillThirdPartyVpnDriverClientImpl::SetParameters( | 
|  | 200     const std::string& object_path_value, | 
|  | 201     const base::DictionaryValue& parameters, | 
|  | 202     const base::Closure& callback, | 
|  | 203     const ShillClientHelper::ErrorCallback& error_callback) { | 
|  | 204   dbus::MethodCall method_call(shill::kFlimflamThirdPartyVpnInterface, | 
|  | 205                                shill::kSetParametersFunction); | 
|  | 206   dbus::MessageWriter writer(&method_call); | 
|  | 207   dbus::MessageWriter array_writer(nullptr); | 
|  | 208   writer.OpenArray("{ss}", &array_writer); | 
|  | 209   for (base::DictionaryValue::Iterator it(parameters); !it.IsAtEnd(); | 
|  | 210        it.Advance()) { | 
|  | 211     if (valid_keys_.find(it.key()) == valid_keys_.end()) { | 
|  | 212       LOG(WARNING) << "Unknown key " << it.key(); | 
|  | 213       continue; | 
|  | 214     } | 
|  | 215     std::string value; | 
|  | 216     if (!it.value().GetAsString(&value)) { | 
|  | 217       LOG(WARNING) << "Non string value " << it.value(); | 
|  | 218       continue; | 
|  | 219     } | 
|  | 220     dbus::MessageWriter entry_writer(nullptr); | 
|  | 221     array_writer.OpenDictEntry(&entry_writer); | 
|  | 222     entry_writer.AppendString(it.key()); | 
|  | 223     entry_writer.AppendString(value); | 
|  | 224     array_writer.CloseContainer(&entry_writer); | 
|  | 225   } | 
|  | 226   writer.CloseContainer(&array_writer); | 
|  | 227   GetHelper(object_path_value) | 
|  | 228       ->CallVoidMethodWithErrorCallback(&method_call, callback, error_callback); | 
|  | 229 } | 
|  | 230 | 
|  | 231 void ShillThirdPartyVpnDriverClientImpl::UpdateConnectionState( | 
|  | 232     const std::string& object_path_value, | 
|  | 233     const uint32_t connection_state, | 
|  | 234     const base::Closure& callback, | 
|  | 235     const ShillClientHelper::ErrorCallback& error_callback) { | 
|  | 236   dbus::MethodCall method_call(shill::kFlimflamThirdPartyVpnInterface, | 
|  | 237                                shill::kUpdateConnectionStateFunction); | 
|  | 238   dbus::MessageWriter writer(&method_call); | 
|  | 239   writer.AppendUint32(connection_state); | 
|  | 240   GetHelper(object_path_value) | 
|  | 241       ->CallVoidMethodWithErrorCallback(&method_call, callback, error_callback); | 
|  | 242 } | 
|  | 243 | 
|  | 244 void ShillThirdPartyVpnDriverClientImpl::SendPacket( | 
|  | 245     const std::string& object_path_value, | 
|  | 246     const std::string& ip_packet, | 
|  | 247     const base::Closure& callback, | 
|  | 248     const ShillClientHelper::ErrorCallback& error_callback) { | 
|  | 249   dbus::MethodCall method_call(shill::kFlimflamThirdPartyVpnInterface, | 
|  | 250                                shill::kSendPacketFunction); | 
|  | 251   dbus::MessageWriter writer(&method_call); | 
|  | 252   writer.AppendArrayOfBytes(reinterpret_cast<const uint8_t*>(ip_packet.data()), | 
|  | 253                             ip_packet.size()); | 
|  | 254   GetHelper(object_path_value) | 
|  | 255       ->CallVoidMethodWithErrorCallback(&method_call, callback, error_callback); | 
|  | 256 } | 
|  | 257 | 
|  | 258 // static | 
|  | 259 void ShillThirdPartyVpnDriverClientImpl::OnPacketReceived( | 
|  | 260     base::WeakPtr<HelperInfo> helper_info, | 
|  | 261     dbus::Signal* signal) { | 
|  | 262   if (!helper_info || !helper_info->observer()) | 
|  | 263     return; | 
|  | 264 | 
|  | 265   dbus::MessageReader reader(signal); | 
|  | 266   const uint8_t* data = nullptr; | 
|  | 267   size_t length = 0; | 
|  | 268   if (reader.PopArrayOfBytes(&data, &length)) | 
|  | 269     helper_info->observer()->OnPacketReceived(data, length); | 
|  | 270 } | 
|  | 271 | 
|  | 272 // static | 
|  | 273 void ShillThirdPartyVpnDriverClientImpl::OnPlatformMessage( | 
|  | 274     base::WeakPtr<HelperInfo> helper_info, | 
|  | 275     dbus::Signal* signal) { | 
|  | 276   if (!helper_info || !helper_info->observer()) | 
|  | 277     return; | 
|  | 278 | 
|  | 279   dbus::MessageReader reader(signal); | 
|  | 280   uint32_t platform_message = 0; | 
|  | 281   if (reader.PopUint32(&platform_message)) | 
|  | 282     helper_info->observer()->OnPlatformMessage(platform_message); | 
|  | 283 } | 
|  | 284 | 
|  | 285 // static | 
|  | 286 void ShillThirdPartyVpnDriverClientImpl::OnSignalConnected( | 
|  | 287     const std::string& interface, | 
|  | 288     const std::string& signal, | 
|  | 289     bool success) { | 
|  | 290   LOG_IF(ERROR, !success) << "Connect to " << interface << " " << signal | 
|  | 291                           << " failed."; | 
|  | 292 } | 
|  | 293 | 
|  | 294 ShillClientHelper* ShillThirdPartyVpnDriverClientImpl::GetHelper( | 
|  | 295     const std::string& object_path_value) { | 
|  | 296   return GetHelperInfo(object_path_value)->helper(); | 
|  | 297 } | 
|  | 298 | 
|  | 299 ShillThirdPartyVpnDriverClientImpl::HelperInfo* | 
|  | 300 ShillThirdPartyVpnDriverClientImpl::FindHelperInfo( | 
|  | 301     const dbus::ObjectPath& object_path) { | 
|  | 302   HelperMap::iterator it = helpers_.find(object_path.value()); | 
|  | 303   return (it != helpers_.end()) ? it->second : nullptr; | 
|  | 304 } | 
|  | 305 | 
|  | 306 ShillThirdPartyVpnDriverClientImpl::HelperInfo* | 
|  | 307 ShillThirdPartyVpnDriverClientImpl::GetHelperInfo( | 
|  | 308     const std::string& object_path_value) { | 
|  | 309   dbus::ObjectPath object_path(object_path_value); | 
|  | 310   HelperInfo* helper_info = FindHelperInfo(object_path); | 
|  | 311   if (helper_info) | 
|  | 312     return helper_info; | 
|  | 313 | 
|  | 314   // There is no helper for the profile, create it. | 
|  | 315   dbus::ObjectProxy* object_proxy = | 
|  | 316       bus_->GetObjectProxy(shill::kFlimflamServiceName, object_path); | 
|  | 317   helper_info = new HelperInfo(object_proxy); | 
|  | 318   helpers_[object_path_value] = helper_info; | 
|  | 319   return helper_info; | 
|  | 320 } | 
|  | 321 | 
|  | 322 }  // namespace | 
|  | 323 | 
|  | 324 ShillThirdPartyVpnDriverClient::ShillThirdPartyVpnDriverClient() { | 
|  | 325 } | 
|  | 326 | 
|  | 327 ShillThirdPartyVpnDriverClient::~ShillThirdPartyVpnDriverClient() { | 
|  | 328 } | 
|  | 329 | 
|  | 330 // static | 
|  | 331 ShillThirdPartyVpnDriverClient* ShillThirdPartyVpnDriverClient::Create() { | 
|  | 332   return new ShillThirdPartyVpnDriverClientImpl(); | 
|  | 333 } | 
|  | 334 | 
|  | 335 }  // namespace chromeos | 
| OLD | NEW | 
|---|