tiny.reticulum.wire.header
Defined in wire.
API (17)
Actions
Public operations.
decode: Reads a packet out ofbytes, 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.encode: Writes the header and the payload intooutand 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.encodedLengthheaderLength
Types and contracts
Public types and contracts.
Context: The header's last byte names what the payload is for: nothing in particular, one of the seven resource-transfer kinds, a cache request, a request or its response, a path response, a command or its status, a channel message, a keepalive, or one of the five link control values, following Reticulum@1.5.0 RNS/Packet.py:…DecodeErrorDestinationTypeEncodeErrorHeaderTypePacketPacketTypeTransportType
Values and defaults
Public values and defaults.
header_one_bytes: 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/R…header_two_bytes: 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.mtu: 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.pathfinder_hops: 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.truncated_hash_bytes: 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.
Source
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
| Definitions | 13 |
|---|---|
| Public names | 25 |
| Members | 20 |
| Version | 26.7.0 |
| Revision | daab053ee433 |