blob: 6142b0f4aac87c9b510f9465dc8a02ff27d71ffb [file] [log] [blame] [edit]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "garnet/bin/guest/cli/socat.h"
#include <iostream>
#include <fuchsia/guest/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include "garnet/bin/guest/cli/serial.h"
#include "lib/app/cpp/environment_services.h"
#include "lib/fidl/cpp/binding.h"
#include "lib/fxl/logging.h"
class SocketAcceptor : public fuchsia::guest::SocketAcceptor {
public:
SocketAcceptor(uint32_t port, async::Loop* loop)
: port_(port), console_(loop) {}
void Accept(uint32_t src_cid, uint32_t src_port, uint32_t port,
AcceptCallback callback) {
FXL_CHECK(port == port_);
zx::socket h1, h2;
zx_status_t status = zx::socket::create(ZX_SOCKET_STREAM, &h1, &h2);
if (status != ZX_OK) {
callback(ZX_ERR_CONNECTION_REFUSED, zx::socket());
return;
}
callback(ZX_OK, std::move(h2));
console_.Start(std::move(h2));
}
private:
uint32_t port_;
SerialConsole console_;
};
void handle_socat_listen(uint32_t env_id, uint32_t port) {
async::Loop loop(&kAsyncLoopConfigMakeDefault);
fuchsia::guest::GuestManagerSyncPtr guestmgr;
component::ConnectToEnvironmentService(guestmgr.NewRequest());
fuchsia::guest::GuestEnvironmentSyncPtr guest_env;
guestmgr->ConnectToEnvironment(env_id, guest_env.NewRequest());
fuchsia::guest::ManagedSocketEndpointSyncPtr vsock_endpoint;
guest_env->GetHostSocketEndpoint(vsock_endpoint.NewRequest());
SocketAcceptor acceptor(port, &loop);
fidl::Binding<fuchsia::guest::SocketAcceptor> binding(&acceptor);
zx_status_t status;
vsock_endpoint->Listen(port, binding.NewBinding(), &status);
if (status != ZX_OK) {
std::cerr << "Failed to listen on port " << port << "\n";
return;
}
loop.Run();
}
void handle_socat_connect(uint32_t env_id, uint32_t cid, uint32_t port) {
async::Loop loop(&kAsyncLoopConfigMakeDefault);
fuchsia::guest::GuestManagerSyncPtr guestmgr;
component::ConnectToEnvironmentService(guestmgr.NewRequest());
fuchsia::guest::GuestEnvironmentSyncPtr guest_env;
guestmgr->ConnectToEnvironment(env_id, guest_env.NewRequest());
zx_status_t status;
zx::socket socket;
fuchsia::guest::ManagedSocketEndpointSyncPtr vsock_endpoint;
guest_env->GetHostSocketEndpoint(vsock_endpoint.NewRequest());
vsock_endpoint->Connect(cid, port, &status, &socket);
if (status != ZX_OK) {
std::cerr << "Failed to connect " << status << "\n";
return;
}
SerialConsole console(&loop);
console.Start(std::move(socket));
loop.Run();
}