17#if PC_ENABLE_AUTH_LOCKOUT
25 uint32_t lock_start_ms;
40LockoutBucket *find_bucket(LockoutCtx &c,
const pc_ip *ip)
52bool bucket_locked(
const LockoutBucket *b, uint32_t now_ms)
55 return b->lock_ms != 0 && (uint32_t)(now_ms - b->lock_start_ms) < b->lock_ms;
60uint32_t auth_lockout_remaining_ms(
const pc_ip *ip, uint32_t now_ms)
66 LockoutBucket *b = find_bucket(s_lock, ip);
67 if (!b || b->lock_ms == 0)
71 uint32_t elapsed = now_ms - b->lock_start_ms;
72 if (elapsed >= b->lock_ms)
76 return b->lock_ms - elapsed;
79void auth_lockout_fail(
const pc_ip *ip, uint32_t now_ms)
86 LockoutBucket *b = find_bucket(s_lock, ip);
102 if ((uint32_t)(now_ms - s_lock.buckets[i].last_ms) > (uint32_t)(now_ms - s_lock.buckets[lru].last_ms))
106 if (!bucket_locked(&s_lock.buckets[i], now_ms) &&
108 (uint32_t)(now_ms - s_lock.buckets[i].last_ms) > (uint32_t)(now_ms - s_lock.buckets[slot].last_ms)))
117 b = &s_lock.buckets[slot];
121 b->lock_start_ms = now_ms;
125 if (b->fails < 0xFFFF)
151 b->lock_start_ms = now_ms;
155void auth_lockout_succeed(
const pc_ip *ip)
161 LockoutBucket *b = find_bucket(s_lock, ip);
167 b->lock_start_ms = 0;
172void auth_lockout_reset(
void)
177 s_lock.buckets[i].lock_start_ms = 0;
178 s_lock.buckets[i].lock_ms = 0;
179 s_lock.buckets[i].last_ms = 0;
180 s_lock.buckets[i].fails = 0;
Per-peer brute-force lockout for HTTP auth (PC_ENABLE_AUTH_LOCKOUT).
bool pc_ip_equal(const pc_ip *a, const pc_ip *b)
True if a and b are the same family and address.
bool pc_ip_is_unspecified(const pc_ip *ip)
True if ip is empty (pc_ip_family::PC_IP_NONE) or the all-zero unspecified address (0....
@ PC_IP_NONE
empty / unparsed
#define PC_AUTH_LOCKOUT_SLOTS
Number of source IPs the auth lockout tracks (BSS bucket table).
#define PC_AUTH_LOCKOUT_THRESHOLD
Consecutive failed auths from one IP before it is locked out.
#define PC_AUTH_LOCKOUT_MAX_MS
Maximum lockout duration in ms (the exponential backoff cap).
#define PC_AUTH_LOCKOUT_BASE_MS
First lockout duration in ms; doubles on each further failure.
A v4 or v6 address in network (big-endian) byte order.