core: upgrade to 0.15.1

This commit is contained in:
Arran Ireland
2025-10-02 10:40:15 +01:00
parent 76911aaae1
commit 3928731834
12 changed files with 223 additions and 217 deletions

View File

@@ -109,7 +109,7 @@ pub fn process(self: *Self) !void {
fn eventsIn(self: *Self, interface: *Interface, now: u64) !void {
while (interface.incoming.pop()) |event_in| {
var event = event_in;
defer event.deinit();
defer event.deinit(self.ally);
try switch (event) {
.announce => |*announce| self.announceTask(interface, announce, now),

View File

@@ -10,7 +10,7 @@ const System = @import("System.zig");
const Self = @This();
const Entry = struct {
ratchets: std.fifo.LinearFifo(Ratchet, .Dynamic),
ratchets: []Ratchet,
last_rotation_time: u64,
};
@@ -37,7 +37,7 @@ pub fn add(self: *Self, endpoint: Hash.Short, now: u64) !Ratchet {
const key = try self.ally.dupe(u8, &endpoint);
try self.entries.put(key, .{
.ratchets = self.ally,
.ratchets = self.ally.alloc(Ratchet, max_ratchets),
.last_rotation_time = now,
});
@@ -46,25 +46,29 @@ pub fn add(self: *Self, endpoint: Hash.Short, now: u64) !Ratchet {
}
pub fn getRatchet(self: *Self, endpoint: Hash.Short, now: u64) !?Ratchet {
if (self.entries.getPtr(&endpoint)) |entry| {
const needs_rotating = now - entry.last_rotation_time >= rotation_period;
_ = self;
_ = endpoint;
_ = now;
if (needs_rotating) {
var seed: [crypto.X25519.seed_length]u8 = undefined;
self.rng.bytes(&seed);
// if (self.entries.getPtr(&endpoint)) |entry| {
// const needs_rotating = now - entry.last_rotation_time >= rotation_period;
const ratchet = try crypto.X25519.KeyPair.generateDeterministic(seed);
// if (needs_rotating) {
// var seed: [crypto.X25519.seed_length]u8 = undefined;
// self.rng.bytes(&seed);
if (entry.ratchets.count >= max_ratchets) {
entry.ratchets.discard(1);
}
// const ratchet = try crypto.X25519.KeyPair.generateDeterministic(seed);
entry.ratchets.writeItem(ratchet.public_key);
entry.last_rotation_time = now;
}
// if (entry.ratchets.count >= max_ratchets) {
// entry.ratchets.discard(1);
// }
return entry.ratchets.peekItem(entry.ratchets.count - 1);
}
// entry.ratchets.writeItem(ratchet.public_key);
// entry.last_rotation_time = now;
// }
// return entry.ratchets.peekItem(entry.ratchets.count - 1);
// }
return null;
}
@@ -74,7 +78,7 @@ pub fn deinit(self: *Self) void {
while (entries.next()) |entry| {
self.ally.free(entry.key_ptr.*);
entry.value_ptr.ratchets.deinit();
// entry.value_ptr.ratchets.deinit();
}
self.entries.deinit();

View File

@@ -12,8 +12,8 @@ const Language = enum {
rust,
};
pub fn data(language: Language, ally: Allocator) !Bytes {
var exports = parseExports(@embedFile("exports.zig"), ally);
pub fn data(ally: Allocator, language: Language) !Bytes {
var exports = parseExports(ally, @embedFile("exports.zig"));
return switch (language) {
.c => try exports.c(),
@@ -22,7 +22,7 @@ pub fn data(language: Language, ally: Allocator) !Bytes {
};
}
fn parseExports(export_data: [:0]const u8, ally: Allocator) Exports {
fn parseExports(ally: Allocator, export_data: [:0]const u8) Exports {
const Ast = std.zig.Ast;
const DocComment = struct {
@@ -51,71 +51,76 @@ fn parseExports(export_data: [:0]const u8, ally: Allocator) Exports {
var exports = Exports.init(ally);
for (root_declarations) |declaration_index| {
const declaration_tag = nodes.items(.tag)[declaration_index];
const main_token = nodes.items(.main_token)[declaration_index];
const declaration_index_value = @intFromEnum(declaration_index);
const declaration_tag = nodes.items(.tag)[declaration_index_value];
const main_token = nodes.items(.main_token)[declaration_index_value];
if (main_token <= 0 or tokens.items(.tag)[main_token - 1] != .keyword_pub) {
continue;
}
if (main_token <= 0 or tokens.items(.tag)[main_token - 1] != .keyword_pub) continue;
if (declaration_tag == .fn_decl) {
var buffer: [1]std.zig.Ast.Node.Index = undefined;
const function_prototype = ast.fullFnProto(
&buffer,
nodes.items(.data)[declaration_index].lhs,
nodes.items(.data)[declaration_index_value].node_and_node[0],
) orelse continue;
const function = exports.functions.addOne() catch continue;
const function = exports.functions.addOne(ally) catch continue;
function.* = .{
.doc_comment = DocComment.search(ast, main_token),
.name = ast.tokenSlice(function_prototype.name_token orelse continue),
.parameters = std.ArrayList(Function.Parameter).init(ally),
.return_value = ast.getNodeSource(function_prototype.ast.return_type),
.parameters = std.ArrayList(Function.Parameter).empty,
.return_value = ast.getNodeSource(function_prototype.ast.return_type.unwrap().?),
};
var parameters = function_prototype.iterate(&ast);
while (parameters.next()) |parameter| {
const name = ast.tokenSlice(parameter.name_token orelse continue);
const @"type" = if (parameter.type_expr != 0) ast.getNodeSource(parameter.type_expr) else "unknown";
const @"type" = if (parameter.type_expr) |index| ast.getNodeSource(index) else "unknown";
function.parameters.append(.{ .name = name, .type = @"type" }) catch continue;
function.parameters.append(ally, .{ .name = name, .type = @"type" }) catch continue;
}
} else if (declaration_tag == .simple_var_decl) {
const variable_declaration = ast.simpleVarDecl(declaration_index);
if (variable_declaration.ast.init_node == 0) continue;
if (variable_declaration.ast.init_node.unwrap() == null) continue;
switch (nodes.items(.tag)[variable_declaration.ast.init_node]) {
switch (nodes.items(.tag)[@intFromEnum(variable_declaration.ast.init_node)]) {
.container_decl_arg, .container_decl, .container_decl_arg_trailing, .container_decl_trailing => {},
else => continue,
}
var buffer: [2]std.zig.Ast.Node.Index = undefined;
const container_declaration = ast.fullContainerDecl(&buffer, variable_declaration.ast.init_node) orelse continue;
const container_declaration = ast.fullContainerDecl(&buffer, variable_declaration.ast.init_node.unwrap().?) orelse continue;
if (tokens.items(.tag)[container_declaration.ast.main_token] != .keyword_enum) continue;
const @"enum" = exports.enums.addOne() catch continue;
const @"enum" = exports.enums.addOne(ally) catch continue;
@"enum".* = .{
.doc_comment = DocComment.search(ast, main_token),
.name = ast.tokenSlice(main_token + 1),
.values = std.ArrayList(Enum.Value).init(ally),
.values = std.ArrayList(Enum.Value).empty,
};
for (container_declaration.ast.members) |member_index| {
if (nodes.items(.tag)[member_index] != .container_field_init) {
continue;
const member_index_value = @intFromEnum(member_index);
if (nodes.items(.tag)[member_index_value] != .container_field_init) continue;
const name = ast.tokenSlice(nodes.items(.main_token)[member_index_value]);
const member_data = nodes.items(.data)[member_index_value];
if (member_data.node_and_opt_node[1].unwrap()) |node| {
const number = ast.getNodeSource(node);
@"enum".values.append(
ally,
.{ .name = name, .number = number },
) catch continue;
}
const name = ast.tokenSlice(nodes.items(.main_token)[member_index]);
const member_data = nodes.items(.data)[member_index];
const number = ast.getNodeSource(member_data.rhs);
@"enum".values.append(.{ .name = name, .number = number }) catch continue;
}
}
}
@@ -133,16 +138,16 @@ const Exports = struct {
fn init(ally: Allocator) Self {
return .{
.ally = ally,
.enums = std.ArrayList(Enum).init(ally),
.functions = std.ArrayList(Function).init(ally),
.enums = std.ArrayList(Enum).empty,
.functions = std.ArrayList(Function).empty,
};
}
fn c(self: *Self) !Bytes {
var bytes = Bytes.init(self.ally);
var bytes = Bytes.empty;
const b = &bytes;
try b.appendSlice(
try b.appendSlice(self.ally,
\\#ifndef RT_CORE_H
\\#define RT_CORE_H
\\
@@ -153,47 +158,47 @@ const Exports = struct {
);
for (self.enums.items) |e| {
try b.appendSlice("// ");
try b.appendSlice(e.doc_comment);
try b.append('\n');
try b.appendSlice(self.ally, "// ");
try b.appendSlice(self.ally, e.doc_comment);
try b.append(self.ally, '\n');
try b.appendSlice("typedef enum {\n");
try b.appendSlice(self.ally, "typedef enum {\n");
for (e.values.items) |v| {
try b.appendSlice(" ");
try b.appendSlice(v.name);
try b.appendSlice(" = ");
try b.appendSlice(v.number);
try b.appendSlice(",\n");
try b.appendSlice(self.ally, " ");
try b.appendSlice(self.ally, v.name);
try b.appendSlice(self.ally, " = ");
try b.appendSlice(self.ally, v.number);
try b.appendSlice(self.ally, ",\n");
}
try b.appendSlice("} ");
try deriveType(b, e.name);
try b.appendSlice(";\n\n");
try b.appendSlice(self.ally, "} ");
try self.deriveType(b, e.name);
try b.appendSlice(self.ally, ";\n\n");
}
for (self.functions.items) |f| {
try b.appendSlice("// ");
try b.appendSlice(f.doc_comment);
try b.append('\n');
try b.appendSlice(self.ally, "// ");
try b.appendSlice(self.ally, f.doc_comment);
try b.append(self.ally, '\n');
try deriveType(b, f.return_value);
try b.append(' ');
try deriveName(b, f.name);
try b.append('(');
try self.deriveType(b, f.return_value);
try b.append(self.ally, ' ');
try self.deriveName(b, f.name);
try b.append(self.ally, '(');
for (f.parameters.items, 0..) |p, i| {
try parameter(b, p.name, p.type);
try self.parameter(b, p.name, p.type);
if (i != f.parameters.items.len - 1) {
try b.appendSlice(", ");
try b.appendSlice(self.ally, ", ");
}
}
try b.appendSlice(");\n\n");
try b.appendSlice(self.ally, ");\n\n");
}
try b.appendSlice(
try b.appendSlice(self.ally,
\\#endif
\\
);
@@ -202,32 +207,34 @@ const Exports = struct {
}
fn rust(self: *Self) !Bytes {
return Bytes.init(self.ally);
_ = self;
return Bytes.empty;
}
fn js(self: *Self) !Bytes {
return Bytes.init(self.ally);
_ = self;
return Bytes.empty;
}
fn parameter(b: *Bytes, name: []const u8, @"type": []const u8) !void {
fn parameter(self: *Self, b: *Bytes, name: []const u8, @"type": []const u8) !void {
if (eql(u8, @"type", "lib.System.SimpleClock.Callback")) {
try b.appendSlice("int64_t (*");
try b.appendSlice(name);
try b.appendSlice(")(void)");
try b.appendSlice(self.ally, "int64_t (*");
try b.appendSlice(self.ally, name);
try b.appendSlice(self.ally, ")(void)");
} else if (eql(u8, @"type", "lib.System.SimpleRng.Callback")) {
try b.appendSlice("void (*");
try b.appendSlice(name);
try b.appendSlice(")(uint8_t* buf, ");
try deriveType(b, "usize");
try b.appendSlice(" length)");
try b.appendSlice(self.ally, "void (*");
try b.appendSlice(self.ally, name);
try b.appendSlice(self.ally, ")(uint8_t* buf, ");
try self.deriveType(b, "usize");
try b.appendSlice(self.ally, " length)");
} else if (eql(u8, @"type", "Error")) {
try reticulumType(b, @"type");
try self.reticulumType(b, @"type");
} else {
try deriveType(b, @"type");
try self.deriveType(b, @"type");
}
}
fn deriveType(b: *Bytes, string: []const u8) !void {
fn deriveType(self: *Self, b: *Bytes, string: []const u8) !void {
const translations = std.StaticStringMap([]const u8).initComptime(.{
.{ "c_int", "int" },
.{ "anyopaque", "void" },
@@ -249,30 +256,30 @@ const Exports = struct {
});
if (translations.get(string)) |translation| {
try b.appendSlice(translation);
try b.appendSlice(self.ally, translation);
} else {
try reticulumType(b, string);
try self.reticulumType(b, string);
}
}
fn reticulumType(b: *Bytes, string: []const u8) !void {
try deriveName(b, string);
try b.appendSlice("_t");
fn reticulumType(self: *Self, b: *Bytes, string: []const u8) !void {
try self.deriveName(b, string);
try b.appendSlice(self.ally, "_t");
}
fn deriveName(b: *Bytes, string: []const u8) !void {
try b.appendSlice("rt_core");
fn deriveName(self: *Self, b: *Bytes, string: []const u8) !void {
try b.appendSlice(self.ally, "rt_core");
if (string.len > 0 and !std.ascii.isUpper(string[0])) {
try b.append('_');
try b.append(self.ally, '_');
}
for (string) |char| {
if (std.ascii.isUpper(char)) {
try b.append('_');
try b.append(std.ascii.toLower(char));
try b.append(self.ally, '_');
try b.append(self.ally, std.ascii.toLower(char));
} else {
try b.append(char);
try b.append(self.ally, char);
}
}
}

View File

@@ -97,29 +97,27 @@ fn makeHash(public: Public) Hash {
const t = std.testing;
test "valid-signature" {
const allocator = t.allocator;
var rng = std.crypto.random;
const identity = try Self.random(&rng);
var message = try data.Bytes.initCapacity(allocator, 0);
defer message.deinit();
var message = try data.Bytes.initCapacity(t.allocator, 0);
defer message.deinit(t.allocator);
try message.appendSlice("this is a message");
try message.appendSlice(t.allocator, "this is a message");
const signature = try identity.sign(message);
try signature.verify(message.items, identity.public.signature);
}
test "invalid-signature" {
const allocator = t.allocator;
var rng = std.crypto.random;
const identity1 = try Self.random(&rng);
const identity2 = try Self.random(&rng);
var message = try data.Bytes.initCapacity(allocator, 0);
defer message.deinit();
var message = try data.Bytes.initCapacity(t.allocator, 0);
defer message.deinit(t.allocator);
try message.appendSlice("this is a message");
try message.appendSlice(t.allocator, "this is a message");
const signature = try identity1.sign(message);
try t.expectError(

View File

@@ -4,7 +4,7 @@ const Allocator = std.mem.Allocator;
pub const Bytes = std.ArrayList(u8);
pub fn makeBytes(slice: []const u8, ally: Allocator) !Bytes {
var bytes = Bytes.init(ally);
try bytes.appendSlice(slice);
var bytes = Bytes.empty;
try bytes.appendSlice(ally, slice);
return bytes;
}

View File

@@ -25,14 +25,14 @@ hash: Hash,
pub fn init(app_name: []const u8, aspects: []const []const u8, ally: Allocator) !Self {
var self = Self{
.ally = ally,
.app_name = AppName.init(ally),
.aspects = Aspects.init(ally),
.app_name = AppName.empty,
.aspects = Aspects.empty,
.hash = undefined,
};
errdefer {
self.app_name.deinit();
self.aspects.deinit();
self.app_name.deinit(self.ally);
self.aspects.deinit(self.ally);
}
for (app_name) |char| {
@@ -41,7 +41,7 @@ pub fn init(app_name: []const u8, aspects: []const []const u8, ally: Allocator)
}
}
try self.app_name.appendSlice(app_name);
try self.app_name.appendSlice(self.ally, app_name);
for (aspects) |aspect| {
for (aspect) |char| {
@@ -50,22 +50,22 @@ pub fn init(app_name: []const u8, aspects: []const []const u8, ally: Allocator)
}
}
var new_aspect = Aspect.init(self.ally);
errdefer new_aspect.deinit();
var new_aspect = Aspect.empty;
errdefer new_aspect.deinit(self.ally);
try new_aspect.appendSlice(aspect);
try self.aspects.append(new_aspect);
try new_aspect.appendSlice(self.ally, aspect);
try self.aspects.append(self.ally, new_aspect);
}
self.hash = blk: {
var name = data.Bytes.init(self.ally);
defer name.deinit();
var name = data.Bytes.empty;
defer name.deinit(self.ally);
try name.appendSlice(app_name);
try name.appendSlice(self.ally, app_name);
for (aspects) |aspect| {
try name.append('.');
try name.appendSlice(aspect);
try name.append(self.ally, '.');
try name.appendSlice(self.ally, aspect);
}
break :blk Hash.of(.{
@@ -78,23 +78,23 @@ pub fn init(app_name: []const u8, aspects: []const []const u8, ally: Allocator)
pub fn clone(self: *const Self) !Self {
var cloned = self.*;
cloned.app_name = try cloned.app_name.clone();
cloned.aspects = Aspects.init(self.ally);
cloned.app_name = try cloned.app_name.clone(self.ally);
cloned.aspects = Aspects.empty;
for (self.aspects.items) |aspect| {
try cloned.aspects.append(try aspect.clone());
try cloned.aspects.append(self.ally, try aspect.clone(self.ally));
}
return cloned;
}
pub fn deinit(self: *Self) void {
self.app_name.deinit();
self.app_name.deinit(self.ally);
for (self.aspects.items) |aspect| {
aspect.deinit();
for (self.aspects.items) |*aspect| {
aspect.deinit(self.ally);
}
self.aspects.deinit();
self.aspects.deinit(self.ally);
self.* = undefined;
}

View File

@@ -1,13 +1,12 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
const LinearFifo = std.fifo.LinearFifo;
pub fn ThreadSafeFifo(comptime T: type) type {
return struct {
pub const Error = Allocator.Error;
const Self = @This();
const Impl = LinearFifo(T, .Dynamic);
const Impl = std.PriorityQueue(T, void, compare);
mutex: std.Thread.Mutex,
impl: Impl,
@@ -15,7 +14,7 @@ pub fn ThreadSafeFifo(comptime T: type) type {
pub fn init(ally: Allocator) Self {
return Self{
.mutex = .{},
.impl = Impl.init(ally),
.impl = .init(ally, {}),
};
}
@@ -23,23 +22,22 @@ pub fn ThreadSafeFifo(comptime T: type) type {
self.mutex.lock();
self.impl.deinit();
self.mutex.unlock();
self.* = undefined;
}
pub fn push(self: *Self, element: T) Error!void {
self.mutex.lock();
defer {
self.mutex.unlock();
}
try self.impl.writeItem(element);
defer self.mutex.unlock();
try self.impl.add(element);
}
pub fn pop(self: *Self) ?T {
self.mutex.lock();
defer {
self.mutex.unlock();
}
return self.impl.readItem();
defer self.mutex.unlock();
return self.impl.removeOrNull();
}
fn compare(_: void, _: T, _: T) std.math.Order {
return .eq;
}
};
}

View File

@@ -5,6 +5,8 @@ const Packet = @import("../packet.zig").Managed;
const Payload = @import("../packet.zig").Payload;
const Hash = @import("../crypto/Hash.zig");
const Allocator = std.mem.Allocator;
// TODO: Perhaps distinguish between tasks and packets.
pub const In = union(enum) {
@@ -22,11 +24,11 @@ pub const In = union(enum) {
payload: Payload,
};
pub fn deinit(self: *@This()) void {
pub fn deinit(self: *@This(), ally: Allocator) void {
switch (self.*) {
.announce => |*announce| {
if (announce.app_data) |app_data| {
app_data.deinit();
if (announce.app_data) |*app_data| {
app_data.deinit(ally);
}
},
.packet => |*packet| {
@@ -34,7 +36,7 @@ pub const In = union(enum) {
},
.plain => |*plain| {
plain.name.deinit();
plain.payload.deinit();
plain.payload.deinit(ally);
},
}
}
@@ -52,53 +54,49 @@ pub const Out = union(enum) {
}
// TODO: Replace this with a cleaner implementation.
pub fn format(this: @This(), comptime fmt: []const u8, options: std.fmt.FormatOptions, w: anytype) !void {
_ = fmt;
_ = options;
pub fn format(this: @This(), writer: *std.Io.Writer) !void {
const F = struct {
const Self = @This();
writer: @TypeOf(w),
io_writer: *std.Io.Writer,
indentation: u8 = 0,
fn init(writer: @TypeOf(w)) Self {
fn init(io_writer: *std.Io.Writer) Self {
return .{
.writer = writer,
.io_writer = io_writer,
};
}
fn indent(self: *Self) !void {
for (0..self.indentation) |_| {
try self.writer.print(" ", .{});
try self.io_writer.print(" ", .{});
}
}
fn entry(self: *Self, key: []const u8, comptime value_fmt: []const u8, args: anytype) !void {
try self.indent();
try self.writer.print(".{s} = ", .{key});
try self.writer.print(value_fmt ++ ",\n", args);
try self.io_writer.print(".{s} = ", .{key});
try self.io_writer.print(value_fmt ++ ",\n", args);
}
fn objectStart(self: *Self, key: []const u8, tag: []const u8) !void {
try self.indent();
try self.writer.print(".{s} = .{s}{{\n", .{ key, tag });
try self.io_writer.print(".{s} = .{s}{{\n", .{ key, tag });
self.indentation += 2;
}
fn objectEnd(self: *Self) !void {
self.indentation -= 2;
try self.indent();
try self.writer.print("}},\n", .{});
try self.io_writer.print("}},\n", .{});
}
fn print(self: *Self, comptime text: []const u8, args: anytype) !void {
try self.writer.print(text, args);
try self.io_writer.print(text, args);
}
};
const hex = std.fmt.fmtSliceHexLower;
var f = F.init(w);
var f = F.init(writer);
switch (this) {
.packet => |p| {
@@ -116,19 +114,19 @@ pub const Out = union(enum) {
});
if (p.interface_access_code.items.len > 0) {
try f.entry("interface_access_code", "{x}", .{hex(p.interface_access_code.items)});
try f.entry("interface_access_code", "{x}", .{p.interface_access_code.items});
}
switch (p.endpoints) {
.normal => |n| {
try f.entry("endpoints", ".normal{{{x}}}", .{
hex(&n.endpoint),
&n.endpoint,
});
},
.transport => |t| {
try f.entry("endpoints", ".transport{{{x}, {x}}}", .{
hex(&t.endpoint),
hex(&t.transport_id),
&t.endpoint,
&t.transport_id,
});
},
}
@@ -139,26 +137,26 @@ pub const Out = union(enum) {
.announce => |a| {
try f.objectStart("payload", "announce");
try f.entry("public.dh", "{x}", .{hex(&a.public.dh)});
try f.entry("public.signature", "{x}", .{hex(&a.public.signature.bytes)});
try f.entry("name_hash", "{x}", .{hex(&a.name_hash)});
try f.entry("noise", "{x}", .{hex(&a.noise)});
try f.entry("public.dh", "{x}", .{&a.public.dh});
try f.entry("public.signature", "{x}", .{&a.public.signature.bytes});
try f.entry("name_hash", "{x}", .{&a.name_hash});
try f.entry("noise", "{x}", .{&a.noise});
var timestamp_bytes: [5]u8 = undefined;
std.mem.writeInt(u40, &timestamp_bytes, a.timestamp, .big);
try f.entry("timestamp", "{x}", .{hex(&timestamp_bytes)});
try f.entry("timestamp", "{x}", .{&timestamp_bytes});
if (a.ratchet) |*ratchet| {
try f.entry("ratchet", "{x}", .{hex(ratchet)});
try f.entry("ratchet", "{x}", .{ratchet});
}
try f.entry("signature", "{x}", .{hex(&a.signature.toBytes())});
try f.entry("signature", "{x}", .{&a.signature.toBytes()});
if (a.application_data.items.len > 0) {
try f.entry("application_data", "{x}", .{hex(a.application_data.items)});
try f.entry("application_data", "{x}", .{a.application_data.items});
}
try f.objectEnd();
},
.raw => |r| {
try f.entry("payload", ".raw{{{x}}}", .{hex(r.items)});
try f.entry("payload", ".raw{{{x}}}", .{r.items});
},
.none => {
try f.entry("payload", ".none", .{});

View File

@@ -50,7 +50,7 @@ pub const Payload = union(enum) {
};
}
pub fn clone(self: Self) !Self {
pub fn clone(self: Self, ally: Allocator) !Self {
return switch (self) {
.announce => |a| Self{
.announce = Announce{
@@ -60,11 +60,11 @@ pub const Payload = union(enum) {
.timestamp = a.timestamp,
.ratchet = a.ratchet,
.signature = a.signature,
.application_data = try a.application_data.clone(),
.application_data = try a.application_data.clone(ally),
},
},
.raw => |r| Self{
.raw = try r.clone(),
.raw = try r.clone(ally),
},
.none => Self.none,
};
@@ -89,10 +89,10 @@ pub const Payload = union(enum) {
};
}
pub fn deinit(self: *Self) void {
pub fn deinit(self: *Self, ally: Allocator) void {
return switch (self.*) {
.announce => |*announce| announce.application_data.deinit(),
.raw => |*raw| raw.deinit(),
.announce => |*announce| announce.application_data.deinit(ally),
.raw => |*raw| raw.deinit(ally),
.none => {},
};
}
@@ -201,13 +201,13 @@ test "validate-raw-announce-roundtrip" {
// Captured from reference implementation - with framing removed.
const raw_announce = "71008133c7ce6d6be9b4070a3b98ee9ecab583dfe79d30200ee5e9f5c5615d45a5b000fb266456840e5f4d010a6fbb4025969f8db5415597e3d7a48431d0534e441d0bdeb78f1064f50b447291dd51617040dc9c40cb5b9adab1314ad270b1297d6fd46ec60bc318e2c0f0d908fc1c2bcdef00686f9b4ef17ec1b73f60b14df6709cb74164bd1890e26ff8a4634bbd855051ef959f413d7f7c8f9ff0f54ee81fb994c4e1975fe6f4b56fb26d2e107bd824d864a6932a2e2c02b1352ad9a31ce1cbeae72902effef1ccdeb7d004fbe527cd39111dc59d0e92c406696f6e323332c0";
var bytes = std.ArrayList(u8).init(ally);
defer bytes.deinit();
var bytes = std.ArrayList(u8).empty;
defer bytes.deinit(ally);
var i: usize = 0;
while (i < raw_announce.len) : (i += 2) {
const byte = std.fmt.parseInt(u8, raw_announce[i .. i + 2], 16) catch break;
try bytes.append(byte);
try bytes.append(ally, byte);
}
var factory = Factory.init(ally, rng, .{});
@@ -262,7 +262,7 @@ test "validate-make-announce" {
var raw_bytes = try data.Bytes.initCapacity(ally, announce_packet.size());
raw_bytes.expandToCapacity();
defer raw_bytes.deinit();
defer raw_bytes.deinit(ally);
const raw_packet = try announce_packet.write(raw_bytes.items);
var p = try factory.fromBytes(raw_packet);

View File

@@ -28,7 +28,7 @@ pub fn init(ally: Allocator) Self {
return Self{
.ally = ally,
.header = .{},
.interface_access_code = data.Bytes.init(ally),
.interface_access_code = data.Bytes.empty,
.endpoints = null,
.context = .none,
.payload = .none,
@@ -41,7 +41,7 @@ pub fn setHeader(self: *Self, header: Header) *Self {
}
pub fn setInterfaceAccessCode(self: *Self, interface_access_code: []const u8) !*Self {
try self.interface_access_code.appendSlice(interface_access_code);
try self.interface_access_code.appendSlice(self.ally, interface_access_code);
if (interface_access_code.len > 0) {
self.header.interface = .authenticated;

View File

@@ -51,8 +51,8 @@ pub fn fromBytes(self: *Self, bytes: []const u8) Error!Packet {
return Error.InvalidAuthentication;
}
var interface_access_code = data.Bytes.init(self.ally);
errdefer interface_access_code.deinit();
var interface_access_code = data.Bytes.empty;
errdefer interface_access_code.deinit(self.ally);
if (self.config.access_code) |access_code| {
if (bytes.len < index + access_code.len) {
@@ -61,7 +61,7 @@ pub fn fromBytes(self: *Self, bytes: []const u8) Error!Packet {
// TODO: I need to decrypt the packet here.
try interface_access_code.appendSlice(bytes[index .. index + access_code.len]);
try interface_access_code.appendSlice(self.ally, bytes[index .. index + access_code.len]);
index += access_code.len;
}
@@ -155,17 +155,17 @@ pub fn fromBytes(self: *Self, bytes: []const u8) Error!Packet {
announce.signature = Signature.fromBytes(signature_bytes);
index += Signature.encoded_length;
var application_data = data.Bytes.init(self.ally);
try application_data.appendSlice(bytes[index..]);
var application_data = data.Bytes.empty;
try application_data.appendSlice(self.ally, bytes[index..]);
announce.application_data = application_data;
break :blk announce;
},
},
else => .{ .raw = blk: {
var raw = data.Bytes.init(self.ally);
errdefer raw.deinit();
try raw.appendSlice(bytes[index..]);
var raw = data.Bytes.empty;
errdefer raw.deinit(self.ally);
try raw.appendSlice(self.ally, bytes[index..]);
break :blk raw;
} },
};
@@ -191,31 +191,32 @@ pub fn makeAnnounce(self: *Self, endpoint: *const Endpoint, application_data: ?[
var ratchet: crypto.Identity.Ratchet = undefined;
self.rng.bytes(&ratchet);
announce.ratchet = ratchet;
announce.application_data = data.Bytes.init(self.ally);
announce.application_data = data.Bytes.empty;
if (application_data) |app_data| {
try announce.application_data.appendSlice(app_data);
try announce.application_data.appendSlice(self.ally, app_data);
}
announce.signature = blk: {
var arena = std.heap.ArenaAllocator.init(self.ally);
defer arena.deinit();
var bytes = data.Bytes.init(arena.allocator());
try bytes.appendSlice(endpoint.hash.short());
try bytes.appendSlice(announce.public.dh[0..]);
try bytes.appendSlice(announce.public.signature.bytes[0..]);
try bytes.appendSlice(announce.name_hash[0..]);
try bytes.appendSlice(announce.noise[0..]);
const arena_allocator = arena.allocator();
var bytes = data.Bytes.empty;
try bytes.appendSlice(arena_allocator, endpoint.hash.short());
try bytes.appendSlice(arena_allocator, announce.public.dh[0..]);
try bytes.appendSlice(arena_allocator, announce.public.signature.bytes[0..]);
try bytes.appendSlice(arena_allocator, announce.name_hash[0..]);
try bytes.appendSlice(arena_allocator, announce.noise[0..]);
var timestamp_bytes: [5]u8 = undefined;
std.mem.writeInt(u40, &timestamp_bytes, announce.timestamp, .big);
try bytes.appendSlice(&timestamp_bytes);
try bytes.appendSlice(arena_allocator, &timestamp_bytes);
if (announce.ratchet) |*r| {
try bytes.appendSlice(r[0..]);
try bytes.appendSlice(arena_allocator, r[0..]);
}
try bytes.appendSlice(announce.application_data.items);
try bytes.appendSlice(arena_allocator, announce.application_data.items);
break :blk try identity.sign(bytes);
};

View File

@@ -43,25 +43,25 @@ pub fn setTransport(self: *Self, transport_id: *const Hash.Short) !void {
pub fn validate(self: *const Self) !void {
switch (self.payload) {
.announce => |a| {
var signed_data = std.ArrayList(u8).init(self.ally);
defer signed_data.deinit();
var signed_data = std.ArrayList(u8).empty;
defer signed_data.deinit(self.ally);
const endpoint_hash = self.endpoints.endpoint();
try signed_data.appendSlice(endpoint_hash[0..]);
try signed_data.appendSlice(a.public.dh[0..]);
try signed_data.appendSlice(a.public.signature.bytes[0..]);
try signed_data.appendSlice(a.name_hash[0..]);
try signed_data.appendSlice(a.noise[0..]);
try signed_data.appendSlice(self.ally, endpoint_hash[0..]);
try signed_data.appendSlice(self.ally, a.public.dh[0..]);
try signed_data.appendSlice(self.ally, a.public.signature.bytes[0..]);
try signed_data.appendSlice(self.ally, a.name_hash[0..]);
try signed_data.appendSlice(self.ally, a.noise[0..]);
var timestamp_bytes: [5]u8 = undefined;
std.mem.writeInt(u40, &timestamp_bytes, a.timestamp, .big);
try signed_data.appendSlice(&timestamp_bytes);
try signed_data.appendSlice(self.ally, &timestamp_bytes);
if (a.ratchet) |*ratchet| {
try signed_data.appendSlice(ratchet[0..]);
try signed_data.appendSlice(self.ally, ratchet[0..]);
}
try signed_data.appendSlice(a.application_data.items);
try signed_data.appendSlice(self.ally, a.application_data.items);
var verifier = try a.signature.verifier(a.public.signature);
verifier.update(signed_data.items);
@@ -218,12 +218,12 @@ pub fn clone(self: *const Self) !Self {
.context = self.context,
.endpoints = self.endpoints,
.header = self.header,
.interface_access_code = try self.interface_access_code.clone(),
.payload = try self.payload.clone(),
.interface_access_code = try self.interface_access_code.clone(self.ally),
.payload = try self.payload.clone(self.ally),
};
}
pub fn deinit(self: *Self) void {
self.interface_access_code.deinit();
self.payload.deinit();
self.interface_access_code.deinit(self.ally);
self.payload.deinit(self.ally);
}