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