Skip to content
This repository was archived by the owner on Jul 31, 2023. It is now read-only.

Commit be93d3a

Browse files
authored
Add B3 propagation helpers. (#363)
1 parent b774bc2 commit be93d3a

9 files changed

Lines changed: 448 additions & 0 deletions

File tree

opencensus/trace/BUILD

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,23 @@ cc_library(
8787
],
8888
)
8989

90+
cc_library(
91+
name = "b3",
92+
srcs = [
93+
"internal/b3.cc",
94+
],
95+
hdrs = [
96+
"propagation/b3.h",
97+
],
98+
copts = DEFAULT_COPTS,
99+
visibility = ["//visibility:public"],
100+
deps = [
101+
":span_context",
102+
"@com_google_absl//absl/base:endian",
103+
"@com_google_absl//absl/strings",
104+
],
105+
)
106+
90107
cc_library(
91108
name = "cloud_trace_context",
92109
srcs = [
@@ -217,6 +234,17 @@ cc_test(
217234
],
218235
)
219236

237+
cc_test(
238+
name = "b3_test",
239+
srcs = ["internal/b3_test.cc"],
240+
copts = TEST_COPTS,
241+
deps = [
242+
":b3",
243+
":span_context",
244+
"@com_google_googletest//:gtest_main",
245+
],
246+
)
247+
220248
cc_test(
221249
name = "cloud_trace_context_test",
222250
srcs = ["internal/cloud_trace_context_test.cc"],
@@ -427,6 +455,18 @@ cc_binary(
427455
],
428456
)
429457

458+
cc_binary(
459+
name = "b3_benchmark",
460+
testonly = 1,
461+
srcs = ["internal/b3_benchmark.cc"],
462+
copts = TEST_COPTS,
463+
linkstatic = 1,
464+
deps = [
465+
":b3",
466+
"@com_github_google_benchmark//:benchmark",
467+
],
468+
)
469+
430470
cc_binary(
431471
name = "cloud_trace_context_benchmark",
432472
testonly = 1,
@@ -504,6 +544,16 @@ cc_binary(
504544
# Fuzzers
505545
# ========================================================================= #
506546

547+
cc_fuzz_target(
548+
name = "b3_fuzzer",
549+
srcs = ["internal/b3_fuzzer.cc"],
550+
corpus = glob(["internal/b3_corpus/*"]),
551+
deps = [
552+
":b3",
553+
"@com_google_absl//absl/strings",
554+
],
555+
)
556+
507557
cc_fuzz_target(
508558
name = "cloud_trace_context_fuzzer",
509559
srcs = ["internal/cloud_trace_context_fuzzer.cc"],

opencensus/trace/CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ opencensus_lib(trace
4848
absl::time
4949
absl::span)
5050

51+
opencensus_lib(trace_b3
52+
PUBLIC
53+
SRCS
54+
internal/b3.cc
55+
DEPS
56+
trace_span_context
57+
absl::base
58+
absl::strings)
59+
5160
opencensus_lib(trace_cloud_trace_context
5261
PUBLIC
5362
SRCS
@@ -113,6 +122,8 @@ opencensus_test(trace_attribute_value_ref_test
113122
opencensus_test(trace_attribute_value_test internal/attribute_value_test.cc
114123
trace)
115124

125+
opencensus_test(trace_b3_test internal/b3_test.cc trace_b3)
126+
116127
opencensus_test(trace_cloud_trace_context_test
117128
internal/cloud_trace_context_test.cc trace_cloud_trace_context)
118129

@@ -199,6 +210,8 @@ opencensus_test(trace_with_span_test
199210
opencensus_benchmark(trace_attribute_value_ref_benchmark
200211
internal/attribute_value_ref_benchmark.cc trace)
201212

213+
opencensus_benchmark(trace_b3_benchmark internal/b3_benchmark.cc trace_b3)
214+
202215
opencensus_benchmark(trace_cloud_trace_context_benchmark
203216
internal/cloud_trace_context_benchmark.cc
204217
trace_cloud_trace_context)
@@ -222,6 +235,11 @@ opencensus_benchmark(trace_with_span_benchmark
222235
trace
223236
trace_with_span)
224237

238+
opencensus_fuzzer(trace_b3_fuzzer
239+
internal/b3_fuzzer.cc
240+
trace_b3
241+
absl::strings)
242+
225243
opencensus_fuzzer(trace_cloud_trace_context_fuzzer
226244
internal/cloud_trace_context_fuzzer.cc
227245
trace_cloud_trace_context

opencensus/trace/internal/b3.cc

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright 2019, OpenCensus Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "opencensus/trace/propagation/b3.h"
16+
17+
#include <cstdint>
18+
#include <cstring>
19+
#include <string>
20+
21+
#include "absl/strings/ascii.h"
22+
#include "absl/strings/escaping.h"
23+
#include "opencensus/trace/span_context.h"
24+
#include "opencensus/trace/span_id.h"
25+
#include "opencensus/trace/trace_id.h"
26+
#include "opencensus/trace/trace_options.h"
27+
28+
namespace opencensus {
29+
namespace trace {
30+
namespace propagation {
31+
32+
namespace {
33+
34+
// Returns true if the string only contains valid hex digits.
35+
bool IsHexDigits(absl::string_view s) {
36+
for (int i = 0; i < s.length(); ++i) {
37+
if (!absl::ascii_isxdigit(s[i])) return false;
38+
}
39+
return true;
40+
}
41+
42+
} // namespace
43+
44+
SpanContext FromB3Headers(absl::string_view b3_trace_id,
45+
absl::string_view b3_span_id,
46+
absl::string_view b3_sampled,
47+
absl::string_view b3_flags) {
48+
static SpanContext invalid;
49+
uint8_t sampled;
50+
51+
if (b3_sampled == "1") {
52+
sampled = 1;
53+
} else if (b3_sampled == "0" || b3_sampled.empty()) {
54+
sampled = 0;
55+
} else {
56+
return invalid;
57+
}
58+
59+
if (b3_flags == "1") {
60+
sampled = 1;
61+
} else if (!b3_flags.empty()) {
62+
return invalid;
63+
}
64+
65+
if (b3_trace_id.length() != 32 && b3_trace_id.length() != 16) return invalid;
66+
if (b3_span_id.length() != 16) return invalid;
67+
68+
if (!IsHexDigits(b3_trace_id)) {
69+
return invalid;
70+
}
71+
if (!IsHexDigits(b3_span_id)) {
72+
return invalid;
73+
}
74+
75+
std::string trace_id_binary = absl::HexStringToBytes(b3_trace_id);
76+
std::string span_id_binary = absl::HexStringToBytes(b3_span_id);
77+
78+
// Extend 64-bit trace_id to 128-bit.
79+
uint8_t extended_trace_id[16];
80+
if (b3_trace_id.length() == 16) {
81+
memset(extended_trace_id, 0, 8);
82+
memcpy(extended_trace_id + 8, trace_id_binary.data(), 8);
83+
}
84+
85+
return SpanContext(
86+
TraceId((b3_trace_id.length() == 16)
87+
? extended_trace_id
88+
: reinterpret_cast<const uint8_t*>(trace_id_binary.data())),
89+
SpanId(reinterpret_cast<const uint8_t*>(span_id_binary.data())),
90+
TraceOptions(&sampled));
91+
}
92+
93+
std::string ToB3TraceIdHeader(const SpanContext& ctx) {
94+
return ctx.trace_id().ToHex();
95+
}
96+
97+
std::string ToB3SpanIdHeader(const SpanContext& ctx) {
98+
return ctx.span_id().ToHex();
99+
}
100+
101+
std::string ToB3SampledHeader(const SpanContext& ctx) {
102+
return ctx.trace_options().IsSampled() ? "1" : "0";
103+
}
104+
105+
} // namespace propagation
106+
} // namespace trace
107+
} // namespace opencensus
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2019, OpenCensus Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "benchmark/benchmark.h"
16+
#include "opencensus/trace/propagation/b3.h"
17+
18+
namespace opencensus {
19+
namespace trace {
20+
namespace propagation {
21+
namespace {
22+
23+
void BM_FromB3Headers_128bitTraceId(benchmark::State& state) {
24+
while (state.KeepRunning()) {
25+
FromB3Headers("463ac35c9f6413ad48485a3953bb6124", "0020000000000001", "1",
26+
"");
27+
}
28+
}
29+
BENCHMARK(BM_FromB3Headers_128bitTraceId);
30+
31+
void BM_FromB3Headers_64bitTraceId(benchmark::State& state) {
32+
while (state.KeepRunning()) {
33+
FromB3Headers("1234567812345678", "0020000000000001", "1", "");
34+
}
35+
}
36+
BENCHMARK(BM_FromB3Headers_64bitTraceId);
37+
38+
void BM_FromB3Headers_InvalidTraceId(benchmark::State& state) {
39+
while (state.KeepRunning()) {
40+
FromB3Headers("463ac35c9f6413ad48485a3953bb612X", "0020000000000001", "1",
41+
"");
42+
}
43+
}
44+
BENCHMARK(BM_FromB3Headers_InvalidTraceId);
45+
46+
} // namespace
47+
} // namespace propagation
48+
} // namespace trace
49+
} // namespace opencensus
50+
51+
BENCHMARK_MAIN();
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
48485a3953bb6124
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2019, OpenCensus Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "absl/strings/string_view.h"
16+
#include "opencensus/trace/propagation/b3.h"
17+
18+
using ::opencensus::trace::propagation::FromB3Headers;
19+
20+
static constexpr char valid_trace_id[] = "463ac35c9f6413ad48485a3953bb612";
21+
static constexpr char valid_span_id[] = "0020000000000001";
22+
static constexpr char valid_sampled[] = "1";
23+
static constexpr char valid_flags[] = "";
24+
25+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
26+
absl::string_view input(reinterpret_cast<const char *>(Data), Size);
27+
FromB3Headers(input, input, input, input);
28+
FromB3Headers(input, valid_span_id, valid_sampled, valid_flags);
29+
FromB3Headers(valid_trace_id, input, valid_sampled, valid_flags);
30+
FromB3Headers(valid_trace_id, valid_span_id, input, valid_flags);
31+
FromB3Headers(valid_trace_id, valid_span_id, valid_sampled, input);
32+
return 0;
33+
}

0 commit comments

Comments
 (0)