Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rust-client: add api-key & listen_multi_addresses #23

Merged
merged 5 commits into from
Jul 9, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 30 additions & 32 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,35 +1,33 @@
# Based on https://github.com/actions-rs/meta/blob/master/recipes/quickstart.md

# commented out until this works again
name: Cargo check

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
check:
name: Check
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2

- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true

- name: Run cargo check
uses: actions-rs/cargo@v1
with:
command: check
args: --manifest-path=rust-client/Cargo.toml

# name: Cargo check
#
# on:
# push:
# branches:
# - main
# pull_request:
# branches:
# - main
#
# jobs:
# check:
# name: Check
# runs-on: ubuntu-latest
# steps:
# - name: Checkout sources
# uses: actions/checkout@v2
#
# - name: Install stable toolchain
# uses: actions-rs/toolchain@v1
# with:
# profile: minimal
# toolchain: stable
# override: true
#
# - name: Run cargo check
# uses: actions-rs/cargo@v1
# with:
# command: check
# args: --manifest-path=rust-client/Cargo.toml
#
68 changes: 43 additions & 25 deletions rust-client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,21 @@ struct Opt {
#[clap(long)]
secret_key_seed: u8,

/// If set to `true`, use relay-v1 protocol.
/// Per default relay-v2 is used.
#[clap(long)]
relay_v1: bool,

/// Api-key used to authenticate our client at the server.
#[clap(long)]
api_key: String,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should pass a secret via a command line argument. This is problematic due to:

  • The secret ends up in the shell's history.
  • Other users can see the secret via /proc.

Instead I would use either an environment variable or a file where the file path can be passed as an argument.

What do you think @elenaf9?

Copy link
Collaborator Author

@elenaf9 elenaf9 Jul 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Reading it from env variable now (50253b0). If it is not present I am logging a warning but still continuing, in case that we ever decide to (temporarily?) disable auth again. Can also change it in a follow up PR to throw an error, if you think that makes more sense.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that it is a mechanism for the server to establish trust to the client and not the other way around, I think defaulting to not using the API key is fine here. 👍

}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let _ = env_logger::try_init();
let opt = Opt::parse();
let api_key = opt.api_key;

let mut client =
grpc::punchr_service_client::PunchrServiceClient::connect(opt.url.clone()).await?;
Expand Down Expand Up @@ -85,13 +92,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
client_id: local_peer_id.to_bytes(),
agent_version: agent_version(),
protocols: protocols.clone().unwrap(),
api_key: api_key.clone(),
});

client.register(request).await?;

let request = tonic::Request::new(grpc::GetAddrInfoRequest {
host_id: local_peer_id.to_bytes(),
all_host_ids: vec![local_peer_id.to_bytes()],
api_key: api_key.clone(),
});

let response = client.get_addr_info(request).await?.into_inner();
Expand All @@ -104,29 +113,19 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.map(Multiaddr::try_from)
.collect::<Result<Vec<_>, libp2p::multiaddr::Error>>()?;

let state = HolePunchState::new(
local_peer_id,
swarm.listeners(),
remote_peer_id,
remote_addrs.clone(),
api_key.clone(),
);

if remote_addrs
.iter()
.all(|a| a.iter().any(|p| p == libp2p::multiaddr::Protocol::Quic))
{
info!(
"Skipping hole punch through to {:?} via {:?} because the Quic transport is not supported.",
remote_peer_id, remote_addrs
);
let unix_time_now = unix_time_now();
let request = grpc::TrackHolePunchRequest {
client_id: local_peer_id.into(),
remote_id: response.remote_id,
remote_multi_addresses: remote_addrs.into_iter().map(|a| a.to_vec()).collect(),
open_multi_addresses: Vec::new(),
has_direct_conns: false,
connect_started_at: unix_time_now,
connect_ended_at: unix_time_now,
hole_punch_attempts: Vec::new(),
error: Some("rust-lib2p doesn't support quic transport yet.".into()),
outcome: grpc::HolePunchOutcome::Cancelled.into(),
ended_at: unix_time_now
};

let request = state.cancel();
client
.track_hole_punch(tonic::Request::new(request))
.await?;
Expand All @@ -140,13 +139,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

swarm.dial(
DialOpts::peer_id(remote_peer_id)
.addresses(remote_addrs.clone())
.addresses(remote_addrs)
.build(),
)?;

let request = HolePunchState::new(local_peer_id, remote_peer_id, remote_addrs)
.drive_hole_punch(&mut swarm)
.await;
let request = state.drive_hole_punch(&mut swarm).await;

client
.track_hole_punch(tonic::Request::new(request))
Expand Down Expand Up @@ -242,7 +239,13 @@ struct HolePunchState {
}

impl HolePunchState {
fn new(client_id: PeerId, remote_id: PeerId, remote_multi_addresses: Vec<Multiaddr>) -> Self {
fn new<'a>(
client_id: PeerId,
client_listen_addrs: impl Iterator<Item = &'a Multiaddr>,
remote_id: PeerId,
remote_multi_addresses: Vec<Multiaddr>,
api_key: String,
) -> Self {
let request = grpc::TrackHolePunchRequest {
client_id: client_id.into(),
remote_id: remote_id.into(),
Expand All @@ -258,6 +261,8 @@ impl HolePunchState {
error: None,
outcome: grpc::HolePunchOutcome::Unknown.into(),
ended_at: 0,
listen_multi_addresses: client_listen_addrs.map(|a| a.to_vec()).collect(),
api_key,
};
HolePunchState {
request,
Expand All @@ -266,6 +271,19 @@ impl HolePunchState {
}
}

fn cancel(mut self) -> grpc::TrackHolePunchRequest {
info!(
"Skipping hole punch through to {:?} via {:?} because the Quic transport is not supported.",
self.request.remote_id, self.request.remote_multi_addresses
);
let unix_time_now = unix_time_now();
self.request.connect_ended_at = unix_time_now;
self.request.ended_at = unix_time_now;
self.request.error = Some("rust-lib2p doesn't support quic transport yet.".into());
self.request.outcome = grpc::HolePunchOutcome::Cancelled.into();
self.request
}

async fn drive_hole_punch(
mut self,
swarm: &mut libp2p::swarm::Swarm<Behaviour>,
Expand Down Expand Up @@ -465,7 +483,7 @@ impl HolePunchAttemptState {
);
grpc::HolePunchAttempt {
opened_at: self.opened_at,
started_at: self.started_at,
started_at: Some(self.started_at),
ended_at,
start_rtt: None,
elapsed_time: (ended_at - self.started_at) as f32 / 1000f32,
Expand Down