Skip to content
This repository has been archived by the owner on Jun 25, 2021. It is now read-only.

Commit

Permalink
fix(end-user): assign clients a xorname which always matches the sect…
Browse files Browse the repository at this point in the history
…ion prefix so they are propoerly routed in a multi-section network
  • Loading branch information
bochaco committed May 24, 2021
1 parent 8bb562f commit ac4a27c
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 12 deletions.
3 changes: 2 additions & 1 deletion src/routing/core/public_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ impl Core {
}

pub fn try_add(&mut self, sender: SocketAddr) -> Result<EndUser> {
self.end_users.try_add(sender)
let section_prefix = self.section.prefix();
self.end_users.try_add(sender, section_prefix)
}

pub fn node(&self) -> &Node {
Expand Down
14 changes: 9 additions & 5 deletions src/routing/enduser_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::{
collections::{btree_map::Entry, BTreeMap},
net::SocketAddr,
};
use xor_name::XorName;
use xor_name::{Prefix, XorName};

pub type SocketId = XorName;
pub(crate) struct EndUserRegistry {
Expand All @@ -36,23 +36,27 @@ impl EndUserRegistry {
self.socket_id_mapping.get(&socket_id)
}

pub fn try_add(&mut self, sender: SocketAddr) -> Result<EndUser> {
pub fn try_add(&mut self, sender: SocketAddr, section_prefix: &Prefix) -> Result<EndUser> {
// create a unique socket id from client socket addr
let user_xorname = XorName::from_content(&[
let socket_id = XorName::from_content(&[
&bincode::serialize(&sender).map_err(|_| Error::FailedSignature)?
]);

// assign a XorName to the end user which belongs to this section's prefix
// so messages directed to this end user are correctly routed back through us
let user_xorname = section_prefix.substituted_in(socket_id);

// TODO: we probably should remove the socket_id from the EndUser struct,
// and pass the socket id separatelly as part of nodes' messages,
// instead of it being part of the SrcLocation/DstLocation in nodes' messages.
// Currently each Elder cannot create a different socket id since that breaks
// aggregation of messages when sent to another section with aggregation AtDestination.
let end_user = EndUser {
xorname: user_xorname,
socket_id: user_xorname,
socket_id,
};

match self.socket_id_mapping.entry(user_xorname) {
match self.socket_id_mapping.entry(socket_id) {
Entry::Vacant(entry) => {
let _ = self.clients.insert(sender, end_user);
let _ = entry.insert(sender);
Expand Down
13 changes: 8 additions & 5 deletions src/routing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,13 +516,16 @@ async fn handle_message(dispatcher: Arc<Dispatcher>, bytes: Bytes, sender: Socke
.copied();

let end_user = match end_user {
Some(end_user) => end_user,
Some(end_user) => {
debug!(
"Message from client {}, socket id already exists: {:?}",
sender, end_user
);
end_user
}
None => {
// this is the first time we receive a message from this client
trace!(
"First message from client {}, creating a socket id and caching it",
sender
);
debug!("First message from client {}, creating a socket id", sender);

// TODO: remove the enduser registry and simply encrypt socket addr with
// this node's keypair and use that as the socket id
Expand Down
7 changes: 6 additions & 1 deletion tests/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ async fn test_messages_client_node() -> Result<()> {
config.local_ip = Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));

let node_addr = node.our_connection_info();
let section_prefix = node.our_prefix().await;
let section_key = *node.section_chain().await.last_key();

let client = QuicP2p::with_config(Some(config), &[node_addr], false)?;
Expand Down Expand Up @@ -97,8 +98,12 @@ async fn test_messages_client_node() -> Result<()> {
node_handler.await??;

if let Some((_, resp)) = incoming_messages.next().await {
let user_xorname =
// the xorname assigned to each end user is computed from
// the client socket addr plus the client section prefix
let socket_id =
XorName::from_content(&[&bincode::serialize(&client_endpoint.socket_addr())?]);
let user_xorname = section_prefix.substituted_in(socket_id);

let expected_bytes = query.serialize(user_xorname, section_key)?;

assert_eq!(resp, expected_bytes);
Expand Down

0 comments on commit ac4a27c

Please sign in to comment.