mod error;
pub mod memory;
use std::cmp::Ordering;
use std::fmt;
pub use self::error::RoutingTableReaderError;
use crate::error::InternalError;
use crate::error::InvalidStateError;
use crate::peer::{PeerAuthorizationToken, PeerTokenPair};
use crate::public_key::PublicKey;
pub trait RoutingTableWriter: Send {
fn add_service(&mut self, service_id: ServiceId, service: Service)
-> Result<(), InternalError>;
fn remove_service(&mut self, service_id: &ServiceId) -> Result<(), InternalError>;
fn add_circuit(
&mut self,
circuit_id: String,
circuit: Circuit,
nodes: Vec<CircuitNode>,
) -> Result<(), InternalError>;
fn add_circuits(&mut self, circuits: Vec<Circuit>) -> Result<(), InternalError>;
fn remove_circuit(&mut self, circuit_id: &str) -> Result<(), InternalError>;
fn add_node(&mut self, node_id: String, node: CircuitNode) -> Result<(), InternalError>;
fn add_nodes(&mut self, nodes: Vec<CircuitNode>) -> Result<(), InternalError>;
fn remove_node(&mut self, node_id: &str) -> Result<(), InternalError>;
fn clone_boxed(&self) -> Box<dyn RoutingTableWriter>;
}
impl Clone for Box<dyn RoutingTableWriter> {
fn clone(&self) -> Self {
self.clone_boxed()
}
}
pub type CircuitNodeIter = Box<dyn ExactSizeIterator<Item = (String, CircuitNode)> + Send>;
pub type CircuitIter = Box<dyn ExactSizeIterator<Item = (String, Circuit)> + Send>;
pub trait RoutingTableReader: Send {
fn get_service(
&self,
service_id: &ServiceId,
) -> Result<Option<Service>, RoutingTableReaderError>;
fn list_services(&self, circuit_id: &str) -> Result<Vec<Service>, RoutingTableReaderError>;
fn list_nodes(&self) -> Result<CircuitNodeIter, RoutingTableReaderError>;
fn get_node(&self, node_id: &str) -> Result<Option<CircuitNode>, RoutingTableReaderError>;
fn list_circuits(&self) -> Result<CircuitIter, RoutingTableReaderError>;
fn get_circuit(&self, circuit_id: &str) -> Result<Option<Circuit>, RoutingTableReaderError>;
fn clone_boxed(&self) -> Box<dyn RoutingTableReader>;
}
impl Clone for Box<dyn RoutingTableReader> {
fn clone(&self) -> Self {
self.clone_boxed()
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Circuit {
circuit_id: String,
roster: Vec<Service>,
members: Vec<String>,
authorization_type: AuthorizationType,
}
impl Circuit {
pub fn new(
circuit_id: String,
roster: Vec<Service>,
members: Vec<String>,
authorization_type: AuthorizationType,
) -> Self {
Circuit {
circuit_id,
roster,
members,
authorization_type,
}
}
pub fn circuit_id(&self) -> &str {
&self.circuit_id
}
pub fn roster(&self) -> &[Service] {
&self.roster
}
pub fn members(&self) -> &[String] {
&self.members
}
pub fn authorization_type(&self) -> &AuthorizationType {
&self.authorization_type
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum AuthorizationType {
Trust,
Challenge,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CircuitNode {
node_id: String,
endpoints: Vec<String>,
public_key: Option<PublicKey>,
}
impl CircuitNode {
pub fn new(node_id: String, endpoints: Vec<String>, public_key: Option<PublicKey>) -> Self {
CircuitNode {
node_id,
endpoints,
public_key,
}
}
pub fn get_peer_auth_token(
&self,
auth_type: &AuthorizationType,
) -> Result<PeerAuthorizationToken, RoutingTableReaderError> {
match auth_type {
AuthorizationType::Trust => Ok(PeerAuthorizationToken::from_peer_id(&self.node_id)),
AuthorizationType::Challenge => {
let public_key = self.public_key.clone().ok_or_else(|| {
RoutingTableReaderError::InvalidStateError(InvalidStateError::with_message(
format!(
"Circuit Node {} does not have public key and challenge
authorization was requested",
self.node_id
),
))
})?;
Ok(PeerAuthorizationToken::from_public_key(
public_key.as_slice(),
))
}
}
}
}
impl Ord for CircuitNode {
fn cmp(&self, other: &Self) -> Ordering {
self.node_id.cmp(&other.node_id)
}
}
impl PartialOrd for CircuitNode {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Service {
service_id: String,
service_type: String,
node_id: String,
arguments: Vec<(String, String)>,
local_peer_id: Option<PeerTokenPair>,
}
impl Service {
pub fn new(
service_id: String,
service_type: String,
node_id: String,
arguments: Vec<(String, String)>,
) -> Self {
Service {
service_id,
service_type,
node_id,
arguments,
local_peer_id: None,
}
}
pub fn service_id(&self) -> &str {
&self.service_id
}
pub fn service_type(&self) -> &str {
&self.service_type
}
pub fn node_id(&self) -> &str {
&self.node_id
}
pub fn arguments(&self) -> &[(String, String)] {
&self.arguments
}
pub fn local_peer_id(&self) -> &Option<PeerTokenPair> {
&self.local_peer_id
}
pub fn set_local_peer_id(&mut self, peer_id: PeerTokenPair) {
self.local_peer_id = Some(peer_id)
}
pub fn remove_local_peer_id(&mut self) {
self.local_peer_id = None
}
pub fn peer_id(&self) -> &Option<PeerTokenPair> {
self.local_peer_id()
}
pub fn set_peer_id(&mut self, peer_id: PeerTokenPair) {
self.set_local_peer_id(peer_id)
}
pub fn remove_peer_id(&mut self) {
self.remove_local_peer_id()
}
}
#[derive(Clone, Debug, Hash, PartialEq)]
pub struct ServiceId {
circuit_id: String,
service_id: String,
}
impl ServiceId {
pub fn new(circuit_id: String, service_id: String) -> Self {
ServiceId {
circuit_id,
service_id,
}
}
pub fn circuit(&self) -> &str {
&self.circuit_id
}
pub fn service_id(&self) -> &str {
&self.service_id
}
pub fn into_parts(self) -> (String, String) {
(self.circuit_id, self.service_id)
}
}
impl fmt::Display for ServiceId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}::{}", self.circuit_id, self.service_id)
}
}
impl Eq for ServiceId {}