use std::net::SocketAddr;
use std::time::{SystemTime, UNIX_EPOCH};
use serde::{Deserialize, Serialize};
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum RelayMessage {
#[serde(rename = "register")]
Register {
peer_id: String,
network_id: String,
protocol_version: u32,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
listen_addrs: Vec<SocketAddr>,
},
#[serde(rename = "register_ack")]
RegisterAck {
success: bool,
message: String,
connected_peers: usize,
},
#[serde(rename = "unregister")]
Unregister { peer_id: String },
#[serde(rename = "relay_message")]
RelayGossipMessage {
from: String,
to: String,
payload: Vec<u8>,
seq: u64,
},
#[serde(rename = "broadcast")]
Broadcast {
from: String,
payload: Vec<u8>,
exclude: Vec<String>,
},
#[serde(rename = "peer_connected")]
PeerConnected { peer: RelayPeerInfo },
#[serde(rename = "peer_disconnected")]
PeerDisconnected { peer_id: String },
#[serde(rename = "get_peers")]
GetPeers { network_id: Option<String> },
#[serde(rename = "peers")]
Peers { peers: Vec<RelayPeerInfo> },
#[serde(rename = "ping")]
Ping { timestamp: u64 },
#[serde(rename = "pong")]
Pong { timestamp: u64 },
#[serde(rename = "hole_punch_request")]
HolePunchRequest {
peer_id: String,
target_peer_id: String,
external_addr: SocketAddr,
},
#[serde(rename = "hole_punch_coordinate")]
HolePunchCoordinate {
peer_id: String,
external_addr: SocketAddr,
},
#[serde(rename = "hole_punch_result")]
HolePunchResult { peer_id: String, success: bool },
#[serde(rename = "error")]
Error { code: u32, message: String },
}
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct RelayPeerInfo {
pub peer_id: String,
pub network_id: String,
pub protocol_version: u32,
pub connected_at: u64,
pub last_seen: u64,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub addresses: Vec<SocketAddr>,
}
impl RelayPeerInfo {
pub fn new(peer_id: String, network_id: String, protocol_version: u32) -> Self {
let now = unix_secs();
Self {
peer_id,
network_id,
protocol_version,
connected_at: now,
last_seen: now,
addresses: Vec::new(),
}
}
}
fn unix_secs() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0)
}