milestone 5: blocklist filtering, local records and conditional forwarding

This commit is contained in:
2026-08-01 16:43:55 +02:00
parent 3baf5d6581
commit 59d94df722
29 changed files with 10257 additions and 81 deletions
+39
View File
@@ -20,6 +20,21 @@ const name = @import("../dns/name.zig");
/// RFC 1035 §4.2.2: the TCP length prefix is 16-bit, so no DNS message can be
/// larger than this on any transport nxdns speaks.
pub const max_message_len = 65535;
/// RFC 1035 §4.2.2 two-byte big-endian length prefix, shared by every
/// stream transport (DoT, plain TCP server, forward-zone TCP fallback).
pub const prefix_len = 2;
pub fn framePrefix(len: u16) [prefix_len]u8 {
var out: [prefix_len]u8 = undefined;
std.mem.writeInt(u16, &out, len, .big);
return out;
}
pub fn parsePrefix(bytes: [prefix_len]u8) u16 {
return std.mem.readInt(u16, &bytes, .big);
}
pub const doh_default_port = 443;
pub const dot_default_port = 853; // RFC 7858 §3.1
pub const doh_default_path = "/dns-query"; // RFC 8484 §4.1 well-known template
@@ -264,6 +279,30 @@ pub fn validateResponse(query: []const u8, response: []const u8) ValidateError!v
const testing = std.testing;
test "framePrefix writes the length big-endian" {
try testing.expectEqualSlices(u8, &.{ 0x00, 0x00 }, &framePrefix(0));
try testing.expectEqualSlices(u8, &.{ 0x00, 0x1d }, &framePrefix(29));
try testing.expectEqualSlices(u8, &.{ 0x01, 0x00 }, &framePrefix(256));
try testing.expectEqualSlices(u8, &.{ 0xff, 0xff }, &framePrefix(65535));
}
test "parsePrefix reads the length big-endian" {
try testing.expectEqual(@as(u16, 0), parsePrefix(.{ 0x00, 0x00 }));
try testing.expectEqual(@as(u16, 29), parsePrefix(.{ 0x00, 0x1d }));
try testing.expectEqual(@as(u16, 256), parsePrefix(.{ 0x01, 0x00 }));
try testing.expectEqual(@as(u16, 65535), parsePrefix(.{ 0xff, 0xff }));
}
test "framePrefix and parsePrefix round-trip" {
for ([_]u16{ 0, 1, 12, 512, 4096, 65534, 65535 }) |len| {
try testing.expectEqual(len, parsePrefix(framePrefix(len)));
}
}
test "the prefix ceiling is the message ceiling" {
try testing.expectEqual(@as(u16, max_message_len), parsePrefix(.{ 0xff, 0xff }));
}
test "parse a DoH url with an explicit path" {
const e = try Endpoint.parse("https://cloudflare-dns.com/dns-query");
try testing.expectEqual(Scheme.doh, e.scheme);