From ca7fafd9d8b228bd8a1a46a4defbda311b244095 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw=20Pitucha?= Date: Wed, 1 Sep 2021 21:23:45 +1000 Subject: [PATCH] Add message receiving usdts This requires the systemtap development package as well as dtrace tool to be present during building. The specific notifications are configured in radicle_link.d and the names can be used to filter the results. Currently the notifications work only on Linux, but a different crate can be used for the same result on MacOS. The result can be tested on a running seed with: ``` sudo bpftrace -p $(pgrep -f radicle-seed-node) -e ' usdt:*/radicle-seed-node:radicleusdt:have_recv { printf("have, peer %s, urn %s\n", str(arg0), str(arg1)); } usdt:*/radicle-seed-node:radicleusdt:want_recv { printf("want, peer %s, urn %s\n", str(arg0), str(arg1)); }' ``` --- librad/Cargo.toml | 8 ++++++++ librad/build.rs | 6 ++++++ librad/radicle_link.d | 4 ++++ librad/src/lib.rs | 5 +++++ librad/src/net/peer/storage.rs | 23 +++++++++++++++++++++++ 5 files changed, 46 insertions(+) create mode 100644 librad/build.rs create mode 100644 librad/radicle_link.d diff --git a/librad/Cargo.toml b/librad/Cargo.toml index f98a82837..00a595784 100644 --- a/librad/Cargo.toml +++ b/librad/Cargo.toml @@ -61,6 +61,11 @@ uuid = { version = "0.8", features = ["v4"] } webpki = "0.21" xorf = "0.7" +[build-dependencies.sonde] +git = "https://github.com/viraptor/sonde-rs" +rev = "88c3b872eaa7fdfe6ffbef34e1c920d4c9401544" +optional = true + [dependencies.deadpool] version = "0.7" default-features = false @@ -143,3 +148,6 @@ features = ["serde"] [dependencies.zeroize] version = "1.1" features = ["zeroize_derive"] + +[features] +usdt = ["sonde"] diff --git a/librad/build.rs b/librad/build.rs new file mode 100644 index 000000000..2a3babc69 --- /dev/null +++ b/librad/build.rs @@ -0,0 +1,6 @@ +fn main() { + #[cfg(feature = "usdt")] + sonde::Builder::new() + .file("./radicle_link.d") + .compile(); +} diff --git a/librad/radicle_link.d b/librad/radicle_link.d new file mode 100644 index 000000000..1b5e1c381 --- /dev/null +++ b/librad/radicle_link.d @@ -0,0 +1,4 @@ +provider radicle_link { + probe have_recv(char*, char*); + probe want_recv(char*, char*); +}; diff --git a/librad/src/lib.rs b/librad/src/lib.rs index 12c728b25..da316b9ea 100644 --- a/librad/src/lib.rs +++ b/librad/src/lib.rs @@ -18,6 +18,11 @@ #![feature(try_trait_v2)] #![feature(control_flow_enum)] +#[cfg(feature = "usdt")] +pub mod usdt { + include!(env!("SONDE_RUST_API_FILE")); +} + #[macro_use] extern crate async_trait; #[macro_use] diff --git a/librad/src/net/peer/storage.rs b/librad/src/net/peer/storage.rs index dab06174c..03275742a 100644 --- a/librad/src/net/peer/storage.rs +++ b/librad/src/net/peer/storage.rs @@ -174,6 +174,25 @@ pub fn urn_context(local_peer_id: PeerId, urn: Either>) -> } } +#[cfg(feature = "usdt")] +fn report_have(peer: &PeerId, urn: &Urn) { + let p: &str = &peer.default_encoding(); + let u: &str = &urn.encode_id(); + crate::usdt::radicle_link::have_recv(p.as_ptr() as *mut _, u.as_ptr() as *mut _); +} + +#[cfg(not(feature = "usdt"))] +fn report_have(peer: &PeerId, urn: &Urn) { } + +#[cfg(feature = "usdt")] +fn report_want(peer: &Option, urn: &Urn) { + let p: &str = &peer.map_or_else(|| "unknown".to_owned(), |o| o.default_encoding()); + let u: &str = &urn.encode_id(); + crate::usdt::radicle_link::want_recv(p.as_ptr() as *mut _, u.as_ptr() as *mut _); +} +#[cfg(not(feature = "usdt"))] +fn report_want(peer: &Option, urn: &Urn) { } + #[async_trait] impl broadcast::LocalStorage for Storage { type Update = gossip::Payload; @@ -187,6 +206,8 @@ impl broadcast::LocalStorage for Storage { let (provider, addr_hints) = provider.into(); + report_have(&provider, &has.urn); + // If the `has` doesn't tell us to look into a specific remote-tracking // branch, assume we want the `provider`'s. let origin = has.origin.unwrap_or(provider); @@ -258,6 +279,8 @@ impl broadcast::LocalStorage for Storage { #[tracing::instrument(level = "debug", skip(self))] async fn ask(&self, want: Self::Update) -> bool { + report_want(&want.origin, &want.urn); + self.git_has( match want.origin { Some(origin) => Right(Originates {