Resolve PTR names over DNS-over-HTTPS and cache them for the record TTL (closes #238)
check / check (push) Successful in 4m39s
check / check (push) Successful in 4m39s
`ptr` keeps its field and shape. It now comes from Google, Cloudflare, AdGuard and Quad9 over RFC 8484, tried in turn within 2 seconds, in place of the host's resolver with no cache. Answers stay in memory and in a new `cache.db` for the record's TTL, at most 250,000 addresses. A reserved address is not sent to any resolver and has an empty `ptr`. Judgement call: each resolver gets an equal share of the time left, so a hung one does not use up the limit. Judgement call: the negative TTL is the smaller of the SOA minimum and the SOA's own TTL. Deviation: the cache is SQLite, by sneak's words, not the JSON file the standing rule asks for. Model: opus-5-5
This commit was merged in pull request #244.
This commit is contained in:
1 parent
641798bb22
commit
0cbd9cd943
21 files changed
+1973
-69
No files matched your search
@@ -0,0 +1,51 @@
|
||||
// Package cachedb opens cache.db, the SQLite file in the state directory that
|
||||
// holds RouteWatch's caches of answers from outside services. It is separate
|
||||
// from the routes database so that a cache write never queues behind a write
|
||||
// to that database.
|
||||
package cachedb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
_ "embed" // for schema.sql
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3" // CGO SQLite driver
|
||||
)
|
||||
|
||||
const (
|
||||
// fileName is the database's file in the state directory.
|
||||
fileName = "cache.db"
|
||||
|
||||
// busyTimeoutMs is how long a write waits for another write to finish.
|
||||
busyTimeoutMs = 5000
|
||||
)
|
||||
|
||||
//go:embed schema.sql
|
||||
var schema string
|
||||
|
||||
// Open opens cache.db in stateDir, creating the file and its tables when they
|
||||
// do not exist. The caller closes the database.
|
||||
func Open(ctx context.Context, stateDir string) (*sql.DB, error) {
|
||||
dsn := fmt.Sprintf(
|
||||
"file:%s?_journal_mode=WAL&_synchronous=NORMAL&_busy_timeout=%d"+
|
||||
"&_txlock=immediate",
|
||||
filepath.Join(stateDir, fileName),
|
||||
busyTimeoutMs,
|
||||
)
|
||||
|
||||
db, err := sql.Open("sqlite3", dsn)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("opening the cache database: %w", err)
|
||||
}
|
||||
|
||||
_, err = db.ExecContext(ctx, schema)
|
||||
if err != nil {
|
||||
_ = db.Close()
|
||||
|
||||
return nil, fmt.Errorf("creating the cache database's tables: %w", err)
|
||||
}
|
||||
|
||||
return db, nil
|
||||
}
|
||||
Reference in new issue
Block a user