Skip to content

Commit 17098c1

Browse files
dmehaladgoffredo
andauthored
Add support for APM Remote Configuration (#74)
Co-authored-by: David Goffredo <[email protected]>
1 parent cc703b2 commit 17098c1

32 files changed

+1239
-123
lines changed

BUILD.bazel

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
cc_library(
22
name = "dd_trace_cpp",
33
srcs = [
4+
"src/datadog/base64.cpp",
45
"src/datadog/cerr_logger.cpp",
56
"src/datadog/clock.cpp",
7+
"src/datadog/config_manager.cpp",
68
"src/datadog/collector_response.cpp",
79
# "src/datadog/curl.cpp", no libcurl
810
"src/datadog/datadog_agent_config.cpp",
@@ -24,6 +26,7 @@ cc_library(
2426
"src/datadog/propagation_style.cpp",
2527
"src/datadog/random.cpp",
2628
"src/datadog/rate.cpp",
29+
"src/datadog/remote_config.cpp",
2730
"src/datadog/runtime_id.cpp",
2831
"src/datadog/span.cpp",
2932
"src/datadog/span_data.cpp",
@@ -45,8 +48,11 @@ cc_library(
4548
"src/datadog/w3c_propagation.cpp",
4649
],
4750
hdrs = [
51+
"src/datadog/base64.h",
4852
"src/datadog/cerr_logger.h",
4953
"src/datadog/clock.h",
54+
"src/datadog/config_manager.h",
55+
"src/datadog/config_update.h",
5056
"src/datadog/collector.h",
5157
"src/datadog/collector_response.h",
5258
# "src/datadog/curl.h", no libcurl
@@ -78,6 +84,7 @@ cc_library(
7884
"src/datadog/propagation_style.h",
7985
"src/datadog/random.h",
8086
"src/datadog/rate.h",
87+
"src/datadog/remote_config.h",
8188
"src/datadog/runtime_id.h",
8289
"src/datadog/sampling_decision.h",
8390
"src/datadog/sampling_mechanism.h",
@@ -95,6 +102,7 @@ cc_library(
95102
"src/datadog/tags.h",
96103
"src/datadog/threaded_event_scheduler.h",
97104
"src/datadog/tracer_config.h",
105+
"src/datadog/tracer_signature.h",
98106
"src/datadog/tracer_telemetry.h",
99107
"src/datadog/tracer.h",
100108
"src/datadog/trace_id.h",

CMakeLists.txt

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@ project(dd-trace-cpp)
77
option(BUILD_COVERAGE "Build code with code coverage profiling instrumentation" OFF)
88
option(BUILD_HASHER_EXAMPLE "Build the example program examples/hasher" OFF)
99
option(BUILD_TESTING "Build the unit tests (test/)" OFF)
10+
option(BUILD_FUZZERS "Build fuzzers" OFF)
11+
option(BUILD_BENCHMARK "Build benchmark binaries" OFF)
1012
option(SANITIZE "Build with address sanitizer and undefined behavior sanitizer" OFF)
11-
option(FUZZ_W3C_PROPAGATION "Build a fuzzer for W3C propagation" OFF)
1213

13-
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
14+
if (NOT CMAKE_BUILD_TYPE)
15+
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
16+
endif ()
17+
1418
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
1519
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
1620
set(CMAKE_CXX_STANDARD 17)
@@ -32,7 +36,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
3236
# But there's one exception: libfuzzer is built with libstdc++ on Ubuntu,
3337
# and so won't link to libc++. So, if any of the FUZZ_* variables are set,
3438
# keep to libstdc++ (the default on most systems).
35-
if (NOT ${FUZZ_W3C_PROPAGATION})
39+
if (NOT ${BUILD_FUZZERS})
3640
add_compile_options(-stdlib=libc++)
3741
add_link_options(-stdlib=libc++)
3842
endif ()
@@ -45,11 +49,12 @@ function(add_sanitizers)
4549
add_link_options(-fsanitize=undefined)
4650
endfunction()
4751

48-
if(FUZZ_W3C_PROPAGATION)
52+
if(BUILD_FUZZERS)
53+
set(BUILD_TESTING OFF)
4954
add_compile_options(-fsanitize=fuzzer)
5055
add_link_options(-fsanitize=fuzzer)
5156
add_sanitizers()
52-
add_subdirectory(fuzz/w3c-propagation)
57+
add_subdirectory(fuzz)
5358
endif()
5459

5560
if (SANITIZE)
@@ -82,8 +87,10 @@ endif()
8287

8388
add_library(dd_trace_cpp-objects OBJECT)
8489
target_sources(dd_trace_cpp-objects PRIVATE
90+
src/datadog/base64.cpp
8591
src/datadog/cerr_logger.cpp
8692
src/datadog/clock.cpp
93+
src/datadog/config_manager.cpp
8794
src/datadog/collector_response.cpp
8895
src/datadog/curl.cpp
8996
src/datadog/datadog_agent_config.cpp
@@ -105,6 +112,7 @@ target_sources(dd_trace_cpp-objects PRIVATE
105112
src/datadog/propagation_style.cpp
106113
src/datadog/random.cpp
107114
src/datadog/rate.cpp
115+
src/datadog/remote_config.cpp
108116
src/datadog/runtime_id.cpp
109117
src/datadog/span.cpp
110118
src/datadog/span_data.cpp
@@ -132,8 +140,11 @@ target_sources(dd_trace_cpp-objects PUBLIC
132140
TYPE HEADERS
133141
BASE_DIRS src/
134142
FILES
143+
src/datadog/base64.h
135144
src/datadog/cerr_logger.h
136145
src/datadog/clock.h
146+
src/datadog/config_manager.h
147+
src/datadog/config_update.h
137148
src/datadog/collector.h
138149
src/datadog/collector_response.h
139150
# src/datadog/curl.h except for curl.h
@@ -165,6 +176,7 @@ target_sources(dd_trace_cpp-objects PUBLIC
165176
src/datadog/propagation_style.h
166177
src/datadog/random.h
167178
src/datadog/rate.h
179+
src/datadog/remote_config.h
168180
src/datadog/runtime_id.h
169181
src/datadog/sampling_decision.h
170182
src/datadog/sampling_mechanism.h
@@ -182,6 +194,7 @@ target_sources(dd_trace_cpp-objects PUBLIC
182194
src/datadog/tags.h
183195
src/datadog/threaded_event_scheduler.h
184196
src/datadog/tracer_config.h
197+
src/datadog/tracer_signature.h
185198
src/datadog/tracer_telemetry.h
186199
src/datadog/tracer.h
187200
src/datadog/trace_id.h

bin/cmake-build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ cd "$(dirname "$0")"/..
66

77
mkdir -p .build
88
cd .build
9-
cmake ..
9+
cmake .. "$@"
1010
make -j "$(nproc)"

fuzz/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
add_subdirectory(base64)
2+
add_subdirectory(w3c-propagation)

fuzz/README.md

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,19 @@ Fuzzers
33
Each subdirectory here contains the source of an executable that [fuzz tests][1]
44
some part of the library using [LLVM's libfuzzer][2].
55

6-
There is a toplevel CMake boolean option associated with each fuzzer. The naming
7-
convention is `FUZZ_<SUBDIRECTORY_WITH_UNDERSCORES>`, e.g.
8-
`FUZZ_W3C_PROPAGATION` for the fuzzer defined in
9-
[fuzz/w3c-propagation/](./w3c-propagation/). The resulting binary is called
10-
`fuzz` by convention.
6+
There is a toplevel CMake boolean option that adds all of the fuzzer
7+
executables to the build: `BUILD_FUZZERS`.
118

12-
When building a fuzzer, the toolchain must be clang-based. For example, this
13-
is how to build the fuzzer in [fuzz/w3c-propagation](./w3c-propagation/) from
14-
the root of the repository:
9+
When building the fuzzers, the toolchain must be clang-based. For example:
1510
```console
16-
$ rm -rf .build && mkdir .build # if toolchain or test setup need clearing
17-
$ cd .build
18-
$ CC=clang CXX=clang++ cmake .. -DFUZZ_W3C_PROPAGATION=ON
19-
$ make -j $(nproc)
20-
$ fuzz/w3c-propagation/fuzz
11+
$ rm -rf .build # if toolchain needs clearing
12+
$ bin/with-toolchain llvm bin/cmake-build -DBUILD_FUZZERS=1
13+
$ .build/fuzz/w3c-propagation/w3c-propagation-fuzz
2114

2215
[... fuzzer output ...]
2316
```
2417

18+
The fuzzer executables are named `.build/fuzz/*/*-fuzz` by convention.
19+
2520
[1]: https://en.wikipedia.org/wiki/Fuzzing
2621
[2]: https://llvm.org/docs/LibFuzzer.html

fuzz/base64/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
add_executable(base64-fuzz main.cpp)
2+
3+
add_dependencies(base64-fuzz dd_trace_cpp-static)
4+
target_link_libraries(base64-fuzz dd_trace_cpp-static)

fuzz/base64/main.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <datadog/base64.h>
2+
#include <datadog/string_view.h>
3+
4+
#include <cstdint>
5+
6+
namespace dd = datadog::tracing;
7+
8+
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, size_t size) {
9+
dd::base64_decode(dd::StringView{(const char*)data, size});
10+
return 0;
11+
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
add_executable(fuzz fuzz.cpp)
1+
add_executable(w3c-propagation-fuzz fuzz.cpp)
22

3-
add_dependencies(fuzz dd_trace_cpp-static)
4-
target_link_libraries(fuzz dd_trace_cpp-static)
3+
add_dependencies(w3c-propagation-fuzz dd_trace_cpp-static)
4+
target_link_libraries(w3c-propagation-fuzz dd_trace_cpp-static)

src/datadog/base64.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#include "base64.h"
2+
3+
#include <cstddef>
4+
#include <cstdint>
5+
6+
namespace datadog {
7+
namespace tracing {
8+
9+
constexpr uint8_t k_sentinel = 255;
10+
constexpr uint8_t _ = k_sentinel; // for brevity
11+
constexpr uint8_t k_eol = 0;
12+
13+
// Invalid inputs are mapped to the value 255. '=' maps to 0.
14+
constexpr uint8_t k_base64_table[] = {
15+
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
16+
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
17+
_, _, _, _, _, _, _, 62, _, _, _, 63, 52, 53, 54, 55, 56, 57,
18+
58, 59, 60, 61, _, _, _, k_eol, _, _, _, 0, 1, 2, 3, 4, 5, 6,
19+
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
20+
25, _, _, _, _, _, _, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
21+
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, _, _, _,
22+
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
23+
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
24+
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
25+
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
26+
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
27+
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
28+
_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
29+
_, _, _, _};
30+
31+
std::string base64_decode(StringView input) {
32+
const size_t in_size = input.size();
33+
34+
std::string output;
35+
output.reserve(in_size);
36+
37+
size_t i = 0;
38+
39+
for (; i + 4 < in_size;) {
40+
uint32_t c0 = k_base64_table[static_cast<size_t>(input[i++])];
41+
uint32_t c1 = k_base64_table[static_cast<size_t>(input[i++])];
42+
uint32_t c2 = k_base64_table[static_cast<size_t>(input[i++])];
43+
uint32_t c3 = k_base64_table[static_cast<size_t>(input[i++])];
44+
45+
if (c0 == k_sentinel || c1 == k_sentinel || c2 == k_sentinel ||
46+
c3 == k_sentinel) {
47+
return "";
48+
}
49+
50+
output.push_back(c0 << 2 | (c1 & 0xF0) >> 4);
51+
output.push_back((c1 & 0x0F) << 4 | ((c2 & 0x3C) >> 2));
52+
output.push_back(((c2 & 0x03) << 6) | (c3 & 0x3F));
53+
}
54+
55+
// If padding is missing, return the empty string in lieu of an Error.
56+
if ((in_size - i) < 4) return "";
57+
58+
uint32_t c0 = k_base64_table[static_cast<size_t>(input[i++])];
59+
uint32_t c1 = k_base64_table[static_cast<size_t>(input[i++])];
60+
uint32_t c2 = k_base64_table[static_cast<size_t>(input[i++])];
61+
uint32_t c3 = k_base64_table[static_cast<size_t>(input[i++])];
62+
63+
if (c0 == k_sentinel || c1 == k_sentinel || c2 == k_sentinel ||
64+
c3 == k_sentinel) {
65+
return "";
66+
}
67+
68+
if (c2 == k_eol) {
69+
// The last quadruplet is of the form "xx==", where only one character needs
70+
// to be decoded.
71+
output.push_back(c0 << 2 | (c1 & 0xF0) >> 4);
72+
} else if (c3 == k_eol) {
73+
// The last quadruplet is of the form "xxx=", where only two character needs
74+
// to be decoded.
75+
output.push_back(c0 << 2 | (c1 & 0xF0) >> 4);
76+
output.push_back((c1 & 0x0F) << 4 | ((c2 & 0x3C) >> 2));
77+
} else {
78+
// The last quadruplet is not padded -> common use case
79+
output.push_back(c0 << 2 | (c1 & 0xF0) >> 4);
80+
output.push_back((c1 & 0x0F) << 4 | ((c2 & 0x3C) >> 2));
81+
output.push_back(((c2 & 0x03) << 6) | (c3 & 0x3F));
82+
}
83+
84+
return output;
85+
}
86+
87+
} // namespace tracing
88+
} // namespace datadog

src/datadog/base64.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
#include <string>
4+
5+
#include "string_view.h"
6+
7+
namespace datadog {
8+
namespace tracing {
9+
10+
// Return the result of decoding the specified padded base64-encoded `input`. If
11+
// `input` is not padded, then return the empty string instead.
12+
std::string base64_decode(StringView input);
13+
14+
} // namespace tracing
15+
} // namespace datadog

0 commit comments

Comments
 (0)