Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b81384666c | |||
|
|
233b944007 |
9 changed files with 78 additions and 16 deletions
|
|
@ -1 +1 @@
|
||||||
Subproject commit 486541b9483356ff49ff3ec7016f87d3ecbeaa0e
|
Subproject commit f3c5037b0a099ae5389486eec77471bd5addab4a
|
||||||
|
|
@ -129,6 +129,20 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_positive_or_default<T>(name: &'static str, default: T) -> Result<T, ConfigError>
|
||||||
|
where
|
||||||
|
T: std::str::FromStr + PartialEq + Default,
|
||||||
|
{
|
||||||
|
let value = parse_or_default(name, default)?;
|
||||||
|
if value == T::default() {
|
||||||
|
return Err(ConfigError::InvalidValue {
|
||||||
|
name,
|
||||||
|
kind: "positive number",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
|
||||||
fn livekit_from_environment() -> Result<Option<LiveKitConfig>, ConfigError> {
|
fn livekit_from_environment() -> Result<Option<LiveKitConfig>, ConfigError> {
|
||||||
livekit_from_values(
|
livekit_from_values(
|
||||||
env::var("LIVEKIT_HOSTNAME").ok(),
|
env::var("LIVEKIT_HOSTNAME").ok(),
|
||||||
|
|
|
||||||
11
src/main.rs
11
src/main.rs
|
|
@ -57,6 +57,17 @@ async fn main() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let keyring = match load_or_create_keyring(
|
||||||
|
&identity_secret,
|
||||||
|
KEYRING_PATH,
|
||||||
|
PUBLIC_KEY_PATH,
|
||||||
|
) {
|
||||||
|
Ok(keyring) => keyring,
|
||||||
|
Err(error) => {
|
||||||
|
eprintln!("Unable to load Omikron keyring: {error}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
let public_key = match omega_database_public_key(&keyring) {
|
let public_key = match omega_database_public_key(&keyring) {
|
||||||
Ok(public_key) => public_key,
|
Ok(public_key) => public_key,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
|
|
|
||||||
|
|
@ -657,8 +657,7 @@ impl OmegaConnection {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let response = match relay_router::route_from_omega(&self.rho, cv).await {
|
let response = match relay_router::route_from_omega(&self.rho, cv).await {
|
||||||
Ok(()) => CommunicationValue::new(CommunicationType::Success)
|
Ok(response) => response.with_id(request_id),
|
||||||
.with_id(request_id),
|
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
log_err!(
|
log_err!(
|
||||||
self.omikron_id as i64,
|
self.omikron_id as i64,
|
||||||
|
|
|
||||||
|
|
@ -135,9 +135,7 @@ impl AppConnection {
|
||||||
None => Err(relay_router::RelayRouteError::DestinationIotaNotLocal),
|
None => Err(relay_router::RelayRouteError::DestinationIotaNotLocal),
|
||||||
};
|
};
|
||||||
let response = match result {
|
let response = match result {
|
||||||
Ok(()) => {
|
Ok(response) => response.with_id(message_id),
|
||||||
CommunicationValue::new(CommunicationType::Success).with_id(message_id)
|
|
||||||
}
|
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
log_err!(
|
log_err!(
|
||||||
self.user_id as i64,
|
self.user_id as i64,
|
||||||
|
|
|
||||||
|
|
@ -166,8 +166,8 @@ impl ClientConnection {
|
||||||
None => Err(relay_router::RelayRouteError::DestinationIotaNotLocal),
|
None => Err(relay_router::RelayRouteError::DestinationIotaNotLocal),
|
||||||
};
|
};
|
||||||
let response = match result {
|
let response = match result {
|
||||||
Ok(()) => {
|
Ok(response) => {
|
||||||
CommunicationValue::new(CommunicationType::Success).with_id(message_id)
|
response.with_id(message_id)
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
log_err!(
|
log_err!(
|
||||||
|
|
@ -201,6 +201,25 @@ impl ClientConnection {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if matches!(
|
||||||
|
relay_router::message_security_class(&cv),
|
||||||
|
relay_router::MessageSecurityClass::AuthenticatedPeerControl
|
||||||
|
) {
|
||||||
|
let Some(rho) = self.get_rho_connection().await else {
|
||||||
|
self.send_error_response(message_id, CommunicationType::ErrorNoIota)
|
||||||
|
.await;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
match rho.await_peer_control(&cv.with_sender(self.user_id)).await {
|
||||||
|
Ok(response) => self.send_message(&response).await,
|
||||||
|
Err(_) => {
|
||||||
|
self.send_error_response(message_id, CommunicationType::ErrorInternal)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Compatibility for clients predating SetUserState. The target
|
// Compatibility for clients predating SetUserState. The target
|
||||||
// user fields, if present, are deliberately ignored: an
|
// user fields, if present, are deliberately ignored: an
|
||||||
// authenticated connection may only change its own state.
|
// authenticated connection may only change its own state.
|
||||||
|
|
@ -884,7 +903,7 @@ impl ClientConnection {
|
||||||
|
|
||||||
let response = CommunicationValue::new(CommunicationType::LoadTxtRecord)
|
let response = CommunicationValue::new(CommunicationType::LoadTxtRecord)
|
||||||
.with_id(message_id)
|
.with_id(message_id)
|
||||||
.add_typed_default(DataType::AppContent, DataValue::Str(record_text));
|
.add_typed_default(DataType::Content, DataValue::Str(record_text));
|
||||||
self.send_message(&response).await;
|
self.send_message(&response).await;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -276,7 +276,7 @@ impl IotaConnection {
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(()) => CommunicationValue::new(CommunicationType::Success).with_id(message_id),
|
Ok(response) => response.with_id(message_id),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
log_err!(
|
log_err!(
|
||||||
self.iota_id as i64,
|
self.iota_id as i64,
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ pub async fn route_relay(
|
||||||
state: &Arc<AppState>,
|
state: &Arc<AppState>,
|
||||||
source: RelaySource,
|
source: RelaySource,
|
||||||
frame: CommunicationValue,
|
frame: CommunicationValue,
|
||||||
) -> Result<(), RelayRouteError> {
|
) -> Result<CommunicationValue, RelayRouteError> {
|
||||||
let (next_hop, frame) = prepare_frame(ensure_relay_frame_id(frame))?;
|
let (next_hop, frame) = prepare_frame(ensure_relay_frame_id(frame))?;
|
||||||
validate_source_next_hop(source, next_hop)?;
|
validate_source_next_hop(source, next_hop)?;
|
||||||
|
|
||||||
|
|
@ -169,7 +169,7 @@ pub async fn route_relay(
|
||||||
pub async fn route_from_omega(
|
pub async fn route_from_omega(
|
||||||
rho: &RhoManager,
|
rho: &RhoManager,
|
||||||
frame: CommunicationValue,
|
frame: CommunicationValue,
|
||||||
) -> Result<(), RelayRouteError> {
|
) -> Result<CommunicationValue, RelayRouteError> {
|
||||||
let (next_hop, frame) = prepare_frame(ensure_relay_frame_id(frame))?;
|
let (next_hop, frame) = prepare_frame(ensure_relay_frame_id(frame))?;
|
||||||
let RouteTarget::Iota(iota_id) = next_hop else {
|
let RouteTarget::Iota(iota_id) = next_hop else {
|
||||||
return Err(RelayRouteError::InvalidRouteTarget(next_hop.id()));
|
return Err(RelayRouteError::InvalidRouteTarget(next_hop.id()));
|
||||||
|
|
@ -193,7 +193,7 @@ async fn route_from_iota(
|
||||||
source_iota_id: u64,
|
source_iota_id: u64,
|
||||||
next_hop: RouteTarget,
|
next_hop: RouteTarget,
|
||||||
frame: CommunicationValue,
|
frame: CommunicationValue,
|
||||||
) -> Result<(), RelayRouteError> {
|
) -> Result<CommunicationValue, RelayRouteError> {
|
||||||
match next_hop {
|
match next_hop {
|
||||||
RouteTarget::User(user_id) => {
|
RouteTarget::User(user_id) => {
|
||||||
let target = rho
|
let target = rho
|
||||||
|
|
@ -206,7 +206,7 @@ async fn route_from_iota(
|
||||||
if !target.has_local_client(user_id).await {
|
if !target.has_local_client(user_id).await {
|
||||||
return Err(RelayRouteError::ClientOffline);
|
return Err(RelayRouteError::ClientOffline);
|
||||||
}
|
}
|
||||||
target.send_relay_to_client(&frame).await.map_err(|error| {
|
target.send_relay_to_client(&frame).await.map(|_| CommunicationValue::new(CommunicationType::Success)).map_err(|error| {
|
||||||
if error == "client offline" {
|
if error == "client offline" {
|
||||||
RelayRouteError::ClientOffline
|
RelayRouteError::ClientOffline
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -240,9 +240,9 @@ async fn route_from_iota(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn route_response(response: CommunicationValue) -> Result<(), RelayRouteError> {
|
fn route_response(response: CommunicationValue) -> Result<CommunicationValue, RelayRouteError> {
|
||||||
if response.is_type(CommunicationType::Success) {
|
if response.is_type(CommunicationType::Success) {
|
||||||
Ok(())
|
Ok(response)
|
||||||
} else {
|
} else {
|
||||||
Err(RelayRouteError::Send(format!(
|
Err(RelayRouteError::Send(format!(
|
||||||
"next Relay hop rejected the frame with {}",
|
"next Relay hop rejected the frame with {}",
|
||||||
|
|
@ -407,4 +407,15 @@ mod tests {
|
||||||
);
|
);
|
||||||
assert_eq!(RouteTarget::from_wire_id(7), None);
|
assert_eq!(RouteTarget::from_wire_id(7), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn successful_route_response_is_not_reconstructed() {
|
||||||
|
let response = CommunicationValue::new(CommunicationType::Success)
|
||||||
|
.with_payload(DataValue::Bytes(vec![9, 8, 7]));
|
||||||
|
let routed = match super::route_response(response.clone()) {
|
||||||
|
Ok(value) => value,
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
assert_eq!(routed.payload(), response.payload());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -328,6 +328,16 @@ impl RhoConnection {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn await_peer_control(
|
||||||
|
&self,
|
||||||
|
cv: &CommunicationValue,
|
||||||
|
) -> Result<CommunicationValue, String> {
|
||||||
|
self.iota_connection
|
||||||
|
.clone()
|
||||||
|
.await_response(cv, Some(std::time::Duration::from_secs(20)))
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn forward_relay_ack(&self, user_id: u64, frame_id: u32) {
|
pub async fn forward_relay_ack(&self, user_id: u64, frame_id: u32) {
|
||||||
let acknowledgement = CommunicationValue::new(CommunicationType::Success)
|
let acknowledgement = CommunicationValue::new(CommunicationType::Success)
|
||||||
.with_id(frame_id)
|
.with_id(frame_id)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue