Skip to content

Commit

Permalink
feat(rust): add UDP support to nodes and multiaddr. refactor multiaddr
Browse files Browse the repository at this point in the history
  • Loading branch information
SanjoDeundiak committed Dec 11, 2024
1 parent d1124b2 commit 6aa2b30
Show file tree
Hide file tree
Showing 46 changed files with 1,016 additions and 537 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use ockam::{node, Context, Result};
use ockam_api::authenticator::enrollment_tokens::TokenAcceptor;
use ockam_api::authenticator::one_time_code::OneTimeCode;
use ockam_api::nodes::NodeManager;
use ockam_api::{multiaddr_to_route, multiaddr_to_transport_route};
use ockam_api::{RemoteMultiaddrResolver, TransportRouteResolver};
use ockam_core::AsyncTryClone;
use ockam_multiaddr::MultiAddr;

Expand Down Expand Up @@ -75,7 +75,9 @@ async fn start_node(ctx: Context, project_information_path: &str, token: OneTime
authority_node.present_token(node.context(), token).await.unwrap();

let project = import_project(project_information_path, node.identities()).await?;
let project_authority_route = multiaddr_to_transport_route(&project.authority_route()).unwrap(); // FIXME: Handle error
let project_authority_route = TransportRouteResolver::default()
.allow_tcp()
.resolve(&project.authority_route())?;

// Create a credential retriever that will be used to obtain credentials
let credential_retriever = Arc::new(RemoteCredentialRetrieverCreator::new(
Expand Down Expand Up @@ -117,7 +119,10 @@ async fn start_node(ctx: Context, project_information_path: &str, token: OneTime

// 5. create a relay on the Ockam orchestrator

let tcp_project_route = multiaddr_to_route(&project.route(), &tcp).await.unwrap(); // FIXME: Handle error
let tcp_project_route = RemoteMultiaddrResolver::default()
.with_tcp(tcp.clone())
.resolve(&project.route())
.await?;
let project_options = SecureChannelOptions::new()
.with_credential_retriever_creator(credential_retriever)?
.with_authority(project.authority_identifier())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use ockam::{route, Context, Result};
use ockam_api::authenticator::enrollment_tokens::TokenAcceptor;
use ockam_api::authenticator::one_time_code::OneTimeCode;
use ockam_api::nodes::NodeManager;
use ockam_api::{multiaddr_to_route, multiaddr_to_transport_route};
use ockam_api::{RemoteMultiaddrResolver, TransportRouteResolver};
use ockam_core::compat::sync::Arc;
use ockam_core::AsyncTryClone;
use ockam_multiaddr::MultiAddr;
Expand Down Expand Up @@ -73,7 +73,9 @@ async fn start_node(ctx: Context, project_information_path: &str, token: OneTime

let project = import_project(project_information_path, node.identities()).await?;

let project_authority_route = multiaddr_to_transport_route(&project.route()).unwrap(); // FIXME: Handle error
let project_authority_route = TransportRouteResolver::default()
.allow_tcp()
.resolve(&project.route())?;

// Create a credential retriever that will be used to obtain credentials
let credential_retriever = Arc::new(RemoteCredentialRetrieverCreator::new(
Expand Down Expand Up @@ -105,7 +107,10 @@ async fn start_node(ctx: Context, project_information_path: &str, token: OneTime

// 4. create a tcp inlet with the above policy

let tcp_project_route = multiaddr_to_route(&project.route(), &tcp).await.unwrap(); // FIXME: Handle error
let tcp_project_route = RemoteMultiaddrResolver::default()
.with_tcp(tcp.clone())
.resolve(&project.route())
.await?;
let project_options = SecureChannelOptions::new()
.with_credential_retriever_creator(credential_retriever)?
.with_authority(project.authority_identifier())
Expand Down
4 changes: 2 additions & 2 deletions implementations/rust/ockam/ockam/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ pub mod tcp {
/// UDP transport
pub mod udp {
pub use ockam_transport_udp::{
RendezvousClient, RendezvousService, UdpBindArguments, UdpBindOptions, UdpPuncture,
UdpPunctureNegotiation, UdpPunctureNegotiationListener,
RendezvousClient, RendezvousService, UdpBind, UdpBindArguments, UdpBindOptions,
UdpPuncture, UdpPunctureNegotiation, UdpPunctureNegotiationListener,
UdpPunctureNegotiationListenerOptions, UdpTransport, UdpTransportExtension,
MAX_MESSAGE_SIZE, UDP,
};
Expand Down
18 changes: 11 additions & 7 deletions implementations/rust/ockam/ockam_api/src/cli_state/trust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::nodes::service::{
CredentialScope, NodeManagerCredentialRetrieverOptions, NodeManagerTrustOptions,
};
use crate::nodes::NodeManager;
use crate::{multiaddr_to_transport_route, ApiError, CliState};
use crate::{ApiError, CliState, TransportRouteResolver};
use ockam::identity::models::ChangeHistory;
use ockam::identity::{IdentitiesVerification, RemoteCredentialRetrieverInfo};
use ockam_core::errcode::{Kind, Origin};
Expand Down Expand Up @@ -46,12 +46,14 @@ impl CliState {
}
};

let authority_route =
multiaddr_to_transport_route(authority_multiaddr).ok_or_else(|| {
let authority_route = TransportRouteResolver::default()
.allow_tcp()
.resolve(authority_multiaddr)
.map_err(|err| {
Error::new(
Origin::Api,
Kind::NotFound,
format!("Invalid authority route: {}", &authority_multiaddr),
format!("Invalid authority route. Err: {}", &err),
)
})?;
let info = RemoteCredentialRetrieverInfo::create_for_project_member(
Expand Down Expand Up @@ -116,12 +118,14 @@ impl CliState {
.authority_identifier()
.ok_or_else(|| ApiError::core("no authority identifier"))?;
let authority_multiaddr = project.authority_multiaddr()?;
let authority_route =
multiaddr_to_transport_route(authority_multiaddr).ok_or_else(|| {
let authority_route = TransportRouteResolver::default()
.allow_tcp()
.resolve(authority_multiaddr)
.map_err(|err| {
Error::new(
Origin::Api,
Kind::NotFound,
format!("Invalid authority route: {}", &authority_multiaddr),
format!("Invalid authority route. Err: {}", &err),
)
})?;

Expand Down
23 changes: 15 additions & 8 deletions implementations/rust/ockam/ockam_api/src/cloud/project/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::error::ApiError;
use crate::output::Output;
use crate::terminal::fmt;

use crate::TransportRouteResolver;
use ockam::identity::{Identifier, Identity, Vault};
use ockam_core::compat::collections::HashSet;
use ockam_core::errcode::{Kind, Origin};
Expand Down Expand Up @@ -66,9 +67,9 @@ impl Project {
// return the host and port of the project node.
// Ex: if access_route is "/dnsaddr/node.dnsaddr.com/tcp/4000/service/api",
// then this will return the string "node.dnsaddr.com:4000".
let socket_addr = multiaddr
.to_socket_addr()
.map_err(|e| ApiError::core(e.to_string()))?;
let socket_addr = TransportRouteResolver::default()
.allow_tcp()
.socket_address(&multiaddr)?;
project_socket_addr = Some(socket_addr.clone());
egress_allow_list.insert(socket_addr);
project_multiaddr = Some(multiaddr);
Expand All @@ -92,9 +93,9 @@ impl Project {
Some(authority_access_route) => {
let multiaddr = MultiAddr::from_str(authority_access_route)
.map_err(|e| ApiError::core(e.to_string()))?;
let socket_addr = multiaddr
.to_socket_addr()
.map_err(|e| ApiError::core(e.to_string()))?;
let socket_addr = TransportRouteResolver::default()
.allow_tcp()
.socket_address(&multiaddr)?;
authority_socket_addr = Some(socket_addr.clone());
egress_allow_list.insert(socket_addr);
authority_multiaddr = Some(multiaddr)
Expand Down Expand Up @@ -260,7 +261,10 @@ impl Output for Project {
fmt::PADDING,
fmt::INDENTATION,
self.project_multiaddr()
.map(|m| m.to_socket_addr().unwrap_or("N/A".to_string()))
.map(|m| TransportRouteResolver::default()
.allow_tcp()
.socket_address(m)
.unwrap_or("N/A".to_string()))
.unwrap_or("N/A".to_string())
)?;
writeln!(
Expand Down Expand Up @@ -301,7 +305,10 @@ impl Output for Project {
fmt::PADDING,
fmt::INDENTATION,
self.authority_multiaddr()
.map(|m| m.to_socket_addr().unwrap_or("N/A".to_string()))
.map(|m| TransportRouteResolver::default()
.allow_tcp()
.socket_address(m)
.unwrap_or("N/A".to_string()))
.unwrap_or("N/A".to_string())
)?;
writeln!(
Expand Down
59 changes: 36 additions & 23 deletions implementations/rust/ockam/ockam_api/src/cloud/secure_clients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ use ockam::identity::{
use ockam::tcp::TcpTransport;
use ockam_core::compat::sync::Arc;
use ockam_core::env::{get_env, get_env_with_default, FromString};
use ockam_core::{Result, Route};
use ockam_core::errcode::{Kind, Origin};
use ockam_core::{Error, Result, Route};
use ockam_multiaddr::MultiAddr;
use ockam_node::Context;

use crate::error::ApiError;
use crate::multiaddr_to_transport_route;
use crate::nodes::NodeManager;
use crate::TransportRouteResolver;

pub const OCKAM_CONTROLLER_ADDR: &str = "OCKAM_CONTROLLER_ADDR";
pub const DEFAULT_CONTROLLER_ADDRESS: &str = "/dnsaddr/orchestrator.ockam.io/tcp/6252/service/api";
Expand Down Expand Up @@ -138,11 +138,16 @@ impl NodeManager {
caller_identifier: &Identifier,
credential_retriever_creator: Option<Arc<dyn CredentialRetrieverCreator>>,
) -> Result<AuthorityNodeClient> {
let authority_route = multiaddr_to_transport_route(authority_route).ok_or_else(|| {
ApiError::core(format!(
"Couldn't convert MultiAddr to route: multiaddr={authority_route}"
))
})?;
let authority_route = TransportRouteResolver::default()
.allow_tcp()
.resolve(authority_route)
.map_err(|err| {
Error::new(
Origin::Api,
Kind::NotFound,
format!("Invalid authority route. Err: {}", &err),
)
})?;

Ok(AuthorityNodeClient {
secure_client: SecureClient::new(
Expand All @@ -167,11 +172,16 @@ impl NodeManager {
project_multiaddr: &MultiAddr,
caller_identifier: &Identifier,
) -> Result<ProjectNodeClient> {
let project_route = multiaddr_to_transport_route(project_multiaddr).ok_or_else(|| {
ApiError::core(format!(
"Couldn't convert MultiAddr to route: multiaddr={project_multiaddr}"
))
})?;
let project_route = TransportRouteResolver::default()
.allow_tcp()
.resolve(project_multiaddr)
.map_err(|err| {
Error::new(
Origin::Api,
Kind::NotFound,
format!("Invalid project node route. Err: {}", &err),
)
})?;

Ok(ProjectNodeClient {
secure_client: SecureClient::new(
Expand All @@ -194,11 +204,9 @@ impl NodeManager {
multiaddr: &MultiAddr,
caller_identifier: &Identifier,
) -> Result<GenericSecureClient> {
let route = multiaddr_to_transport_route(multiaddr).ok_or_else(|| {
ApiError::core(format!(
"Couldn't convert MultiAddr to route: multiaddr={multiaddr}"
))
})?;
let route = TransportRouteResolver::default()
.allow_tcp()
.resolve(multiaddr)?;

Ok(GenericSecureClient {
secure_client: SecureClient::new(
Expand Down Expand Up @@ -233,11 +241,16 @@ impl NodeManager {

pub async fn controller_route() -> Result<Route> {
let multiaddr = Self::controller_multiaddr();
multiaddr_to_transport_route(&multiaddr).ok_or_else(|| {
ApiError::core(format!(
"Couldn't convert MultiAddr to route: multiaddr={multiaddr}"
))
})
TransportRouteResolver::default()
.allow_tcp()
.resolve(&multiaddr)
.map_err(|err| {
Error::new(
Origin::Api,
Kind::NotFound,
format!("Invalid controller route. Err: {}", &err),
)
})
}
}

Expand Down
2 changes: 2 additions & 0 deletions implementations/rust/ockam/ockam_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub mod logs;
mod schema;

mod date;
mod multiaddr_resolver;
mod rendezvous_healthcheck;
pub mod test_utils;
mod ui;
Expand All @@ -52,6 +53,7 @@ mod util;
pub use cli_state::CliState;
pub use date::UtcDateTime;
pub use error::*;
pub use multiaddr_resolver::*;
pub use nodes::service::default_address::*;
pub use rendezvous_healthcheck::*;
pub use session::connection_status::ConnectionStatus;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use crate::multiaddr_resolver::invalid_multiaddr_error;
use ockam_core::errcode::{Kind, Origin};
use ockam_core::{Address, Error, Result, Route, LOCAL};
use ockam_multiaddr::proto::{DnsAddr, Ip4, Ip6, Node, Secure, Service, Worker};
use ockam_multiaddr::{MultiAddr, Protocol};

pub struct LocalMultiaddrResolver {}

impl LocalMultiaddrResolver {
/// Try to convert a local multi-address to an Ockam route.
pub fn resolve(ma: &MultiAddr) -> Result<Route> {
let mut rb = Route::new();
for p in ma.iter() {
match p.code() {
// Only hops that are directly translated to existing workers are allowed here
Worker::CODE => {
let local = p
.cast::<Worker>()
.ok_or_else(|| invalid_multiaddr_error(ma))?;
rb = rb.append(Address::new_with_string(LOCAL, &*local))
}
Service::CODE => {
let local = p
.cast::<Service>()
.ok_or_else(|| invalid_multiaddr_error(ma))?;
rb = rb.append(Address::new_with_string(LOCAL, &*local))
}
Secure::CODE => {
let local = p
.cast::<Secure>()
.ok_or_else(|| invalid_multiaddr_error(ma))?;
rb = rb.append(Address::new_with_string(LOCAL, &*local))
}

Node::CODE => {
return Err(Error::new(
Origin::Api,
Kind::Invalid,
"unexpected code: node. clean_multiaddr should have been called",
));
}

code @ (Ip4::CODE | Ip6::CODE | DnsAddr::CODE) => {
return Err(Error::new(
Origin::Api,
Kind::Invalid,
format!(
"unexpected code: {code}. The address must be a local address {ma}"
),
));
}

_ => {
return Err(invalid_multiaddr_error(ma));
}
}
}

Ok(rb.into())
}
}
28 changes: 28 additions & 0 deletions implementations/rust/ockam/ockam_api/src/multiaddr_resolver/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
mod local_resolver;
mod remote_resolver;
mod reverse_local_converter;
mod transport_route_resolver;

pub use local_resolver::*;
use ockam_core::errcode::{Kind, Origin};
use ockam_core::Error;
use ockam_multiaddr::MultiAddr;
pub use remote_resolver::*;
pub use reverse_local_converter::*;
pub use transport_route_resolver::*;

fn invalid_multiaddr_error(ma: &MultiAddr) -> Error {
Error::new(
Origin::Api,
Kind::Misuse,
format!("Invalid multiaddr {}", ma),
)
}

fn multiple_transport_hops_error(ma: &MultiAddr) -> Error {
Error::new(
Origin::Api,
Kind::Unsupported,
format!("Only one hop is allowed in a multiaddr. Multiaddr={}", ma),
)
}
Loading

0 comments on commit 6aa2b30

Please sign in to comment.