blob: 441c6c0a3040f37dbd1cc76a725605115a338fef [file] [log] [blame]
// Copyright 2019 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.
#ifndef SRC_DEVELOPER_SSHD_HOST_SERVICE_H_
#define SRC_DEVELOPER_SSHD_HOST_SERVICE_H_
#include <fidl/fuchsia.boot/cpp/fidl.h>
#include <fidl/fuchsia.component/cpp/fidl.h>
#include <lib/async/dispatcher.h>
#include <lib/async/wait.h>
#include <lib/fidl/cpp/wire/unknown_interaction_handler.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/process.h>
#include <lib/zx/socket.h>
#include <sys/socket.h>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include <fbl/unique_fd.h>
#include "src/lib/fsl/tasks/fd_waiter.h"
namespace sshd_host {
// Name of the collection that contains sshd shell child components.
inline constexpr std::string_view kShellCollection = "shell";
class Service;
// Service relies on the default async dispatcher and is not thread safe.
class Service {
public:
Service(async_dispatcher_t* dispatcher, uint16_t port);
~Service();
private:
struct Controller;
void Wait();
void Launch(fbl::unique_fd conn);
void OnStop(zx_status_t status, Controller* controller);
async_dispatcher_t* dispatcher_;
fbl::unique_fd sock_;
fsl::FDWaiter waiter_;
uint64_t next_child_num_ = 0;
struct Controller final : public fidl::AsyncEventHandler<fuchsia_component::ExecutionController> {
Controller(Service* service, uint64_t child_num, std::string child_name,
fidl::ClientEnd<fuchsia_component::ExecutionController> client_end,
async_dispatcher_t* dispatcher, fidl::SyncClient<fuchsia_component::Realm> realm,
zx::socket stderr_socket);
~Controller();
void OnStop(fidl::Event<fuchsia_component::ExecutionController::OnStop>& event) override {
service_->OnStop(event.stopped_payload().status().value_or(ZX_OK), this);
}
void on_fidl_error(fidl::UnbindInfo error) override {
FX_LOGS(WARNING) << "encountered FIDL error " << error;
service_->OnStop(error.ToError().status(), this);
}
void handle_unknown_event(
fidl::UnknownEventMetadata<fuchsia_component::ExecutionController> metadata) override {
FX_LOGS(WARNING) << "fuchsia.component/ExecutionController delivered unknown event "
<< metadata.event_ordinal;
}
void Wait();
void OnStderr(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
const zx_packet_signal_t* signal);
fidl::Client<fuchsia_component::ExecutionController>& operator->() { return client_; }
Service* service_;
uint64_t child_num_;
std::string child_name_;
fidl::Client<fuchsia_component::ExecutionController> client_;
fidl::SyncClient<fuchsia_component::Realm> realm_;
zx::socket stderr_socket_;
async::WaitMethod<Controller, &Controller::OnStderr> stderr_waiter_;
std::string stderr_buf_;
};
std::map<uint64_t, Controller> controllers_;
};
} // namespace sshd_host
#endif // SRC_DEVELOPER_SSHD_HOST_SERVICE_H_