mirror of
https://github.com/pi-hole/FTL.git
synced 2026-08-20 15:52:36 +01:00
685d46bbfb9d8d98264de80089880febdfdf2e25
`_FTL_new_query()` asks `find_mac()` for a client's hardware address whenever `client->hwlen` is still unset. For a client that has no ARP entry the lookup returns nothing, `hwlen` stays unset, and the next query asks again - so the lookup runs on *every* query for the lifetime of that client. That is the normal case for anything behind a router and for every loopback client, including the internal handoff FTL's own encrypted-DNS listeners use. It is not cheap. `find_mac()` may trigger a netlink call to refresh the ARP table, and the SHM lock is deliberately dropped around it so the I/O does not block other threads. Measured over 20 000 queries from a loopback client, with the per-component counters behind `debug.performance`: ``` new_query -> find_mac (netlink) 20000 calls, avg 66.8 us new_query -> lock_shm() wait after find_mac 20000 calls, avg 107.8 us new_query (total under lock) 20002 calls, avg 541.6 us ``` The lookup fired on all 20 000 queries, and re-acquiring the lock afterwards cost more than the work the unlock was protecting. Together the two account for some 27% of FTL's per-query cost, spent re-learning that the answer is still no. Remember when a lookup came back empty and skip it for a minute (`MAC_LOOKUP_BACKOFF`), rather than never: an ARP entry that appears later is still picked up on the next attempt. A client whose MAC is already known is unaffected, as `hwlen` short-circuits the check before the new one. Loopback clients are skipped outright: 127.0.0.0/8 and ::1 never appear in the neighbour table, so unlike a client that may gain an ARP entry later there is nothing to come back for, and one lookup per backoff interval would still be one too many. This adds `hwaddr_next_try` to `clientsData`, so the shared-memory version goes to 18. The field is a `uint32_t` of monotonic seconds placed in the alignment padding between `hash` and `groupspos`, so it costs nothing: measured with and without it, `sizeof(clientsData)` is 688 either way and `ippos` stays at offset 64, the cache-line start that padding exists to guarantee. `clientsData` is a per-client object held in shared memory, so a `time_t` appended to it would have cost 16 bytes each and pushed `ippos` across the boundary. Signed-off-by: DL6ER <dl6er@dl6er.de>
…
Network-wide ad blocking via your own Linux hardware
FTLDNS (pihole-FTL) provides an interactive API and also generates statistics for Pi-hole®'s Web interface.
- Fast: stats are read directly from memory by coupling our codebase closely with
dnsmasq - Versatile: upstream changes to
dnsmasqcan quickly be merged in without much conflict - Lightweight: runs smoothly with minimal hardware and software requirements such as Raspberry Pi Zero
- Interactive: our API can be used to interface with your projects
- Insightful: stats normally reserved inside of
dnsmasqare made available so you can see what's really happening on your network
Official documentation
The official FTLDNS documentation can be found here.
Installation
FTLDNS (pihole-FTL) is automatically installed when installing Pi-hole.
IMPORTANT
FTLDNS will disable any existing installations of
dnsmasq. This is because FTLDNS isdnsmasq+ Pi-hole's code, so both cannot run simultaneously.
Languages
C
96.8%
C++
1.1%
Python
1%
Shell
0.7%
CMake
0.3%