Skip to content

Commit

Permalink
chore(rust): add low latency example
Browse files Browse the repository at this point in the history
  • Loading branch information
SanjoDeundiak committed Dec 30, 2024
1 parent 0572200 commit 9a9ac59
Show file tree
Hide file tree
Showing 12 changed files with 431 additions and 0 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"examples/rust/file_transfer",
"examples/rust/get_started",
"examples/rust/tcp_inlet_and_outlet",
"examples/rust/low_latency_portal",
"examples/rust/mitm_node",
"implementations/rust/ockam/*",
"tools/docs/example_blocks",
Expand Down
1 change: 1 addition & 0 deletions examples/rust/low_latency_portal/.rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
max_width = 120
15 changes: 15 additions & 0 deletions examples/rust/low_latency_portal/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "low_latency_portal"
version = "0.1.0"
authors = ["Ockam Developers"]
edition = "2021"
license = "Apache-2.0"
publish = false
rust-version = "1.70.0"

[dependencies]
ockam = { path = "../../../implementations/rust/ockam/ockam", features = ["aws-lc"] }
serde = { version = "1.0.215", features = ["derive"] }
serde_json = "1.0"
hex = "0.4.3"
log = "0.4.22"
1 change: 1 addition & 0 deletions examples/rust/low_latency_portal/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Low latency portal
90 changes: 90 additions & 0 deletions examples/rust/low_latency_portal/examples/config-generator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use low_latency_portal::{InletConfig, OutletConfig, RelayConfig};
use ockam::compat::rand::{thread_rng, RngCore};
use ockam::identity::{Identities, IdentityBuilder, Vault};
use ockam::transport::HostnamePort;
use ockam::vault::{
EdDSACurve25519SecretKey, SigningSecret, SoftwareVaultForSigning, EDDSA_CURVE25519_SECRET_KEY_LENGTH,
};
use ockam::{Context, Result};

#[ockam::node]
async fn main(ctx: Context) -> Result<()> {
let identity_vault = SoftwareVaultForSigning::create().await?;

let mut inlet_key_binary = [0u8; EDDSA_CURVE25519_SECRET_KEY_LENGTH];
let mut outlet_key_binary = [0u8; EDDSA_CURVE25519_SECRET_KEY_LENGTH];
let mut relay_key_binary = [0u8; EDDSA_CURVE25519_SECRET_KEY_LENGTH];

{
let mut rng = thread_rng();

rng.fill_bytes(&mut inlet_key_binary);
rng.fill_bytes(&mut outlet_key_binary);
rng.fill_bytes(&mut relay_key_binary);
}

let inlet_key = identity_vault
.import_key(SigningSecret::EdDSACurve25519(EdDSACurve25519SecretKey::new(
inlet_key_binary,
)))
.await?;
let outlet_key = identity_vault
.import_key(SigningSecret::EdDSACurve25519(EdDSACurve25519SecretKey::new(
outlet_key_binary,
)))
.await?;
let relay_key = identity_vault
.import_key(SigningSecret::EdDSACurve25519(EdDSACurve25519SecretKey::new(
relay_key_binary,
)))
.await?;

let mut vault = Vault::create().await?;
vault.identity_vault = identity_vault;

let identities = Identities::builder().await?.with_vault(vault).build();
let inlet_identifier = IdentityBuilder::new(identities.identities_creation())
.with_existing_key(inlet_key)
.build()
.await?;
let outlet_identifier = IdentityBuilder::new(identities.identities_creation())
.with_existing_key(outlet_key)
.build()
.await?;
let relay_identifier = IdentityBuilder::new(identities.identities_creation())
.with_existing_key(relay_key)
.build()
.await?;

let inlet_config = InletConfig {
inlet_change_history: hex::encode(identities.export_identity(&inlet_identifier).await?),
inlet_identity_key: hex::encode(inlet_key_binary),
inlet_address: HostnamePort::new("0.0.0.0", 4000),
relay_address: HostnamePort::new("127.0.0.1", 4001),
outlet_identifier: outlet_identifier.to_string(),
outlet_relay_name: "outlet_relay".to_string(),
};

let outlet_config = OutletConfig {
outlet_change_history: hex::encode(identities.export_identity(&outlet_identifier).await?),
outlet_identity_key: hex::encode(outlet_key_binary),
outlet_relay_name: "outlet_relay".to_string(),
outlet_peer_address: HostnamePort::new("127.0.0.1", 5000),
relay_identifier: relay_identifier.to_string(),
relay_address: HostnamePort::new("127.0.0.1", 4001),
inlet_identifiers: vec![inlet_identifier.to_string()],
};

let relay_config = RelayConfig {
relay_change_history: hex::encode(identities.export_identity(&relay_identifier).await?),
relay_identity_key: hex::encode(relay_key_binary),
outlet_identifier: outlet_identifier.to_string(),
relay_listener_address: HostnamePort::new("0.0.0.0", 4001),
};

std::fs::write("inlet.config.json", serde_json::to_vec(&inlet_config).unwrap()).unwrap();
std::fs::write("outlet.config.json", serde_json::to_vec(&outlet_config).unwrap()).unwrap();
std::fs::write("relay.config.json", serde_json::to_vec(&relay_config).unwrap()).unwrap();

ctx.stop().await
}
105 changes: 105 additions & 0 deletions examples/rust/low_latency_portal/examples/inlet-node.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
use log::info;
use low_latency_portal::{parse, InletConfig};
use ockam::identity::models::ChangeHistory;
use ockam::identity::{Identifier, SecureChannelOptions, SecureChannels, TrustIdentifierPolicy, Vault};
use ockam::tcp::{TcpConnectionOptions, TcpInletOptions, TcpTransport};
use ockam::vault::{EdDSACurve25519SecretKey, SigningSecret, SoftwareVaultForSigning};
use ockam::{route, Context, Result};
use std::str::FromStr;

#[ockam::node]
async fn main(ctx: Context) -> Result<()> {
let args: Vec<String> = std::env::args().collect();

info!("A");
let config = if let Some(config) = args.get(1) {
config.clone()
} else {
let config = std::fs::read("inlet.config.json").unwrap();
String::from_utf8(config).unwrap()
};

info!("B");
let config: InletConfig = parse(&config)?;
info!("C");

let outlet_identifier = Identifier::from_str(&config.outlet_identifier)?;
let inlet_identity_key = hex::decode(config.inlet_identity_key).unwrap();
let inlet_change_history = ChangeHistory::import_from_string(&config.inlet_change_history)?;

info!("D");

let tcp = TcpTransport::create(&ctx).await?;

info!("E");

let identity_vault = SoftwareVaultForSigning::create().await?; // FIXME: 16ms

info!("F");

let relay_identity_key = EdDSACurve25519SecretKey::new(inlet_identity_key.try_into().unwrap());

info!("G");
let relay_identity_key = SigningSecret::EdDSACurve25519(relay_identity_key);

info!("H");

identity_vault.import_key(relay_identity_key).await?;

info!("J");

let mut vault = Vault::create().await?; // FIXME: 25ms
vault.identity_vault = identity_vault;

info!("K");

let secure_channels = SecureChannels::builder().await?.with_vault(vault).build(); // FIXME: 16 ms

info!("L");

let inlet_identifier = secure_channels
.identities()
.identities_verification()
.import_from_change_history(None, inlet_change_history)
.await?;

info!("M");

let tcp_connection_to_relay = tcp
.connect(config.relay_address.to_string(), TcpConnectionOptions::new())
.await?;

info!("N");

let secure_channel_to_outlet = secure_channels
.create_secure_channel(
&ctx,
&inlet_identifier,
route![
tcp_connection_to_relay,
format!("forward_to_{}", config.outlet_relay_name),
"api"
],
SecureChannelOptions::new().with_trust_policy(TrustIdentifierPolicy::new(outlet_identifier)),
)
.await?;

info!("O");

tcp.create_inlet(
config.inlet_address.to_string(),
route![secure_channel_to_outlet, "outlet"],
TcpInletOptions::new(),
)
.await?;

info!("P");

info!("Initialized successfully");

ctx.stop().await?;

info!("Q");

Ok(())
}
94 changes: 94 additions & 0 deletions examples/rust/low_latency_portal/examples/outlet-node.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
use log::info;
use low_latency_portal::{parse, OutletConfig};
use ockam::identity::models::ChangeHistory;
use ockam::identity::{
Identifier, SecureChannelListenerOptions, SecureChannelOptions, SecureChannels, TrustIdentifierPolicy,
TrustMultiIdentifiersPolicy, Vault,
};
use ockam::remote::{RemoteRelay, RemoteRelayOptions};
use ockam::tcp::{TcpConnectionOptions, TcpOutletOptions, TcpTransport};
use ockam::vault::{EdDSACurve25519SecretKey, SigningSecret, SoftwareVaultForSigning};
use ockam::{route, Context, Result};
use std::str::FromStr;

#[ockam::node]
async fn main(ctx: Context) -> Result<()> {
let args: Vec<String> = std::env::args().collect();

let config = if let Some(config) = args.get(1) {
config.clone()
} else {
let config = std::fs::read("outlet.config.json").unwrap();
String::from_utf8(config).unwrap()
};

let config: OutletConfig = parse(&config)?;

let relay_identifier = Identifier::from_str(&config.relay_identifier)?;
let outlet_identity_key = hex::decode(config.outlet_identity_key).unwrap();
let inlet_identifiers = config
.inlet_identifiers
.iter()
.map(|i| Identifier::from_str(i).unwrap())
.collect();
let outlet_change_history = ChangeHistory::import_from_string(&config.outlet_change_history)?;

let tcp = TcpTransport::create(&ctx).await?;

let identity_vault = SoftwareVaultForSigning::create().await?;
let outlet_identity_key = EdDSACurve25519SecretKey::new(outlet_identity_key.try_into().unwrap());
let outlet_identity_key = SigningSecret::EdDSACurve25519(outlet_identity_key);
identity_vault.import_key(outlet_identity_key).await?;

let mut vault = Vault::create().await?;
vault.identity_vault = identity_vault;

let secure_channels = SecureChannels::builder().await?.with_vault(vault).build();

let outlet_identifier = secure_channels
.identities()
.identities_verification()
.import_from_change_history(None, outlet_change_history)
.await?;

let tcp_connection_options = TcpConnectionOptions::new();
let secure_channel_options =
SecureChannelOptions::new().with_trust_policy(TrustIdentifierPolicy::new(relay_identifier));
let secure_channel_listener_options = SecureChannelListenerOptions::new()
.as_consumer(&secure_channel_options.producer_flow_control_id())
.with_trust_policy(TrustMultiIdentifiersPolicy::new(inlet_identifiers));
let tcp_outlet_options =
TcpOutletOptions::new().as_consumer(&secure_channel_listener_options.spawner_flow_control_id());

tcp.create_outlet("outlet", config.outlet_peer_address, tcp_outlet_options)
.await?;

secure_channels
.create_secure_channel_listener(&ctx, &outlet_identifier, "api", secure_channel_listener_options)
.await?;

let tcp_connection_to_relay = tcp
.connect(config.relay_address.to_string(), tcp_connection_options)
.await?;
let secure_channel_to_relay = secure_channels
.create_secure_channel(
&ctx,
&outlet_identifier,
route![tcp_connection_to_relay, "api"],
secure_channel_options,
)
.await?;

let relay_options = RemoteRelayOptions::new();
RemoteRelay::create_static(
&ctx,
route![secure_channel_to_relay],
config.outlet_relay_name,
relay_options,
)
.await?;

info!("Initialized successfully");

Ok(())
}
Loading

0 comments on commit 9a9ac59

Please sign in to comment.