use super::*; //////////////////////////////////////////////////////////////////////////////////////////////////// // Compiled Privacy Objects /// An encrypted private/safety route hop #[derive(Clone, Debug)] pub struct RouteHopData { /// The nonce used in the encryption ENC(Xn,DH(PKn,SKapr)) pub nonce: Nonce, /// The encrypted blob pub blob: Vec, } /// How to find a route node #[derive(Clone, Debug)] pub enum RouteNode { /// Route node is optimized, no contact method information as this node id has been seen before NodeId(NodeId), /// Route node with full contact method information to ensure the peer is reachable PeerInfo(PeerInfo), } impl fmt::Display for RouteNode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "{}", match self { RouteNode::NodeId(x) => x.key.encode(), RouteNode::PeerInfo(pi) => pi.node_id.key.encode(), } ) } } /// An unencrypted private/safety route hop #[derive(Clone, Debug)] pub struct RouteHop { /// The location of the hop pub node: RouteNode, /// The encrypted blob to pass to the next hop as its data (None for stubs) pub next_hop: Option, } /// The kind of hops a private route can have #[derive(Clone, Debug)] pub enum PrivateRouteHops { /// The first hop of a private route, unencrypted, route_hops == total hop count FirstHop(RouteHop), /// Private route internal node. Has > 0 private route hops left but < total hop count Data(RouteHopData), /// Private route has ended (hop count = 0) Empty, } /// A private route for receiver privacy #[derive(Clone, Debug)] pub struct PrivateRoute { /// The public key used for the entire route pub public_key: DHTKey, pub hop_count: u8, pub hops: PrivateRouteHops, } impl PrivateRoute { /// Empty private route is the form used when receiving the last hop pub fn new_empty(public_key: DHTKey) -> Self { Self { public_key, hop_count: 0, hops: PrivateRouteHops::Empty, } } /// Stub route is the form used when no privacy is required, but you need to specify the destination for a safety route pub fn new_stub(public_key: DHTKey, node: RouteNode) -> Self { Self { public_key, hop_count: 1, hops: PrivateRouteHops::FirstHop(RouteHop { node, next_hop: None, }), } } /// Remove the first unencrypted hop if possible pub fn pop_first_hop(&mut self) -> Option { match &mut self.hops { PrivateRouteHops::FirstHop(first_hop) => { let first_hop_node = first_hop.node.clone(); // Reduce hop count if self.hop_count > 0 { self.hop_count -= 1; } else { error!("hop count should not be 0 for first hop"); } // Go to next hop self.hops = match first_hop.next_hop.take() { Some(rhd) => PrivateRouteHops::Data(rhd), None => PrivateRouteHops::Empty, }; return Some(first_hop_node); } PrivateRouteHops::Data(_) => return None, PrivateRouteHops::Empty => return None, } } } impl fmt::Display for PrivateRoute { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "PR({:?}+{}{})", self.public_key, self.hop_count, match &self.hops { PrivateRouteHops::FirstHop(fh) => { format!("->{}", fh.node) } PrivateRouteHops::Data(_) => { "->?".to_owned() } PrivateRouteHops::Empty => { "".to_owned() } } ) } } #[derive(Clone, Debug)] pub enum SafetyRouteHops { /// Has >= 1 safety route hops Data(RouteHopData), /// Has 0 safety route hops Private(PrivateRoute), } #[derive(Clone, Debug)] pub struct SafetyRoute { pub public_key: DHTKey, pub hop_count: u8, pub hops: SafetyRouteHops, } impl SafetyRoute { pub fn new_stub(public_key: DHTKey, private_route: PrivateRoute) -> Self { assert!(matches!(private_route.hops, PrivateRouteHops::Data(_))); Self { public_key, hop_count: 0, hops: SafetyRouteHops::Private(private_route), } } } impl fmt::Display for SafetyRoute { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "SR({:?}+{}{})", self.public_key, self.hop_count, match &self.hops { SafetyRouteHops::Data(_) => "".to_owned(), SafetyRouteHops::Private(p) => format!("->{}", p), } ) } }