fastn_net/
ping.rs

1/// Response message sent back after receiving a ping.
2pub const PONG: &[u8] = b"pong\n";
3pub const ACK_PONG: &[u8] = b"ack\npong\n";
4
5/// Sends a ping message to test connectivity with a peer.
6///
7/// Opens a bidirectional stream, sends a `Protocol::Ping` message,
8/// and waits for a PONG response. Used for connection health checks.
9///
10/// # Errors
11///
12/// Returns an error if:
13/// - Failed to open bidirectional stream
14/// - Failed to send ping message
15/// - Failed to receive or incorrect pong response
16pub async fn ping(conn: &iroh::endpoint::Connection) -> eyre::Result<()> {
17    tracing::info!("ping called");
18    let (mut send_stream, mut recv_stream) = conn.open_bi().await?;
19    tracing::info!("got bi, sending ping");
20    send_stream
21        .write_all(&serde_json::to_vec(&crate::Protocol::Ping)?)
22        .await?;
23    tracing::info!("sent ping, sending newline");
24    send_stream.write_all("\n".as_bytes()).await?;
25    tracing::info!("newline sent, waiting for reply");
26    let msg = recv_stream
27        .read_to_end(1000)
28        .await
29        .inspect_err(|e| tracing::error!("failed to read: {e}"))?;
30    tracing::info!("got {:?}, {PONG:?}", str::from_utf8(&msg));
31    if msg != ACK_PONG {
32        return Err(eyre::anyhow!("expected {PONG:?}, got {msg:?}"));
33    }
34    tracing::info!("got reply, finishing stream");
35    send_stream.finish()?;
36    tracing::info!("finished stream");
37    Ok(())
38}