reckon_db_discovery (reckon_db v5.1.0)
View SourceCluster discovery for reckon-db
Handles node discovery via UDP multicast (LAN) or Kubernetes DNS. Ported from LibCluster's gossip strategy.
Protocol (v2, since 5.1.0): 1. Broadcast {gossip_v2, NodeBin, Timestamp, Hmac} every BROADCAST_INTERVAL, where Hmac = HMAC-SHA256 over the node name and timestamp keyed with the cluster secret. The secret itself never goes on the wire (v1 broadcast it in cleartext). 2. On receive: safe-decode, constant-time HMAC check, freshness window, THEN net_kernel:connect_node/1. The node name travels as a binary and is only atomized after authentication, so unauthenticated LAN datagrams can neither grow the atom table nor trigger term decoding of attacker-shaped structures. 3. On node up: trigger Khepri cluster join via StoreCoordinator
Discovery requires an explicitly configured cluster secret: the RECKON_DB_CLUSTER_SECRET env var, or the cluster_secret application environment key. Without one, cluster-mode discovery stays passive: no broadcasts, inbound gossip ignored. v1 shipped a hardcoded default secret, which made every unconfigured deployment trust any LAN host.
Summary
Types
-type index_decl() :: tags | event_type | {meta, Key :: binary()}.
-type integrity_config() :: disabled | #{enabled := true, key_source := integrity_key_source()}.
-type integrity_key_source() :: {env_var, EnvName :: binary()} | {sealed_file, Path :: file:filename()}.
-type store_config() :: #store_config{store_id :: atom(), data_dir :: string(), mode :: single | cluster, timeout :: pos_integer(), writer_pool_size :: pos_integer(), reader_pool_size :: pos_integer(), gateway_pool_size :: pos_integer(), options :: map(), integrity :: integrity_config(), indexes :: [index_decl()]}.
Functions
Get list of discovered nodes
-spec start_link(store_config()) -> {ok, pid()} | {error, term()}.
-spec trigger_discovery(atom()) -> ok.
Trigger immediate discovery broadcast