Présentation du projet
Le dépôt esp32-c3-adblock propose un bloqueur DNS de type Pi‑hole fonctionnant sur un microcontrôleur ESP32‑C3 coûtant environ 2 $, sans mémoire PSRAM. La liste de blocage comprend 537 000 domaines, stockés sous forme de hachages 40 bits (5 octets) dans la mémoire flash interne de 4 MB. Le dispositif répond aux requêtes DNS en UDP, renvoie 0.0.0.0 pour les domaines bloqués et transmet les autres à un résolveur amont.
Architecture du stockage
Chaque domaine est converti en hachage FNV‑1a de 40 bits, puis inséré dans un tableau trié conservé en flash. La recherche s’effectue par binary‑search, ce qui évite toute allocation dynamique en RAM. Le tableau occupe environ 0,7 MB pour 140 000 entrées, laissant ~50 KB de RAM disponible pour le reste du firmware. Le tableau complet de 537 k hachages nécessite ~2,5 MB de flash, toujours compatible avec la capacité du C3.
query ──▶ extract domain
──▶ FNV‑1a hash (+ suffixes)
──▶ binary‑search flash table
├─ hit ──▶ answer 0.0.0.0
└─ miss ──▶ forward to upstreamPerformances et contraintes
Le temps moyen de recherche est d’environ 10 ms, incluant le RTT Wi‑Fi, et correspond à ~18 lectures flash. Le taux de collisions reste nul pour 141 k domaines et passe à 1 collision pour 537 k, conformément à la borne de l’anniversaire pour un espace de 40 bits. Réduire la taille du hachage à 32 bits aurait économisé 20 % de flash mais introduit ~7 collisions à 250 k entrées, tandis que passer à 64 bits augmenterait la consommation de 3 octets par entrée sans bénéfice réel.
Le projet fonctionne également sur les variantes ESP32 classiques (DevKit, WROOM) avec 4 MB flash et PSRAM optionnel, grâce à la même logique de hachage en flash. Sur un ESP32‑S3 de 16 MB, le même schéma peut contenir ~2,7 M domaines, contre ~466 k si l’on stocke les chaînes en PSRAM.
Implications et limites
Le principal avantage réside dans la réduction de la consommation de RAM, rendant le bloqueur déployable sur des modules très économiques. La dépendance à la flash impose toutefois une durée de vie limitée par le nombre d’écritures, mais le tableau est écrit une seule fois lors du flashage initial. L’absence de PSRAM simplifie l’alimentation : le dispositif se branche directement sur le port USB d’un routeur ou sur un chargeur de téléphone, à condition d’utiliser un adaptateur capable de fournir un courant stable.
Du point de vue de la sécurité, le tableau de hachages est en lecture seule après le flashage, ce qui empêche les modifications non autorisées depuis le réseau. Les seules voies de mise à jour passent par le tableau OTA protégé par des identifiants définis dans secrets.h. Cette approche limite les vecteurs d’attaque, mais requiert une gestion rigoureuse des mots de passe pour éviter un accès complet au tableau de configuration.