• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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