Skip to documentation
SLOP

tiny.reticulum.wire.header

Reference tiny.reticulum wire header

Defined in wire.

API (17)

Actions

Public operations.

Types and contracts

Public types and contracts.

Values and defaults

Public values and defaults.

No direct callersNo direct callswireheader
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallstest sourcelib.reticulum.src.wire.header.test_Reticulum@...py:172,184-186 frames link request pr...test sourcelib.reticulum.src.wire.header.test_Reticulum@...py:222-230 requires header two transp...wire.Contextdecodewire.Flagsdecodewire.headerheaderLengthwire.headerdecode
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.reticulum.src.wire.header.test_Reticulum@...py:172,184-186 frames link request pr...test sourcelib.reticulum.src.wire.header.test_Reticulum@...py:222-230 requires header two transp...private sourcelib.reticulum.src.wire.linkrequestFramewire.headerencodedLengthwire.headerheaderLengthprivate sourcelib.reticulum.src.wire.headerwireDestinationTypewire.headerencode
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallswire.headerencodewire.headerheaderLengthwire.headerencodedLength
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.reticulum.src.wire.hashsuffixOffsetwire.headerdecodewire.headerencodewire.headerencodedLengthtest sourcelib.reticulum.src.wire.header.test_Reticulum@...py:150-151 fixes both header sizeswire.linklinkIdwire.headerheaderLength
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/reticulum/src/wire/header.zig

zig
const std = @import("std");const context = @import("context.zig");const flags = @import("flags.zig");const assert = std.debug.assert;pub const HeaderType = flags.HeaderType;pub const TransportType = flags.TransportType;pub const DestinationType = flags.DestinationType;pub const PacketType = flags.PacketType;pub const Context = context.Context;/// Five hundred bytes, the largest Reticulum datagram (*packet*) every/// Reticulum implementation accepts, for a caller sizing the buffer it reads a/// frame into and checking its own payload against this before building a/// packet, following Reticulum@1.5.0 RNS/Reticulum.py:93. Writing refuses a/// packet longer than this and reading refuses bytes longer than this.pub const mtu: u16 = 500;/// Nineteen bytes, the header shape that carries no transport id (the 16 bytes/// naming a node the packet passes through): the flags byte, the hop count, a/// 16-byte destination hash, and the context byte, for a caller working out/// where a payload starts behind the shorter of the two headers, following/// Reticulum@1.5.0 RNS/Reticulum.py:150.pub const header_one_bytes: u16 = 19;/// Thirty-five bytes, the header shape that carries a 16-byte transport id/// ahead of the destination hash, for a caller working out where a payload/// starts behind the longer of the two headers, following Reticulum@1.5.0/// RNS/Reticulum.py:151.pub const header_two_bytes: u16 = 35;/// Sixteen bytes, the width of a destination hash and of a transport id inside/// a header, for a caller sizing those fields in a header, following/// Reticulum@1.5.0 RNS/Reticulum.py:148.pub const truncated_hash_bytes: u8 = 16;/// One hundred twenty-eight, the hop count at and above which a packet is/// refused, for a caller checking how far a packet has traveled before/// forwarding the packet again, following Reticulum@1.5.0 RNS/Transport.py:115./// Writing and reading both return `error.InvalidHops` at this count.pub const pathfinder_hops: u8 = 128;pub const Packet = struct {    ifac: u1,    header: HeaderType,    context_flag: u1,    transport: TransportType,    destination_type: DestinationType,    packet_type: PacketType,    hops: u8,    transport_id: ?[truncated_hash_bytes]u8,    destination: [truncated_hash_bytes]u8,    context: Context,    payload: []const u8,};pub const DecodeError = error{    InvalidHops,    MissingTransportId,    PacketTooLarge,    PacketTooShort,};pub const EncodeError = error{    InvalidHops,    MissingTransportId,    OutputTooSmall,    PacketTooLarge,    UnexpectedTransportId,};pub fn headerLength(header: HeaderType) u16 {    return switch (header) {        .one => header_one_bytes,        .two => header_two_bytes,    };}pub fn encodedLength(packet: Packet) EncodeError!u16 {    if (packet.hops >= pathfinder_hops) return error.InvalidHops;    switch (packet.header) {        .one => if (packet.transport_id != null) return error.UnexpectedTransportId,        .two => if (packet.transport_id == null) return error.MissingTransportId,    }    const header_bytes: usize = headerLength(packet.header);    const total = std.math.add(usize, header_bytes, packet.payload.len) catch        return error.PacketTooLarge;    assert(total >= header_bytes);    if (total > mtu) return error.PacketTooLarge;    return @intCast(total);}fn wireDestinationType(packet: Packet) DestinationType {    if (packet.context == .lrproof) return .link;    return packet.destination_type;}/// Writes the header and the payload into `out` and returns the bytes written,/// for a caller writing a built packet into the buffer handed to a network/// interface, following Reticulum@1.5.0 RNS/Packet.py:178-239. The call returns/// `error.InvalidHops` at 128 hops or above, `error.UnexpectedTransportId` for/// a HEADER_1 packet that carries a transport id, `error.MissingTransportId`/// for a HEADER_2 packet that lacks one, `error.PacketTooLarge` past 500 bytes,/// and `error.OutputTooSmall` when `out` is shorter than the packet. A packet/// whose context byte is `lrproof` goes out addressed as a link whatever/// destination type it carries, because a link request proof answers a link.pub fn encode(packet: Packet, out: []u8) EncodeError![]u8 {    const encoded_bytes = try encodedLength(packet);    const total: usize = encoded_bytes;    assert(total <= mtu);    if (out.len < total) return error.OutputTooSmall;    assert(out.len >= total);    out[0] = (flags.Flags{        .ifac = packet.ifac,        .header = packet.header,        .context = packet.context_flag,        .transport = packet.transport,        .destination = wireDestinationType(packet),        .packet = packet.packet_type,    }).encode();    out[1] = packet.hops;    const payload_start: usize = headerLength(packet.header);    assert(payload_start <= total);    switch (packet.header) {        .one => std.mem.copyForwards(u8, out[2..18], &packet.destination),        .two => {            std.mem.copyForwards(u8, out[2..18], &packet.transport_id.?);            std.mem.copyForwards(u8, out[18..34], &packet.destination);        },    }    out[payload_start - 1] = packet.context.encode();    std.mem.copyForwards(u8, out[payload_start..total], packet.payload);    return out[0..total];}/// Reads a packet out of `bytes`, for a caller splitting the bytes a network/// interface delivered into fields it can read, following Reticulum@1.5.0/// RNS/Packet.py:243-271. The call returns `error.PacketTooLarge` past 500/// bytes, `error.PacketTooShort` under two bytes or under the header its flags/// byte claims, `error.MissingTransportId` for a HEADER_2 packet of fewer than/// 18 bytes, and `error.InvalidHops` at 128 hops or above. The payload field/// points into the caller's own buffer, so it stays good as long as that buffer/// does.pub fn decode(bytes: []const u8) DecodeError!Packet {    if (bytes.len > mtu) return error.PacketTooLarge;    if (bytes.len < 2) return error.PacketTooShort;    const unpacked = flags.Flags.decode(bytes[0]);    if (bytes[1] >= pathfinder_hops) return error.InvalidHops;    const payload_start: usize = headerLength(unpacked.header);    if (unpacked.header == .two and bytes.len < 18) return error.MissingTransportId;    if (bytes.len < payload_start) return error.PacketTooShort;    assert(payload_start <= bytes.len);    const transport_id: ?[truncated_hash_bytes]u8 = switch (unpacked.header) {        .one => null,        .two => bytes[2..18].*,    };    const destination: [truncated_hash_bytes]u8 = switch (unpacked.header) {        .one => bytes[2..18].*,        .two => bytes[18..34].*,    };    return .{        .ifac = unpacked.ifac,        .header = unpacked.header,        .context_flag = unpacked.context,        .transport = unpacked.transport,        .destination_type = unpacked.destination,        .packet_type = unpacked.packet,        .hops = bytes[1],        .transport_id = transport_id,        .destination = destination,        .context = Context.decode(bytes[payload_start - 1]),        .payload = bytes[payload_start..],    };}test "Reticulum@1.5.0 RNS/Reticulum.py:150-151 fixes both header sizes" {    try std.testing.expectEqual(@as(u16, 19), headerLength(.one));    try std.testing.expectEqual(@as(u16, 35), headerLength(.two));}test "Reticulum@1.5.0 RNS/Packet.py:172,184-186 frames link request proofs" {    const link_id: [16]u8 = @splat(0xa5);    const packet = Packet{        .ifac = 0,        .header = .one,        .context_flag = 0,        .transport = .broadcast,        .destination_type = .single,        .packet_type = .proof,        .hops = 0,        .transport_id = null,        .destination = link_id,        .context = .lrproof,        .payload = &.{},    };    var raw: [header_one_bytes]u8 = undefined;    const encoded = try encode(packet, &raw);    try std.testing.expectEqual(DestinationType.link, flags.Flags.decode(encoded[0]).destination);    try std.testing.expectEqualSlices(u8, &link_id, encoded[2..18]);    const decoded = try decode(encoded);    try std.testing.expectEqual(Context.lrproof, decoded.context);    try std.testing.expectEqual(DestinationType.link, decoded.destination_type);}test "Reticulum@1.5.0 RNS/Packet.py:222-230 requires header two transport IDs" {    const packet = Packet{        .ifac = 0,        .header = .two,        .context_flag = 0,        .transport = .transport,        .destination_type = .plain,        .packet_type = .data,        .hops = 0,        .transport_id = null,        .destination = @splat(0),        .context = .none,        .payload = &.{},    };    var raw: [header_two_bytes]u8 = undefined;    try std.testing.expectError(error.MissingTransportId, encode(packet, &raw));    try std.testing.expectError(error.MissingTransportId, decode(&.{ 0x40, 0x00 }));}

Source: lib/reticulum/src/wire/root.zig:51

zig
pub const header = @import("header.zig");

Audit

Definitions13
Public names25
Members20
Version26.7.0
Revisiondaab053ee433