-
-
Notifications
You must be signed in to change notification settings - Fork 561
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(rust): add low latency example
- Loading branch information
1 parent
0572200
commit 9a9ac59
Showing
12 changed files
with
431 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
max_width = 120 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Low latency portal |
90 changes: 90 additions & 0 deletions
90
examples/rust/low_latency_portal/examples/config-generator.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
105
examples/rust/low_latency_portal/examples/inlet-node.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(()) | ||
} |
Oops, something went wrong.