• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 #include "host/libs/config/adb/adb.h"
17 
18 #include "host/libs/config/cuttlefish_config.h"
19 #include "host/libs/config/known_paths.h"
20 
21 namespace cuttlefish {
22 namespace {
23 
24 class AdbHelper {
25  public:
INJECT(AdbHelper (const CuttlefishConfig::InstanceSpecific & instance,const AdbConfig & config))26   INJECT(AdbHelper(const CuttlefishConfig::InstanceSpecific& instance,
27                    const AdbConfig& config))
28       : instance_(instance), config_(config) {}
29 
ModeEnabled(const AdbMode & mode) const30   bool ModeEnabled(const AdbMode& mode) const {
31     return config_.Modes().count(mode) > 0;
32   }
33 
ConnectorTcpArg() const34   std::string ConnectorTcpArg() const {
35     return "0.0.0.0:" + std::to_string(instance_.adb_host_port());
36   }
37 
ConnectorVsockArg() const38   std::string ConnectorVsockArg() const {
39     return "vsock:" + std::to_string(instance_.vsock_guest_cid()) + ":5555";
40   }
41 
VsockTunnelEnabled() const42   bool VsockTunnelEnabled() const {
43     return instance_.vsock_guest_cid() > 2 && ModeEnabled(AdbMode::VsockTunnel);
44   }
45 
VsockHalfTunnelEnabled() const46   bool VsockHalfTunnelEnabled() const {
47     return instance_.vsock_guest_cid() > 2 &&
48            ModeEnabled(AdbMode::VsockHalfTunnel);
49   }
50 
TcpConnectorEnabled() const51   bool TcpConnectorEnabled() const {
52     bool vsock_tunnel = VsockTunnelEnabled();
53     bool vsock_half_tunnel = VsockHalfTunnelEnabled();
54     return config_.RunConnector() && (vsock_tunnel || vsock_half_tunnel);
55   }
56 
VsockConnectorEnabled() const57   bool VsockConnectorEnabled() const {
58     return config_.RunConnector() && ModeEnabled(AdbMode::NativeVsock);
59   }
60 
61  private:
62   const CuttlefishConfig::InstanceSpecific& instance_;
63   const AdbConfig& config_;
64 };
65 
66 class AdbConnector : public CommandSource {
67  public:
INJECT(AdbConnector (const AdbHelper & helper))68   INJECT(AdbConnector(const AdbHelper& helper)) : helper_(helper) {}
69 
70   // CommandSource
Commands()71   std::vector<Command> Commands() override {
72     Command console_forwarder_cmd(ConsoleForwarderBinary());
73     Command adb_connector(AdbConnectorBinary());
74     std::set<std::string> addresses;
75 
76     if (helper_.TcpConnectorEnabled()) {
77       addresses.insert(helper_.ConnectorTcpArg());
78     }
79     if (helper_.VsockConnectorEnabled()) {
80       addresses.insert(helper_.ConnectorVsockArg());
81     }
82 
83     if (addresses.size() == 0) {
84       return {};
85     }
86     std::string address_arg = "--addresses=";
87     for (auto& arg : addresses) {
88       address_arg += arg + ",";
89     }
90     address_arg.pop_back();
91     adb_connector.AddParameter(address_arg);
92     std::vector<Command> commands;
93     commands.emplace_back(std::move(adb_connector));
94     return std::move(commands);
95   }
96 
97   // SetupFeature
Name() const98   std::string Name() const override { return "AdbConnector"; }
Enabled() const99   bool Enabled() const override {
100     return helper_.TcpConnectorEnabled() || helper_.VsockConnectorEnabled();
101   }
102 
103  private:
Dependencies() const104   std::unordered_set<SetupFeature*> Dependencies() const override { return {}; }
Setup()105   bool Setup() override { return true; }
106 
107   const AdbHelper& helper_;
108 };
109 
110 class SocketVsockProxy : public CommandSource {
111  public:
INJECT(SocketVsockProxy (const AdbHelper & helper,const CuttlefishConfig::InstanceSpecific & instance,KernelLogPipeProvider & log_pipe_provider))112   INJECT(SocketVsockProxy(const AdbHelper& helper,
113                           const CuttlefishConfig::InstanceSpecific& instance,
114                           KernelLogPipeProvider& log_pipe_provider))
115       : helper_(helper),
116         instance_(instance),
117         log_pipe_provider_(log_pipe_provider) {}
118 
119   // CommandSource
Commands()120   std::vector<Command> Commands() override {
121     std::vector<Command> commands;
122     if (helper_.VsockTunnelEnabled()) {
123       Command adb_tunnel(SocketVsockProxyBinary());
124       adb_tunnel.AddParameter("-adbd_events_fd=", kernel_log_pipe_);
125       /**
126        * This socket_vsock_proxy (a.k.a. sv proxy) runs on the host. It assumes
127        * that another sv proxy runs inside the guest. see:
128        * shared/config/init.vendor.rc The sv proxy in the guest exposes
129        * vsock:cid:6520 across the cuttlefish instances in multi-tenancy. cid is
130        * different per instance.
131        *
132        * This host sv proxy should cooperate with the guest sv proxy. Thus, one
133        * end of the tunnel is vsock:cid:6520 regardless of instance number.
134        * Another end faces the host adb daemon via tcp. Thus, the server type is
135        * tcp here. The tcp port differs from instance to instance, and is
136        * instance.adb_host_port()
137        *
138        */
139       adb_tunnel.AddParameter("--server=tcp");
140       adb_tunnel.AddParameter("--vsock_port=6520");
141       adb_tunnel.AddParameter("--server_fd=", tcp_server_);
142       adb_tunnel.AddParameter("--vsock_cid=", instance_.vsock_guest_cid());
143       commands.emplace_back(std::move(adb_tunnel));
144     }
145     if (helper_.VsockHalfTunnelEnabled()) {
146       Command adb_tunnel(SocketVsockProxyBinary());
147       adb_tunnel.AddParameter("-adbd_events_fd=", kernel_log_pipe_);
148       /*
149        * This socket_vsock_proxy (a.k.a. sv proxy) runs on the host, and
150        * cooperates with the adbd inside the guest. See this file:
151        *  shared/device.mk, especially the line says "persist.adb.tcp.port="
152        *
153        * The guest adbd is listening on vsock:cid:5555 across cuttlefish
154        * instances. Sv proxy faces the host adb daemon via tcp. The server type
155        * should be therefore tcp, and the port should differ from instance to
156        * instance and be equal to instance.adb_host_port()
157        */
158       adb_tunnel.AddParameter("--server=tcp");
159       adb_tunnel.AddParameter("--vsock_port=", 5555);
160       adb_tunnel.AddParameter("--server_fd=", tcp_server_);
161       adb_tunnel.AddParameter("--vsock_cid=", instance_.vsock_guest_cid());
162       commands.emplace_back(std::move(adb_tunnel));
163     }
164     return commands;
165   }
166 
167   // SetupFeature
Name() const168   std::string Name() const override { return "SocketVsockProxy"; }
Enabled() const169   bool Enabled() const override {
170     return helper_.VsockTunnelEnabled() || helper_.VsockHalfTunnelEnabled();
171   }
172 
173  private:
Dependencies() const174   std::unordered_set<SetupFeature*> Dependencies() const override {
175     return {static_cast<SetupFeature*>(&log_pipe_provider_)};
176   }
Setup()177   bool Setup() override {
178     tcp_server_ =
179         SharedFD::SocketLocalServer(instance_.adb_host_port(), SOCK_STREAM);
180     if (!tcp_server_->IsOpen()) {
181       LOG(ERROR) << "Unable to create socket_vsock_proxy server socket: "
182                  << tcp_server_->StrError();
183       return false;
184     }
185     kernel_log_pipe_ = log_pipe_provider_.KernelLogPipe();
186     return true;
187   }
188 
189   const AdbHelper& helper_;
190   const CuttlefishConfig::InstanceSpecific& instance_;
191   KernelLogPipeProvider& log_pipe_provider_;
192   SharedFD kernel_log_pipe_;
193   SharedFD tcp_server_;
194 };
195 
196 }  // namespace
197 
198 fruit::Component<fruit::Required<KernelLogPipeProvider, const AdbConfig,
199                                  const CuttlefishConfig::InstanceSpecific>>
LaunchAdbComponent()200 LaunchAdbComponent() {
201   return fruit::createComponent()
202       .addMultibinding<CommandSource, AdbConnector>()
203       .addMultibinding<CommandSource, SocketVsockProxy>()
204       .addMultibinding<SetupFeature, AdbConnector>()
205       .addMultibinding<SetupFeature, SocketVsockProxy>();
206 }
207 
208 }  // namespace cuttlefish
209