checkpoint
This commit is contained in:
		@@ -58,8 +58,8 @@ impl RoutingTable {
 | 
			
		||||
            out += &format!(
 | 
			
		||||
                "{},{},{},{},{}",
 | 
			
		||||
                BOOTSTRAP_TXT_VERSION,
 | 
			
		||||
                MIN_VERSION,
 | 
			
		||||
                MAX_VERSION,
 | 
			
		||||
                MIN_CRYPTO_VERSION,
 | 
			
		||||
                MAX_CRYPTO_VERSION,
 | 
			
		||||
                self.node_id().encode(),
 | 
			
		||||
                some_hostname.unwrap()
 | 
			
		||||
            );
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@ mod routing_table_inner;
 | 
			
		||||
mod stats_accounting;
 | 
			
		||||
mod tasks;
 | 
			
		||||
 | 
			
		||||
use crate::dht::*;
 | 
			
		||||
use crate::crypto::*;
 | 
			
		||||
use crate::network_manager::*;
 | 
			
		||||
use crate::rpc_processor::*;
 | 
			
		||||
use crate::xx::*;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
use super::*;
 | 
			
		||||
use crate::dht::*;
 | 
			
		||||
use crate::crypto::*;
 | 
			
		||||
use alloc::fmt;
 | 
			
		||||
 | 
			
		||||
// Connectionless protocols like UDP are dependent on a NAT translation timeout
 | 
			
		||||
 
 | 
			
		||||
@@ -49,9 +49,9 @@ struct RouteSpecDetail {
 | 
			
		||||
    /// Directions this route is guaranteed to work in
 | 
			
		||||
    directions: DirectionSet,
 | 
			
		||||
    /// Stability preference (prefer reliable nodes over faster)
 | 
			
		||||
    stability: Stability,
 | 
			
		||||
    pub stability: Stability,
 | 
			
		||||
    /// Sequencing preference (connection oriented protocols vs datagram)
 | 
			
		||||
    sequencing: Sequencing,
 | 
			
		||||
    pub sequencing: Sequencing,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// The core representation of the RouteSpecStore that can be serialized
 | 
			
		||||
@@ -616,11 +616,11 @@ impl RouteSpecStore {
 | 
			
		||||
        routing_table: RoutingTable,
 | 
			
		||||
        safety_selection: SafetySelection,
 | 
			
		||||
        private_route: PrivateRoute,
 | 
			
		||||
    ) -> Result<Option<CompiledRoute>, RPCError> {
 | 
			
		||||
    ) -> EyreResult<Option<CompiledRoute>> {
 | 
			
		||||
        let pr_hopcount = private_route.hop_count as usize;
 | 
			
		||||
        let max_route_hop_count = self.max_route_hop_count;
 | 
			
		||||
        if pr_hopcount > max_route_hop_count {
 | 
			
		||||
            return Err(RPCError::internal("private route hop count too long"));
 | 
			
		||||
            bail!("private route hop count too long");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // See if we are using a safety route, if not, short circuit this operation
 | 
			
		||||
@@ -628,7 +628,7 @@ impl RouteSpecStore {
 | 
			
		||||
            SafetySelection::Unsafe(sequencing) => {
 | 
			
		||||
                // Safety route stub with the node's public key as the safety route key since it's the 0th hop
 | 
			
		||||
                if private_route.first_hop.is_none() {
 | 
			
		||||
                    return Err(RPCError::internal("can't compile zero length route"));
 | 
			
		||||
                    bail!("can't compile zero length route");
 | 
			
		||||
                }
 | 
			
		||||
                let first_hop = private_route.first_hop.as_ref().unwrap();
 | 
			
		||||
                let opt_first_hop = match &first_hop.node {
 | 
			
		||||
@@ -707,10 +707,10 @@ impl RouteSpecStore {
 | 
			
		||||
        // Ensure the total hop count isn't too long for our config
 | 
			
		||||
        let sr_hopcount = safety_spec.hop_count;
 | 
			
		||||
        if sr_hopcount == 0 {
 | 
			
		||||
            return Err(RPCError::internal("safety route hop count is zero"));
 | 
			
		||||
            bail!("safety route hop count is zero");
 | 
			
		||||
        }
 | 
			
		||||
        if sr_hopcount > max_route_hop_count {
 | 
			
		||||
            return Err(RPCError::internal("safety route hop count too long"));
 | 
			
		||||
            bail!("safety route hop count too long");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // See if we can optimize this compilation yet
 | 
			
		||||
@@ -746,10 +746,10 @@ impl RouteSpecStore {
 | 
			
		||||
                    // Encrypt the previous blob ENC(nonce, DH(PKhop,SKsr))
 | 
			
		||||
                    let dh_secret = crypto
 | 
			
		||||
                        .cached_dh(&safety_rsd.hops[h], &safety_rsd.secret_key)
 | 
			
		||||
                        .map_err(RPCError::map_internal("dh failed"))?;
 | 
			
		||||
                        .wrap_err("dh failed")?;
 | 
			
		||||
                    let enc_msg_data =
 | 
			
		||||
                        Crypto::encrypt_aead(blob_data.as_slice(), &nonce, &dh_secret, None)
 | 
			
		||||
                            .map_err(RPCError::map_internal("encryption failed"))?;
 | 
			
		||||
                            .wrap_err("encryption failed")?;
 | 
			
		||||
 | 
			
		||||
                    // Make route hop data
 | 
			
		||||
                    let route_hop_data = RouteHopData {
 | 
			
		||||
@@ -759,26 +759,23 @@ impl RouteSpecStore {
 | 
			
		||||
 | 
			
		||||
                    // Make route hop
 | 
			
		||||
                    let route_hop = RouteHop {
 | 
			
		||||
                        node: match optimize {
 | 
			
		||||
                        node: if optimize {
 | 
			
		||||
                            // Optimized, no peer info, just the dht key
 | 
			
		||||
                            true => RouteNode::NodeId(NodeId::new(safety_rsd.hops[h])),
 | 
			
		||||
                            RouteNode::NodeId(NodeId::new(safety_rsd.hops[h]))
 | 
			
		||||
                        } else {
 | 
			
		||||
                            // Full peer info, required until we are sure the route has been fully established
 | 
			
		||||
                            false => {
 | 
			
		||||
                                let node_id = safety_rsd.hops[h];
 | 
			
		||||
                                let pi = rti
 | 
			
		||||
                                    .with_node_entry(node_id, |entry| {
 | 
			
		||||
                                        entry.with(rti, |_rti, e| {
 | 
			
		||||
                                            e.make_peer_info(node_id, RoutingDomain::PublicInternet)
 | 
			
		||||
                                        })
 | 
			
		||||
                            let node_id = safety_rsd.hops[h];
 | 
			
		||||
                            let pi = rti
 | 
			
		||||
                                .with_node_entry(node_id, |entry| {
 | 
			
		||||
                                    entry.with(rti, |_rti, e| {
 | 
			
		||||
                                        e.make_peer_info(node_id, RoutingDomain::PublicInternet)
 | 
			
		||||
                                    })
 | 
			
		||||
                                    .flatten();
 | 
			
		||||
                                if pi.is_none() {
 | 
			
		||||
                                    return Err(RPCError::internal(
 | 
			
		||||
                                        "peer info should exist for route but doesn't",
 | 
			
		||||
                                    ));
 | 
			
		||||
                                }
 | 
			
		||||
                                RouteNode::PeerInfo(pi.unwrap())
 | 
			
		||||
                                })
 | 
			
		||||
                                .flatten();
 | 
			
		||||
                            if pi.is_none() {
 | 
			
		||||
                                bail!("peer info should exist for route but doesn't");
 | 
			
		||||
                            }
 | 
			
		||||
                            RouteNode::PeerInfo(pi.unwrap())
 | 
			
		||||
                        },
 | 
			
		||||
                        next_hop: Some(route_hop_data),
 | 
			
		||||
                    };
 | 
			
		||||
@@ -838,6 +835,86 @@ impl RouteSpecStore {
 | 
			
		||||
        Ok(Some(compiled_route))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Assemble private route for publication
 | 
			
		||||
    pub fn assemble_private_route(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        rti: &RoutingTableInner,
 | 
			
		||||
        routing_table: RoutingTable,
 | 
			
		||||
        key: &DHTKey,
 | 
			
		||||
    ) -> EyreResult<PrivateRoute> {
 | 
			
		||||
        let rsd = self
 | 
			
		||||
            .detail(&key)
 | 
			
		||||
            .ok_or_else(|| eyre!("route does not exist"))?;
 | 
			
		||||
 | 
			
		||||
        // See if we can optimize this compilation yet
 | 
			
		||||
        // We don't want to include full nodeinfo if we don't have to
 | 
			
		||||
        let optimize = rsd.reachable;
 | 
			
		||||
 | 
			
		||||
        // Make innermost route hop to our own node
 | 
			
		||||
        let mut route_hop = RouteHop {
 | 
			
		||||
            node: if optimize {
 | 
			
		||||
                RouteNode::NodeId(NodeId::new(routing_table.node_id()))
 | 
			
		||||
            } else {
 | 
			
		||||
                RouteNode::PeerInfo(rti.get_own_peer_info(RoutingDomain::PublicInternet))
 | 
			
		||||
            },
 | 
			
		||||
            next_hop: None,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let crypto = routing_table.network_manager().crypto();
 | 
			
		||||
        // Loop for each hop
 | 
			
		||||
        let hop_count = rsd.hops.len();
 | 
			
		||||
        for h in (0..hop_count).rev() {
 | 
			
		||||
            let nonce = Crypto::get_random_nonce();
 | 
			
		||||
 | 
			
		||||
            let blob_data = {
 | 
			
		||||
                let mut rh_message = ::capnp::message::Builder::new_default();
 | 
			
		||||
                let mut rh_builder = rh_message.init_root::<veilid_capnp::route_hop::Builder>();
 | 
			
		||||
                encode_route_hop(&route_hop, &mut rh_builder)?;
 | 
			
		||||
                builder_to_vec(rh_message)?
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // Encrypt the previous blob ENC(nonce, DH(PKhop,SKpr))
 | 
			
		||||
            let dh_secret = crypto
 | 
			
		||||
                .cached_dh(&rsd.hops[h], &rsd.secret_key)
 | 
			
		||||
                .wrap_err("dh failed")?;
 | 
			
		||||
            let enc_msg_data = Crypto::encrypt_aead(blob_data.as_slice(), &nonce, &dh_secret, None)
 | 
			
		||||
                .wrap_err("encryption failed")?;
 | 
			
		||||
            let route_hop_data = RouteHopData {
 | 
			
		||||
                nonce,
 | 
			
		||||
                blob: enc_msg_data,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            route_hop = RouteHop {
 | 
			
		||||
                node: if optimize {
 | 
			
		||||
                    // Optimized, no peer info, just the dht key
 | 
			
		||||
                    RouteNode::NodeId(NodeId::new(rsd.hops[h]))
 | 
			
		||||
                } else {
 | 
			
		||||
                    // Full peer info, required until we are sure the route has been fully established
 | 
			
		||||
                    let node_id = rsd.hops[h];
 | 
			
		||||
                    let pi = rti
 | 
			
		||||
                        .with_node_entry(node_id, |entry| {
 | 
			
		||||
                            entry.with(rti, |_rti, e| {
 | 
			
		||||
                                e.make_peer_info(node_id, RoutingDomain::PublicInternet)
 | 
			
		||||
                            })
 | 
			
		||||
                        })
 | 
			
		||||
                        .flatten();
 | 
			
		||||
                    if pi.is_none() {
 | 
			
		||||
                        bail!("peer info should exist for route but doesn't",);
 | 
			
		||||
                    }
 | 
			
		||||
                    RouteNode::PeerInfo(pi.unwrap())
 | 
			
		||||
                },
 | 
			
		||||
                next_hop: Some(route_hop_data),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let private_route = PrivateRoute {
 | 
			
		||||
            public_key: key.clone(),
 | 
			
		||||
            hop_count: hop_count.try_into().unwrap(),
 | 
			
		||||
            first_hop: Some(route_hop),
 | 
			
		||||
        };
 | 
			
		||||
        Ok(private_route)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Mark route as published
 | 
			
		||||
    /// When first deserialized, routes must be re-published in order to ensure they remain
 | 
			
		||||
    /// in the RouteSpecStore.
 | 
			
		||||
 
 | 
			
		||||
@@ -126,8 +126,8 @@ impl RoutingDomainDetailCommon {
 | 
			
		||||
                        network_class: self.network_class.unwrap_or(NetworkClass::Invalid),
 | 
			
		||||
                        outbound_protocols: self.outbound_protocols,
 | 
			
		||||
                        address_types: self.address_types,
 | 
			
		||||
                        min_version: MIN_VERSION,
 | 
			
		||||
                        max_version: MAX_VERSION,
 | 
			
		||||
                        min_version: MIN_CRYPTO_VERSION,
 | 
			
		||||
                        max_version: MAX_CRYPTO_VERSION,
 | 
			
		||||
                        dial_info_detail_list: self.dial_info_details.clone(),
 | 
			
		||||
                        relay_peer_info: self
 | 
			
		||||
                            .relay_node
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user