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

Commit

Permalink
feat(enduser): add mapping between socketaddr and pk
Browse files Browse the repository at this point in the history
- First simple impl.
Todo:
- map between socket_id (a random hash) and socketaddr.
- more granular errors.
- documentation
- file organisation
  • Loading branch information
oetyng committed Feb 23, 2021
1 parent 5465fa8 commit 1ff902d
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 5 deletions.
75 changes: 72 additions & 3 deletions src/routing/approved.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,61 @@ use bytes::Bytes;
use ed25519_dalek::Verifier;
use itertools::Itertools;
use resource_proof::ResourceProof;
use sn_data_types::{PublicKey as EndUserPK, Signature as EndUserSig};
use sn_messaging::{
network_info::{
Error as TargetSectionError, GetSectionResponse, Message as NetworkInfoMsg, NetworkInfo,
},
node::NodeMessage,
DstLocation, MessageType, SrcLocation,
};
use std::{cmp, net::SocketAddr, slice, unimplemented};
use std::{
cmp,
collections::{BTreeMap, HashSet},
net::SocketAddr,
slice, unimplemented,
};
use tokio::sync::mpsc;
use xor_name::{Prefix, XorName};

pub(crate) const RESOURCE_PROOF_DATA_SIZE: usize = 64;
pub(crate) const RESOURCE_PROOF_DIFFICULTY: u8 = 2;
const KEY_CACHE_SIZE: u8 = 5;

struct EndUserRegistry {
clients: BTreeMap<SocketAddr, EndUserPK>,
end_users: BTreeMap<EndUserPK, HashSet<SocketAddr>>,
}

impl EndUserRegistry {
pub fn new() -> Self {
Self {
clients: BTreeMap::default(),
end_users: BTreeMap::default(),
}
}

pub fn get_enduser(&self, socketaddr: &SocketAddr) -> Option<EndUserPK> {
self.clients.get(socketaddr).copied()
}

pub fn add(&mut self, socketaddr: SocketAddr, public_key: EndUserPK) {
match self.end_users.get_mut(&public_key) {
Some(clients) => {
if !clients.contains(&socketaddr) {
let _ = clients.insert(socketaddr);
}
}
None => {
let mut set = HashSet::default();
let _ = set.insert(socketaddr);
let _ = self.end_users.insert(public_key, set);
let _ = self.clients.insert(socketaddr, public_key);
}
}
}
}

// The approved stage - node is a full member of a section and is performing its duties according
// to its persona (adult or elder).
pub(crate) struct Approved {
Expand All @@ -69,6 +109,7 @@ pub(crate) struct Approved {
pub(super) event_tx: mpsc::UnboundedSender<Event>,
joins_allowed: bool,
resource_proof: ResourceProof,
end_users: EndUserRegistry,
}

impl Approved {
Expand Down Expand Up @@ -100,9 +141,14 @@ impl Approved {
event_tx,
joins_allowed: true,
resource_proof: ResourceProof::new(RESOURCE_PROOF_DATA_SIZE, RESOURCE_PROOF_DIFFICULTY),
end_users: EndUserRegistry::new(),
}
}

pub fn get_enduser(&self, sender: &SocketAddr) -> Option<EndUserPK> {
self.end_users.get_enduser(sender)
}

pub fn node(&self) -> &Node {
&self.node
}
Expand Down Expand Up @@ -244,16 +290,39 @@ impl Approved {
message: MessageType::NetworkInfo(response),
}]
}
NetworkInfoMsg::BootstrapCmd {
end_user,
socketaddr_sig,
} => {
if let Ok(data) = &bincode::serialize(&sender) {
if end_user.verify(&socketaddr_sig, data).is_ok() {
self.end_users.add(sender, end_user);
return vec![];
}
}

let response = NetworkInfoMsg::BootstrapError(TargetSectionError::InvalidBootstrap);
debug!("Sending {:?} to {}", response, sender);

vec![Command::SendMessage {
recipients: vec![sender],
delivery_group_size: 1,
message: MessageType::NetworkInfo(response),
}]
}
NetworkInfoMsg::GetSectionResponse(_) => {
if let Some(RelocateState::InProgress(tx)) = &mut self.relocate_state {
trace!("Forwarding {:?} to the bootstrap task", message);
let _ = tx.send((MessageType::NetworkInfo(message), sender)).await;
}

vec![]
}
NetworkInfoMsg::BootstrapError(error) => {
error!("BootstrapError received: {:?}", error);
vec![]
}
NetworkInfoMsg::NetworkInfoUpdate(error) => {
error!("TargetSectionError received: {:?}", error);
error!("NetworkInfoUpdate received: {:?}", error);
vec![]
}
}
Expand Down
21 changes: 19 additions & 2 deletions src/routing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use ed25519_dalek::{Keypair, PublicKey, Signature, Signer};
use itertools::Itertools;
use sn_messaging::{
client::Message as ClientMessage,
network_info::{ErrorResponse, Message as NetworkInfoMsg},
network_info::{Error as TargetSectionError, ErrorResponse, Message as NetworkInfoMsg},
node::NodeMessage,
DstLocation, EndUser, MessageType, SrcLocation, WireMsg,
};
Expand Down Expand Up @@ -416,6 +416,23 @@ async fn handle_message(stage: Arc<Stage>, bytes: Bytes, sender: SocketAddr) {
}
}
MessageType::ClientMessage(message) => {
let enduser = stage.state.lock().await.get_enduser(&sender);
let public_key = match enduser {
Some(public_key) => public_key,
None => {
// we are not yet bootstrapped, todo: inform enduser in a better way of this
let command = Command::SendMessage {
recipients: vec![sender],
delivery_group_size: 1,
message: MessageType::NetworkInfo(NetworkInfoMsg::BootstrapError(
TargetSectionError::InvalidBootstrap,
)),
};
let _ = task::spawn(stage.handle_commands(command));
return;
}
};

if let Some(client_pk) = message.target_section_pk() {
if let Some(bls_pk) = client_pk.bls() {
if let Err(error) = stage.check_key_status(&bls_pk).await {
Expand All @@ -439,7 +456,7 @@ async fn handle_message(stage: Arc<Stage>, bytes: Bytes, sender: SocketAddr) {
let event = Event::ClientMessageReceived {
msg: Box::new(message),
user: EndUser::Client {
public_key: sn_data_types::PublicKey::from(crypto::gen_keypair().public),
public_key,
socket_id: sender,
},
};
Expand Down

0 comments on commit 1ff902d

Please sign in to comment.