allow foreign network forward nic data

This commit is contained in:
sijie.sun
2024-03-23 22:42:49 +08:00
committed by Sijie.Sun
parent 269146c9f8
commit 6c2a240966
8 changed files with 188 additions and 59 deletions
@@ -150,9 +150,18 @@ impl ForeignNetworkClient {
pub async fn send_msg(&self, msg: Bytes, peer_id: PeerId) -> Result<(), Error> {
if let Some(next_hop) = self.get_next_hop(peer_id) {
return self.peer_map.send_msg_directly(msg, next_hop).await;
let ret = self.peer_map.send_msg_directly(msg, next_hop).await;
if ret.is_err() {
tracing::error!(
?ret,
?peer_id,
?next_hop,
"foreign network client send msg failed"
);
}
return ret;
}
Err(Error::RouteError("no next hop".to_string()))
Err(Error::RouteError(Some("no next hop".to_string())))
}
pub fn list_foreign_peers(&self) -> Vec<PeerId> {
@@ -57,12 +57,12 @@ impl ForeignNetworkManagerData {
let network_name = self
.peer_network_map
.get(&dst_peer_id)
.ok_or_else(|| Error::RouteError("network not found".to_string()))?
.ok_or_else(|| Error::RouteError(Some("network not found".to_string())))?
.clone();
let entry = self
.network_peer_maps
.get(&network_name)
.ok_or_else(|| Error::RouteError("no peer in network".to_string()))?
.ok_or_else(|| Error::RouteError(Some("no peer in network".to_string())))?
.clone();
entry.peer_map.send_msg(msg, dst_peer_id).await
}
@@ -287,6 +287,28 @@ impl ForeignNetworkManager {
self.start_packet_recv().await;
self.register_peer_rpc_service().await;
}
pub async fn list_foreign_networks(&self) -> DashMap<String, Vec<PeerId>> {
let ret = DashMap::new();
for item in self.data.network_peer_maps.iter() {
let network_name = item.key().clone();
ret.insert(network_name, vec![]);
}
for mut n in ret.iter_mut() {
let network_name = n.key().clone();
let Some(item) = self
.data
.network_peer_maps
.get(&network_name)
.map(|v| v.clone())
else {
continue;
};
n.value_mut().extend(item.peer_map.list_peers().await);
}
ret
}
}
#[cfg(test)]
+18 -3
View File
@@ -56,7 +56,7 @@ macro_rules! wait_response {
match &resp_payload {
$pattern => $out_var = $value,
_ => {
log::error!(
tracing::error!(
"unexpected packet: {:?}, pattern: {:?}",
rsp_bytes,
stringify!($pattern)
@@ -67,6 +67,7 @@ macro_rules! wait_response {
};
}
#[derive(Debug)]
pub struct PeerInfo {
magic: u32,
pub my_peer_id: PeerId,
@@ -348,13 +349,15 @@ impl PeerConn {
self.conn_id
}
#[tracing::instrument]
pub async fn do_handshake_as_server(&mut self) -> Result<(), TunnelError> {
let mut stream = self.tunnel.pin_stream();
let mut sink = self.tunnel.pin_sink();
tracing::info!("waiting for handshake request from client");
wait_response!(stream, hs_req, CtrlPacketPayload::HandShake(x) => x);
self.info = Some(PeerInfo::from(hs_req));
log::info!("handshake request: {:?}", hs_req);
tracing::info!("handshake request: {:?}", hs_req);
let hs_req = self
.global_ctx
@@ -365,6 +368,7 @@ impl PeerConn {
Ok(())
}
#[tracing::instrument]
pub async fn do_handshake_as_client(&mut self) -> Result<(), TunnelError> {
let mut stream = self.tunnel.pin_stream();
let mut sink = self.tunnel.pin_sink();
@@ -375,9 +379,10 @@ impl PeerConn {
.run(|| packet::Packet::new_handshake(self.my_peer_id, &self.global_ctx.network));
sink.send(hs_req.into()).await?;
tracing::info!("waiting for handshake request from server");
wait_response!(stream, hs_rsp, CtrlPacketPayload::HandShake(x) => x);
self.info = Some(PeerInfo::from(hs_rsp));
log::info!("handshake response: {:?}", hs_rsp);
tracing::info!("handshake response: {:?}", hs_rsp);
Ok(())
}
@@ -535,6 +540,16 @@ impl Drop for PeerConn {
}
}
impl Debug for PeerConn {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("PeerConn")
.field("conn_id", &self.conn_id)
.field("my_peer_id", &self.my_peer_id)
.field("info", &self.info)
.finish()
}
}
#[cfg(test)]
mod tests {
use std::sync::Arc;
+22 -10
View File
@@ -5,7 +5,7 @@ use std::{
};
use async_trait::async_trait;
use futures::{StreamExt, TryFutureExt};
use futures::StreamExt;
use tokio::{
sync::{
@@ -67,11 +67,18 @@ impl PeerRpcManagerTransport for RpcTransport {
.ok_or(Error::Unknown)?;
let peers = self.peers.upgrade().ok_or(Error::Unknown)?;
if foreign_peers.has_next_hop(dst_peer_id) {
let ret = peers.send_msg(msg.clone(), dst_peer_id).await;
if matches!(ret, Err(Error::RouteError(..))) && foreign_peers.has_next_hop(dst_peer_id) {
tracing::info!(
?dst_peer_id,
?self.my_peer_id,
"failed to send msg to peer, try foreign network",
);
return foreign_peers.send_msg(msg, dst_peer_id).await;
}
peers.send_msg(msg, dst_peer_id).map_err(|e| e.into()).await
ret
}
async fn recv(&self) -> Result<Bytes, Error> {
@@ -484,13 +491,18 @@ impl PeerManager {
let mut errs: Vec<Error> = vec![];
for peer_id in dst_peers.iter() {
let send_ret = self
.peers
.send_msg(
packet::Packet::new_data_packet(self.my_peer_id, peer_id.clone(), &msg).into(),
*peer_id,
)
.await;
let msg: Bytes =
packet::Packet::new_data_packet(self.my_peer_id, peer_id.clone(), &msg).into();
let send_ret = self.peers.send_msg(msg.clone(), *peer_id).await;
if matches!(send_ret, Err(Error::RouteError(..)))
&& self.foreign_network_client.has_next_hop(*peer_id)
{
let foreign_send_ret = self.foreign_network_client.send_msg(msg, *peer_id).await;
if foreign_send_ret.is_ok() {
continue;
}
}
if let Err(send_ret) = send_ret {
errs.push(send_ret);
+3 -3
View File
@@ -87,7 +87,7 @@ impl PeerMap {
}
None => {
log::error!("no peer for dst_peer_id: {}", dst_peer_id);
return Ok(());
return Err(Error::RouteError(None));
}
}
@@ -119,13 +119,13 @@ impl PeerMap {
}
let Some(gateway_peer_id) = gateway_peer_id else {
log::error!(
tracing::trace!(
"no gateway for dst_peer_id: {}, peers: {:?}, my_peer_id: {}",
dst_peer_id,
self.peer_map.iter().map(|v| *v.key()).collect::<Vec<_>>(),
self.my_peer_id
);
return Ok(());
return Err(Error::RouteError(None));
};
self.send_msg_directly(msg.clone(), gateway_peer_id).await?;