checkpoint
This commit is contained in:
parent
6d5df71ac1
commit
fc6eb6e84a
@ -17,9 +17,9 @@ pub struct SafetySpec {
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct CompiledRoute {
|
pub struct CompiledRoute {
|
||||||
/// The safety route attached to the private route
|
/// The safety route attached to the private route
|
||||||
safety_route: SafetyRoute,
|
pub safety_route: SafetyRoute,
|
||||||
/// The secret used to encrypt the message payload
|
/// The secret used to encrypt the message payload
|
||||||
secret: DHTKeySecret,
|
pub secret: DHTKeySecret,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
@ -600,7 +600,7 @@ impl RouteSpecStore {
|
|||||||
&mut self,
|
&mut self,
|
||||||
rti: &RoutingTableInner,
|
rti: &RoutingTableInner,
|
||||||
routing_table: RoutingTable,
|
routing_table: RoutingTable,
|
||||||
safety_spec: SafetySpec,
|
safety_spec: Option<SafetySpec>,
|
||||||
private_route: PrivateRoute,
|
private_route: PrivateRoute,
|
||||||
) -> Result<Option<CompiledRoute>, RPCError> {
|
) -> Result<Option<CompiledRoute>, RPCError> {
|
||||||
let pr_hopcount = private_route.hop_count as usize;
|
let pr_hopcount = private_route.hop_count as usize;
|
||||||
@ -608,7 +608,18 @@ impl RouteSpecStore {
|
|||||||
return Err(RPCError::internal("private route hop count too long"));
|
return Err(RPCError::internal("private route hop count too long"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See if we are using a safety route, if not, short circuit this operation
|
||||||
|
if safety_spec.is_none() {
|
||||||
|
// Safety route stub with the node's public key as the safety route key since it's the 0th hop
|
||||||
|
return Ok(Some(CompiledRoute {
|
||||||
|
safety_route: SafetyRoute::new_stub(routing_table.node_id(), private_route),
|
||||||
|
secret: routing_table.node_id_secret(),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
let safety_spec = safety_spec.unwrap();
|
||||||
|
|
||||||
// See if the preferred route is here
|
// See if the preferred route is here
|
||||||
|
let safety_route_public_key;
|
||||||
let opt_safety_rsd: Option<&mut RouteSpecDetail> =
|
let opt_safety_rsd: Option<&mut RouteSpecDetail> =
|
||||||
if let Some(preferred_route) = safety_spec.preferred_route {
|
if let Some(preferred_route) = safety_spec.preferred_route {
|
||||||
self.detail_mut(&preferred_route)
|
self.detail_mut(&preferred_route)
|
||||||
@ -650,19 +661,21 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
// xxx implement caching first!
|
// xxx implement caching first!
|
||||||
|
|
||||||
// xxx implement, ensure we handle hops == 0 for our safetyspec
|
|
||||||
|
|
||||||
// Ensure the total hop count isn't too long for our config
|
// Ensure the total hop count isn't too long for our config
|
||||||
let sr_hopcount = safety_spec.hop_count;
|
let sr_hopcount = safety_spec.hop_count;
|
||||||
if sr_hopcount > self.max_route_hop_count {
|
if sr_hopcount == 0 {
|
||||||
return Err(RPCError::internal("private route hop count too long"));
|
return Err(RPCError::internal("safety route hop count is zero"));
|
||||||
}
|
}
|
||||||
let total_hopcount = sr_hopcount + pr_hopcount;
|
if sr_hopcount > self.max_route_hop_count {
|
||||||
|
return Err(RPCError::internal("safety route hop count too long"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if we can optimize this compilation yet
|
||||||
|
// We don't want to include full nodeinfo if we don't have to
|
||||||
|
//let optimize = safety_rsd.
|
||||||
|
|
||||||
// Create hops
|
// Create hops
|
||||||
let hops = if sr_hopcount == 0 {
|
let hops = {
|
||||||
SafetyRouteHops::Private(private_route)
|
|
||||||
} else {
|
|
||||||
// start last blob-to-encrypt data off as private route
|
// start last blob-to-encrypt data off as private route
|
||||||
let mut blob_data = {
|
let mut blob_data = {
|
||||||
let mut pr_message = ::capnp::message::Builder::new_default();
|
let mut pr_message = ::capnp::message::Builder::new_default();
|
||||||
@ -681,16 +694,13 @@ impl RouteSpecStore {
|
|||||||
// (outer hop is a RouteHopData, not a RouteHop).
|
// (outer hop is a RouteHopData, not a RouteHop).
|
||||||
// Each loop mutates 'nonce', and 'blob_data'
|
// Each loop mutates 'nonce', and 'blob_data'
|
||||||
let mut nonce = Crypto::get_random_nonce();
|
let mut nonce = Crypto::get_random_nonce();
|
||||||
|
let crypto = routing_table.network_manager().crypto();
|
||||||
for h in (1..sr_hopcount).rev() {
|
for h in (1..sr_hopcount).rev() {
|
||||||
// Get blob to encrypt for next hop
|
// Get blob to encrypt for next hop
|
||||||
blob_data = {
|
blob_data = {
|
||||||
// Encrypt the previous blob ENC(nonce, DH(PKhop,SKsr))
|
// Encrypt the previous blob ENC(nonce, DH(PKhop,SKsr))
|
||||||
let dh_secret = self
|
let dh_secret = crypto
|
||||||
.crypto
|
.cached_dh(&safety_rsd.hops[h], &safety_rsd.secret_key)
|
||||||
.cached_dh(
|
|
||||||
&safety_route_spec.hops[h].dial_info.node_id.key,
|
|
||||||
&safety_route_spec.secret_key,
|
|
||||||
)
|
|
||||||
.map_err(RPCError::map_internal("dh failed"))?;
|
.map_err(RPCError::map_internal("dh failed"))?;
|
||||||
let enc_msg_data =
|
let enc_msg_data =
|
||||||
Crypto::encrypt_aead(blob_data.as_slice(), &nonce, &dh_secret, None)
|
Crypto::encrypt_aead(blob_data.as_slice(), &nonce, &dh_secret, None)
|
||||||
@ -704,7 +714,7 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
// Make route hop
|
// Make route hop
|
||||||
let route_hop = RouteHop {
|
let route_hop = RouteHop {
|
||||||
dial_info: safety_route_spec.hops[h].dial_info.clone(),
|
node: safety_route_spec.hops[h].dial_info.clone(),
|
||||||
next_hop: Some(route_hop_data),
|
next_hop: Some(route_hop_data),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -744,12 +754,15 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
// Build safety route
|
// Build safety route
|
||||||
let safety_route = SafetyRoute {
|
let safety_route = SafetyRoute {
|
||||||
public_key: safety_route_spec.public_key,
|
public_key: safety_rsd.
|
||||||
hop_count: safety_route_spec.hops.len() as u8,
|
hop_count: safety_spec.hop_count as u8,
|
||||||
hops,
|
hops,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(safety_route)
|
Ok(Some(CompiledRoute {
|
||||||
|
safety_route,
|
||||||
|
secret: todo!(),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark route as published
|
/// Mark route as published
|
||||||
|
@ -21,6 +21,7 @@ mod rpc_validate_dial_info;
|
|||||||
mod rpc_value_changed;
|
mod rpc_value_changed;
|
||||||
mod rpc_watch_value;
|
mod rpc_watch_value;
|
||||||
|
|
||||||
|
pub use coders::*;
|
||||||
pub use destination::*;
|
pub use destination::*;
|
||||||
pub use operation_waiter::*;
|
pub use operation_waiter::*;
|
||||||
pub use rpc_error::*;
|
pub use rpc_error::*;
|
||||||
@ -29,7 +30,6 @@ use super::*;
|
|||||||
use crate::dht::*;
|
use crate::dht::*;
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
use capnp::message::ReaderSegments;
|
use capnp::message::ReaderSegments;
|
||||||
use coders::*;
|
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
use network_manager::*;
|
use network_manager::*;
|
||||||
use receipt_manager::*;
|
use receipt_manager::*;
|
||||||
@ -55,6 +55,8 @@ struct RPCMessageHeader {
|
|||||||
connection_descriptor: ConnectionDescriptor,
|
connection_descriptor: ConnectionDescriptor,
|
||||||
/// The routing domain the message was sent through
|
/// The routing domain the message was sent through
|
||||||
routing_domain: RoutingDomain,
|
routing_domain: RoutingDomain,
|
||||||
|
/// The private route the message was received through
|
||||||
|
private_route: Option<DHTKey>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -134,7 +136,7 @@ struct RenderedOperation {
|
|||||||
message: Vec<u8>, // The rendered operation bytes
|
message: Vec<u8>, // The rendered operation bytes
|
||||||
node_id: DHTKey, // Destination node id we're sending to
|
node_id: DHTKey, // Destination node id we're sending to
|
||||||
node_ref: NodeRef, // Node to send envelope to (may not be destination node id in case of relay)
|
node_ref: NodeRef, // Node to send envelope to (may not be destination node id in case of relay)
|
||||||
hop_count: usize, // Total safety + private route hop count
|
hop_count: usize, // Total safety + private route hop count + 1 hop for the initial send
|
||||||
}
|
}
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -396,16 +398,25 @@ impl RPCProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wrap an operation with a private route inside a safety route
|
// Wrap an operation with a private route inside a safety route
|
||||||
pub(super) fn wrap_with_route(xxx continue here
|
pub(super) fn wrap_with_route(
|
||||||
&self,
|
&self,
|
||||||
safety_spec: SafetySpec,
|
safety_spec: Option<SafetySpec>,
|
||||||
private_route: PrivateRoute,
|
private_route: PrivateRoute,
|
||||||
message_data: Vec<u8>,
|
message_data: Vec<u8>,
|
||||||
) -> Result<RenderedOperation, RPCError> {
|
) -> Result<NetworkResult<RenderedOperation>, RPCError> {
|
||||||
let compiled_route: CompiledRoute = self.routing_table().with_route_spec_store(|rss| {
|
let routing_table = self.routing_table();
|
||||||
|
let compiled_route: CompiledRoute =
|
||||||
|
match self.routing_table().with_route_spec_store(|rss, rti| {
|
||||||
// Compile the safety route with the private route
|
// Compile the safety route with the private route
|
||||||
rss.compile_safety_route(self.safety_spec, private_route)
|
rss.compile_safety_route(rti, routing_table, safety_spec, private_route)
|
||||||
})?;
|
})? {
|
||||||
|
Some(cr) => cr,
|
||||||
|
None => {
|
||||||
|
return Ok(NetworkResult::no_connection_other(
|
||||||
|
"private route could not be compiled at this time",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Encrypt routed operation
|
// Encrypt routed operation
|
||||||
// Xmsg + ENC(Xmsg, DH(PKapr, SKbsr))
|
// Xmsg + ENC(Xmsg, DH(PKapr, SKbsr))
|
||||||
@ -421,30 +432,42 @@ impl RPCProcessor {
|
|||||||
let operation = RoutedOperation::new(nonce, enc_msg_data);
|
let operation = RoutedOperation::new(nonce, enc_msg_data);
|
||||||
|
|
||||||
// Prepare route operation
|
// Prepare route operation
|
||||||
let route = RPCOperationRoute {
|
let route_operation = RPCOperationRoute {
|
||||||
safety_route,
|
safety_route: compiled_route.safety_route,
|
||||||
operation,
|
operation,
|
||||||
};
|
};
|
||||||
let operation =
|
let operation = RPCOperation::new_statement(
|
||||||
RPCOperation::new_statement(RPCStatement::new(RPCStatementDetail::Route(route)), None);
|
RPCStatement::new(RPCStatementDetail::Route(route_operation)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
// Convert message to bytes and return it
|
// Convert message to bytes and return it
|
||||||
let mut route_msg = ::capnp::message::Builder::new_default();
|
let mut route_msg = ::capnp::message::Builder::new_default();
|
||||||
let mut route_operation = route_msg.init_root::<veilid_capnp::operation::Builder>();
|
let mut route_operation = route_msg.init_root::<veilid_capnp::operation::Builder>();
|
||||||
operation.encode(&mut route_operation)?;
|
operation.encode(&mut route_operation)?;
|
||||||
let out = builder_to_vec(route_msg)?;
|
let out_message = builder_to_vec(route_msg)?;
|
||||||
|
|
||||||
// out_node_id = sr
|
// Get the first hop this is going to
|
||||||
// .hops
|
let out_node_id = compiled_route
|
||||||
// .first()
|
.safety_route
|
||||||
// .ok_or_else(RPCError::else_internal("no hop in safety route"))?
|
.hops
|
||||||
// .dial_info
|
.first()
|
||||||
// .node_id
|
.ok_or_else(RPCError::else_internal("no hop in safety route"))?
|
||||||
// .key;
|
.dial_info
|
||||||
|
.node_id
|
||||||
|
.key;
|
||||||
|
|
||||||
//out_hop_count = 1 + sr.hops.len();
|
let out_hop_count =
|
||||||
|
(1 + compiled_route.safety_route.hop_count + private_route.hop_count) as usize;
|
||||||
|
|
||||||
Ok(out)
|
let out = RenderedOperation {
|
||||||
|
message: out_message,
|
||||||
|
node_id: out_node_id,
|
||||||
|
node_ref: compiled_route.first_hop,
|
||||||
|
hop_count: out_hop_count,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(NetworkResult::value(out))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Produce a byte buffer that represents the wire encoding of the entire
|
/// Produce a byte buffer that represents the wire encoding of the entire
|
||||||
@ -455,8 +478,8 @@ impl RPCProcessor {
|
|||||||
&self,
|
&self,
|
||||||
dest: Destination,
|
dest: Destination,
|
||||||
operation: &RPCOperation,
|
operation: &RPCOperation,
|
||||||
) -> Result<RenderedOperation, RPCError> {
|
) -> Result<NetworkResult<RenderedOperation>, RPCError> {
|
||||||
let out: RenderedOperation;
|
let out: NetworkResult<RenderedOperation>;
|
||||||
|
|
||||||
// Encode message to a builder and make a message reader for it
|
// Encode message to a builder and make a message reader for it
|
||||||
// Then produce the message as an unencrypted byte buffer
|
// Then produce the message as an unencrypted byte buffer
|
||||||
@ -471,12 +494,12 @@ impl RPCProcessor {
|
|||||||
match dest {
|
match dest {
|
||||||
Destination::Direct {
|
Destination::Direct {
|
||||||
target: ref node_ref,
|
target: ref node_ref,
|
||||||
safety,
|
safety_spec,
|
||||||
}
|
}
|
||||||
| Destination::Relay {
|
| Destination::Relay {
|
||||||
relay: ref node_ref,
|
relay: ref node_ref,
|
||||||
target: _,
|
target: _,
|
||||||
safety,
|
safety_spec,
|
||||||
} => {
|
} => {
|
||||||
// Send to a node without a private route
|
// Send to a node without a private route
|
||||||
// --------------------------------------
|
// --------------------------------------
|
||||||
@ -485,7 +508,7 @@ impl RPCProcessor {
|
|||||||
let (node_ref, node_id) = if let Destination::Relay {
|
let (node_ref, node_id) = if let Destination::Relay {
|
||||||
relay: _,
|
relay: _,
|
||||||
target: ref dht_key,
|
target: ref dht_key,
|
||||||
safety: _,
|
safety_spec: _,
|
||||||
} = dest
|
} = dest
|
||||||
{
|
{
|
||||||
(node_ref.clone(), dht_key.clone())
|
(node_ref.clone(), dht_key.clone())
|
||||||
@ -495,36 +518,36 @@ impl RPCProcessor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Handle the existence of safety route
|
// Handle the existence of safety route
|
||||||
match safety {
|
match safety_spec {
|
||||||
false => {
|
None => {
|
||||||
// If no safety route is being used, and we're not sending to a private
|
// If no safety route is being used, and we're not sending to a private
|
||||||
// route, we can use a direct envelope instead of routing
|
// route, we can use a direct envelope instead of routing
|
||||||
out = RenderedOperation {
|
out = NetworkResult::value(RenderedOperation {
|
||||||
message,
|
message,
|
||||||
node_id,
|
node_id,
|
||||||
node_ref,
|
node_ref,
|
||||||
hop_count: 1,
|
hop_count: 1,
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
true => {
|
Some(safety_spec) => {
|
||||||
// No private route was specified for the request
|
// No private route was specified for the request
|
||||||
// but we are using a safety route, so we must create an empty private route
|
// but we are using a safety route, so we must create an empty private route
|
||||||
let private_route = PrivateRoute::new_stub(node_id);
|
let private_route = PrivateRoute::new_stub(node_id);
|
||||||
|
|
||||||
// Wrap with safety route
|
// Wrap with safety route
|
||||||
out = self.wrap_with_route(true, private_route, message)?;
|
out = self.wrap_with_route(Some(safety_spec), private_route, message)?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Destination::PrivateRoute {
|
Destination::PrivateRoute {
|
||||||
private_route,
|
private_route,
|
||||||
safety,
|
safety_spec,
|
||||||
reliable,
|
reliable,
|
||||||
} => {
|
} => {
|
||||||
// Send to private route
|
// Send to private route
|
||||||
// ---------------------
|
// ---------------------
|
||||||
// Reply with 'route' operation
|
// Reply with 'route' operation
|
||||||
out = self.wrap_with_route(safety, private_route, message)?;
|
out = self.wrap_with_route(safety_spec, private_route, message)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,7 +625,7 @@ impl RPCProcessor {
|
|||||||
node_id,
|
node_id,
|
||||||
node_ref,
|
node_ref,
|
||||||
hop_count,
|
hop_count,
|
||||||
} = self.render_operation(dest, &operation)?;
|
} = network_result_try!(self.render_operation(dest, &operation)?);
|
||||||
|
|
||||||
// Calculate answer timeout
|
// Calculate answer timeout
|
||||||
// Timeout is number of hops times the timeout per hop
|
// Timeout is number of hops times the timeout per hop
|
||||||
@ -665,7 +688,7 @@ impl RPCProcessor {
|
|||||||
node_id,
|
node_id,
|
||||||
node_ref,
|
node_ref,
|
||||||
hop_count: _,
|
hop_count: _,
|
||||||
} = self.render_operation(dest, &operation)?;
|
} = network_result_try!(self.render_operation(dest, &operation)?);
|
||||||
|
|
||||||
// Send statement
|
// Send statement
|
||||||
let bytes = message.len() as u64;
|
let bytes = message.len() as u64;
|
||||||
@ -749,7 +772,7 @@ impl RPCProcessor {
|
|||||||
node_id,
|
node_id,
|
||||||
node_ref,
|
node_ref,
|
||||||
hop_count: _,
|
hop_count: _,
|
||||||
} = self.render_operation(dest, &operation)?;
|
} = network_result_try!(self.render_operation(dest, &operation)?);
|
||||||
|
|
||||||
// Send the reply
|
// Send the reply
|
||||||
let bytes = message.len() as u64;
|
let bytes = message.len() as u64;
|
||||||
|
@ -48,6 +48,19 @@ impl PrivateRoute {
|
|||||||
first_hop: None,
|
first_hop: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn simplify(self) -> Self {
|
||||||
|
Self {
|
||||||
|
public_key: self.public_key,
|
||||||
|
hop_count: self.hop_count,
|
||||||
|
first_hop: self.first_hop.map(|h| RouteHop {
|
||||||
|
node: match h.node {
|
||||||
|
RouteNode::NodeId(ni) => RouteNode::NodeId(ni),
|
||||||
|
RouteNode::PeerInfo(pi) => RouteNode::NodeId(pi.node_id),
|
||||||
|
},
|
||||||
|
next_hop: h.next_hop,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for PrivateRoute {
|
impl fmt::Display for PrivateRoute {
|
||||||
@ -79,6 +92,16 @@ pub struct SafetyRoute {
|
|||||||
pub hops: SafetyRouteHops,
|
pub hops: SafetyRouteHops,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SafetyRoute {
|
||||||
|
pub fn new_stub(public_key: DHTKey, private_route: PrivateRoute) -> Self {
|
||||||
|
Self {
|
||||||
|
public_key,
|
||||||
|
hop_count: 0,
|
||||||
|
hops: SafetyRouteHops::Private(private_route),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for SafetyRoute {
|
impl fmt::Display for SafetyRoute {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
|
Loading…
Reference in New Issue
Block a user