Create a vsock_half_tunnel mode.

This uses native adb/vsock support in the guest, but presents a TCP
connection on the host that can be used across the network. This is a
compromise between the high-performance vsock code and remote access.

Observed behavior with adb push/pull:
$ adb push ~/tmp/100m /data/local/tmp
1 file pushed. 135.9 MB/s (104857600 bytes in 0.736s)
$ adb push ~/tmp/100m /data/local/tmp
1 file pushed. 229.4 MB/s (104857600 bytes in 0.436s)
$ adb pull /data/local/tmp ~/tmp/100m2
1 file pulled. 13.2 MB/s (104857600 bytes in 7.603s)

Push is surprisingly close to the performance of native_vsock, while
pull is still comparable to tunnel and vsock_tunnel.

Test: Run with -adb_mode=vsock_half_tunnel
Bug: 121166534
Change-Id: Ia11ff2915b7799d7dbbc3f6a99de33e5ad9e19b3
diff --git a/host/commands/launch/flags.cc b/host/commands/launch/flags.cc
index 4548588..ae5d0e6 100644
--- a/host/commands/launch/flags.cc
+++ b/host/commands/launch/flags.cc
@@ -119,9 +119,13 @@
               vsoc::DefaultHostArtifactsPath("bin/socket_vsock_proxy"),
               "Location of the socket_vsock_proxy binary.");
 DEFINE_string(adb_mode, "",
-              "Mode for adb connection. Can be 'usb' for usb forwarding, "
-              "'tunnel' for tcp connection, 'vsock_tunnel' for vsock tcp,"
-              "or a comma separated list of types as in 'usb,tunnel'");
+              "Mode for ADB connection. Can be 'usb' for USB forwarding, "
+              "'tunnel' for a TCP connection tunneled through VSoC, "
+              "'vsock_tunnel' for a TCP connection tunneled through vsock, "
+              "'native_vsock' for a  direct connection to the guest ADB over "
+              "vsock, 'vsock_half_tunnel' for a TCP connection forwarded to "
+              "the guest ADB server, or a comma separated list of types as in "
+              "'usb,tunnel'");
 DEFINE_bool(run_adb_connector, true,
             "Maintain adb connection by sending 'adb connect' commands to the "
             "server. Only relevant with --adb_mode=tunnel or vsock_tunnel");
diff --git a/host/commands/launch/launch.cc b/host/commands/launch/launch.cc
index 497b6c4..80cebd6 100644
--- a/host/commands/launch/launch.cc
+++ b/host/commands/launch/launch.cc
@@ -18,6 +18,7 @@
 constexpr char kAdbModeTunnel[] = "tunnel";
 constexpr char kAdbModeNativeVsock[] = "native_vsock";
 constexpr char kAdbModeVsockTunnel[] = "vsock_tunnel";
+constexpr char kAdbModeVsockHalfTunnel[] = "vsock_half_tunnel";
 constexpr char kAdbModeUsb[] = "usb";
 
 cvd::SharedFD CreateIvServerUnixSocket(const std::string& path) {
@@ -58,9 +59,17 @@
       && AdbModeEnabled(config, kAdbModeVsockTunnel);
 }
 
+bool AdbVsockHalfTunnelEnabled(const vsoc::CuttlefishConfig& config) {
+  return config.vsock_guest_cid() > 2
+      && AdbModeEnabled(config, kAdbModeVsockHalfTunnel);
+}
+
 bool AdbTcpConnectorEnabled(const vsoc::CuttlefishConfig& config) {
+  bool tunnel = AdbTunnelEnabled(config);
+  bool vsock_tunnel = AdbVsockHalfTunnelEnabled(config);
+  bool vsock_half_tunnel = AdbVsockHalfTunnelEnabled(config);
   return config.run_adb_connector()
-      && (AdbTunnelEnabled(config) || AdbVsockTunnelEnabled(config));
+      && (tunnel || vsock_tunnel || vsock_half_tunnel);
 }
 
 bool AdbVsockConnectorEnabled(const vsoc::CuttlefishConfig& config) {
@@ -244,6 +253,16 @@
     process_monitor->StartSubprocess(std::move(adb_tunnel),
                                      GetOnSubprocessExitCallback(config));
   }
+  if (AdbVsockHalfTunnelEnabled(config)) {
+    cvd::Command adb_tunnel(config.socket_vsock_proxy_binary());
+    adb_tunnel.AddParameter("--vsock_port=5555");
+    adb_tunnel.AddParameter(
+        std::string{"--tcp_port="} + std::to_string(GetHostPort()));
+    adb_tunnel.AddParameter(std::string{"--vsock_guest_cid="} +
+                            std::to_string(config.vsock_guest_cid()));
+    process_monitor->StartSubprocess(std::move(adb_tunnel),
+                                     GetOnSubprocessExitCallback(config));
+  }
 }
 
 void LaunchIvServerIfEnabled(cvd::ProcessMonitor* process_monitor,