Skip to content

Architecture

The Settings Syncer is the read-side bridge between Redis and the DNS filtering consumers. Upstream producers (IP Mapper, Admin Portal) write subscriber sessions and settings to Redis. The Settings Syncer picks those changes up — via both initial bulk load and ongoing pubsub — and writes them into a local LMDB. The filtering consumers read that LMDB at query time.

Role in Platform Filter

flowchart LR
    IM[(IP Mapper)] -- persist + publish --> R[(Redis)]
    AP[Admin Portal] -- settings + profiles --> R
    R -- initial bulk load --> SS[Settings Syncer]
    R -- pubsub updates --> SS
    SS -- write --> DB[(LMDB)]
    DB -. read .-> REC[Recursor]
    DB -. read .-> DD[DNSdist]
    DB -. read .-> SIM[Simulator]

The Settings Syncer does not write back to Redis and has no inbound API. It is a pure consumer: everything flows from Redis into LMDB.

Multiple Redis servers can be configured. Each server runs its own syncer instance in parallel, writing to the shared LMDB. All instances share a single LMDB environment.

Sync model

The Settings Syncer operates in two sequential phases per server:

Subscribe. Before loading any data, the syncer opens a Redis pubsub subscription on all configured channels. This ensures that no update published while the bulk load runs is missed.

Bulk load. With the subscription live, the syncer reads the full current state from each Redis server and writes it into LMDB. Updates received on the subscription during this phase are queued and applied afterward.

Once the bulk load finishes, the syncer processes queued and incoming pubsub messages indefinitely. If the connection drops, the syncer closes the subscription, waits for restart_wait, then starts the subscribe → bulk-load cycle again.

Note

no_bulk and no_subscribe are test-only parameters. Do not set them in production.

Server modes and channels

Each server entry carries a mode (or an explicit channels list) that controls which Redis channels are synced.

admin mode

Syncs the four admin channels:

Channel LMDB database Content
oid_user oid_user Opaque-ID → username mapping
user_settings user_settings Username → subscriber settings (protobuf)
device_profile device_profile Username+device → filter profile
settings settings Global dynamic filter settings

ipmapper mode

Syncs the two IP mapping channels:

Channel LMDB database Content
ip4p (or ip4p:<region>) ip4p IPv4+port → opaque-ID (sorted set, 6-byte keys)
ip6 ip6 IPv6 → opaque-ID (sorted set, 16-byte keys)

IPv4 entries are keyed as 4-byte IP address + 2-byte port, supporting CG-NAT deployments where multiple subscribers share an IP. In case of CG-NAT the region parameter below must be set and the SettingsSyncer will generate the correct channel names internally.

single mode

Single mode emulates the "legacy" behavior where both admin and ipmapper channels are synched from one server. This is equivalent to having one admin and one ipmapper server pointing at the same Redis instance.

channels (explicit list)

Instead of mode, a server can specify channels explicitly. This is for advanced deployments where the standard mode groupings do not match the Redis layout.

Region

The region field on redis names a CG-NAT region. When set, servers using ipmapper or single mode subscribe to ip4p:<region> instead of ip4p, and the bulk load reads from the region-specific Redis key. This allows a single LMDB to hold IP mappings from multiple regional Redis servers without collision.

Timestamp channel

All servers also automatically subscribe to the timestamp channel regardless of mode. The pdns-pf-redis-timestamper publishes a Unix timestamp to this channel periodically. The Settings Syncer uses the gap between the published timestamp and local time to measure subscription latency, reported as settings_syncer_incr_latency_msec.

LMDB databases written

DBI name Written by mode
oid_user admin, single
user_settings admin, single
device_profile admin, single
settings admin, single
ip4p ipmapper, single
ip6 ipmapper, single

All DBIs live in the single LMDB environment at lmdb.dir_path.