Repository navigation
Conversation
Every request of every visitor read all networks of both lists and tested each in PHP; the exact-address part compared LOWER(ipaddress), which no index can serve. With 150000 blocked addresses and 20000 blocked IPv6 networks that was 65-70 ms of database work per request (1-2 ms now). Addresses and networks are stored in one canonical form (IpHelper::canonicalEntry()), so the entries which can contain an address are known (IpHelper::lookupCandidates(): the address and its network for each prefix length) and one indexed IN query finds them. The plugin converts the existing entries once, before its first lookup after the update (the installer script can't, the previous version's class may be loaded already); blocks and tracked addresses are written canonical. Indexes on both tables. The component's forms store canonical entries as well (matching branch of com_bfstop). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LhhhdjhErC9ZiaS4HyRjsh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
onAfterRoute()runs for every request of every visitor and looked the address up in the block list and in the allow list. Each lookup read every network (CIDR) row of the table and tested it in PHP, and the exact-address part comparedLOWER(ipaddress), which no index can serve (and there was no index). Every IPv6 client the plugin blocks adds a network row, so a botnet could make every page of the site slower.Measured here (PostgreSQL 16, 150,000 blocked addresses + 20,000 blocked IPv6 /64 networks + 50 allow list ranges, all active): 65-70 ms of database work per request, for IPv4 and IPv6 visitors alike.
Change
IpHelper::canonicalEntry()): compressed lower case, networks as their masked network address and prefix length (2001:db8:1::/48,203.0.113.0/24).IpHelper::lookupCandidates(): 34 strings for IPv4, 130 for IPv6). Oneipaddress IN (...)query on a new index finds them; the matching in PHP is gone.blockIP(), the tracked address of a client (IpHelper::trackedAddress()), and - in the matching com_bfstop PR - the edit forms' tables.addressesCanonical). The installer script can't do that reliably: during an update the previous version'sDatabaseHelpermay already be loaded in that request. Scanning 170,000 entries takes 0.3 s; the conversion is idempotent (it also runs again after a settings save, which drops bookkeeping values).bannedip.ipaddressandallowlist.ipaddressin the install scripts (MySQL, PostgreSQL) andsql/updates/2.0.0.sql(2.0.0 is not released yet).Behaviour changes to be aware of
203.0.113.77/24is kept as203.0.113.0/24,2001:DB8::1as2001:db8::1). What is blocked or allowed stays the same.64:ff9b::c000:207instead of64:ff9b::192.0.2.7) - consistent everywhere, since all code usestrackedAddress().Tests
canonicalEntry()(19 cases incl. malformed prefixes),lookupCandidates(), and that every candidate is canonical and contains the address.Component side: codeling/com_bfstop (branch
cidr-lookup-cost).Generated by Claude Code