Handle connect request in IPR (#4183)
* wip: first attempt at connected clients * redo connected clients * fix bug in if statement
This commit is contained in:
Generated
+1
@@ -6634,6 +6634,7 @@ dependencies = [
|
||||
"nym-tun",
|
||||
"nym-wireguard",
|
||||
"nym-wireguard-types",
|
||||
"rand 0.8.5",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
||||
@@ -27,6 +27,7 @@ nym-task = { path = "../../common/task" }
|
||||
nym-tun = { path = "../../common/tun" }
|
||||
nym-wireguard = { path = "../../common/wireguard" }
|
||||
nym-wireguard-types = { path = "../../common/wireguard-types" }
|
||||
rand = "0.8.5"
|
||||
reqwest.workspace = true
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#![cfg_attr(not(target_os = "linux"), allow(dead_code))]
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
net::{IpAddr, SocketAddr},
|
||||
path::Path,
|
||||
};
|
||||
@@ -161,6 +162,7 @@ impl IpPacketRouterBuilder {
|
||||
tun_task_response_rx,
|
||||
mixnet_client,
|
||||
task_handle,
|
||||
connected_clients: Default::default(),
|
||||
};
|
||||
|
||||
log::info!("The address of this client is: {self_address}");
|
||||
@@ -180,7 +182,7 @@ impl IpPacketRouterBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
#[cfg_attr(not(target_os = "linux"), allow(unused))]
|
||||
struct IpPacketRouter {
|
||||
_config: Config,
|
||||
request_filter: request_filter::RequestFilter,
|
||||
@@ -188,6 +190,13 @@ struct IpPacketRouter {
|
||||
tun_task_response_rx: nym_tun::tun_task_channel::TunTaskResponseRx,
|
||||
mixnet_client: nym_sdk::mixnet::MixnetClient,
|
||||
task_handle: TaskHandle,
|
||||
|
||||
connected_clients: HashMap<IpAddr, ConnectedClient>,
|
||||
}
|
||||
|
||||
struct ConnectedClient {
|
||||
nym_address: Recipient,
|
||||
last_activity: std::time::Instant,
|
||||
}
|
||||
|
||||
#[cfg_attr(not(target_os = "linux"), allow(unused))]
|
||||
@@ -202,11 +211,39 @@ impl IpPacketRouter {
|
||||
);
|
||||
|
||||
let request_id = connect_request.request_id;
|
||||
let _requested_ip = connect_request.ip;
|
||||
let requested_ip = connect_request.ip;
|
||||
let reply_to = connect_request.reply_to;
|
||||
// TODO: ignoring reply_to_hops and reply_to_avg_mix_delays for now
|
||||
|
||||
Ok(Some(IpPacketResponse::new_static_connect_failure(
|
||||
// Check that the IP is available in the set of connected clients
|
||||
if self.connected_clients.contains_key(&requested_ip) {
|
||||
log::info!("Requested IP is not available");
|
||||
return Ok(Some(IpPacketResponse::new_static_connect_failure(
|
||||
request_id, reply_to,
|
||||
)));
|
||||
}
|
||||
|
||||
// Check that the nym address isn't already registered
|
||||
if self
|
||||
.connected_clients
|
||||
.values()
|
||||
.any(|client| client.nym_address == reply_to)
|
||||
{
|
||||
log::info!("Nym address is already registered");
|
||||
return Ok(Some(IpPacketResponse::new_static_connect_failure(
|
||||
request_id, reply_to,
|
||||
)));
|
||||
}
|
||||
|
||||
// Insert the new connected client
|
||||
let connected_client = ConnectedClient {
|
||||
nym_address: reply_to,
|
||||
last_activity: std::time::Instant::now(),
|
||||
};
|
||||
self.connected_clients
|
||||
.insert(requested_ip, connected_client);
|
||||
|
||||
Ok(Some(IpPacketResponse::new_static_connect_success(
|
||||
request_id, reply_to,
|
||||
)))
|
||||
}
|
||||
@@ -246,6 +283,15 @@ impl IpPacketRouter {
|
||||
let dst_str = dst.map_or(dst_addr.to_string(), |dst| dst.to_string());
|
||||
log::info!("Received packet: {packet_type}: {src_addr} -> {dst_str}");
|
||||
|
||||
// Check if there is a connected client for this src_addr. If there is, update the last activity time
|
||||
// for the client. If there isn't, drop the packet.
|
||||
if let Some(client) = self.connected_clients.get_mut(&src_addr) {
|
||||
client.last_activity = std::time::Instant::now();
|
||||
} else {
|
||||
log::info!("Dropping packet: no connected client for {src_addr}");
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// Filter check
|
||||
if let Some(dst) = dst {
|
||||
if !self.request_filter.check_address(&dst).await {
|
||||
@@ -258,11 +304,11 @@ impl IpPacketRouter {
|
||||
log::warn!("Ignoring filter check for packet without port number! TODO!");
|
||||
}
|
||||
|
||||
// TODO: set the tag correctly. Can we just reuse sender_tag?
|
||||
// TODO: consider changing from Vec<u8> to bytes::Bytes?
|
||||
let peer_tag = 0;
|
||||
// TODO: consider just removing the tag
|
||||
let tag = 0;
|
||||
self.tun_task_tx
|
||||
.try_send((peer_tag, data_request.ip_packet.into()))
|
||||
.try_send((tag, data_request.ip_packet.into()))
|
||||
.map_err(|err| IpPacketRouterError::FailedToSendPacketToTun { source: err })?;
|
||||
|
||||
Ok(None)
|
||||
@@ -343,15 +389,18 @@ impl IpPacketRouter {
|
||||
},
|
||||
packet = self.tun_task_response_rx.recv() => {
|
||||
if let Some((_tag, packet)) = packet {
|
||||
// Read recipient from env variable NYM_CLIENT_ADDR which is a base58
|
||||
// string of the nym-address of the client that the packet should be
|
||||
// sent back to.
|
||||
//
|
||||
// In the near future we will let the client expose it's nym-address
|
||||
// directly, and after that, provide SURBS
|
||||
let recipient = std::env::var("NYM_CLIENT_ADDR").ok().and_then(|addr| {
|
||||
Recipient::try_from_base58_string(addr).ok()
|
||||
});
|
||||
// TODO: skip full parsing we we only need dst_addr
|
||||
let Ok(ParsedPacket {
|
||||
packet_type: _,
|
||||
src_addr: _,
|
||||
dst_addr,
|
||||
dst: _,
|
||||
}) = parse_packet(&packet) else {
|
||||
log::warn!("Failed to parse packet");
|
||||
continue;
|
||||
};
|
||||
|
||||
let recipient = self.connected_clients.get(&dst_addr).map(|c| c.nym_address);
|
||||
|
||||
if let Some(recipient) = recipient {
|
||||
let lane = TransmissionLane::General;
|
||||
@@ -367,7 +416,7 @@ impl IpPacketRouter {
|
||||
log::error!("IpPacketRouter [main loop]: failed to send packet to mixnet: {err}");
|
||||
};
|
||||
} else {
|
||||
log::error!("NYM_CLIENT_ADDR not set or invalid");
|
||||
log::error!("IpPacketRouter [main loop]: no nym-address recipient for packet");
|
||||
}
|
||||
} else {
|
||||
log::trace!("IpPacketRouter [main loop]: stopping since channel closed");
|
||||
|
||||
Reference in New Issue
Block a user