asimov_protocol/
ping_protocol.rs1use alloc::{boxed::Box, sync::Arc};
6use core::{error::Error, result::Result};
7use iroh::{
8 Endpoint, EndpointAddr,
9 endpoint::Connection,
10 protocol::{AcceptError, ProtocolHandler},
11};
12use iroh_metrics::{Counter, MetricsGroup};
13use tokio::time::{Duration, Instant};
14
15pub const PING_ALPN: &[u8] = b"asimov/ping";
17
18#[derive(Debug, Default, MetricsGroup)]
20#[metrics(name = "ping")]
21pub struct PingMetrics {
22 pub pings_sent: Counter,
24
25 pub pings_recv: Counter,
27}
28
29#[derive(Debug, Clone)]
31pub struct PingProtocol {
32 metrics: Arc<PingMetrics>,
34}
35
36impl Default for PingProtocol {
37 fn default() -> Self {
38 Self::new()
39 }
40}
41
42impl PingProtocol {
43 pub fn new() -> Self {
45 Self {
46 metrics: Arc::new(PingMetrics::default()),
47 }
48 }
49
50 pub fn metrics(&self) -> &Arc<PingMetrics> {
52 &self.metrics
53 }
54
55 pub async fn ping(
57 &self,
58 endpoint: &Endpoint,
59 addr: EndpointAddr,
60 ) -> Result<Duration, Box<dyn Error>> {
61 let conn = endpoint.connect(addr, PING_ALPN).await?;
63
64 let (mut send, mut recv) = conn.open_bi().await?;
66
67 let start = Instant::now();
69
70 send.write_all(b"PING").await?;
72 send.finish()?;
73
74 let response = recv.read_to_end(4).await?;
76 assert_eq!(&response, b"PONG");
77
78 let duration = start.elapsed();
80
81 self.metrics.pings_sent.inc();
83
84 conn.close(0u32.into(), b"BYE!");
86
87 Ok(duration)
88 }
89}
90
91impl ProtocolHandler for PingProtocol {
92 async fn accept(&self, connection: Connection) -> n0_error::Result<(), AcceptError> {
97 let node_id = connection.remote_id();
98 #[cfg(feature = "std")]
99 std::eprintln!("Accepted a connection from node {node_id}"); let (mut send, mut recv) = connection.accept_bi().await?;
103
104 let req = recv.read_to_end(4).await.map_err(AcceptError::from_err)?;
106 assert_eq!(&req, b"PING");
107
108 self.metrics.pings_recv.inc();
110
111 send.write_all(b"PONG")
113 .await
114 .map_err(AcceptError::from_err)?;
115 send.finish()?;
116
117 connection.closed().await;
120
121 Ok(())
122 }
123}