1 /* 2 * Copyright (C) 2020 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 #pragma once 18 19 #include <sys/types.h> 20 21 #include <atomic> 22 #include <cstdint> 23 #include <map> 24 #include <memory> 25 #include <optional> 26 #include <set> 27 28 #include "common/libs/fs/shared_fd.h" 29 #include "host/libs/allocd/alloc_utils.h" 30 #include "host/libs/allocd/request.h" 31 #include "host/libs/allocd/resource.h" 32 #include "host/libs/allocd/utils.h" 33 34 namespace cuttlefish { 35 36 class Session { 37 public: Session(uint32_t session_id,uid_t uid)38 explicit Session(uint32_t session_id, uid_t uid) 39 : session_id_(session_id), uid_(uid) {} ~Session()40 ~Session() { ReleaseAllResources(); } 41 GetSessionID()42 uint32_t GetSessionID() { return session_id_; } GetUID()43 uid_t GetUID() { return uid_; } 44 GetActiveInterfaces()45 const std::set<std::string>& GetActiveInterfaces() { 46 return active_interfaces_; 47 } 48 Insert(const std::map<uint32_t,std::shared_ptr<StaticResource>> & resources)49 void Insert( 50 const std::map<uint32_t, std::shared_ptr<StaticResource>>& resources) { 51 managed_resources_.insert(resources.begin(), resources.end()); 52 } 53 ReleaseAllResources()54 bool ReleaseAllResources() { 55 bool success = true; 56 for (auto& res : managed_resources_) { 57 success &= res.second->ReleaseResource(); 58 } 59 managed_resources_.clear(); 60 61 return success; 62 } 63 ReleaseResource(uint32_t resource_id)64 bool ReleaseResource(uint32_t resource_id) { 65 auto it = managed_resources_.find(resource_id); 66 if (it == managed_resources_.end()) { 67 return false; 68 } 69 70 auto success = it->second->ReleaseResource(); 71 if (success) { 72 managed_resources_.erase(it); 73 } 74 75 return success; 76 } 77 78 private: 79 uint32_t session_id_{}; 80 uid_t uid_{}; 81 std::set<std::string> active_interfaces_; 82 std::map<uint32_t, std::shared_ptr<StaticResource>> managed_resources_; 83 }; 84 85 /* Manages static resources while the daemon is running. 86 * When resources, such as network interfaces are requested the ResourceManager 87 * allocates the resources and takes ownership of them. It will keep maintain 88 * the resource, until requested to release it(i.e. destroy it and/or tear down 89 * related config). When the daemon is stopped, it will walk its list of owned 90 * resources, and deallocate them from the system. 91 * 92 * Clients can request new resources by connecting to a socket, and sending a 93 * JSON request, detailing the type of resource required. 94 */ 95 struct ResourceManager { 96 public: 97 ResourceManager() = default; 98 99 ~ResourceManager(); 100 101 void SetSocketLocation(const std::string& sock_name); 102 103 void SetUseEbtablesLegacy(bool use_legacy); 104 105 void JsonServer(); 106 107 private: 108 uint32_t AllocateResourceID(); 109 uint32_t AllocateSessionID(); 110 111 bool AddInterface(const std::string& iface, IfaceType ty, uint32_t id, 112 uid_t uid); 113 114 bool RemoveInterface(const std::string& iface, IfaceType ty); 115 116 bool ValidateRequest(const Json::Value& request); 117 118 bool ValidateRequestList(const Json::Value& config); 119 120 bool ValidateConfigRequest(const Json::Value& config); 121 122 Json::Value JsonHandleIdRequest(); 123 124 Json::Value JsonHandleShutdownRequest(SharedFD client_socket); 125 126 Json::Value JsonHandleCreateInterfaceRequest(SharedFD client_socket, 127 const Json::Value& request); 128 129 Json::Value JsonHandleDestroyInterfaceRequest(const Json::Value& request); 130 131 Json::Value JsonHandleStopSessionRequest(const Json::Value& request, 132 uid_t uid); 133 134 bool CheckCredentials(SharedFD client_socket, uid_t uid); 135 SetUseIpv4BridgeResourceManager136 void SetUseIpv4Bridge(bool ipv4) { use_ipv4_bridge_ = ipv4; } 137 SetUseIpv6BridgeResourceManager138 void SetUseIpv6Bridge(bool ipv6) { use_ipv6_bridge_ = ipv6; } 139 140 std::optional<std::shared_ptr<Session>> FindSession(uint32_t id); 141 142 private: 143 std::atomic_uint32_t global_resource_id_ = 0; 144 std::atomic_uint32_t session_id_ = 0; 145 std::set<std::string> active_interfaces_; 146 std::map<uint32_t, std::shared_ptr<Session>> managed_sessions_; 147 std::map<uint32_t, std::shared_ptr<StaticResource>> pending_add_; 148 std::string location = kDefaultLocation; 149 bool use_ipv4_bridge_ = true; 150 bool use_ipv6_bridge_ = true; 151 bool use_ebtables_legacy_ = false; 152 cuttlefish::SharedFD shutdown_socket_; 153 }; 154 155 } // namespace cuttlefish 156