The escape record: skippable in a frame, refused as a key (L2/L3 codec)¶
len == 0 cannot spell a segment record — path syntax has no empty
segment, so /a//b is invalid rather than a spelling of /a/b. That makes zero free to
reserve, and
RFC-0018
§5.4 spends it on the escape record: 00 <u8 kind> <u8 len> <len bytes>.
Its whole value is an asymmetry (CONTEXT.md §Segment / view). In a frame
path an escape is admissible: a forwarder that does not implement kind steps over it by
the record’s declared length rather than dropping a frame it is only relaying. In canonical
/ key context it is rejected: the vertex-map key must stay pure-string, so that a byte
prefix still implies an ancestor.
What to notice¶
The skip needs no knowledge of the kind. The example escapes with kind
0x7F, which this build assigns no meaning to at all, andpacked_record_spanstill steps over it and lands exactly on the next literal record. The node least likely to implement a kind is precisely the node that must step over it, which is why the record is self-delimiting.The two contexts are two functions, not a bool argument.
packed_record_span(frame path) admits the escape;packed_path_valid_key(canonical) refuses it, andwire::path_keyanswersnulloptfor the decodedPATH. No call site has to decide the question with a flag it might pass the wrong way round.The frame is still well-formed. The escape-bearing
PATHdecodes cleanly — it is a valid frame that is not a key. Those are different verdicts and the example asserts both.kPackedEscapeKindLabel(0x16) is a kind this layer never mints. It is the kind RFC-0027 uses for its path-label element, and RFC-0027 is implemented — but minting lives in the forwarder and only on a node given a mint table (off by default), never here:packed_path.hppstays kind-agnostic by design, and emitting an escape is not minting a label. In this example the escape is simply bytes that arrived.Nothing here is conditional — the target builds and runs under every CI leg.
Source¶
1/*
2 * SPDX-License-Identifier: Apache-2.0
3 * SPDX-FileCopyrightText: Copyright 2026 avatarsd LLC
4 */
5
6/**
7 * @file
8 * @brief ONE CONCEPT — the escape record: admissible in a frame path, rejected as a key.
9 *
10 * `len == 0` cannot spell a segment record (path syntax has no empty segment), so RFC-0018
11 * §5.4 reserves it for the **escape record** `00 <u8 kind> <u8 len> <len bytes>`. Its whole
12 * point is asymmetry (`CONTEXT.md` §Segment / view): a forwarder steps over a `kind` it does
13 * not implement **by the record's declared length** rather than dropping a frame it is only
14 * relaying, while canonical / key context REFUSES it — a label is not canonical bytes, and
15 * the vertex-map key must stay pure-string.
16 *
17 * Both halves are checked here, including the skip over a kind this build has never heard
18 * of. `kPackedEscapeKindLabel` (`0x16`) is the kind RFC-0027's path-label element uses.
19 * **This layer never mints one**: `packed_path.hpp` is kind-agnostic and emitting an escape
20 * is not minting a label — that is the forwarder's business, and only on a node given a
21 * mint table (RFC-0027 §8.3, off by default). Here the escape is simply bytes that arrived.
22 *
23 * Runs under ctest as `example_wire_path_escape`; returns non-zero on any failed check.
24 */
25
26#include <cstddef>
27#include <cstdint>
28#include <cstdio>
29#include <optional>
30#include <vector>
31
32#include "libtracer/packed_path.hpp"
33#include "libtracer/tlv_emit.hpp"
34#include "libtracer/tracer.hpp"
35
36namespace {
37
38using tr::wire::opt_t;
39using tr::wire::type_t;
40
41/** @brief Report expectation @p what and record a failure on @p ok. */
42void check(bool& ok, bool cond, const char* what) {
43 std::printf(" [%s] %s\n", cond ? "ok" : "FAIL", what);
44 ok = ok && cond;
45}
46
47/** @brief A `kind` byte this build assigns no meaning to — the non-implementing hop's case. */
48constexpr std::uint8_t kUnknownKind = 0x7F;
49
50} // namespace
51
52int main() {
53 bool ok = true;
54 const std::vector<std::byte> payload(4, std::byte{0xEE});
55
56 // "sensor" then an escape of an UNKNOWN kind then "temp".
57 std::vector<std::byte> body;
58 check(ok, tr::wire::emit_path_segment(body, "sensor"), "a literal record leads");
59 const std::size_t at = body.size();
60 check(ok, tr::wire::emit_path_escape(body, kUnknownKind, payload), "the escape record appends");
61 check(ok, tr::wire::emit_path_segment(body, "temp"), "and a literal record follows it");
62
63 const std::span<const std::byte> view(body);
64 check(ok, tr::wire::packed_record_is_escape(view, at),
65 "the record at that offset is an escape");
66 check(ok, tr::wire::packed_escape_kind(view, at) == kUnknownKind, "its kind reads back");
67 const auto esc = tr::wire::packed_escape_payload(view, at);
68 check(ok, esc && esc->size() == payload.size(), "and its declared payload is delimited");
69
70 // The forwarding property: step over it knowing nothing but its length.
71 const std::size_t span = tr::wire::packed_record_span(view, at);
72 std::printf("stepped over kind 0x%02X in %zu bytes without implementing it\n", kUnknownKind,
73 span);
74 check(ok, span == tr::wire::kPackedEscapeOverhead + payload.size(),
75 "packed_record_span steps over an unknown kind by its declared length");
76 check(ok, tr::wire::packed_record_is_escape(view, at + span) == false,
77 "landing exactly on the next literal record");
78
79 // The other half of the asymmetry: this body is not a key and never becomes one.
80 check(ok, !tr::wire::packed_path_valid_key(view), "an escape-bearing body is not a valid key");
81 std::vector<std::byte> frame;
82 tr::wire::emit_tlv(frame, type_t::PATH, opt_t{}, body);
83 const auto decoded = tr::wire::decode(frame);
84 check(ok, decoded.has_value(), "the frame itself is well-formed and decodes");
85 check(ok, decoded && tr::wire::path_key(*decoded) == std::nullopt,
86 "yet path_key refuses it — canonical context rejects the escape");
87 return ok ? 0 : 1;
88}
See also: path module · frame codec · addressing reference.