namespace DodoSSH.Contracts;
///
/// A request for permission to relay to a host.
///
///
/// There is deliberately no address field. The server resolves the target from
/// , which must belong to a vault the caller holds Connect on and must have
/// relay enabled. Accepting a client-supplied address would turn the relay into an
/// authenticated open TCP proxy into the operator's network; see ADR 0004.
///
/// The host to reach.
///
/// A configured port forward to use instead of the host's own SSH port. Resolved server-side the
/// same way.
///
public sealed record RelayTicketRequest(
Guid HostId,
Guid? PortForwardId);
///
/// A short-lived, single-use ticket authorising exactly one relay connection.
///
///
/// The ticket grants no API access at all, which is why the WebSocket endpoint can accept it
/// alone. It is also the extraction seam: a standalone relay process needs only the data
/// protection key ring and the replay-guard table, no authorization code.
///
///
/// Opaque token. Sent as the ticket.<token> element of the
/// Sec-WebSocket-Protocol header, because constrained WebSocket clients cannot set
/// arbitrary headers.
///
/// Absolute URL of the relay endpoint.
/// Required WebSocket subprotocol.
/// Correlates the ticket with the resulting session record.
/// Expiry, at most 30 seconds out.
public sealed record RelayTicketResponse(
string Ticket,
Uri WebSocketUrl,
string SubProtocol,
Guid SessionId,
DateTimeOffset ExpiresAt);
/// Why a relay session ended.
public enum RelaySessionCloseReason
{
/// Not a legal value.
Unspecified = 0,
/// The client closed the connection.
ClientClosed = 1,
/// The target closed the connection.
TargetClosed = 2,
/// No traffic within the idle timeout.
IdleTimeout = 3,
/// The maximum session duration was reached.
DurationLimit = 4,
/// The server is shutting down and drained the session.
ServerShutdown = 5,
/// The connection to the target failed.
TargetUnreachable = 6,
/// An error ended the session.
Error = 7,
}
///
/// An audit record of one relay session.
///
///
/// Byte counts and duration are recorded; content never is. The relay forwards SSH ciphertext,
/// so session recording is impossible in this mode by construction — the compliance strength
/// and the limitation are the same fact.
///
/// The session.
/// Host that was reached.
/// Resolved target hostname.
/// Resolved target port.
/// When the session opened.
/// When it closed, or null while still open.
/// Bytes forwarded from client to target.
/// Bytes forwarded from target to client.
/// Why it ended.
public sealed record RelaySessionSummary(
Guid SessionId,
Guid HostId,
string TargetHost,
int TargetPort,
DateTimeOffset StartedAt,
DateTimeOffset? EndedAt,
long BytesClientToTarget,
long BytesTargetToClient,
RelaySessionCloseReason CloseReason);