db-mode config changes apply live in-process
settings and upstream writes now follow a prepare, commit, publish, retire contract: candidates are built and validated before the database transaction, published as infallible pointer swaps, and old generations retire after their readers drain. per-query policy values snapshot once per query; upstream pool, cache, rate limiter, sessions, api limiter, log sink, blocklist scheduler and the query-log queue each gained one named live operation. restart_required shrinks from every scalar key to the bind keys and web.enabled; the admin ui drops its restart notices for everything else. file mode is unchanged.
This commit is contained in:
@@ -32,6 +32,7 @@ const forward_zones = @import("../local/forward_zones.zig");
|
||||
const handler = @import("handler.zig");
|
||||
const header = @import("../dns/header.zig");
|
||||
const local_tables = @import("local_tables.zig");
|
||||
const logger_controller = @import("../storage/logger_controller.zig");
|
||||
const logger_mod = @import("../storage/logger.zig");
|
||||
const provenance = @import("../storage/provenance.zig");
|
||||
const manager = @import("../filter/manager.zig");
|
||||
@@ -47,8 +48,10 @@ const rate_limiter = @import("rate_limiter.zig");
|
||||
const record = @import("../dns/record.zig");
|
||||
const records = @import("../local/records.zig");
|
||||
const response = @import("../filter/response.zig");
|
||||
const retention_mod = @import("../storage/retention.zig");
|
||||
const shutdown = @import("shutdown.zig");
|
||||
const transport = @import("../upstream/transport.zig");
|
||||
const upstream_owner = @import("../upstream/owner.zig");
|
||||
const types = @import("../dns/types.zig");
|
||||
const udp_server = @import("udp_server.zig");
|
||||
|
||||
@@ -79,11 +82,10 @@ const zone_ttl: u32 = 120;
|
||||
|
||||
/// The handler every case starts from: an upstream, the blocking options and
|
||||
/// the empty local tables. Each case wires in the collaborators it exercises.
|
||||
fn baseHandler(client: transport.Client) handler.Handler {
|
||||
fn baseHandler(up: *upstream_owner.Owner) handler.Handler {
|
||||
return .{
|
||||
.upstream = client,
|
||||
.blocking = blocking,
|
||||
.forward_read_timeout = forward_timeout,
|
||||
.upstream = up,
|
||||
.policy = .{ .blocking = blocking, .forward_read_timeout = forward_timeout },
|
||||
};
|
||||
}
|
||||
|
||||
@@ -265,6 +267,11 @@ fn fixtureManager(m: *manager.Manager, snapshot: *matcher.Snapshot) void {
|
||||
.paths = undefined,
|
||||
.fetcher = undefined,
|
||||
.update = .{},
|
||||
.schedule_mutex = .init,
|
||||
.schedule_version = 0,
|
||||
.schedule_anchor_s = null,
|
||||
.schedule_event = .unset,
|
||||
.schedule_clock = .real,
|
||||
.total_budget = forward_timeout,
|
||||
.lock = .init,
|
||||
.writer_lock = .init,
|
||||
@@ -317,10 +324,12 @@ test "S7 case 1: a blocked domain is answered with the zero address and logged"
|
||||
|
||||
var queue_buf: [log_queue_len]logger_mod.Entry = undefined;
|
||||
var lg: logger_mod.Logger = .init(.{}, &queue_buf);
|
||||
var sink: query_sink.QuerySink = .init(&lg, null);
|
||||
var log_owner: logger_controller.Borrowed = .{};
|
||||
var sink: query_sink.QuerySink = .init(log_owner.over(&lg), null);
|
||||
|
||||
var fake: FakeUpstream = .{ .reply = .a };
|
||||
var h = baseHandler(fake.client());
|
||||
var h_owner: upstream_owner.Borrowed = .{};
|
||||
var h = baseHandler(h_owner.client(fake.client()));
|
||||
h.manager = &mgr;
|
||||
h.sink = &sink;
|
||||
|
||||
@@ -374,7 +383,8 @@ test "S7 case 2: an allow rule beats the blocklist and the upstream answers" {
|
||||
fixtureManager(&mgr, &snapshot);
|
||||
|
||||
var fake: FakeUpstream = .{ .reply = .a };
|
||||
var h = baseHandler(fake.client());
|
||||
var h_owner: upstream_owner.Borrowed = .{};
|
||||
var h = baseHandler(h_owner.client(fake.client()));
|
||||
h.manager = &mgr;
|
||||
|
||||
var loop = try Loop.bind(gpa, io, &h);
|
||||
@@ -411,7 +421,8 @@ test "S7 case 3: a local record answers authoritatively without an upstream" {
|
||||
defer table.deinit(gpa);
|
||||
|
||||
var fake: FakeUpstream = .{ .reply = .a };
|
||||
var h = baseHandler(fake.client());
|
||||
var h_owner: upstream_owner.Borrowed = .{};
|
||||
var h = baseHandler(h_owner.client(fake.client()));
|
||||
var tables: local_tables.LocalTables = .{ .records = table };
|
||||
h.local_tables = &tables;
|
||||
|
||||
@@ -479,12 +490,13 @@ test "S7 case 4: a forward zone reaches its resolver, bypasses the blocklist and
|
||||
defer cache.deinit();
|
||||
|
||||
var fake: FakeUpstream = .{ .reply = .a };
|
||||
var h = baseHandler(fake.client());
|
||||
var h_owner: upstream_owner.Borrowed = .{};
|
||||
var h = baseHandler(h_owner.client(fake.client()));
|
||||
h.manager = &mgr;
|
||||
var tables: local_tables.LocalTables = .{ .zones = zones };
|
||||
h.local_tables = &tables;
|
||||
h.cache = &cache;
|
||||
h.negative_ttl_max = 3600;
|
||||
h.policy.negative_ttl_max = 3600;
|
||||
|
||||
var loop = try Loop.bind(gpa, io, &h);
|
||||
defer loop.stop(gpa, io);
|
||||
@@ -533,12 +545,14 @@ test "S7 case 5: a cached answer comes back with a fresh id, an aged ttl and a l
|
||||
|
||||
var queue_buf: [log_queue_len]logger_mod.Entry = undefined;
|
||||
var lg: logger_mod.Logger = .init(.{}, &queue_buf);
|
||||
var sink: query_sink.QuerySink = .init(&lg, null);
|
||||
var log_owner: logger_controller.Borrowed = .{};
|
||||
var sink: query_sink.QuerySink = .init(log_owner.over(&lg), null);
|
||||
|
||||
var fake: FakeUpstream = .{ .reply = .a };
|
||||
var h = baseHandler(fake.client());
|
||||
var h_owner: upstream_owner.Borrowed = .{};
|
||||
var h = baseHandler(h_owner.client(fake.client()));
|
||||
h.cache = &cache;
|
||||
h.negative_ttl_max = 3600;
|
||||
h.policy.negative_ttl_max = 3600;
|
||||
h.sink = &sink;
|
||||
|
||||
var loop = try Loop.bind(gpa, io, &h);
|
||||
@@ -622,10 +636,12 @@ test "S7 case 6: a cname into a blocked target blocks the original question" {
|
||||
|
||||
var queue_buf: [log_queue_len]logger_mod.Entry = undefined;
|
||||
var lg: logger_mod.Logger = .init(.{}, &queue_buf);
|
||||
var sink: query_sink.QuerySink = .init(&lg, null);
|
||||
var log_owner: logger_controller.Borrowed = .{};
|
||||
var sink: query_sink.QuerySink = .init(log_owner.over(&lg), null);
|
||||
|
||||
var fake: FakeUpstream = .{ .reply = .{ .cname = "tracker.example.org" } };
|
||||
var h = baseHandler(fake.client());
|
||||
var h_owner: upstream_owner.Borrowed = .{};
|
||||
var h = baseHandler(h_owner.client(fake.client()));
|
||||
h.manager = &mgr;
|
||||
h.sink = &sink;
|
||||
|
||||
@@ -681,7 +697,8 @@ test "S7 case 7: safe search answers the original question with a cname to the t
|
||||
fixtureManager(&mgr, &snapshot);
|
||||
|
||||
var fake: FakeUpstream = .{ .reply = .a };
|
||||
var h = baseHandler(fake.client());
|
||||
var h_owner: upstream_owner.Borrowed = .{};
|
||||
var h = baseHandler(h_owner.client(fake.client()));
|
||||
h.manager = &mgr;
|
||||
|
||||
var loop = try Loop.bind(gpa, io, &h);
|
||||
@@ -733,10 +750,12 @@ test "S7 case 8: the third query inside the window is refused" {
|
||||
|
||||
var queue_buf: [log_queue_len]logger_mod.Entry = undefined;
|
||||
var lg: logger_mod.Logger = .init(.{}, &queue_buf);
|
||||
var sink: query_sink.QuerySink = .init(&lg, null);
|
||||
var log_owner: logger_controller.Borrowed = .{};
|
||||
var sink: query_sink.QuerySink = .init(log_owner.over(&lg), null);
|
||||
|
||||
var fake: FakeUpstream = .{ .reply = .a };
|
||||
var h = baseHandler(fake.client());
|
||||
var h_owner: upstream_owner.Borrowed = .{};
|
||||
var h = baseHandler(h_owner.client(fake.client()));
|
||||
h.limiter = &limiter;
|
||||
h.sink = &sink;
|
||||
|
||||
@@ -785,7 +804,8 @@ test "S7 case 9: pause lifts filtering and unpause restores it" {
|
||||
paused.pauseFor(std.Io.Clock.real.now(io).toSeconds(), null);
|
||||
|
||||
var fake: FakeUpstream = .{ .reply = .a };
|
||||
var h = baseHandler(fake.client());
|
||||
var h_owner: upstream_owner.Borrowed = .{};
|
||||
var h = baseHandler(h_owner.client(fake.client()));
|
||||
h.manager = &mgr;
|
||||
h.pause = &paused;
|
||||
|
||||
@@ -831,10 +851,12 @@ test "S7 case 10: the querying client is materialised as a row" {
|
||||
try db.applyPragmas(&database, .{});
|
||||
_ = try migrations.migrate(&database);
|
||||
|
||||
var tracker: clients.Tracker = .init(30);
|
||||
var retention_days: retention_mod.RetentionDays = .init(30);
|
||||
var tracker: clients.Tracker = .init(&retention_days);
|
||||
|
||||
var fake: FakeUpstream = .{ .reply = .a };
|
||||
var h = baseHandler(fake.client());
|
||||
var h_owner: upstream_owner.Borrowed = .{};
|
||||
var h = baseHandler(h_owner.client(fake.client()));
|
||||
h.tracker = &tracker;
|
||||
|
||||
var loop = try Loop.bind(gpa, io, &h);
|
||||
|
||||
Reference in New Issue
Block a user