Skip to main content

iroh_services/
protocol.rs

1use anyhow::Result;
2use irpc::{channel::oneshot, rpc_requests};
3use rcan::Rcan;
4use serde::{Deserialize, Serialize};
5use uuid::Uuid;
6
7use crate::{caps::Caps, net_diagnostics::DiagnosticsReport};
8
9/// The main ALPN for connecting from the client to the cloud node.
10pub const ALPN: &[u8] = b"/iroh/n0des/1";
11
12pub type IrohServicesClient = irpc::Client<IrohServicesProtocol>;
13
14#[rpc_requests(message = ServicesMessage)]
15#[derive(Debug, Serialize, Deserialize)]
16#[allow(clippy::large_enum_variant)]
17pub enum IrohServicesProtocol {
18    #[rpc(tx=oneshot::Sender<()>)]
19    Auth(Auth),
20    #[rpc(tx=oneshot::Sender<RemoteResult<()>>)]
21    PutMetrics(PutMetrics),
22    #[rpc(tx=oneshot::Sender<Pong>)]
23    Ping(Ping),
24
25    #[rpc(tx=oneshot::Sender<RemoteResult<()>>)]
26    PutNetworkDiagnostics(PutNetworkDiagnostics),
27
28    #[rpc(tx=oneshot::Sender<RemoteResult<()>>)]
29    GrantCap(GrantCap),
30
31    #[rpc(tx=oneshot::Sender<RemoteResult<()>>)]
32    SendAlert(SendAlert),
33}
34
35/// Dedicated protocol for cloud-to-endpoint net diagnostics connections.
36#[rpc_requests(message = NetDiagnosticsMessage)]
37#[derive(Debug, Serialize, Deserialize)]
38#[allow(clippy::large_enum_variant)]
39pub enum ClientHostProtocol {
40    #[rpc(tx=oneshot::Sender<()>)]
41    Auth(Auth),
42    #[rpc(tx=oneshot::Sender<RemoteResult<DiagnosticsReport>>)]
43    RunNetworkDiagnostics(RunNetworkDiagnostics),
44}
45
46pub type RemoteResult<T> = Result<T, RemoteError>;
47
48#[derive(Clone, Serialize, Deserialize, thiserror::Error, Debug)]
49pub enum RemoteError {
50    #[error("Missing capability: {}", _0.to_strings().join(", "))]
51    MissingCapability(Caps),
52    #[error("Unauthorized: {}", _0)]
53    AuthError(String),
54    #[error("Internal server error")]
55    InternalServerError,
56}
57
58/// Authentication on first request
59#[derive(Debug, Serialize, Deserialize)]
60pub struct Auth {
61    pub caps: Rcan<Caps>,
62}
63
64/// Request to store the given metrics data
65#[derive(Debug, Serialize, Deserialize)]
66pub struct PutMetrics {
67    pub session_id: Uuid,
68    pub update: iroh_metrics::encoding::Update,
69}
70
71/// Simple ping requests
72#[derive(Debug, Serialize, Deserialize)]
73pub struct Ping {
74    pub req_id: [u8; 16],
75}
76
77/// Simple ping response
78#[derive(Debug, Serialize, Deserialize)]
79pub struct Pong {
80    pub req_id: [u8; 16],
81}
82
83/// Publishing network diagnostics
84#[derive(Debug, Serialize, Deserialize)]
85pub struct PutNetworkDiagnostics {
86    pub report: crate::net_diagnostics::DiagnosticsReport,
87}
88
89/// ask this node to run diagnostics & return the result.
90/// present even without the net_diagnostics feature flag because the request
91/// struct is empty in both cases
92#[derive(Debug, Serialize, Deserialize)]
93pub struct RunNetworkDiagnostics;
94
95/// Grant a capability token to the remote endpoint. The remote should store
96/// the RCAN and use it when dialing back to authorize its requests.
97#[derive(Debug, Serialize, Deserialize)]
98pub struct GrantCap {
99    pub cap: Rcan<Caps>,
100}
101
102/// Information about a captured error-level log event.
103#[derive(Debug, Clone, Serialize, Deserialize)]
104pub struct AlertInfo {
105    pub target: String,
106    pub message: String,
107    pub file: Option<String>,
108    pub line: Option<u32>,
109    pub timestamp_ms: u64,
110    #[serde(default)]
111    pub iroh_version: String,
112    #[serde(default)]
113    pub iroh_n0des_version: String,
114    /// Up to 200 recent log messages captured before this error, providing
115    /// context for what led to the alert.
116    #[serde(default)]
117    pub context: Vec<LogEntry>,
118}
119
120/// A single log entry captured in the context ring buffer.
121#[derive(Debug, Clone, Serialize, Deserialize)]
122pub struct LogEntry {
123    pub level: String,
124    pub target: String,
125    pub message: String,
126    pub timestamp_ms: u64,
127}
128
129/// Send an alert to n0des when an error-level log event is captured.
130#[derive(Debug, Serialize, Deserialize)]
131pub struct SendAlert {
132    pub session_id: Uuid,
133    pub alert: AlertInfo,
134}