hightower_node/
lib.rs

1pub mod context;
2
3use context::CommonContext;
4use hightower_client::HightowerConnection;
5use tracing::{debug, error};
6
7const GATEWAY_URL_KEY: &[u8] = b"gateway/url";
8
9pub async fn run(context: &CommonContext) -> Result<HightowerConnection, String> {
10    // Get gateway URL from context or use default
11    let gateway_url = context
12        .kv
13        .get_bytes(GATEWAY_URL_KEY)
14        .ok()
15        .flatten()
16        .and_then(|bytes| String::from_utf8(bytes).ok())
17        .unwrap_or_else(|| "http://127.0.0.1:8008".to_string());
18
19    // Get auth token from context
20    let auth_token = context
21        .kv
22        .get_bytes(context::HT_AUTH_KEY)
23        .map_err(|e| format!("Failed to get auth token: {:?}", e))?
24        .ok_or_else(|| "Auth token not found in context".to_string())?;
25
26    let auth_token = String::from_utf8(auth_token)
27        .map_err(|e| format!("Invalid auth token encoding: {:?}", e))?;
28
29    debug!(gateway_url = %gateway_url, "Connecting to gateway");
30
31    // Connect using hightower-client - handles everything:
32    // - Keypair generation
33    // - Transport server creation
34    // - IP discovery via STUN
35    // - Gateway registration
36    // - Peer management
37    // - Persistence
38    let connection = HightowerConnection::connect(&gateway_url, &auth_token)
39        .await
40        .map_err(|e| {
41            error!(error = ?e, "Failed to connect to gateway");
42            format!("Failed to connect to gateway: {:?}", e)
43        })?;
44
45    debug!(
46        node_id = %connection.node_id(),
47        assigned_ip = %connection.assigned_ip(),
48        "Connected to gateway"
49    );
50
51    // Ping gateway to verify WireGuard connectivity
52    if let Err(e) = connection.ping_gateway().await {
53        error!(error = ?e, "Failed to ping gateway over WireGuard");
54    } else {
55        debug!("Successfully pinged gateway over WireGuard");
56    }
57
58    Ok(connection)
59}
60
61pub async fn deregister(connection: HightowerConnection) -> Result<(), String> {
62    connection
63        .disconnect()
64        .await
65        .map_err(|e| format!("Failed to disconnect: {:?}", e))
66}