webterm_agent/models/
handshaker.rs1use crate::agent_version::agent_version_to_flatbuffers;
2use crate::config::Config;
3use crate::messaging::process_r2a_handshake::process_r2a_handshake;
4use crate::models::agent_error::AgentError;
5use crate::models::relay::Relay;
6use reqwest::Client;
7use std::sync::Arc;
8use tracing::info;
9use webterm_core::flatbuffers_helpers::read_message;
10use webterm_core::generated::flatbuffers_schema::handshake_v1::R2aHandshakeRoot;
11use webterm_core::serialisers::handshake_v1::a2r_handshake_builder::A2rHandshakeBuilder;
12
13pub struct Handshaker {
14 pub result_relay: Arc<Relay>,
15 pub result_nonce: String,
16}
17
18impl Handshaker {
19 pub async fn run(config: Arc<Config>) -> Result<Self, AgentError> {
20 let relay = config.random_relay();
21 let mut subname = config.original_device_subname().to_string();
22 loop {
23 let result = initiate(config.clone(), relay.clone(), subname).await;
24
25 match result {
26 Ok((relay, nonce)) => {
27 return Ok(Self {
28 result_nonce: nonce,
29 result_relay: relay,
30 });
31 }
32 Err(AgentError::RelayErrorAgentAlreadyExists) => {
33 subname = config.try_new_device_subname()
34 }
35 Err(e) => {
36 return Err(e);
37 }
38 }
39 }
40 }
41}
42
43async fn initiate(
44 config: Arc<Config>,
45 relay: Arc<Relay>,
46 subname: String,
47) -> Result<(Arc<Relay>, String), AgentError> {
48 info!(
49 "Starting handshake: {} with device {}/{}",
50 relay.host(),
51 config.device_name(),
52 subname
53 );
54 let payload = A2rHandshakeBuilder::new()
55 .root_request_connection(config.device_name(), &subname)
56 .to_flatbuffers(agent_version_to_flatbuffers());
57 let url = relay.handshake_url();
58
59 let client = Client::new();
60 let response = client.post(url).body(payload.0).send().await?;
61
62 let body = response.bytes().await?;
63 let message = read_message::<R2aHandshakeRoot>(&body)?;
64 let output = process_r2a_handshake(message).await?;
65
66 Ok((relay, output.auth_nonce))
67}