2022-09-25 22:04:53 +00:00
|
|
|
use super::*;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub enum Target {
|
|
|
|
NodeId(NodeId),
|
2022-11-22 23:26:39 +00:00
|
|
|
PrivateRoute(DHTKey),
|
2022-09-25 22:04:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct RoutingContextInner {}
|
|
|
|
|
|
|
|
pub struct RoutingContextUnlockedInner {
|
2022-10-22 01:27:07 +00:00
|
|
|
/// Safety routing requirements
|
|
|
|
safety_selection: SafetySelection,
|
2022-09-25 22:04:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for RoutingContextInner {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
// self.api
|
|
|
|
// .borrow_mut()
|
|
|
|
// .routing_contexts
|
|
|
|
// //.remove(&self.id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct RoutingContext {
|
|
|
|
/// Veilid API handle
|
|
|
|
api: VeilidAPI,
|
|
|
|
inner: Arc<Mutex<RoutingContextInner>>,
|
|
|
|
unlocked_inner: Arc<RoutingContextUnlockedInner>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl RoutingContext {
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
pub(super) fn new(api: VeilidAPI) -> Self {
|
|
|
|
Self {
|
|
|
|
api,
|
|
|
|
inner: Arc::new(Mutex::new(RoutingContextInner {})),
|
|
|
|
unlocked_inner: Arc::new(RoutingContextUnlockedInner {
|
2022-10-22 01:27:07 +00:00
|
|
|
safety_selection: SafetySelection::Unsafe(Sequencing::NoPreference),
|
2022-09-25 22:04:53 +00:00
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-19 01:53:45 +00:00
|
|
|
pub fn with_default_privacy(self) -> Result<Self, VeilidAPIError> {
|
|
|
|
let config = self.api.config()?;
|
|
|
|
let c = config.get();
|
|
|
|
Ok(Self {
|
2022-09-25 22:04:53 +00:00
|
|
|
api: self.api.clone(),
|
|
|
|
inner: Arc::new(Mutex::new(RoutingContextInner {})),
|
|
|
|
unlocked_inner: Arc::new(RoutingContextUnlockedInner {
|
2022-10-22 01:27:07 +00:00
|
|
|
safety_selection: SafetySelection::Safe(SafetySpec {
|
|
|
|
preferred_route: None,
|
|
|
|
hop_count: c.network.rpc.default_route_hop_count as usize,
|
|
|
|
stability: Stability::LowLatency,
|
|
|
|
sequencing: Sequencing::NoPreference,
|
|
|
|
}),
|
2022-09-25 22:04:53 +00:00
|
|
|
}),
|
2022-10-19 01:53:45 +00:00
|
|
|
})
|
|
|
|
}
|
2022-10-22 01:27:07 +00:00
|
|
|
pub fn with_privacy(self, safety_spec: SafetySpec) -> Result<Self, VeilidAPIError> {
|
2022-10-19 01:53:45 +00:00
|
|
|
Ok(Self {
|
|
|
|
api: self.api.clone(),
|
|
|
|
inner: Arc::new(Mutex::new(RoutingContextInner {})),
|
|
|
|
unlocked_inner: Arc::new(RoutingContextUnlockedInner {
|
2022-10-22 01:27:07 +00:00
|
|
|
safety_selection: SafetySelection::Safe(safety_spec),
|
2022-10-19 01:53:45 +00:00
|
|
|
}),
|
|
|
|
})
|
2022-09-25 22:04:53 +00:00
|
|
|
}
|
|
|
|
|
2022-10-22 01:27:07 +00:00
|
|
|
pub fn with_sequencing(self, sequencing: Sequencing) -> Self {
|
2022-09-25 22:04:53 +00:00
|
|
|
Self {
|
|
|
|
api: self.api.clone(),
|
|
|
|
inner: Arc::new(Mutex::new(RoutingContextInner {})),
|
|
|
|
unlocked_inner: Arc::new(RoutingContextUnlockedInner {
|
2022-10-22 01:27:07 +00:00
|
|
|
safety_selection: match self.unlocked_inner.safety_selection {
|
|
|
|
SafetySelection::Unsafe(_) => SafetySelection::Unsafe(sequencing),
|
|
|
|
SafetySelection::Safe(safety_spec) => SafetySelection::Safe(SafetySpec {
|
|
|
|
preferred_route: safety_spec.preferred_route,
|
|
|
|
hop_count: safety_spec.hop_count,
|
|
|
|
stability: safety_spec.stability,
|
|
|
|
sequencing,
|
|
|
|
}),
|
|
|
|
},
|
2022-09-25 22:04:53 +00:00
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
2022-10-22 01:27:07 +00:00
|
|
|
pub fn sequencing(&self) -> Sequencing {
|
|
|
|
match self.unlocked_inner.safety_selection {
|
|
|
|
SafetySelection::Unsafe(sequencing) => sequencing,
|
|
|
|
SafetySelection::Safe(safety_spec) => safety_spec.sequencing,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pub fn safety_spec(&self) -> Option<SafetySpec> {
|
|
|
|
match self.unlocked_inner.safety_selection {
|
|
|
|
SafetySelection::Unsafe(_) => None,
|
|
|
|
SafetySelection::Safe(safety_spec) => Some(safety_spec.clone()),
|
|
|
|
}
|
|
|
|
}
|
2022-09-25 22:04:53 +00:00
|
|
|
|
|
|
|
pub fn api(&self) -> VeilidAPI {
|
|
|
|
self.api.clone()
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn get_destination(
|
|
|
|
&self,
|
|
|
|
target: Target,
|
|
|
|
) -> Result<rpc_processor::Destination, VeilidAPIError> {
|
|
|
|
let rpc_processor = self.api.rpc_processor()?;
|
|
|
|
|
|
|
|
match target {
|
|
|
|
Target::NodeId(node_id) => {
|
|
|
|
// Resolve node
|
|
|
|
let mut nr = match rpc_processor.resolve_node(node_id.key).await {
|
|
|
|
Ok(Some(nr)) => nr,
|
2022-11-22 23:26:39 +00:00
|
|
|
Ok(None) => return Err(VeilidAPIError::KeyNotFound { key: node_id.key }),
|
2022-09-25 22:04:53 +00:00
|
|
|
Err(e) => return Err(e.into()),
|
|
|
|
};
|
2022-10-22 01:27:07 +00:00
|
|
|
// Apply sequencing to match safety selection
|
|
|
|
nr.set_sequencing(self.sequencing());
|
|
|
|
|
2022-09-25 22:04:53 +00:00
|
|
|
Ok(rpc_processor::Destination::Direct {
|
|
|
|
target: nr,
|
2022-10-22 01:27:07 +00:00
|
|
|
safety_selection: self.unlocked_inner.safety_selection,
|
2022-09-25 22:04:53 +00:00
|
|
|
})
|
|
|
|
}
|
2022-11-22 23:26:39 +00:00
|
|
|
Target::PrivateRoute(pr) => {
|
|
|
|
// Get remote private route
|
|
|
|
let rss = self.api.routing_table()?.route_spec_store();
|
2022-11-25 19:21:55 +00:00
|
|
|
let Some(private_route) = rss
|
|
|
|
.get_remote_private_route(&pr)
|
|
|
|
else {
|
|
|
|
return Err(VeilidAPIError::KeyNotFound { key: pr });
|
|
|
|
};
|
|
|
|
|
2022-11-22 23:26:39 +00:00
|
|
|
Ok(rpc_processor::Destination::PrivateRoute {
|
|
|
|
private_route,
|
|
|
|
safety_selection: self.unlocked_inner.safety_selection,
|
|
|
|
})
|
|
|
|
}
|
2022-09-25 22:04:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// App-level Messaging
|
|
|
|
|
|
|
|
#[instrument(level = "debug", err, skip(self))]
|
|
|
|
pub async fn app_call(
|
|
|
|
&self,
|
|
|
|
target: Target,
|
|
|
|
request: Vec<u8>,
|
|
|
|
) -> Result<Vec<u8>, VeilidAPIError> {
|
|
|
|
let rpc_processor = self.api.rpc_processor()?;
|
|
|
|
|
|
|
|
// Get destination
|
|
|
|
let dest = self.get_destination(target).await?;
|
|
|
|
|
|
|
|
// Send app message
|
|
|
|
let answer = match rpc_processor.rpc_call_app_call(dest, request).await {
|
|
|
|
Ok(NetworkResult::Value(v)) => v,
|
|
|
|
Ok(NetworkResult::Timeout) => return Err(VeilidAPIError::Timeout),
|
2022-10-04 17:09:03 +00:00
|
|
|
Ok(NetworkResult::NoConnection(e)) | Ok(NetworkResult::AlreadyExists(e)) => {
|
2022-09-25 22:04:53 +00:00
|
|
|
return Err(VeilidAPIError::NoConnection {
|
|
|
|
message: e.to_string(),
|
|
|
|
})
|
|
|
|
}
|
2022-10-04 17:09:03 +00:00
|
|
|
|
2022-09-25 22:04:53 +00:00
|
|
|
Ok(NetworkResult::InvalidMessage(message)) => {
|
|
|
|
return Err(VeilidAPIError::Generic { message })
|
|
|
|
}
|
|
|
|
Err(e) => return Err(e.into()),
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(answer.answer)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[instrument(level = "debug", err, skip(self))]
|
|
|
|
pub async fn app_message(
|
|
|
|
&self,
|
|
|
|
target: Target,
|
|
|
|
message: Vec<u8>,
|
|
|
|
) -> Result<(), VeilidAPIError> {
|
|
|
|
let rpc_processor = self.api.rpc_processor()?;
|
|
|
|
|
|
|
|
// Get destination
|
|
|
|
let dest = self.get_destination(target).await?;
|
|
|
|
|
|
|
|
// Send app message
|
|
|
|
match rpc_processor.rpc_call_app_message(dest, message).await {
|
|
|
|
Ok(NetworkResult::Value(())) => {}
|
|
|
|
Ok(NetworkResult::Timeout) => return Err(VeilidAPIError::Timeout),
|
2022-10-04 17:09:03 +00:00
|
|
|
Ok(NetworkResult::NoConnection(e)) | Ok(NetworkResult::AlreadyExists(e)) => {
|
2022-09-25 22:04:53 +00:00
|
|
|
return Err(VeilidAPIError::NoConnection {
|
|
|
|
message: e.to_string(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
Ok(NetworkResult::InvalidMessage(message)) => {
|
|
|
|
return Err(VeilidAPIError::Generic { message })
|
|
|
|
}
|
|
|
|
Err(e) => return Err(e.into()),
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////
|
|
|
|
/// DHT Values
|
|
|
|
|
|
|
|
pub async fn get_value(&self, _value_key: ValueKey) -> Result<Vec<u8>, VeilidAPIError> {
|
|
|
|
panic!("unimplemented");
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn set_value(
|
|
|
|
&self,
|
|
|
|
_value_key: ValueKey,
|
|
|
|
_value: Vec<u8>,
|
|
|
|
) -> Result<bool, VeilidAPIError> {
|
|
|
|
panic!("unimplemented");
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn watch_value(
|
|
|
|
&self,
|
|
|
|
_value_key: ValueKey,
|
|
|
|
_callback: ValueChangeCallback,
|
|
|
|
) -> Result<bool, VeilidAPIError> {
|
|
|
|
panic!("unimplemented");
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn cancel_watch_value(&self, _value_key: ValueKey) -> Result<bool, VeilidAPIError> {
|
|
|
|
panic!("unimplemented");
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////
|
|
|
|
/// Block Store
|
|
|
|
|
|
|
|
pub async fn find_block(&self, _block_id: BlockId) -> Result<Vec<u8>, VeilidAPIError> {
|
|
|
|
panic!("unimplemented");
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn supply_block(&self, _block_id: BlockId) -> Result<bool, VeilidAPIError> {
|
|
|
|
panic!("unimplemented");
|
|
|
|
}
|
|
|
|
}
|