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:
Jon Häggblad
2023-11-27 13:18:31 +01:00
committed by GitHub
parent 44395f8466
commit ca2ad13579
3 changed files with 67 additions and 16 deletions
Generated
+1
View File
@@ -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 }
+65 -16
View File
@@ -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");