milestone 18: collapse duplicated infrastructure into shared listener core, crud list helper, resource shells, transport race, name and line helpers, ui modules
CI / test (push) Successful in 1m22s
CI / test-aarch64 (push) Successful in 5m6s
CI / frontend (push) Successful in 45s
CI / cross (push) Successful in 7m53s
CI / docker (push) Failing after 1h10m57s

This commit is contained in:
2026-08-07 18:20:30 +02:00
parent c50c6d285a
commit 6f67940995
82 changed files with 3167 additions and 3114 deletions
+4 -23
View File
@@ -52,7 +52,9 @@ pub const Records = struct {
var buf: [types.max_name_len]u8 = undefined;
for (rows) |row| {
const owner = normalizeName(row.name, &buf) catch return error.BadRecordName;
// A record whose owner can never be matched — a high byte, or the
// root — is a configuration error, not a record that never answers.
const owner = name.normalizeText(row.name, &buf) catch return error.BadRecordName;
const value = try parseValue(row.rtype, row.value);
try spans.append(gpa, .{
.offset = owners.items.len,
@@ -187,27 +189,6 @@ fn rankRun(records: []const Record, wanted: u2) []const Record {
return records[start..end];
}
const NameError = error{BadName};
/// Lowercases over ASCII, strips one trailing dot, and checks the result is a
/// name `dns.name.fromText` accepts. A byte ≥ 0x80 is rejected: query names
/// arrive ASCII-lowercased, so a high byte here could never be matched and a
/// record that can never answer is a configuration error worth reporting. The
/// root name is rejected for the same reason — nothing can match it.
fn normalizeName(text: []const u8, buf: *[types.max_name_len]u8) NameError![]const u8 {
var rest = text;
if (rest.len > 0 and rest[rest.len - 1] == '.') rest = rest[0 .. rest.len - 1];
if (rest.len == 0 or rest.len > types.max_name_len) return error.BadName;
for (rest, 0..) |byte, i| {
if (byte >= 0x80) return error.BadName;
buf[i] = std.ascii.toLower(byte);
}
const normalized = buf[0..rest.len];
_ = name.fromText(normalized) catch return error.BadName;
return normalized;
}
fn parseValue(rtype: model.RecordType, text: []const u8) error{BadRecordValue}!Value {
switch (rtype) {
.a => {
@@ -226,7 +207,7 @@ fn parseValue(rtype: model.RecordType, text: []const u8) error{BadRecordValue}!V
},
.cname => {
var buf: [types.max_name_len]u8 = undefined;
const target = normalizeName(text, &buf) catch return error.BadRecordValue;
const target = name.normalizeText(text, &buf) catch return error.BadRecordValue;
return .{ .cname = name.fromText(target) catch return error.BadRecordValue };
},
}