macula_session_proof_rate (macula v13.2.2)
View SourceHow many handshake v5 session proofs this station signs: by default at most 30 a minute for one client node, and 30 a second for all clients together (plans/DESIGN_NEIGHBOUR_CHANNEL_BINDING.md section 3, "Signing cost as an attack surface"). A composite session proof costs 6 to 10 ms of signing, so the total bounds this station's signing to about a quarter of one core, and a reconnect storm of 1000 clients is admitted in about 30 seconds. The station asks only after the client's CONNECT proof has verified, so a refusal here costs the client a composite signature of its own. Past either limit the station refuses CONNECT with session_proof_rate, and the refusal names the limit.
The fleet's CPUs differ several-fold, so both limits are macula application environment options, session_proofs_per_node_per_minute and session_proofs_per_second, read once when this process starts and never looked up per handshake. A value that is not an integer of at least 1 refuses the start, naming itself. set_limits/2 replaces both at run time, under the same rule, for a station whose limits come from its own configuration.
Fixed windows: the minute and the second a request falls in. This process only owns the table and purges the windows that ended, once a minute; every count goes to the table directly.
Summary
Functions
Whether the station may sign one more session proof for the client NodeId at Now (milliseconds). A refused request spends nothing: both windows are read first and counted only when the proof will be signed, so a client refused on the total keeps its own budget (Fable round 2).
The limits in force, as read at start.
Delete the windows that ended before Now.
Replace both limits, once macula has started: before any proof or while connections are live, the next proof is counted against the new limits, and the windows already counted stay. Both are checked first, as at start, so an invalid value changes neither and names itself. They are also written to the macula application environment, so a restart of this process rereads them instead of silently putting the defaults back.
How many windows the table holds.
Types
-type limits() :: #{per_node_per_minute := pos_integer(), per_second := pos_integer()}.
Functions
-spec allow(<<_:256>>, integer()) -> ok | {error, {session_proof_rate, per_node_per_minute | per_second}}.
Whether the station may sign one more session proof for the client NodeId at Now (milliseconds). A refused request spends nothing: both windows are read first and counted only when the proof will be signed, so a client refused on the total keeps its own budget (Fable round 2).
-spec limits() -> limits().
The limits in force, as read at start.
-spec purge(integer()) -> ok.
Delete the windows that ended before Now.
Replace both limits, once macula has started: before any proof or while connections are live, the next proof is counted against the new limits, and the windows already counted stay. Both are checked first, as at start, so an invalid value changes neither and names itself. They are also written to the macula application environment, so a restart of this process rereads them instead of silently putting the defaults back.
-spec windows() -> non_neg_integer().
How many windows the table holds.