// 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.
library fuchsia.virtualization;

using zx;

/// `HOST_CID` is the reserved context ID (CID) of the host.
///
/// CIDs for guests are assigned by the Manager and can be found in the
/// corresponding `InstanceInfo` structure.
const HOST_CID uint32 = 2;
const DEFAULT_GUEST_CID uint32 = 3;

/// Exposed by guests capable of listening via vsocks. On a request to establish
/// a connection, the `Accept` method will be called. If the port is open and
/// accepting connections, the implementation should return `ZX_OK`.
///
/// Also see `GuestVsockEndpoint`.
protocol GuestVsockAcceptor {
    Accept(resource struct {
        src_cid uint32;
        src_port uint32;
        port uint32;
        socket zx.handle:SOCKET;
    }) -> (struct {}) error zx.status;
};

/// Exposed by a host capable of listening via vsocks. A variant of a
/// `GuestVsockAcceptor` that is responsible for creating the `socket` with which
/// to communicate.
protocol HostVsockAcceptor {
    Accept(struct {
        src_cid uint32;
        src_port uint32;
        port uint32;
    }) -> (resource struct {
        socket zx.handle:SOCKET;
    }) error zx.status;
};

/// Exposed by a host capable of connecting via vsocks. This allows a guest to
/// identify itself via {src_cid, src_port}, and request to connect to
/// {cid, port}. The host should return `ZX_OK`, and create a socket with which
/// to communicate.
protocol HostVsockConnector {
    Connect(struct {
        src_cid uint32;
        src_port uint32;
        cid uint32;
        port uint32;
    }) -> (resource struct {
        socket zx.handle:SOCKET;
    }) error zx.status;
};

/// Exposed by guests capable of handling vsock traffic. During
/// initialization the Manager will assign a unique CID to this endpoint and
/// provide a `HostVsockConnector` that can be used to establish outbound
/// connections. The implementation should provide a `GuestVsockAcceptor`
/// implementation that can handle any inbound connection requests.
@discoverable
protocol GuestVsockEndpoint {
    SetContextId(resource struct {
        cid uint32;
        connector client_end:HostVsockConnector;
        acceptor server_end:GuestVsockAcceptor;
    });
    -> OnShutdown(struct {
        src_cid uint32;
        src_port uint32;
        dst_cid uint32;
        dst_port uint32;
    });
};

/// Exposed by a host to provide the ability for listeners to be multiplexed by
/// port and to manage dynamic port allocation for outbound connections.
@discoverable
protocol HostVsockEndpoint {
    /// Instructs the device to listen for guest initiated connections to a given port by
    /// using `acceptor` when the guest creates a connection.
    ///
    /// Possible errors:
    ///     - ZX_ERR_ALREADY_BOUND: A client is already listening on this port.
    Listen(resource struct {
        port uint32;
        acceptor client_end:HostVsockAcceptor;
    }) -> (struct {}) error zx.status;

    /// Attempts to create a vsock connection to a guest on 'guest_port'. Uses a dynamically chosen
    /// ephemeral host port.
    ///
    /// Possible errors:
    ///     - ZX_ERR_NO_RESOURCES: The device couldn't allocate an unused host port.
    ///     - ZX_ERR_CONNECTION_REFUSED: The guest refused this connection.
    ///
    /// Other errors are related to socket creation, see
    /// [zx_socket_create](https://fuchsia.dev/fuchsia-src/reference/syscalls/socket_create.md)
    Connect2(struct {
        guest_port uint32;
    }) -> (resource struct {
        socket zx.handle:SOCKET;
    }) error zx.status;
};
