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

feature: ddcommon-net2 crate #766

Draft
wants to merge 14 commits into
base: levi/split-net
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
158 changes: 105 additions & 53 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ members = [
"ddcommon",
"ddcommon-ffi",
"ddcommon-net1",
"ddcommon-net2",
"ddtelemetry",
"ddtelemetry-ffi",
"dogstatsd",
Expand Down
547 changes: 536 additions & 11 deletions LICENSE-3rdparty.yml

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ LIBDD_OUTPUT_FOLDER=/opt/release cargo build -p builder --features profiling,tel
```

#### Build scripts
This is the non-prefered way of building a release, it's use is discouraged and it will be soon deprecated in favour of
using the builder crate.
This is the non-preferred way of building a release, it's use is discouraged and it will be soon deprecated in favour
of using the builder crate.

To package a release with the generated ffi header and CMake module, use the `build-profiling-ffi.sh` / `build-telemetry-ffi.sh` helper scripts.
Here's an example of using on of these scripts, placing the output inside `/opt/libdatadog`:
Expand Down
9 changes: 6 additions & 3 deletions builder/src/arch/apple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,20 @@ pub const REMOVE_RPATH: bool = true;
pub const BUILD_CRASHTRACKER: bool = true;
pub const RUSTFLAGS: [&str; 2] = ["-C", "relocation-model=pic"];

#[allow(clippy::zombie_processes)]
pub fn fix_rpath(lib_path: &str) {
if REMOVE_RPATH {
let lib_name = lib_path.split('/').last().unwrap();

Command::new("install_name_tool")
let status = Command::new("install_name_tool")
.arg("-id")
.arg("@rpath/".to_string() + lib_name)
.arg(lib_path)
.spawn()
.status()
.expect("Failed to fix rpath");

if !status.success() {
panic!("Failed to fix rpath: {status}");
}
}
}

Expand Down
7 changes: 6 additions & 1 deletion builder/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,12 @@ impl Builder {

pub fn add_cmake(&self) {
let libs = arch::NATIVE_LIBS.to_owned();
let cmake_path: PathBuf = [&self.target_dir, "DatadogConfig.cmake"].iter().collect();
let cmake_dir: PathBuf = [&self.target_dir, "cmake"].iter().collect();
fs::create_dir_all(cmake_dir).expect("Failed to create cmake dir");

let cmake_path: PathBuf = [&self.target_dir, "cmake", "DatadogConfig.cmake"]
.iter()
.collect();
let mut origin = project_root();
origin.push("cmake");
origin.push("DatadogConfig.cmake.in");
Expand Down
7 changes: 5 additions & 2 deletions builder/src/crashtracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@ pub struct CrashTracker {
impl CrashTracker {
fn gen_binaries(&self) -> Result<()> {
if arch::BUILD_CRASHTRACKER {
let mut datadog_root = project_root();
datadog_root.push(self.target_dir.as_ref());

let mut crashtracker_dir = project_root();
crashtracker_dir.push("crashtracker");
let _dst = cmake::Config::new(crashtracker_dir.to_str().unwrap())
.define("Datadog_ROOT", self.target_dir.as_ref())
.define("CMAKE_INSTALL_PREFIX", self.target_dir.as_ref())
.define("Datadog_ROOT", datadog_root.to_str().unwrap())
.define("CMAKE_INSTALL_PREFIX", self.target_dir.to_string())
.build();
}

Expand Down
1 change: 0 additions & 1 deletion crashtracker-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,5 @@ datadog-crashtracker = { path = "../crashtracker" }
ddcommon = { path = "../ddcommon" }
ddcommon-ffi = { path = "../ddcommon-ffi", default-features = false }
ddcommon-net1 = { path = "../ddcommon-net1" }
hyper = {version = "0.14", features = ["backports", "deprecated"], default-features = false}
symbolic-demangle = { version = "12.8.0", default-features = false, features = ["rust", "cpp", "msvc"], optional = true }
symbolic-common = { version = "12.8.0", default-features = false, optional = true }
3 changes: 1 addition & 2 deletions data-pipeline-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,4 @@ build_common = { path = "../build-common" }
[dependencies]
data-pipeline = { path = "../data-pipeline" }
ddcommon-ffi = { path = "../ddcommon-ffi", default-features = false }
bytes = "1.4"
libc = "0.2.153"
tinybytes = { path = "../tinybytes" }
16 changes: 13 additions & 3 deletions data-pipeline-ffi/src/trace_exporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,27 @@ pub unsafe extern "C" fn ddog_trace_exporter_free(handle: Box<TraceExporter>) {
///
/// * `handle` - The handle to the TraceExporter instance.
/// * `trace` - The traces to send to the Datadog Agent in the input format used to create the
/// TraceExporter.
/// TraceExporter. The memory for the trace must be valid for the life of the call to this
/// function.
/// * `trace_count` - The number of traces to send to the Datadog Agent.
#[no_mangle]
pub unsafe extern "C" fn ddog_trace_exporter_send(
handle: &TraceExporter,
trace: ByteSlice,
trace_count: usize,
) -> MaybeError {
// TODO - handle errors - https://datadoghq.atlassian.net/browse/APMSP-1095
// necessary that the trace be static for the life of the FFI function call as the caller
// currently owns the memory.
//APMSP-1621 - Properly fix this sharp-edge by allocating memory on the Rust side
let static_trace: ByteSlice<'static> = std::mem::transmute(trace);

// TODO: APMSP-1095 - properly handle errors from the send call
handle
.send(trace.as_bytes(), trace_count)
.send(
tinybytes::Bytes::from_static(static_trace.as_slice()),
trace_count,
)
.unwrap_or(String::from(""));

MaybeError::None
}
4 changes: 3 additions & 1 deletion data-pipeline/examples/send-traces-with-stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ fn main() {
traces.push(trace);
}
let data = rmp_serde::to_vec_named(&traces).unwrap();
exporter.send(&data, 100).unwrap();
let data_as_bytes = tinybytes::Bytes::from(data);

exporter.send(data_as_bytes, 100).unwrap();
exporter.shutdown(None).unwrap();
}
31 changes: 15 additions & 16 deletions data-pipeline/src/trace_exporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,15 +254,11 @@ impl TraceExporter {

/// Send msgpack serialized traces to the agent
#[allow(missing_docs)]
pub fn send(&self, data: &[u8], trace_count: usize) -> Result<String, String> {
pub fn send(&self, data: tinybytes::Bytes, trace_count: usize) -> Result<String, String> {
self.check_agent_info();
match self.input_format {
TraceExporterInputFormat::Proxy => self.send_proxy(data, trace_count),
TraceExporterInputFormat::V04 => {
self.send_deser_ser(tinybytes::Bytes::copy_from_slice(data))
// TODO: APMSP-1582 - Refactor data-pipeline-ffi so we can leverage a type that
// implements tinybytes::UnderlyingBytes trait to avoid copying
}
TraceExporterInputFormat::Proxy => self.send_proxy(data.as_ref(), trace_count),
TraceExporterInputFormat::V04 => self.send_deser_ser(data),
}
}

Expand Down Expand Up @@ -1188,7 +1184,7 @@ mod tests {
..Default::default()
}];

let data = rmp_serde::to_vec_named(&vec![trace_chunk]).unwrap();
let data = tinybytes::Bytes::from(rmp_serde::to_vec_named(&vec![trace_chunk]).unwrap());

// Wait for the info fetcher to get the config
while mock_info.hits() == 0 {
Expand All @@ -1197,7 +1193,7 @@ mod tests {
})
}

exporter.send(data.as_slice(), 1).unwrap();
exporter.send(data, 1).unwrap();
exporter.shutdown(None).unwrap();

mock_traces.assert();
Expand Down Expand Up @@ -1315,8 +1311,10 @@ mod tests {
..Default::default()
}],
];
let bytes = rmp_serde::to_vec_named(&traces).expect("failed to serialize static trace");
let _result = exporter.send(&bytes, 1).expect("failed to send trace");
let bytes = tinybytes::Bytes::from(
rmp_serde::to_vec_named(&traces).expect("failed to serialize static trace"),
);
let _result = exporter.send(bytes, 1).expect("failed to send trace");

assert_eq!(
&format!(
Expand Down Expand Up @@ -1347,9 +1345,8 @@ mod tests {
stats_socket.local_addr().unwrap().to_string(),
);

let _result = exporter
.send(b"some_bad_payload", 1)
.expect("failed to send trace");
let bad_payload = tinybytes::Bytes::copy_from_slice(b"some_bad_payload".as_ref());
let _result = exporter.send(bad_payload, 1).expect("failed to send trace");

assert_eq!(
&format!(
Expand Down Expand Up @@ -1382,8 +1379,10 @@ mod tests {
name: BytesString::from_slice(b"test").unwrap(),
..Default::default()
}]];
let bytes = rmp_serde::to_vec_named(&traces).expect("failed to serialize static trace");
let _result = exporter.send(&bytes, 1).expect("failed to send trace");
let bytes = tinybytes::Bytes::from(
rmp_serde::to_vec_named(&traces).expect("failed to serialize static trace"),
);
let _result = exporter.send(bytes, 1).expect("failed to send trace");

assert_eq!(
&format!(
Expand Down
1 change: 0 additions & 1 deletion ddcommon-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ chrono = { version = "0.4.38", features = ["std"] }
crossbeam-queue = "0.3.11"
ddcommon = { path = "../ddcommon" }
ddcommon-net1 = { path = "../ddcommon-net1" }
hyper = {version = "0.14", features = ["backports", "deprecated"], default-features = false}
serde = "1.0"

[dev-dependencies]
Expand Down
13 changes: 7 additions & 6 deletions ddcommon-ffi/src/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@

use crate::slice::AsBytes;
use crate::Error;
use hyper::http::uri::{Authority, Parts};
use std::borrow::Cow;
use std::str::FromStr;

use ddcommon_net1 as net;
use ddcommon_net1::dep::http;

use http::uri::{Authority, Parts};
use net::parse_uri;
use std::borrow::Cow;
use std::str::FromStr;

/// Wrapper type to generate the correct FFI name.
pub struct Endpoint(net::Endpoint);
Expand Down Expand Up @@ -49,7 +50,7 @@ pub extern "C" fn ddog_endpoint_from_api_key(api_key: crate::CharSlice) -> Box<E
parts.authority = Some(Authority::from_static("datadoghq.com"));
Box::new(
net::Endpoint {
url: hyper::Uri::from_parts(parts).unwrap(),
url: http::Uri::from_parts(parts).unwrap(),
api_key: Some(api_key.to_utf8_lossy().to_string().into()),
..Default::default()
}
Expand All @@ -73,7 +74,7 @@ pub extern "C" fn ddog_endpoint_from_api_key_and_site(
});
*endpoint = Box::into_raw(Box::new(
net::Endpoint {
url: hyper::Uri::from_parts(parts).unwrap(),
url: http::Uri::from_parts(parts).unwrap(),
api_key: Some(api_key.to_utf8_lossy().to_string().into()),
..Default::default()
}
Expand Down
2 changes: 1 addition & 1 deletion ddcommon-net1/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ hyper = { version = "0.14", features = ["http1", "client", "tcp", "stream", "bac
hyper-util = "0.1"
lazy_static = "1.4"
pin-project = "1"
rustls = { version = "0.23", default-features = false }
rustls = { version = "0.23", default-features = false, features = ["ring"] }
rustls-native-certs = { version = "0.7" }
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.23", features = ["rt", "macros"] }
Expand Down
11 changes: 11 additions & 0 deletions ddcommon-net1/src/connector/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ lazy_static! {
};
}

#[cfg(not(feature = "use_webpki_roots"))]
lazy_static! {
static ref INIT_CRYPTO_PROVIDER: () = {
#[cfg(unix)]
rustls::crypto::ring::default_provider()
.install_default()
.expect("Failed to install default CryptoProvider");
};
}

impl Default for Connector {
fn default() -> Self {
DEFAULT_CONNECTOR.clone()
Expand Down Expand Up @@ -123,6 +133,7 @@ fn build_https_connector_with_webpki_roots(

#[cfg(not(feature = "use_webpki_roots"))]
fn load_root_certs() -> anyhow::Result<rustls::RootCertStore> {
*INIT_CRYPTO_PROVIDER; // One-time initialization of a crypto provider if needed
let mut roots = rustls::RootCertStore::empty();

for cert in rustls_native_certs::load_native_certs()? {
Expand Down
4 changes: 4 additions & 0 deletions ddcommon-net1/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ use std::str::FromStr;

pub mod connector;

pub mod dep {
pub use http;
}

pub type HttpClient = hyper::Client<connector::Connector, hyper::Body>;
pub type HttpResponse = hyper::Response<hyper::Body>;
pub type HttpRequestBuilder = hyper::http::request::Builder;
Expand Down
30 changes: 30 additions & 0 deletions ddcommon-net2/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/
# SPDX-License-Identifier: Apache-2.0

[package]
name = "ddcommon-net2"
rust-version.workspace = true
edition.workspace = true
version.workspace = true
license.workspace = true

[lib]
bench = false

[features]
default = []
use_native_roots = ["rustls-native-certs", "tokio-rustls/ring"]
use_webpki_roots = ["webpki-roots" ,"tokio-rustls/aws-lc-rs"]

[dependencies]
ddcommon = { path = "../ddcommon" }
hex = { version = "0.4" }
hyper = { version = "1", default-features = false }
hyper-util = { version = "0.1", default-features = false, features = ["tokio"] }
rustls-native-certs = { version = "0.8", optional = true }
serde = { version = "1.0", features = ["derive"] }
thiserror = { version = "2" }
tokio = { version = "1.41" }
tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "tls12"] }
tokio-util = { version = "0.7" }
webpki-roots = { version = "0.26", optional = true }
Loading
Loading