mirror of
https://github.com/ion232/reticulum-zig.git
synced 2025-12-22 06:37:05 +00:00
core: upgrade to 0.15.1
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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, ×tamp_bytes, a.timestamp, .big);
|
||||
try f.entry("timestamp", "{x}", .{hex(×tamp_bytes)});
|
||||
try f.entry("timestamp", "{x}", .{×tamp_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", .{});
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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, ×tamp_bytes, announce.timestamp, .big);
|
||||
try bytes.appendSlice(×tamp_bytes);
|
||||
try bytes.appendSlice(arena_allocator, ×tamp_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);
|
||||
};
|
||||
|
||||
@@ -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, ×tamp_bytes, a.timestamp, .big);
|
||||
try signed_data.appendSlice(×tamp_bytes);
|
||||
try signed_data.appendSlice(self.ally, ×tamp_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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user