From 85453852d530768d7445ba7fd4c2f88464c596aa Mon Sep 17 00:00:00 2001 From: developer Date: Sun, 27 Sep 2026 11:20:34 +0000 Subject: [PATCH] initial commit --- .codesearch/codesearch.db | Bin 0 -> 2547712 bytes .codesearch/session.json | 23 + STATUS.md | 207 ++ cmd/fancy-dns/main.go | 126 + deploy/config.example.yaml | 204 ++ deploy/local.example.zone | 25 + deploy/zones/local.rpz.zone.example | 23 + go.mod | 25 + go.sum | 52 + internal/acl/acl.go | 422 ++++ internal/api/api.go | 623 +++++ internal/api/auth.go | 291 +++ internal/api/handlers.go | 701 ++++++ internal/app/app.go | 786 +++++++ internal/app/harness_test.go | 246 ++ internal/app/hooks.go | 922 ++++++++ internal/app/integration_test.go | 794 +++++++ internal/app/testutil_test.go | 94 + internal/blocklist/manager.go | 647 +++++ internal/blocklist/parse.go | 535 +++++ internal/blocklist/set.go | 737 ++++++ internal/cache/cache.go | 209 ++ internal/cache/lru.go | 362 +++ internal/cache/manager.go | 596 +++++ internal/cache/store.go | 251 ++ internal/cluster/cluster.go | 630 +++++ internal/config/config.go | 1098 +++++++++ internal/config/store.go | 126 + internal/engine/engine.go | 1126 +++++++++ internal/engine/reverse.go | 202 ++ internal/localzone/store.go | 451 ++++ internal/metrics/metrics.go | 478 ++++ internal/qlog/counts.go | 148 ++ internal/qlog/qlog.go | 712 ++++++ internal/resolver/pool.go | 598 +++++ internal/server/server.go | 848 +++++++ internal/server/stats.go | 56 + internal/web/dist/.gitkeep | 1 + internal/web/dist/index.html | 3 + internal/web/web.go | 99 + internal/zonefile/zonefile.go | 532 +++++ web/.codesearch/codesearch.db | Bin 0 -> 344064 bytes web/.gitignore | 24 + web/.oxlintrc.json | 8 + web/README.md | 32 + web/index.html | 13 + web/package-lock.json | 2488 ++++++++++++++++++++ web/package.json | 31 + web/public/favicon.svg | 1 + web/public/icons.svg | 24 + web/src/App.css | 184 ++ web/src/App.tsx | 122 + web/src/assets/hero.png | Bin 0 -> 13057 bytes web/src/assets/react.svg | 1 + web/src/assets/vite.svg | 1 + web/src/components/layout/AppShell.tsx | 264 +++ web/src/components/layout/HealthPill.tsx | 32 + web/src/components/layout/LoadingBlock.tsx | 18 + web/src/components/layout/PageError.tsx | 36 + web/src/components/layout/PageHeader.tsx | 28 + web/src/components/layout/ThemeToggle.tsx | 75 + web/src/components/layout/index.ts | 8 + web/src/components/ui/Badge.tsx | 35 + web/src/components/ui/Button.tsx | 72 + web/src/components/ui/Card.tsx | 111 + web/src/components/ui/ConfirmDialog.tsx | 48 + web/src/components/ui/CopyButton.tsx | 51 + web/src/components/ui/Dialog.tsx | 103 + web/src/components/ui/EmptyState.tsx | 38 + web/src/components/ui/IconButton.tsx | 45 + web/src/components/ui/Input.tsx | 88 + web/src/components/ui/Kbd.tsx | 15 + web/src/components/ui/Pagination.tsx | 61 + web/src/components/ui/Progress.tsx | 51 + web/src/components/ui/SectionTitle.tsx | 28 + web/src/components/ui/Select.tsx | 71 + web/src/components/ui/Skeleton.tsx | 15 + web/src/components/ui/Spinner.tsx | 22 + web/src/components/ui/StatCard.tsx | 80 + web/src/components/ui/Switch.tsx | 64 + web/src/components/ui/Table.tsx | 145 ++ web/src/components/ui/Tabs.tsx | 64 + web/src/components/ui/Textarea.tsx | 51 + web/src/components/ui/Toast.tsx | 174 ++ web/src/components/ui/Tooltip.tsx | 43 + web/src/components/ui/index.ts | 36 + web/src/hooks/useApi.ts | 107 + web/src/hooks/useAutoRefresh.ts | 54 + web/src/hooks/useDebounced.ts | 20 + web/src/hooks/useTimeRange.ts | 44 + web/src/index.css | 246 ++ web/src/lib/api.ts | 546 +++++ web/src/lib/cn.ts | 7 + web/src/lib/format.ts | 168 ++ web/src/lib/types.ts | 298 +++ web/src/main.tsx | 10 + web/src/pages/Blocklists.tsx | 342 +++ web/src/pages/Clients.tsx | 558 +++++ web/src/pages/Dashboard.tsx | 490 ++++ web/src/pages/Domains.tsx | 378 +++ web/src/pages/Upstreams.tsx | 584 +++++ web/tsconfig.app.json | 28 + web/tsconfig.json | 7 + web/tsconfig.node.json | 23 + web/vite.config.ts | 26 + 105 files changed, 24846 insertions(+) create mode 100644 .codesearch/codesearch.db create mode 100644 .codesearch/session.json create mode 100644 STATUS.md create mode 100644 cmd/fancy-dns/main.go create mode 100644 deploy/config.example.yaml create mode 100644 deploy/local.example.zone create mode 100644 deploy/zones/local.rpz.zone.example create mode 100644 go.mod create mode 100644 go.sum create mode 100644 internal/acl/acl.go create mode 100644 internal/api/api.go create mode 100644 internal/api/auth.go create mode 100644 internal/api/handlers.go create mode 100644 internal/app/app.go create mode 100644 internal/app/harness_test.go create mode 100644 internal/app/hooks.go create mode 100644 internal/app/integration_test.go create mode 100644 internal/app/testutil_test.go create mode 100644 internal/blocklist/manager.go create mode 100644 internal/blocklist/parse.go create mode 100644 internal/blocklist/set.go create mode 100644 internal/cache/cache.go create mode 100644 internal/cache/lru.go create mode 100644 internal/cache/manager.go create mode 100644 internal/cache/store.go create mode 100644 internal/cluster/cluster.go create mode 100644 internal/config/config.go create mode 100644 internal/config/store.go create mode 100644 internal/engine/engine.go create mode 100644 internal/engine/reverse.go create mode 100644 internal/localzone/store.go create mode 100644 internal/metrics/metrics.go create mode 100644 internal/qlog/counts.go create mode 100644 internal/qlog/qlog.go create mode 100644 internal/resolver/pool.go create mode 100644 internal/server/server.go create mode 100644 internal/server/stats.go create mode 100644 internal/web/dist/.gitkeep create mode 100644 internal/web/dist/index.html create mode 100644 internal/web/web.go create mode 100644 internal/zonefile/zonefile.go create mode 100644 web/.codesearch/codesearch.db create mode 100644 web/.gitignore create mode 100644 web/.oxlintrc.json create mode 100644 web/README.md create mode 100644 web/index.html create mode 100644 web/package-lock.json create mode 100644 web/package.json create mode 100644 web/public/favicon.svg create mode 100644 web/public/icons.svg create mode 100644 web/src/App.css create mode 100644 web/src/App.tsx create mode 100644 web/src/assets/hero.png create mode 100644 web/src/assets/react.svg create mode 100644 web/src/assets/vite.svg create mode 100644 web/src/components/layout/AppShell.tsx create mode 100644 web/src/components/layout/HealthPill.tsx create mode 100644 web/src/components/layout/LoadingBlock.tsx create mode 100644 web/src/components/layout/PageError.tsx create mode 100644 web/src/components/layout/PageHeader.tsx create mode 100644 web/src/components/layout/ThemeToggle.tsx create mode 100644 web/src/components/layout/index.ts create mode 100644 web/src/components/ui/Badge.tsx create mode 100644 web/src/components/ui/Button.tsx create mode 100644 web/src/components/ui/Card.tsx create mode 100644 web/src/components/ui/ConfirmDialog.tsx create mode 100644 web/src/components/ui/CopyButton.tsx create mode 100644 web/src/components/ui/Dialog.tsx create mode 100644 web/src/components/ui/EmptyState.tsx create mode 100644 web/src/components/ui/IconButton.tsx create mode 100644 web/src/components/ui/Input.tsx create mode 100644 web/src/components/ui/Kbd.tsx create mode 100644 web/src/components/ui/Pagination.tsx create mode 100644 web/src/components/ui/Progress.tsx create mode 100644 web/src/components/ui/SectionTitle.tsx create mode 100644 web/src/components/ui/Select.tsx create mode 100644 web/src/components/ui/Skeleton.tsx create mode 100644 web/src/components/ui/Spinner.tsx create mode 100644 web/src/components/ui/StatCard.tsx create mode 100644 web/src/components/ui/Switch.tsx create mode 100644 web/src/components/ui/Table.tsx create mode 100644 web/src/components/ui/Tabs.tsx create mode 100644 web/src/components/ui/Textarea.tsx create mode 100644 web/src/components/ui/Toast.tsx create mode 100644 web/src/components/ui/Tooltip.tsx create mode 100644 web/src/components/ui/index.ts create mode 100644 web/src/hooks/useApi.ts create mode 100644 web/src/hooks/useAutoRefresh.ts create mode 100644 web/src/hooks/useDebounced.ts create mode 100644 web/src/hooks/useTimeRange.ts create mode 100644 web/src/index.css create mode 100644 web/src/lib/api.ts create mode 100644 web/src/lib/cn.ts create mode 100644 web/src/lib/format.ts create mode 100644 web/src/lib/types.ts create mode 100644 web/src/main.tsx create mode 100644 web/src/pages/Blocklists.tsx create mode 100644 web/src/pages/Clients.tsx create mode 100644 web/src/pages/Dashboard.tsx create mode 100644 web/src/pages/Domains.tsx create mode 100644 web/src/pages/Upstreams.tsx create mode 100644 web/tsconfig.app.json create mode 100644 web/tsconfig.json create mode 100644 web/tsconfig.node.json create mode 100644 web/vite.config.ts diff --git a/.codesearch/codesearch.db b/.codesearch/codesearch.db new file mode 100644 index 0000000000000000000000000000000000000000..8ac4f19081e198167c0fb9daf835d22cbf99a433 GIT binary patch literal 2547712 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

5HsKkobd}r1;dXWQ9lkWOiThOQZIJpi z8_e_qDDl;J+Zuuu{)YOh&X@>2b;SJQnD59C_un%dI~^I-zNStQs3fZZoBd4iy=CV#G>G zOY5>)@!ufg>J54lh$f6>uwvy6MnXc+NK~|!wxC~#SLeseT7uJ$-{UZNnfc=?pp&oyXlmVWK!XEYynrVStX%U-qGr%L10~H_D|x zX;R!$*BZ2<)cv(AAC`z5;4%-z29k_=r!cHkEecwkg%KgLJ<(t8FyG;Gl2yvvZwPnb zMr&H*AZ4yGXh`%>L&qn49Jh~+3DshMBB|QAz0;XuR>N1@io2TC{Z$zTr7Zf={d!sS z)YMHaX`2QSU2Ra4Xe=`SUx>;<64AdkRx&X_lDu&3OzWOzUtpS}v7XGp;kcAo87=lZ zmaQpY#jfaOTir7pE?%LC1xBKIurgNDm5L@!zQVN6)M08cc};6gWu{z{(=^Ux#V){m z#+Qvx8h>fL!FZ){ud&5gV?4vS(m2=XGLAQzg$?~z4bNjA;7-FK!=;8jh9=n0Uu`Hc zfX`)U3WzH z1Z?MDr@I7}^Uv08)D`O7y2-jxI-T|_?K|3+wNGn*ul<$wM(qLZdD@`1TDw8JOgmpY zUF*<}&?+^bXx`SmtogI%QOz$kH)t-`oDaK$jT$fP<}cCY|9|&S`HvssugTbTP*`cj zq2F?wwd>$AG67k`pC-%IrmllaLv|+1)wZsKOUT?O`*TOLE7x}&TnwX}#;x_`U{r>r z#sE&Cl!K1!wF-;83aeAn}wcOBk za1ojO^f#63AlgE*l}U$_Vb(H0Y!;AROMh!^xe6)gBVw%b1}N`&lsEP%n#xCjZZ6RY zD>)=G9?zl2G+QdyS-K7ukVQ=PL0+ywJRcd+lYj&D4&ZUfDZM|HBBAE^L zuol{kFKE8%aupuWqQ@|FTCT!lvf8Q)G{M$=oj)jkk*Ew|qy&Bqhyqz;Qx=dH`ywy_ zEL3oljAV+sTnC9~QfwPcS(K~6e+FVk%riR6le!L0*T9KEl^3Sg8emTq$5F~hbRC?g znF4dIm>S{?7N#nlBy<)@g;#yK9SmKfl*!Ej6^N5!jo!2UtyCeIR3T!5S*`_L2GLcv zL3TVlm7WPF5ak*?6DD1;fm5D@XH)4Jiq+C}cpjBuwZDo6oYnfS!*i*T_?lLmx(sx$u7(7M$v&>J(O(U->#LE| zEXoPyVuG-ALGc`lqbPC4C%D?!byy#Ia=(*$?+t3cezMlQ_QHq}zrE^0_*2)8*Xa&uDF)%EQn zl1VAalSKu{GAPo7^RN{lJC(^`8^K$lLL8nvU`)6^=sP=5f%bKHDm53`PeFhCw z=#a%Jltlw3Xq0k16-iqF$6F{SZ0FXtp>;$VX6`yfJ}OY@w4H#;JhYuE)89cqv{n(Na8pt13sTw+N-I|cvJk!qU=2*P??dfW zvTzSlflha*jUv#KBt8_RQu9MU@Fx!hN?69nzFqJCfE>(poq&ZxbEnP%S<7qDMnZNK-@7_?pn1 zsV;3@hkVos(0Z{e&9!@|nrfFm%~q)NU5BbfLu^8uJXA@+Z9*w8u|ex?NB0V#IUm|W zt%RIW)MBECpHK>$sc+W6f;nk$7Aftk#`uS9le!LVqSt}kBUoqrcqaV_Biv*ei{2D8 za2z^AP?E&HY7+Q#WUXw*-7fTVh=>w6O_TrzTJ#CzOKuHB^Ptk%K=ohWi1a~{X}zfN zZRktjEKJYC-TGEp@wKEljc65kXB-mt=V_aQRQHHdsG-)iS~QKC3QRK&Rgf%XdI{g& zTWKIWR89#St1A==?N(8NO`YWkZ>Cy-=M;ZabvaJhYlV$^8ZpY@Ge=9d-$h}dYf@@5 zlaA^}2NREZ=!E%ueEOru!fA=SzYYnxgsT*~cS!}K{)!qQ_Bk=6l8XZR=`Cug zWO9t0;m{8+P?cfwA`bFV9_s(0dO~-mr}tA)wlxXwM$Djxbfw)AsyB5v#1n3oawzph zqGFk$Y@s5l^r2n*=oz`hKrRjSTSc^plA=V)?RYjD z5}>3Ts1HB_RG?azns0#rdZJCC#ONc`GSuWVM%f@LMfD984VrnI7qc%MEqjjyuY{pw z5?pnh%C(j@zlf#k&%_1ATn<-ksz<4Y$X5#ZtL`NY$z>Dern;FPHG471MdTVP9DEw% z86f>~A#tUKAc-tHsdo8WT0s0zM+FqX*=BB3s*P0m{||5P0UuX!wGVIKTejG8k-IH7 zSzg(eR%IpkCfRcL+F&rn-l|<`o3=<=fib3I0s%r5sJ)@YPD~&`APIyPLLh|lCYTTc zD?;cHdT-xz=I-vjYp{{>{(qnKgE`OMnKNhRPP;Q_&cTp@^`I{pvPCL&FyeIy z)qF6@GChlupoQWam%5TVPWiwA7|X{;BG7O}&0S4iRxl1kuu27L%2gkGgX)DWovRa8 zw&5KUF?pIpNT_K9-0)*XU=&qS&h;1lK>mJmUbKK!A5b^IIE)2vwq>d^tm0|LgklW| zt@;Z|QdeD9O;W1vgCsoLtRe=tQQ^>1AhGI3$_*nuOq*eSjvubT8bOWOHQ$F&64hQ3 zkOoVNL9U!wk;_66?p?}B z%+t-Ipi}TMYzh3`^tkDM(;e{NcfILS*!=G_g-p9m+f8dti%k`#nWk|j5jP3m6aOXt z4fY1^77vQoi06r&VvBfk)+6CGafGN6-WUEQ{8e~RxJ~F4E*8!bl7d&*0sDeWgbHDX zFcz25zvAEJ|Hc26|AX~?{x1F?e;xlLevih0-3uRoB6crU@KyXQzL+<1pL1__Aov)yli;daG&88!}W&!hE9Xuu+6Z{FwZd6Fw&saf2@B^|D68M`g`@i z)DP%?qCZ#Pp%3a$(r?r+(^u+e=tt}I@cZ`~W|&8HztJ7gU8}ng`xgP-@wzqGyC~C5 z(23fwV1e;P?UUO3wYO>iNBa})Ik=;{)FmA)&A0gA5hYNlzLzP}8dW6{vBU zMS)f?eoTStD{2*}Vva+BW=&N}Rx;rM#WPsBP@rP#bOjRmd+D>A)kK6$jwIGMT1Mfc zL;eK|mGzCyxn7Q~ImA-o<$ah>$QJvFz41RC@yl*s@`zt{d9FI*mxd*6`EDzHbZ58r>z}rq5QGlH%1acUoUnt$QdP}YjfV-ky z3bfnbu0WgC-=shr*R5Be@uRL*AcO93J`aqisK;#uxT5r2CHA@l_5!?N?cKTl=0p1R zjZxaOpx3ZBIX6ennqtY3#n$I@q{u&>WyL;$66+dPW?3=3%X_^Np6V%4!jg#_vjZKi zj1$zar{$j054(M@W_u+)$INlj@09ok)dh31wLs5z`*O8MXqV>`#j{Q8Ls^O4&K-xc z{m}(yd#ZCgp3lZ3*cJJY0`2xat3bOvDFtd=`o02Hl}Rn6M4FL1SXyQw2Mr) zC?Gn`2?~e-?kaNsL>YP0yF9nZpkWD{(b?=xlhK7M^6BUeop&G~HL*8wtqi&%U&>&Y zw_XMt*F7kM^^NDqpmEs=GH6)xXBmtieWDCR{t_7&bbE4@i=8uCPE_QolXlWJT_EVj z^VkKZeYI@sa?xfARqk2Yp@e?$B@)!49?T8_*`FGg_T>}d8;96mk!_MV>x(BgtbIud z$B)WQ#q6m;*O`~i7pKarRN|ki&Ksx1J*u-)N{n^TxO`c#ib!Iu%ccrq?rN@4pvGkv zDNwPsS%F0U+w7nPzl7MR!H9YG>cU^HSDhu~njLkl{ZGgU>yLFoLQK}CR6jcHc^RCUTA6F6-o1%G<>{{I9eLW-T$-nM`&;w$F3&Z2`c%(? zJiWeA%+pP)tMhc@vd{8#!;;E8y?Sv|p02XJou_9_N#*I1i8BB3MaSoV7ll>1`o%Q0 z%ey+)B`_VKg;*4@Pj&V$6%ZAT#evi-5gGmNx7ajhbp&|rUY!D6b;fN9bmg8K6zIpN z2NdX%(-$ewk52nif%c~{pyhM8FwHB_1)Xmw(D|LWDA0MG0}6C*=cx*GR=Zt+_O+W8 z=*(2Ub9$1e$L`GaR8R7>*yS?lio7I)RHR4-$?&~0NQ7^aK|CCgL0fo=3}T@_${-rL zS_YBOd>OR1D!2t(o|K;iT7D@5UyE4=C%I3N!3nz(GT3qI4Kmoa^II7>x7uW|Wm8ZF ziz*f3EUYwUC(EqU$+CxXg9&aBBr4{7rG%oeB{vk|DO<$8n;Wd)g%BNkZ*pnj4~@$n zz-QP58oNCKns?w^JKOdGs%+L?Y`}Pu?2Dr5E2!`}6evv?ouWnH)9F&vLuvCQG;FLd)rvu*GfJZdq$tY^ku!w2X)UfKSbDnqM?O z4KD(Bn-7|M&6k451v(?zB; zOmWy0IKi~Rw8B(vDm9HY3D_0*P<%~%Ui^#rfOw~Plh_Sw1N+337!*$tw}>mmN^zDr zPBaPM3hxQ82!9j)B-|_9D%>Dk1)YX7gt*`rb_yGXr9!1JODGlu{tNys{ssOC++w(c zzlrbW&*x9)W4wpo&adTb_)=&#Sa~(~A@?fx9QOqF27ble$XyMu1betP&dY7%)^Llt z3hWMy=5)qSjc*(OVSLi~5cC@k7<*tB@mymk_6K$vHy9TgZN{lai&10v$ncus?}k4c zesB0CG#q|nIN#7^h#1_4Ertd|jiJ;q)*$M?)qjXxg6H*5=Lv0_jRx6p4I(Xcc1Qd-OqGAx=XQ%+@WjL?Si($D(nH5>L%iI zORN1v`zCBTJgI$1dx!QW?KRqqwR_=t!LM~{S81!YrP_&Ft5&D^O!Jl|qxq}mkD9wR z2Q|H#%QWX|IyFJf4(uH))+|8N;P&-3VSS17M>yi#*SD7TjyeO5P6BHP1ia9%7WVbg zb`;;-!Dji6*Q54bvfaBkn|^7AQ2m}HnuGPJuYy9mr8fGyfeVla~!_#7nk3`&sn zv{IJSDa&xDD^|yn&=EABh`Bo`qiJjtHRN#B*H=+G^4!WtLls1m=T<(|<|leG(e9v& z=t)GkHzz57=C;-2X=x=efjGxJ4kpZa5++_ja*ZR>#mZYuX+b6QmEbNJlwusa#ycTco}^L(OwUunZNo#z=0fkPp2H*6;AWMUgj%1-4^d? zZFj|yO)qnn?RR%39FVh@PAm9uxTCthonB6FC#CGDL&xv!ppy=tJCce;Is+s|FC7*0 z-qvQK>7WWb(q0omrS{SRG2fMHu8dGS?2QqO zcXc^jbrdzqcm&)b0ucgjEr~cq3{%9;h`%%JqGus`7V@Mjs4&c3eM_s)L$%r4LRkmn z)l}{vZP}+P>pH946}9w`{MPfqkcUd$%-VTpyg6o1QDk-?+~!KRw+CG*;_IV#(UJ7n zgCv2MBuLi=E1GKvdYI&%PFFkiz+N{K)>}z~QLl^MNL`I{5$N4SN8(N`=v^##M+c=p zmC{Sc@l@r^dA+ZVQZw)MX}nwfd=kBhU^Tsoo%AM9HOWX#OM<Loh(woNp zEGifsE#gou+}!S>k)ro_5~0oR)Z*E3$QB1vY3Pfw2D6<+LVF__wh_MwjTOC4`Z*Ac zQoU@YN(^*)I$CPmXwvB2LS=OYViAhDnPRqA*y+J0dJt|21PE-z19dWic8RLoKvfwI z2ZJ<1^sc9Po{*=LDqbpIv5XP&;mmT6}jDSuOvXaQ+#_{a~tK%RHxjYPy~Y}l2ubl zTX2Ntp@-5ul@3IjE9tG<*_(w&dXLWu)r(%HIu-G?c_?KCt0R9~9qYDCdkQY3DLai}y=)$p6l!k4IuAW7Cs|U#1PzV7HmZ?UH%-aCbE(uV4%UK5X^M}zS+ki#bQfC$ z^s@QM-Q}X}NePYba>r^}YSKaD104~{VkTwL+L>;q*G*2v`Hoh~VLIjDPdIgGfF)?p zYEJ^KHs*8c5N{gAYok%VcPdHjY6<(3td)?86ei{h#)C~zX)lfPy-YnSV3$ULiA;RE z6Utk?6R5K^2fg9080(kgiD9@k+TyCGbmNF&OR6ePLKU-g9jq^pWpoXz0ya|xTWToI zXewM=tCtdwqQue8bR9h?q6Zj(N$Qa-lVDZ4Gf0n^x>Hw2C()$tq>iLmufg&jy+7e@ zW(>@XK^vplJQc+ZgxV01f{%GAu|SCfaV8X-qwp%A>(a}yF6?(DJCpTnxH6Jtp#Ua5 zh-o0;bJYcio1VCN)5J|j8HR(bDQGE9+MDR01R4TdhtMQ?_E6cXaD#`k>Y=$xoo0gfoJQFuYNfY5CaGP9Pj>rONGLb5vJNfaoN#ZcnzLpgjpH zXqr|$J#jV@bcN#09tWjwqxAknjCyB}q{8I$&?=&bO;F7)^iBXaK?U1u>5cS|mILpu zqK4NKBB|q1TBY{15-(qS3pJn~HaE3(c2Nb8wh|ggsx?JV0<54IN06kMl6Y`LO_}(? zmlSK9GZD*2u`2COdcd?vQZ1cvj5j?Vrtgu0HiRdTilxxTdfe2;QqZDpp+#{I%}IQc z2E`sWB}H4P8TYU$DUAgW=u@c(ZJ3xrpF(tVG)a=4Op><8e9<^DVpCFxhVGu7lttW| ziicT!oJev<+QYS&HF`+Ff$!=JcD6)nX}rbWj(XEfsg!*tL9wWn)K6DZv-7*4 zsv3<@I`*j)fUPhB%bA#Q4^yF~ZzXj{(3=df?AXT=lnk4F6qC(IjEC8>TQ$k}lFBmM z{5rnXL+1IW_e{USSNL3$PJBfC5zgMN!c*|!w?mlBzm6~F1iutt#}9Eo!k6#_<4fQ7 zr!yA*X}7BG{{BDlG4Ubs9(>i`BHk?ai`R;mix-LKhEc9jv}hI$iw=;(Y@23`(snW_%lN))|0!oXT%BeXz}0DO{Q+{AU8X58z<89@ zSxedK(44vcGIeP5vIFEL8)=VaSazFak}#LHbwkwUP0UZaniJ|)fow<*H}@dRJve6h z0dkLx+=pO^J(qhx%AML|0)E>UA0QXmWtve++mSy|c>kto2Pqn<{g$N%$VqnDknGv# zB!I#T{8Up9QTr^81LPySOfynx{qhI$_XcBXuch_?8M80bScj3)6IOdHOAe4%>@rP( zanc{i(zPuaUvZF(+`{ty5Ly{yw>rA~Ai0emwsCo-P50#o$!GNNS!8RQY`QlbB%jek zH&MRwU>NadX^KmJ*n;FXGRUSiI-wB{2LYaFiZr9}1GGxCSHgssrdVl(_{dr&<;AS& z@^6^EX&CN;*|(q4!ux^OnaYtK(mj?%WH+ zVfZH3mmLhC+EC(S*&S1q_)At|rOEZWgUyV?Pz$awxxVV4pC$djnOt9Z(8stG7z{o} z^%a<0UvbdO5)ai%`S+PzZ#w8vc|`mnFY50fkLjZhh`8C81- zmam7JusWZxdSvY(SiK%76Z47q$ymKPc7EG(GsHi9_H`@=v z=rt1mK;>>s*q~1u@shl@s-=fu?;43FLpS!AIogs@X_%vQ^BIRZkuqCVD+OSLkUUJW7q7)#GJxfol{zOD2|jR>QeJDMRelM!wjhb zZozj5G;C%Fiw?CRX{mbRu`|uapOSqmY&Xa|#k}}XjHUj8#*j@tsZj1o^A;b9BKa(J z*|DouYCOfsD7=JV7fO0dkz&XmVab0WcPaVU!pz6ctviHC*fB#rkyh?L_ku*+vw*A* z9nn=+rjx$J$ZWac$vov7XC54m;rL=2u# zq7#O{4q`l5GDAJ4GPm&s>&Ur@f|dlZ$+S&c_J*+9EvH3i`}{d`UCAgm1m;T?T+7P& zB?mD)5Fe$TwxjczBQ0KY%ZxeVqJtPEmQDMw^<vj2=jBMGF~voli_ooPp!zep*-#Wy#LW9c$qf^05}0*&ZORkta7r z{GniT0DS|t`L&aaz~XXZF?9%EZxRckiM9w>zhx`lgjOIyHV~IFL#P~y3r}VGZfDf; z9NGU{q`F^aeZYE_bu}#gKa4Z|jTVdf3G=1qE#}dt!=|gCrEe7<#a_Th(IPx8oC^y9 z0{NFUM9)V-+d)t#i9gj48iwa05s znnyL~;8fYHeoTF#daYWAY=`^rI~LkkWN_hQS>=#?d9gue3vQG6l4?5)7;g)9`J!t3 zj1`$p{~eE}L<3z13#;wI(#%H2V<`I(N;&39TN3lMOEVk(D+Xl}gEH;%%zDP)m|qgv z=Bbom&T+Wb?r9CH=a}j<>%d~_vAx#>6Wg&;#Pt~Uv@8+vsi#e=%QUgHBagK$qDZ>} zGT_cnLOqRNnOTdZHqDHoer4m`smCeGkWh~^F3(6CLPK#H$dVG1Vrk~~^ zc7<%3GNmsZ7Wcb*N-_(lFA)v3`?3bH@lB~Nwl2@m9+6E`JcOYlp&&z)*c%nwDI z)kXTH8QLVWX^vT++obt6&%)XSlGUn}Tb7}nqG9+QqzVz`Hzab4Gqh1;84z}*%jq$d(8thx@R?Jl)=ylMq1_{!#x|US=$UIBmv=SFgWX#n%A-e(E|KIJP7Bjy zYgB_azL+H+%GP79II3^SL1@;==eN8&vxu?q4Pgr{&*B?KNh2qj2Q8l#^WeYMWcf7e zI_1-7i-Y`t?ji4=-{_ZR7D~lD)>yEuu06bs5@5gX_++A6`S`i~6NBBE&rN^UUUyf!VSQZKz?tc^Exf^(E&2DC^LwFHt1& z8aT`%eV&&BMf!Z=x=hXRiv&I>K&mW zQ^7d=Up)^m&MW|*VYuNf^gO&UGoK|Nig!{hQe!Hm=i$1{JeK&s@H||fDVM|^LItvX z2W8L0i!-+26}iy!a8qV3OaA}D^YFq<8RPX|c^+PznZptfWf8&ZpwRR1;!NrAl0Tww zT>OZ3VP-ZydFQSS(TZE#Pc*`CjangM;7zgop9B?^kI;g zkDKpwvGZPGWo9P0lxd2Gz=atQO9WJRLl)d;&M~=Lvn(@%F&RoN=9t{2sENBYOES|L zhoRI&j>E6=mGLXhqD%?W<2Ydm>jn&Hs#_Gf-=e9{Ok=5sk~^jTMLy?WK=P?bJ8MWe zvpo&f&5FEl<`!k9u=GR8TS|XZKKGlD`(!Eg5GG!H8OD>UeudZb{<_7PNs{zK8Ut8* zc?9hj>N69ieVmKjF*Z%gvnV-d;Jbr zv5{ux>$OWVGuFRA`~QITDov|(zqJe6|0lpA zz;dhIIuqLeoaGD4+pq}ml;wWQt(F1HWv~a3vNT&xw5+!*u`IAmvy8B)%Hc2wMQ_&5O);y>o!H`iXio)Bb;1_l)il*a(=epouP~C{JNdGO}gc}1-e<#{WojB)xM|wm-cVk zKWgvN9@JhBzYXVTJGCM0ZtZq$lXj`r4vPU3v=*&a^RedNn&&i+YaZ0xrTK+s03H}G z9`2Tm6d!iGG+ON6!;B7@Sf*=MZ?mf=K3ZWByn$UtfvqeSfnC)LOED-FVq7$y^v^WD z_FdjPvef!DSC9_1#+T}JIvca3XN99EOIAC#S*55c=awDp8V@YJv{$dFyGM!v?WL{L z*rgj^vc*-|=5KCw?%2gHhrxAe1p45|Kbwu|cW#GX94>SEk{<8Irhnw=6%OgP8vVY! zc60vsk_qo+lj1^xKSvsL7i43&n%6A`E+bq`^d}>Z&uOE3p#Xo7kRBM-NYnNtcqP zXVH*!=iirLw|$*EuF6KWSJJ`vJ-y&#skA`5ytX{Op~;Y^8<#ia>4qh%^7Q!8(glCkTG%z#C)iEPEXLKSSyGYN z?gp+rl}fTQxHqvtfx4pEYGluL`;CfcyF7napiS$~R-lbdxHO0Bn^Kk=*1oAg>lq5`d6j4OM2o{j|x1*)>Wra%>QE>xhB32!UV_@c3LW%yCi`&TJ3 zu6+JZj_u!@_=N)P_Hhcd%d04r|5T53+n<%#ziHjKikKUlCM(eTM(Gy36ti*Z>xyR$ zi{DkCSyLWXpppsu6=?kE5(O%@zNJ7Sk89qz`^IvhA|9`RxH-N~0dcFfUI7PGXTPO@ zxIH^V0byiBy22@OzIN{;>@uW;t~?zj!R1Q{{rGg;7|)~qU9}2yW@fp%4D$H-zkG#oL z!KU^5WU#U62^nly^Og+OH{K?Lb*uj=gS9JH%b;=DQ!;2+YLvn1Mc>H4vEWS^RFqAX zL3ycH2D7HTErXH?(sff-Z{v$Dke?J=T`~}b(K0aT(9&_a8ENcfhQ^T_Ke-khH?243$c;_AbL9HQ$8+SmhSPH7+LaACa?Oga9ND<+ z%pBRUdhv-la%KH*a-?IyTRF0#Y)XzSpZ!ISoHb={jx3pQQH~rx+LR-Ut^GMt zbKCshkaNci*|!j@avuLPc1;yl2s=HM&1vV3AY(<4p6J~H|Ol1(` z;u=YAf_oEA8SM7GB7seeu_+~kb*t}{LDOnM25VQrt^jORux!^Xe^~|% zODD*{vEV)#RLnU?2IaFqkwMw?RvDB`xLXF}N8Q3MTvI-gZa^=&;Wlt+% z!;*3(bS$`72`kF3Qo{1tuPWiJDFshUChk-|9bY8bi^_^oY?W@61L9VBD7|L+eNuPK z;+6GSg~3o(?s>(W%W@3}<}qLlAuP>^r0}WQ-!)bm1tJO9ixh=3vM8Er4(#?%P@s+L z_A1bZwc{12ad~!46rprw(@)3>5Fit#Ugrt7W{U&+u|9NUpS18{zW?yau>TSzM$gMG zQ`qypiR@yJq22!MQiP#h-rr<}AjXZ$vx^<}Y-N3q;#pO>WG)E@_=s6icCO-Cd8tL} zs4!Q8%>O6bJ)0}$yqGNpRCi#Bbz{@-nLQ65jst+1MXX|F4Da|+_G~XEGdlB+_*6p6 z-hRYSXxo=di}BnC)%ek=Y$nnd7WIeUGP7H`Z!VbKTA$5Tin2G331Wfjc-31f+!udV z`*Yk7-=;0qe5rX7Hsm@q>orr=AF3ZwU#E_$SE-9tZ|V2qYqV7NCG5%FU`;|_V6^4m zun%~lWv9hv{>uCp-1U!|mzzhL{$;uyHvWz?%{HlVbN?>!C(!3#FO~{l;4Z;U!s&uj zm;>(ue}i?tGx_8Ba^AoVa=+!Sfd7EC+;rnt#>2*2jr)yW<5J^j!<&YOach1LzLm@H zjr@%M=ep;0x2xxz$+(W~N`wMig$MYTP*nQ~d!{B>x z7;z7jYPWu0KTZV~Y>7vkaT0-xHi^#JxBO7NVdVMXFycNijJWp?Bkp}=+T)H^ZWrbz zW(b^0UOIQkG0TP=bIy=smJT`Q?CIJyM=8;Ix0e-VLBR+vH#ofPrbsMB`s5yX09#X7XLy9$XNU>%NDc1BM#VR>^yI2*CrR5e>x^T!b z>xUe(ZpbkmLylQHj#)kAm{miLX&-XT$|1+BDA%5Jl)k%)ob<%QiY`2VhPLTw zk>TKn4I6WZ5T|SiapnvmPU#Th9HX~w z6I^CF*OG=ELYL(@OB1vaDlM~MhtLe~1RtB3F>N(9nCeaQOeN4m;Ki@S_r+Jl=dzXu4~RY1e_Efi z{=s^;X`kt0{jc>0^}YJb_2=m~=$GrOaXxR=YjvOM-qK~nOU1Kc!ypLX1)If{VvRUQ zoGOlm-2$EPCG-{E5C(;3g(rlEg?ohCVX5#+;cOwod@rtnox&REEKCzd3mpGBJQ=*g zKaaZ>5AnBYR`WMQXW=LOh5TMVr7wji#!c{LP|cUZbHKCE2)Ijkv+io$`LG4ptlI(4 z0S;IKEY|Vb&$R#1{u_5N9)KOdo3-801~?1a01>TMyHmRb{sR_6A7GAl3akODH6LnT z(L9TL8uw~$)7+@JR&%jtpC$!sfTw7-T3@&JTd%NQAnmV++VL7mRd(JfChbJccDSrs z9gLUP@d3>xl17tdEk(-GD`i^zNI}1&pkG(ehZXdFGOeyx&5|H{*-B8X0HYosr>&xBE1>mEYV#Csft`hE z&rlBAVg6|Pl{sq4>v`&LBeXL#+vDjiFdYKDhQQ?6R1e$ZsR+5DntYs9TLKgeZ-b(4 zuyeZi2wY!?OEiUe(z!?AvkLL}^NzsoBk=Ac@UA29DTR2{U?JvbeLP5XInz(fBWx->L2ahP|yA|}Eg0>hL<8XJu4KjI=OztO++hQ zTK>0J^VBc%)X#F%l#g@Na{YtOeVQJIoTtVr{qcTgBPd2)KT8A6q^B-_1+Y*+ND@)jlVD!`Oy z6ky{26ydyM8+y;KR-nJ25v z+3RxCil}tkq2tA|2FIu;^1t1kr@C{L_M|+uc%*igW;^T%(O|y`7JW)m)QYxm-_RJ1 zPp(nWc1p7i&Sm-kWmJbNHeLD+)WmCOrrVYZhh21bI%*_qim9-@rgqY)3i@Q3p0JD4 zj-n(}7G{abUuTI)r&C$Cr93$6N=$u334W&pca7HC5Y0_CEMa_M6>K6Tr#4cF@;}0{ z_(X>!TQ=JCiwof78>CF#vnz5$d5)NyC8pnF{8QmO<~6=33Dm7q@n#-F7CW{VOS6~Oea61>4GpJi%$Qb9kVp#P$v zA6L+KDd=Cz^xRDfnza^bcAQ(S_6(hkM%F`1rylY*Y4peHKmVg+3!)3YYa zbopfp`g)n3u9%6Z|4Z@vpn}eht7H^t`acxEU!kCz6m+A4ULw;aA1mnVEqAIyQvFPO z3H0tP{Q~IiS^5mnYqN9%=*3xjCFqJQT>*M#mbQW(m!)-}O<7tk=R5T(nV#~Rg8r+5 zUL@0#6bp|@Cnf~P?GAXZU;BqIo?3=>NWOlYC4jSw0x#lu&C+KW*nYRLT zh4iUpJxoQ-((ILIX~hsQPtjz{XUSDlK0!glX`Badz-tN z+s%zP{?+&+<1)hshMyTuHH^fUdk<{ZPts*{*T5pZS^FpL9&L^0O=NOr!5{mOTy@P# z4!0sF9?O7M_VPpS)`JuJUA_bsP`<=GvhS+?as~Xjc7sdVu((KGOxb-z_(;z)D+9BQ zU^adj%-D``v&`g!#b7era)C(_ivk4~auECAFh!9nOTh#;Jal`8$7K7F<#`t6(ba*; zFy0d}DJ;*kD3A7oA&Ii3dkd$ksj0y`$Q?J6B^>4$9NS#mT zCG^Uoykc3|z3vA^Dd3U=GLvVER(CgnN!c+)$>)AFS)M3b*u55PrcOOdi8kQYBYlJ< z@`NnIpNbZBuR-Ej)aJjhI7`7O_X^zKj7H?7zY}Y_S5wks$WHQpN9@~+)^)E!!UYSCBKC2y1f18p!g+afKdg*K zlX&Ec$x`N}T^eW_APG{8BJGYMalcl`1EPr0sv1&2{3c?j^+LXhT6RVIdo+ z&LpEUm#c-<-HV4W%#rWyN|b34*w~IH%&Jh(7lHSf>=?e<=Xa$-_zW+6X_t>$*}ah1 z%s5J`Jc5k`*T9mUqBUM7Hg?w&6Wef@?KKHzYjLHb4v`> zxx&(J#}FAXE=ShKIpWgp+95Ld-n!UVw4}R6Vo+#mE;qp{}ctQBS zv2k^jj9IS=_&lu=dBg}67ngKb9ZP`kFkrm$0>p}zciWNPR&q=M@^4RKS1?4k2o2qp z#KJZl7I}_&QG%$;3h*g8c3n{3-&++faZ&dIN`LI4$mt78v8!lJ_k5(TEIUdm*tsS- zfzL~x|Aozb`Er~rGOhZq!a%kx-Lw77c?cuYNN zOK~Lv?kE&W@?$jHW6p}O(6YR{l#ZJCCA!xYs!a>J+IW_@)FdKSl&H*s4Q3^ zzQdw!#G>w5#A3z|NrA}#TZ>!hI&fY92NotXDfRdtN`1t#5dl)<)|h zYlU^XwaBVvXYbEh{tW+rw_1K`x!Q6bJ9j_Dve~lAQfskUrdUQi$pjlduDD z7xVvjf%$ZE*z7WIGp{z+nr-H(<`K;M-X_zni#j?h@`yF3APB6SxiBQqIoJ<|c4v;3=>06&L)#mjZ)>AG|g-EQ4>-CEru-FzK9v*|eP$J$r5&uO2~-lx4y`%~@J z+KaFY(+2Nf0560P?7lJINk)Fbw0irwt>#>j2Vz$Wry;SNTeCS=6CaCj5s*=S$`Ir?b#qyoMG z!Sw`#t-gexyzUIFBl%nb=J#xX`74ZekrSc;atNh{4>zrG-@qF3`w=FmI|Gf#1|B!a zhu8q~z7a|W+Udb+itno?S0@9^7gSe(JlG7Zqzt^RH7wE!iWGr6ATV7{Og-d(ZeSVx z40mJj6EeVDK>6)KI~?{P))I;(NyNMpCgbGNWndANy)}^Zlas)Kg_J(pOb$o}nDZx3 zT|32M&Y#jDSB#}`P?~nQ{w7yb1GQ8SoDRiv!I2Q(JA6T;L2;Q1!IN$aTuV0^-vg?I5>d1I+nT zOR7ChU>-e5rr{V8Ny;fnTawi-^ZXR-Ah(bMb4lEm&e}Bj#2a9~pW>CQ88P2aX?SGA z@1<1qmReTy*~BT(L2iczm}|mx&__PF24)hgRIA7BrlK<6PjCW=Sku|d@wJodsDToS zRom*VCm&t|(}-CJPGC?8Q}INd2*5CclfxtCny@((A!d`Q-YQvnnd2vKa~nAa8<h*odM!@J;r?cEzLtcpAe;SDoPm_qnycH(A0S7s`>QCc=x;;v+lKPnssP<%n zTpaaxPzvU!vY$CAY;B=8+0Pt6r2m(kAsR$7-od22k^@mu6 zC2HEbYSH=dLo5A|in%(w;w|Lku)l?(x1`|h4-y1P0_-%R!~v?xU_}_O52%??z#D1y zQ#3zCONWS`54o$Q%Zv$U5HYshp>vvf$Dx1yu;@ZT%-xs&v9l98MzI(@Z_AeP3OZKk^F!u9BV{hR1b zC97IG+ndSJS^q|Ql%SEie*-0Vg;`bi;EUBI4*1d?u6IOYz@ zlcp)8e+{Kdw2;rTel{8TaIYJ50~NG6%BpiU#p$eIZIaDJogFlA_OGNko;1yA{WKNv z%(rGg%|z;s7;CD_sO;`mUjQDjkYXu4f}1Vs0nGbTTN2(wQAdj@Ua~#b;ihS{e-YJD zxGPA$&-&SP6mqdTuctbPCo30u=IXB_!LTFm9J#OGp__&2$m^(1y6SyVKWyrN5A#Xb zYKI?Gh{)!oSUZu`ByBQHwOhsdLEMd@!$p$Vk%KxJNWq(!4!x)nm4{VAdomggF~^hr z(wr3PAU+F-PiGCapZO$NGVZQyAujW%JV9?;XN>%(_Loz+s~oJRY?P*pwVAn8%+_{v z3B)O*IB>Cw$-I9K#qmX{8<$cyZb`J+T^-&!R%$jcwfZCUbQbI6Zcj_KBWY(ZWhT{0 zON!jV_0J&w(GbiQ0kFv_9Byl)+A3kS)gEoB3EIQecIo}IIVu_PQvsNJ!ZvqXr&9bsQdvMjr&JaZeE{*brj9jRuaSqhptG%yyyBb$$&P~@4+tCCE2{>^97r!yNJ|Xk}-EY5U6D0OOsO~ zj(3K1Jf-u**r>zNJMU_5Pcx3pfi4VjQ>$VQbUV^r;ffkIhA{`aDQSq*QL2{KdN0eH z`6mpuNL^b)<&KaO-+ncPqH6n?Yr>?zC0&m+eS0X4 z%O7lOWe-nh8O3~c^hWxacfwG8J4NiGh%GI#pqoauJ~lC>Voq(*zP?UfDVlV!J>_d} z_SUsGV>(3)nxWK{4yOR$zRXFXJKaw6QXiY6;&B>~`{%$J`YLQ%PcZGQE{lXGa(l z1%y6{37rTuS9hV}_w}(EDqLF`Vh*;M4_!x3#|WDS!Y|vTTPZPp>_X)RH zmNTF!;I-_qtb@jVg=L0itf1pR<=-^FY>F`*TskV-S9`y$k)S~z*N47*K?n7Z*ebj zPir2~+@ZNy(+yqrGc^f~Uvr{n1HNtT+5zE1;Z@-|;c?+U;a9?q!ZpH0!Wpm}=!LJt zbwU~UNA7prt=x^c192gD8W+Y5h*P-ZxQ$!`w}h+V=5e#Q$*=)v=Jdv|jUOA|F}`Aa z0eb;|F+Oa(7q=k}8E-W97_a<}J-{i((MG-D6T@qUzZ)Jk{MPVu!}W%X4QId_;BMT6 zSZSy-%ruNK81$d&U&n61WBT9ee*t|8+6#!m7NAqV3O5aA>Bs7gy3cfP=>DPmv+f?< zA?ySESa+tbP3MNj#cExR4&HOI2k^P}P3`mA$F=urZ_!K?YMJJLyLP@XSs1Bp(VnVx zLi>NAcDi<~R?vK-`9Slk<{z3TG>!P1tC_1JwL4g2_arw(y}q$`Yr9pP(-(@8h8j+b z!oh@Z>^DmAr4oFq1Rp8^Q*p~Ncw7184JCM030_u$K_z%j37F=L)8~oCy<_hr?UyWl zhk{Pa^q6N9^nilySI|stT;enO1L=3VhE$xA;}}&ktt*jf^~DOBDKklY)aOaR6Q8k% zWZHVWOsg;CuTU9L{fhDxs|#PruM6RAg|Mp-ZYY3bJ}-oy6~a#o;o(B~w?g>WLioRh z@To%hXd%3{5dN|d-cks=3n5nsjfGHC2n(xjOkv|5{cSugpng}%>O!aKqjxHO3uwL?2=6moU44&qy%e~V2u(qD!>?~_n+l9hBbg3xLFzP zCM7T^z-YG;oU8;plwgzjUDfef)}zuAom-NLXAmN?S%t125V1+s5>PiYt{7DwM#c1ap*NmJ&=? z0;W};Ekf}m<&*JBFjfghDS=f9L?z&qKu4DkkPkB(vmF+p#@sO;%BuKw8@YSZ8Bs-n+(~|CPOx~$&d|RGGv374B2QU z!;OVfRTMz0z5rqouPlOvEduhaENl@VL$(Nz;U|S@KPrT5%9JC2Q26xyLik=Ge76w( zrx3nf2;VA%Zx+Hg3L(2uN_QNConzKeYnEt>Q>Jz7=799O?gbk9w_wAmh+PU}6uZdD zs7d*!6Y|v9JY~sKnmom>rBT|EpXPoW`B9#FKTo}zr{2j^Z{;a=8;WsZ7f2cP@7z;rz)aZq+w5rCbDa-*=XWOMKq%{Oi0mGk1L+2*lIGX2D&Xd z;xYF2C7o2jhYO&gyb#*x3hWkFl5Xm)4@SJBCNs{sNCwkAV=qvG^Aupr^$IZhUAkz> z97;1~8tb2qz<)dfKX?Q_a0G5G#JZ_R;K@he@kij|Bk;&0u=NPclm7pp_A8b31MADy z!;t@X*a5h~dbRaJ>lxNo>nYYv)>YOT>m2JutHr9ed|-La^1S6q%LA6%Ed7?Bu=D>` z%Wlh7%S!A4%(RTNa5(*c$NVDm0&u7K2J;o>3(W2K_TOP%XI_M}|A}Va^d;^&4dV9w zA5Hg|ZZ-9rF2`4Y+7vLIYI2%ZnW{{srm@Tmz}wo4u@&S2zLu3HoZ#(T<26{xo$L;amsyIlUpD-3WL(9>x70J6$x0VTaK}djFB6 z9ZgHOo1Xa+_Hm%MV}mRa4f}}oT5R_DIz8ah%y1o8l9HM)VmDY0duZ#QdG|nHwi`ws zcI#$fC(nnKhNSCn*O(5wu-OIP;b_ul*YbyV)Balk_X6zV;aw<(Iu?QkqFpZ@K9zRG zVr($9n-8Bt`;0NHhhoW4+HN|0GVS%b+=*!1od9H8e|}dm1e>Pdw3E^%$WvLu&K;(m zKea1n*9eDCpqdK%yg?UY?V$XaBWt^cKYTp4IMq0+wU6Kq)9#--!cDvSkcpaVm!}@E~WgScs9gHNBWNkI- zuNMYs_gGEd@9Oo&L3X|wjpOGw`Z?kABHZMIL~hP#p}hvAbUfuIF#*x=pa*FS6f|C zQLix$Hd78&UZkc&Om$^Ny}>l-qj&EOHV2c5dV?^?jxZB+i5JN|#4Hd^#UUX#=%z#w z7jbeCr|JNHWapRF_6m@@NTiDDI+TFz4JX~8PNA5sZism@iRp^RUFmxBAhiuN%P{m@ zlJy#Ha3>R}x?aN%(y1lYPdz6LoFS3u zS#Q17Gs(v;} z4p2T}u!#yEMsKD%V`?-NRrMP4;2Nq2$cWEkR{f2X1^GCv*9n6Slqg2;61?gB60N+W zUdIp8`K8)kh3eu4SAyni9JS!fG-+IkdW~gpIdyxwGUST;@WxDo%UDtTo~o*I#%^G36JB(F!Uo)24B`qwPL4goRWXdJkx{*1>ve>KK~XeU(TO!qrj1 zTd=GE?I0R&DU5VXp(f6D5%Hvk#K!ngZ!ry4)5{Fu@EkRQ)=erkYP`r`5@odxGL;$_ z_=VaiT}*d-aJ@A?~KL~8d@MIsnn>wt~B}!H#nc#ktb585eMf{=wzdF<4 zY!aA7Ow^&i*%2nSXJ!ev&Nw)e*aML2B%~2rJC~w>AT$(Lc|iOU=VQ{ zaa1y;*Hn7GM4snpQ zY@j#=HF<|t7@RKHLN9xqN!R!N$pq)+O=0K^n+lAah67PA5dpfj6rSO>>a z_j2cMqBu~YW9WGY4j2PThk0-`8~j}`(;o7L9NZu~)ohC;9F{@YSBC6397FRDdGTx{ zy%kr|p*0V}h&YXC^tJ0H`K(kl7c8wf&>P4=wb~tm^(Z{#xj}Zk>52tWNE6k!^fn!3 z!k|dSO5pp^2T=qP1@9v0MbVHyPx&WOZmCbTix!5l9Q>dL^79GIm5@VCa&*LlNh%$( zRZ)ep>A~wTW%d#u={2DuGG~w!Xfa_-PYw;A*+ZQp8I3u3OXhTvD3!e)yqO54ajky4uxG)JZXh#DOD(F2hrt%P+? zK0^~A?@A@34r7MYcA&oGuw-cJL(P#v6pW6jJf^pkfO#WG!lpg1FOsH$ZX-$9ss}AU z~*HXFNn4DVCHc)Pw2zifm zg$addgxtI*=*4TcW*Si3e0M;f6f&#nF*sp#v1V4$V+`NY^+|`8&#WZD;uyP-(F)2a z6{Dd6uh5cVGh-rqBbD0FGO8kU!Z@pcQZ-da{eHxtSG9y*73N6{1Q}BAQ75n(!k~jz zL+U+hR1=0-F|!cQ@NQ_ehdk?9;jmZXb445@`3##LqcM!-e1=VrG`K+WTI#iIykoaY zP{TD;4N@Ld;cS+a<{Za1E>lIXA|C5PeKQRomeipaGL=*xp(sojqwXpQuz?0(0Rdkp zmRV>w^Qql+(v12$@pKEdc8;31mH+D#(j39jdKa^n_iB!jqX&)nNeDiJ2LAqQ)qYLeJzf)2WCq zG+tAtgz8&r5)Px7na1LwmnIy#5t*qplLmY)s2WSN8<$}!sIerC8j~q*jJ7!_Z&E_V z!WFNE<1?h+qmH3EP>>1Kor7o=LWZgL(AtOk?>I`{M$%GaE2iYpNQkwMu_TnVGNB4% zb0Ql&F$iFLc%$JJ6?Etg_?rGqcwcx^cp3imo`Ej?BhaS*4bH}Y4jXkn!d1eLp;f<6 z=n@h_Nbm`#;+%Yo&?KxB7D2;)9(3%d3gd*4f*@%5ui$O(Km2R_Apac9&-|JH1Ai~R zzkdm@djotoY}oyXKbJoPU*a)7$h+}1z8(7ajr=mcj<19c{tSK+KZdvPMqb5z4o`e< zasTFC;0|+7a)06;fS-Wdt)FAR;w|gHtuJ8D;z{gUJYfB;^>*A`xY62+y^Bk+dvTWa zGk2_mWM6B zhd+Z`VO8*dEZ14Cuw0BCj=h#nXgai5JeHGTUvQIUjb*u|-eSjXhnbeima!JAg@dKR zFU%jB-!{L3osVbDPnjPzKWP3PydWMj-(>DHUjrS8{pPcA3nB%p3eD!-<`d0MXhN(u zFTs6?1?D;C67vM}D6XATAXhVg7WboiSb?I>#z&?57>ox z9NG}SH{Jzr4hM|?gI$v=uy1mnaj&rxHX>VaQ{rUfamG!?HOA$}dZQgTCT7B4;#hc0 zE6-3iu)IT#|@0fuq$(q?oQn; zu)El=yB0SwF4CQ&+k^d?s4k#$!6)N3-3DEQZYeA=R_Mxf)8U(Ow9c$Ez(3<>+V`QG z@v`=x+GlV_;}Pxs+TUn@1^*j2XnV9*sZ<7-Vyr43DFq{>z$yh6DKJZcNeVyekF&k%D)m;B6^*OA6kUf;Xh#bt!mF3SO0hSES(IQt+}A z{7VX6l7c}g$VkD9Qt*Nl{8I{^mx6y#V7K*}-q2oRxAh=6-)_4e!I^g3bqLaSTQ`EZ z-F7X4R=e#Q1YW!CY6Pd)ZC4>U-fp`R!DhSd3IuEIwx1waVYgk5V4>Z18GR`|(-2&1w{;=7+-^%FxX5nnL~xGX)`4J;-PVqv-EK=Eh}vyQ1OdA(fxuD2lV#NwpN^CR{ zVOeZ3Cb0m!AWD-36^#X35|wmKqG)di86fk7;uqA+gqlZ-i5=IYO4Cpp`SS7$YdRPU( zGJ06R@rC~1(Zl?J-$oBB2Yf$zSQ+5R=wYRRk46t$1bAoku!VqEM-N*-&6tt8g<&(p zCWeg+8yH#`)-$YQSj(`6;WUQT467KL8CEi^U|7!3#L&nPWN2Vm#!$~t$56{q!%)qz zlwk=&6~khNN`?xC0E3^QoS}@NlwlFWLI$OJ<}-CF!zm0WGt6T+iD53oi41cXW;4uU zn8`4Mp@hN5P|V!~O?Xi;UDE3}zU_FpyyYLw|;T3`qoOsUC*D41E|98G17$ zF!W*&oi;61blS93(P`6CMW;{C;R%Mv z86IPJl;IJE0}Kx{JjC!I!vhTa8SZDekKta1dl>F!xQpRVhC3K;XSj{wR)$*`Zf3ZN z;YNlV81^w-&u|^XwG7uVT+MJ5!<7tIFkH@X8N;OvmoV&Q*u&7qu$y5Q!^I32F>jH7K>vZx-OFu*b^j->7hI3J?s8q{J_o;lTXDv}&Q<1`<(j5= z)$i$E3;X_`oF6)0c0PvRx3s^%$=QHkv?b0-_$BLscYTB7N5{uvcmHnK^R9cl zcAV-ca!kO9{$B8_|C{|Y{g3w7?2p^;uwQ{+qU&MLf2ugoKLUR8yTF?N2YiEg1^)5x zlCOa+{}y?LTp^z*=gOnu8NUnc_`kNjgRctr+xEeRf4gmst=9b|&i~V%eu}M+&1wA; z_WN&GpT@U>>+t*aEbCfC7F=L0#(w@tYagpi`UjT#?@5R7+w>-!(%&wvma3$=u-YFl z4Mx-g8-9C!X?Y9r3hseV!(Eo`IG>0kW^rtk1e@sR0Z(`}|JO*>(yztXhCbP9eGPK1?yACt@Y zkMUdM2gVnTj~H*qFTWke&Bo=%O5;h!0-VYpX6$Wr;#B_E29x1^#AAHeaGT*u!%oBL zh|5@Rm}$r{j5Q22^gu*{XWb9EZ^ki>WB!S-k=P~2UO2wGB4p;C>a!bYcPJF&HFm+1VDJm*&;^@%B@uAG0lrSrlFG#4i z?c=4mRne|3FOO)jd)Q<0MxGL|R1^juFhABOt1VqnAkNmV_8sf&zjlm~%dWIrb zm~ZWnGIdH>hm_RhE*(0bW*P?lsOEW7uX@!A=Y)VGR=t;N*EDpJrXI*zeG(=&%0br7UcY>CZ|r` zpe9q3Uk#BsHsNom$qzjon`IbCXyrqZDX8hEBU3Qvl`EYU`)G96#p~XPOxU_AAu?fo zQ$|Q@am%`3FoIrH-!Fo0ta(3z4%XZlK`*Q689~=ouZ*B;mVOdJpSWOB1f8FCO9Y)a zaX~33ii3sPC(lHV_GcCF9j( zYVv$#Y!Vk6nCpUPD)mnZ=pbmL#gQqP{x&N0t;k%w?(fKi9c!h?gssh=DJAAx76pnT z=+wc_D!rKaaa|@Vg{*9<#up?WM>BiwT`lOgwx`z+X5uQI%<+p=jEckOU4`;AlZGKP$aMN_P5J z9a7@Eex&45(S*|ul@?P)=#_&UPtii-QdEUNAefyIekGyfE#PmtMp+Sw@7L{EGgKw- z_ZD2ICX1$pR%RhRJ@-pBH#>tPpyPdq^2$hkSItdLUZE!AyY5#eL=x8RIPD9i`G`zS z{z*j*>?00-VAck&wAx$HsMLaZt%BC8YD4uBN-3WHMhBUxQ<6HQ3?Ce;G?KV05S*TO zTVz5(&To+kQ>RRbOo)%YEF!_5pEWSl0OFnR3f-2_?8q;HSn9V&NMOQxIU-?~ZvEpC z2^Z_uF9|i0$n@;f@U|dcV>r*vD-99!`o@EyswVk$jaRA3RdwNpAnu|-j+(pB|C5?r zPUTN{4>;HIH|Pq4TmX~UfL^k z=o`E2AgIW?Ggf{dzTUiYsxm!Stgf#JT?UqPQ=ac{TDc@RbM8b3_N8$%$eHtchk4}z ze`#fZWwiO5%4q?-Um0ISuBzLqqDm{i31w3iEX+TpoybZ*yPcRaendA@e=4`Xs(~sT zzj)A3uF# z5jbsJn7>Eq7vfi&Zu81MN@WY$TX00F8k{d^s1r4g3@c>wL%Lc$ywyMIKJ0$PeT93I zJK)I0KC;FBnf)o8yWeVGihbb`IBWl{{DOR|e4ZS1=eviv?XIt32XHHF0Gi+fU=kwk zIj{r%mh*t~TIbm~@joBC+ryk)5ozxO$CHkmuycKyqg=1k$LkCAqxEa_e*IJWoAo;l z!ws?eKlFzUPa1AAY%?r2af@`_0c{e|Zb`lcz|D`0f5Wq70sEskIbZk}YQQhdAN?G0qL_ZAjsh zY$Ge{X3>%EhLOPlg-;VUaX8qRLY{2#Kln+;&KRc77?#c$=FS+_&KOc>40~q`xif~X zGlsh}hO0A%vonT+;&_KEk zbdj9sBH7lxI#VCxbqKo*Vixfu}@kSRZiY@|kRsE~l3(Jn^xm*xkdp9$5#?W`h&~?J_{M#AhpUxP6 zcgFauGsd5tG5+X`@q1^C-#TOb+8N`Q&KN&;#`vi-#*dvbe&~$xeP@jCI%9mBXqb<*G`Y()xlNkfM(qJ|t~UD|ZT8vP?6b7ltz`di zaOLZ83O*kv=^t_5=)TN-wtFMa&R4ombWd|p9nc*G;ayuJc@* zT+3Y*u6eFP*Em-)?EW3jf1F=B--Xxzhn%-LuW;^w-G8%l3BCh(om227pqJC-)H!~@ z*MR374>)dcTq3Ogm&5A+WQW&5{{DM8Wcd2~!TyQ;b$ofa*S^nwk^OXgv%S(j*FF`e z(g(uRzbyYPe)_E>oJ`x&R$ z-^7=N2c&&CxxNJ_)=Q50>qokNIRyWh_!hjaF8>HKD@;_7`!4i}o5gOp@9wuxhaJIU~Bb00; z!M-F|7AP;pegg>#8(P>Ym6cGn3Iids;}4ct@Cf0io@}s4Qn;zdPDG`+PZ-cvHdUeY z;Kkz$tWB7?l{j1W^dx(_#$Y8JBGfjP#J22-gWp+l+E7tdso49K7@!l`(zY8>mbhE? zbZ2`_#a>uwM$YRM3)d0@M6kQ9SWJmJrn|aQlJGGAui~|pltiDT$p-_zLefX^5;U)H z91Kgu5>$v=R7jAjk^Bbh>sFSRn4pJ~^jKV1w^T?uNUE%vZpJ57Sj5*g(KUUDCYJ+r zZG(uuAy{HWP%{-2T?n7lpL7w2?1inA9z&61NG5_t4*f z{DbI_@TAcMBfX$VXrSH$Q^Trq3}$rMwq?`qGlba7JUL8rJYmtKq>fmj) z)WPdua)>nay|xh>~Tk9!?<^H;Dn$R!QtqjA&?y(o|4sgc&!rrK_baK%D^g+3;n;t=s0O*2Un1 zvQkT1x#)aM*`CiDMbdh)O(j>cm>f*+7?kSX}3^EOSh3%d|O3RwWy*6q%<}T zXg{JPrloB@xd2y21nZ2%Qz;P!p~6g$Hfl(B;f+KwJf{Mmj7P(KvwSJWIf{rHm?vt0 z%)Uz`JXe_Bih&It`JRBwe#kdcnS@`G;0lZ-5p#AH24 zsteB(RTb2`W>CMZt0*y|EG1MH@*aS1y$v*xwfU%yYD5PX_P4Nz^x;unYL%d{u=XL` zOB-3>!p^aw(Psg-kSd2N14Gk?LJJoZ!gq^c7Z95~Dqu^SG9wdQn;0j71|Le1FPgBn z9I+L!ukSpsmhmQ>j^&NP?iZ0 zMrj*redsqQKvv)6uP4U=K57H9zZHunRB_^FaT27IO>ErDS#;zu50}Cz_HX({ekkTAch-N));Cs?5~P=xjqTC zKua$TXX1{cs%)w)t0Vs;ctlHED(Q;zS`DJzgjFtVsz;5Xh8RhjvmcY74>^sXoN&&H z)E-VvfSUGAhE~I_;ku%!wi=OpNK`Dqs1ctVIwYe6sOf4N11JH_Okx?X z4nRi`!k%1YnMApu znth4LlKfZLmRAK@Q|M{5_`;J(mFQ=}fd!Q3b&?e6O}PrMIzA&RJAqo4 zt)7FTxkRWK`W#E03e_7=m5(W-wy~=vemtlxe)rrM+ zZ0cBQH{qopzILchu^kH?@ajaBkJ;Htvoj3&@xVr56pv)wLMtyk4+$;pbPIYYtonUc zR2nV6`kJPdJ`0Lqqax6B<-_vbMiFH&57ah_!b_p*Lkr?Qi@2|JrOyV!3`yZCikg8I zT=XC4j7k#mWYEdsLKKyRA{(e1DsOvKX?hw4@DzfuBXCHAT5D<3iHfHc6MKBrJ$A37 zlBADKA4{d&%}Xyi@IZa+7E5naz0c%q*-b7j!oH$>F)h1Sckn|+Mc=)O3P_VB%Cozf z>Vs59|H4b!?v-kdU__F(xlgtDprIV}Vek0-?<+sIXX|Bft}8uMU@WjUwWy3VN{oRtMgNNb%asA2d^U@_(fplWJNhoU9HED-yh&5;{_$08(wIuYCTyc z1%rd0e&WIXJeUbF;}4oBAB4~T zDNf085Hb1U5q+=4J`TPC?vNMD17O#GnXSS$z%mDGR^#v z`D*jY<{qXuP3N0VGWCFs^Dg5;;{g0dJ>TFp$ohx%%k`Q17~SW(i;j6@T_k!BRNHhT zocj2H_|=yZY$#8mw{8S~Uuog9;N^JnYYfbU$Bg9A8{|m5`Q~wbXEzu4lLwPOjln~b zhFAt2SZdP^i`6GOF-KyXpYqG9uczz)33$KG!MfL&&}-0vB^rWORQ)XKbJoO+164NN zMF}obq)zy95m^+nPqr#YL%s;Rg_x3l$j*5P7SyN5DF*D2WUp_K;vT@uejr=9?mNsp1<*O-Ci^ChV%nv$Rx=S7o(vTz17XGLo+oPyUeM@ zi%?a)v5P(ZK&iMjUaOO+ZgtNR)lh15Crv)ENZi_2t3A}W3OA%w0PzZGbjPF}SSWJn zew^iY(#@syMyGx9fd#BFLS=W_w^h$}3XMzaM^X;SLy$xIf%*TD;`Wf@_I^1BP8GKf zK2F8$VZ}@Eqk@&UyD|@)B63MQ&YHJT(J6!FMw^^<;AC-g_kqW!zqon1(4MkD4cO3) z=ZQSx#vErJq7K!Wglf|!XC64|KT<|&S4M&|bN?e{#Len*7$qokqP8*_hm#=ipUj5E z%4}F{%s=eGz5l^%m<#oeG2C+v`G@<8oQ``o%sKXKm?KX)+(+nh{Ig+3|{0^Xw5#HAo4o?*|2}d*|5JM{cta2a{RMluh4AR z%btEXUfg=TvtfK_QixBQe7L8$^>}B)`0%8_6GD7U+Tl2n!|~3BaWsZ78^+luAMU{# zALncs*I_n{gW}!)BgMOi6z|?I=WsW1>+#Np-NTBv&xYMynTKOVF2_3?#m;Xqan094ipp5%JQbybyp-c>vas5Zi z#B{1mj9hrwiM)mw#>8qY6ZDy3rZ93NRgChS+!DH&3OB|f-O$aAvMv9xL*%B}TRP-s zIYy7MIA-Nw@f6DM0%d`Rm1S7ZSG;2 zvrW@bw_~=y9V6SBr7P4q|K`p-Y(vgThS+$GoM{6fNBpEUd{-P;A--D#4d1!PAGV5{ zVQ)Nrx@s=KjZd^N}KQVM#dz z8j!&ej0CgDAYQBUsGk059(|~(sHkZ)eCp0UY{Jch@k>}k=UVb-i;qyEkqvK8D-Cj} zgdo4J8{W2L95y1GzS{MUFBv&vhsp3*d$m8-W$IyrxOY@{jUu$)`zU^@!6-S0zR*$M zFUj-P!(pM}QEBpFy~wEl@n!S~3PHJ0D20{d;Ai>~d&Xg%$U(Cz+l%sWdrdyvCG&%I z;@(89c5J`*L2ALN_-tMmG(6~@{J~mr^DwQh*M9T;^|Z4&yJ*&l_$Y{9`G)&rGCo-I zpA`M>_M+eImfer)KGDPf|LySlzr(%7y&N9%=D2eWqugWN1Ki!*M%Op+j`tG00^I4k z#&t2`{;hT`b)Djx?n-wJa&>oEoWD9hcfRR72!D4sIQKZua;|gMJ4@l;F2_06Indby z-w=L-Kf5;^PZ~V%_kXM7YWM`$?pOy8cIA%Qjy%VB`1|h(uK<78zqG$&f6o4({bu`K zd#n94SRR~gFR-WE2ixQ9lKiXu8N3oc0Z;!|$vfoDaua+I&XM!vaq>X9yKIKX!H;au z+a9&u4X*%~+IHBs+Sb{Ewo2^$7u&LIV{L^_30{|De3;1cN^sYPmlWx;HC2N;K)|L&5>@}vGQ%SV=%Est7m zw_Jgp|BaSqmQqCT%d(8JBw1oCdh_?@!|?9^koiXUd$3#Bihch|^IUVjIn6v6-sB|H zucpsTubUn>-EO)ZUr9D%&%Xlx;)+e#rm?2M?&nNB5xws>$MV45-Am<;O#tKnC}Cx(|1-SB3^Uc@$BWpElQ4YLi15p=wNia}Sfu3A{FwoX{3{YB6P-N=yt43I)^bI9cWjN$kI(o7}%#uF__^5n2Mj-7MX%v&WTKcZBKJ#$}U~Y zIK|pW$!BZxP{o>u6V^4FBj`ZYUlH`8it{7r1!emqXz%oMBj}=OgCgkZdCMZ`Y1wdy zkQlBrRG2-2o;o=;g3g=xS_GXt0S1$*`_ob_5p?R1mJA#gn zT^H*7lz#&$u@zo8gk7M>5=j@Y3)$}~Dbupc)tWcxV3T=Ws2_`baL*5s2|Lz=JBpB4 z6gWp+l7@x;#t6E&Fg1eqPCqe%o;vB<2s&@leGznO@@EnB@WJsB^uRt3sdex}hn6I@ zgnv~nysL9prV{&S&YKfK7Z+X>K^NrsBIwlQBN23b*Xa?oU9OIp_ArH@5)(v!rUz1& zzFje-6BUn2HAc`o)?`M|>lttWk4Qhg7S{ z_^#Kg$vAh!gY5F8(5#9;r(l-`F9gs34|8N_NJ@ z9a2shmDwRBzU#B00>iC$uplR7F-=~+8*1tmi%z1Z=l!apQj@nRmW}ujPwULKZ6Pk` zyh#HUvq*4htjrBfM}fwoX_MNC>AAbx3A?-~)YoW(Nz4>0LVY1X_P8@=^$bmA4F<1C{YxCsr_4=km zv|UO|WpPn@=(1?qrqJc|+^a&Dse=(dKuoR;4T}PIhp!iueHp%w*ap^vs#tBIvwHt_V6cIkZ^u{qeEzUn54W zp#AF_*GABb0-?o+`9;(EMDX(_4ve64CxqNWuzXTNas)p&;=}NB?2~)-o z4Qq^Dg&_IfoBAuc&Cc zA>dzFep+Ng-lXPmAt6Dv4&M=Cnh|->G-HfNK*vgtNI>U$Bq9MFEHt%yCHEQnENr%;B-bAOG%$*Q2 zp%?e2CPxTcOs&coSw?lzKTKfw4Gj~h3sacD5-~~{1k$@5Wl2S$?u`W1LO|Ghw)a0VTYie>qS;#MxxVN})yPE4QSg9rp^ApwN^xTjG zCUI{;&h2XMwCvl|Wd4-r)nwkJLN%E?VXB(U&Ip-zi<~o3eQIv%kjKv{86TUj zCga=@T)RA8>C2QeUb*b@PGvw*0{n5H;RZyepn{u}HxET-$C@vdF~kY0YD4}?m|o}) zxk_O=KK4>&#wWUH+W9JKdhQ=8YU-pPRFuW^rLs2ES2t71(EEf1J(1`-G0K7fGIhuj z#RNWl#*{E)WzMFVZ~vqCSAIE02{cm=tk>5u6l{pN-gBffun9z33jfi3tnutTmh zI054rFJZzn1}E%XyD@^^u_iUt9F*h0KEJ9-yY1Z&iS6#7-3E6NV(uaz00FpZx*9+C zWX$=Xm4XE8OIOs=ueb3^EAbm7Qnte*kZ>RnEN`M;Z`;?%#%;P+^+)1tr`l$~d)_Ep zqOA+O_CIaA55J<@Y_0IpUnl=4e;~goKL%fXyKvsVQTEHT#c6wwX%GDU8*JYgE;n3Y z_|v%3u-Wjn@pID_W0~m()4S%eu4`R8?K6x+Tvf)&u35&*jSre0G2G)C>gtXdcPF{b z&L8a0nbsI?cD`ji-?`tp(0M8B2G%>5S$8>$oq3K}qr;hKOoT_l@1$nO`;KQF4@z;c z9Js)7CVUFk!2A6)gGqnH(A%)gu+UIoNR?*dcm2O615VJ-upTf^!wChi^-SZl_IKd{ zFlY^!V@-9AB;!qnXYpG<)tYFPrN5-lq~}fDq$j2O;fF9!x>7pFexLm-!#h%?G#|h6 zOL5|VjMU#;E^WdrF<3G<5!@D@0q-_lXYX!bgeZTPS}w3`v8=XK)0YbCt)^$;cOb(u z(7w#l!}zX6GXG|V|8Mgf<|pAP@D}@adz<+R_zOJKyvAH@wpe~KjW=c4&F)Ve8SX=f zV{nW668CoZN_W6L7w0iXyZgCg5T)Qt*Sq$8u0yW<_7uZrv{kWrHiDH-vW>9C!J6Sq zobWg3ztX>}e;J*DqJXZVxVBZnnZku1`5v=APH}BT$O}4BHcR~25 zNySkJ>i~-K+kS^Q^&p%al;MjaBB0C;1xuP**C5@}-8jO~ks;kg#SmEpry;6Rph5cf zs7!-aD@A*rqeKoeob)x3vm0QpfDUf>ox*L-Zm6oP3^Z6Sw;E#&rGCG>o3fd^xURIO zYNqlDK^Czv%jtmgYzjdo_oM)y;_xvYimYppyQ`lgolET54bAjDlRT$bz9BaD?WYnY z54CRYLXlIEFsGqf9z^wkr9$8lO9RaYKe2>{ z2$CI?Csa_~DBl64_xwWN#fX}v+&Z4ZVh3uM`x>mndKgo}rN|Bi$TFNO7Uz!g zaE2Tae5?bhY~?trf-^0}_`F|`Ywb@D4#!}z_M?o&(ITq|NGdLKC>oQsH`R#9ZgyS0 zHNlPWsDk3I)=O}yiJ$;NMsRBy=N_|k=1WNR*%SdQD9xr~`tjP{7+~$JUCe`Y68bWA z_qnJa%U7g72l~mOTCh4qB`f_3A)OoR%-aX))a_9sqC%QmsU9n;8iI|!2I((WA7#u{ zf+$J9nP=-v^qiA%CRq20ItM=BW0*%pEw8A|$|;h*vz)3kQ4NuF&{$4dmN%}HKBe;U zQz~Y|=*IK~-9+)@f{RUusb+AEzO*V}`i?miGD;GGbw$`9UxnoiQS+j^wvh}UUN_F8 ztV8iMeYFAU29ZGV)`~=6GNTBMi{8asGnSvJLBpg;#C8rW!|~Z-91WE8f?FHJLE_xH zM%|C3FjuS+FE?mO5$z$msF*E+#>Z9FPe-YYk6GT;nf+8?amq;EB{~s)gy3`o~;)w)wh=b`KTT)mChMw2fWPs1(#faxRAR85VR z040ipuYMaofuj%8`SLpYZZGADK1>=G2AYjeQb~kn*01FoSt5`zG9cM$!quD%TC zU~N4ug?v+KFj!U5j8H<8qotYXnCKa{ z1nXg)xtvOm2D4!o7MNXE zSy>&hRgy{~!4{zEo2`Vi#Pm}iwB9G~u0y!QBAkD>iLmIi!{l9&+@eTwXas5fEKC-_ z-pH0kokV1XeKv}ri6x^cV9TbepIueYkN-j_)KFTB&)f}-VoEmWhnEQy%a;415h6st({%|U6al4mx@OjPnb zSCLXurEQ`mus;WL2eb2PPWqofitGEOwWXc1MR-c*7lKT`ukvXxI^d~Htoi5e5#n5z0IgBx5Y zpBfWyJzNM6&nUcNSJh7C$jCvP2$nAD45Q{Q>%TO*#ETw2*(xt&roSj>CD9wKG##Ow z1)Wn-Y5G!70Y1tqt)g*LhGPU}QnR=$4OW#~=97{t1BAK;%UoxS&cRc&Mf7e=D{%J< zztTs9FioksybuHpHB|j#mc^)meWU43YFgU=uk{z#!KNW#NTN#Ol)Ri-rmvktkiB^4 zvo=!W;2IONoOi^tUlajpQ%ZfUjYbI~H`BYZMczTHwF z9!DVuXJR@reMb3Vmdh2fjC~EX{2F4Z0$|}ayUz5ZC_-fbCkF7#;~8BSycjB(Nw0~l z{C>QGV1d;A;rv494!<{AHz-^lURJkjvW_h3qz6SUm5WbhIU;nS=@afZ)yi9~rI89X zmjYDMCUurLa%^Z4iEJ>Ii&eW}R-n;P?OLzv7Wo=(t)$@{dM6I`1@k`jD;{QB-e@yl z>V8AlBRpJ`0$6LQl|rdBO_|T9nJb(k34%F%QjmQKn>TREo)j-SC?4p(a$)sFlqRP~|8IXfg90RDVpD1Q1oRw$Xfh zd(OoocB%O`@nn&+H)y`I{gxtR0ecVg{`N=bB8f($`M!3s91b#VzQ4URIW$|E?`=;I zho;T9(nLhX!EiPGM(-XKc)iel?*2*VREDSYrl=M=drph8)P&!Nj*2Q;=B3B!{C^jH zoX$PUHNly0ze)aBPPJ{Zz9+4+JZ?!eZ8Y9)c+Aif0{`QGEiX3Jr%t@CBg_FtRbFuUNYVRJ$TQf)qA9}io@`wT_7Y20~oR+Q6g@7Rv>m| zfGs>we$V34pa;FV9yTIjgBZo?|M(s#>_S?STl;nqtrOpUV5KvrGMfJSKMk?0e>FN; zNOQVAT4ze_MB9)FkGjMf;#}6Ht$mcniW^+jBE?jxt&fh?lk{)vf9Jwtc4=q~l~xc( z7gr>AQeMIH;A4f-CRlFC?SVhkRxsqLtM}l?LRGbg+7~84uuUxwAOQ8Tn@8(mY{S%2 z)SB3p2TuR~EqZ56i#}@OJga{rG;;9q#?Py>IxdFwun@|G^ z;^+nx$;WEI;U2V#crzGT6#gnU#FI?+aGsE&K`cN`u;i+3gwlvcjhpa3>8&H{Gn!#U zRfMZUJjwLO0Zw z<8qE_?L`xS-Voon@2D1I%&4dZ-DuHoMf2gqU^xGyFQ|bbfjKy&1&v>td(jz$!IuZ0 z@9F~{Hg6`2J~;1y?*nRgMQzxkhHnmKCknk`QENO8flVcgB=QEoU!%KQ1S}q*T>}N-2n=%P5i~pIe4s*6pKA zz1nsv%q2~2?V*&k|Cmx|Olj1TcGdUflGZoCM^9Z-5Wi(YO}Ui2j9#*p_-6!&WC2&rGa{2g@?0IZm+;6 zh~RK!hFPYp)DNTR`s%u7Pb~>~Fv4)uho)#5@8IIhn`Z?a!gy-yJmD8X%uiT;tE-PW zBekn>d}=H2WXoD((Z%#OeSF;Dbu}^TqP5Dpb=)SR5<|U95J$I!NX8HtDlR;$@ootp zAGMyEkwG*;aAbY}7KffS%w--|uph50_yr#}lSdW9P}~y~=b?_N{c%1jtaMjJ>G&Z{ zYhs$BDSg^$tTgWhhO}ntXtg<=^yVwI;*0Sk*Rw`RSF5ZnLH-fcg-8mWf);Exx<}2y zFTyc3=e)F@rYK$58pBE_CM8wnMgOg_pqW&o->fh?P;_p;5^A@T$?%QjQG}Gwlh9vD z@T_hZgbM_G-=~!}RE^3TW4lO{yjUICK1-i&ep~1M-Tj06OZUg_cipeS58zYSiM|gu z0XMj>a_`0I;B(w(!au-jcm=G1eZWHZN$wf$>Fyl&1ot@iNcUj3#~ttP>c**M>{b5) zUxJ^*X5cN?%dTf#kGmdp-R-)?b)D;SL=?Qh)#}>fTIX8nTH-2qo$8w7Dt6_&rnoX( zqg}&X16+x&9xk`b>e4&^Ks14`oS!(~bH46;!TGfF5!e^p;k?m#weu3^Mb2}bTb&!7 zr#YLPwa!XJADjn!gF-|cnCKjjD1^z*B={SQbvm48$3Ko=9p5>=I6Ahy-D$VT|H{9? ztHBXO8+-@01&8D(<%i{a<=fRdP_ShPA;0d9GX{7s%Q23G!HZ zggi*@EBC|+2w675=itw_Z{Qi>19%>M39$(uvprzD%XTw75ME~6Wjh~H3OC~{#R^-! zt;$vgn}pdmuWhPrvMn8FE{59r+j`r&+gvsn6Ip+^{$TwQ5ewe6z6KA4Pa$%_eb(Ep zH(0MiB*P1>=fGZJ10o+Z!t+9fbs-`k%&<eh@g-mjh2Q< z1EfT$hvb&5k{+H8f3$pM`NZ-bA}hRLdD`*_d>-CmxzTbp{2pF}NDEtG0dbn82@w}6 zEsHGkEHiNeBG)p}GTxGc2n1*&isY>L-X5?4^3(RKl(2f-W=ft z(A3T3L|oc`VcYS&@rdyw_{MnEc*yvq@nPe=h;gwGQ6Tpicj|N$oYPk%BB%O_o?%Kv zPW2T%&6J3o>MMGZDG@o~T5KJVXvpwIgkpxWpC6AG90Wm)BHvrk^{Tg8OdB3vH(*5Q0 zehK*5=RE@W#^?P4@R`s1Ip71I_cOqoKJTZ1mwet&0MGcm9|Ioqc|QU?;PZY6xXb4~ z47l0n{Qz*S&-*^$GN1Q7z%HNnUBLN1?>m6)KJVLr%|7p2fVDpFn}8KQ?;C)6pZ9e@ zmCyScpv>oe6>y5r`wC#T&-*gK>+`+@nCkPs2$<~iz5qz~d7lT2@_7#dhWfnE0s8yA z&jNb;yw3o-`@9DME}!>lfaLRv9#UL1i5k4PXd=S|h7%Yv88R5s8PXWWGmK*x%P@vv zG{Y!{RE89WkqjdkhBFLf7|Jk&A(>$?!ytx%38ZW$43@$k3Z1fuR>e zJVQ^0IEEe!-5I(u#4>bch+%*ySE@lbgNwn*;9#&b$P6|HD}%&fVK6gb5}-Vd3m_?6)ohMyUJV)&8a2Zrw%zGL{7;Twjp8NOop zlHmx$7Yv^>e8%u8!zT7sH(lcQD+} za2vy|47V`c%y1LKjSM$1>|?l|;W~zE8LnZtn&B#jD;cg}xSZiKhD#YPVc5&ChoOyO zH^VN5iy1CrxR7Bd!w!ZE7|v%nkKtT~a~RHMIE$f`VLQV%hOG=|GMvG1I>Q!*%?z6u zHZp8rXkl2-u#RCZ!y1Ou7*;c^VrXVq$*{t;46C8{3B<0zGWa+E%iv=GEQ5~%unax| zz%qCMfMxJu0G7dr09Xbe1Yj9_0Dxt1KLE?%{QxY3_W`gB-V4Aocn<)};N1W$gLeV2 z4BiRAGI$37%i!$*EQ7aU^A5}4tpF^8w*asVQpjj5gEs-N4BiO9GI#?3%iul$mci=* zSO%{HU>Up?fMxI+0G2^Ic8q24Dgc(jD*;#ruK-{fyc~dK@G=0F!Ak*H1}_0%8QcrN zGPnnTWv~r^WpFnD%it~mmcfewSO&>E7?!~c0aym{Rz%C-4gi+H3jkOK&j(-`JP&|n z@LT|v!E*pu2G0gy8RY&_G?^P`IYSdeBSVm(fnga#JwqKsEkg}MHN#SdB@9&ziy0~z zDi{I`eui>}GKNxyMGOlW7BI|bIF;cPhLaiQF`UFOm*GT)ISjKIW--iUn88rO;A1Fe z@G=xJ6f#U_C}5bzkk2rcA&()KA%`KGA&X%O!(?uiCz+bWFp*&b!wC$T3>ggR3~3DG z8OAY;Wf;RSnqd?}DnkmxNQMy%!x@G#3}qO?kjyZcVGzSWh5-!y8Tv6KF?bmIGW20c zWa!P1z|e~!o}nj0977L=?hM@+Vi~$J#4vPWa5K0VoD2>IJA=$%W3VzvGTNhF|Gv(2 zj;Y!-%`^ZW=ihj0lIzR_W;|5}Tx_qDZWio{S<9 zke-Mlkt01GMPiVASrmyr@}=4mx+C%>Q6wId_ePP}FT*GPF&jgvb=|FUTNH_X^6n@S zSIN8jm`>2QH~BJn*-R0Kcj=p8g7I-Jw%hoa7TaNbw7)4w)t~UGv!SXyn4%yapnp=T ziYoJvv^c8FeyK95%-vE&RGB-aKvbFAC4W?z8>I56GUrHTQDwGBrBP)nr9~doWK|=I zui2{5o-5>wwFTVx;2VKf^82nPDEb(otv3RFlP=BADU3#1NnQ%8Z>Qir*zqreQQ!`#$SV7k;{Zt5tIFLjuk zItt`U9ph;ab5lowKGHdfrZm-RDwb;chvudI(%Bl^>!hiY!R%>wAORF@vE2U-)Zj-c9gIg-C(BO`e zmTPd6q^8cfx<8~w4esYsP=kAg)S$sVUs~4Nl%{$QQ;*QqQhn#lxl&!{%$ZVc=gjF+ zP3O$XQg!Fdq0-XMnLVW?eN88HoNU6s3v_22pVNBtUtxS!i(PJfMvHxt@t_uavhisx zcB=6yE%tEZlUnTl#wTe1f4RBOfA|0YyZ`_H>i)m^6~sk+0v;0YG2d#w9v%_e%sb3y znNK&bH#eIb%uCIF^L+D(W}kVQIm?`B9%CME9%%04_|Wk-zAZiHc*60J;~w~uyxwtz zqs_6yahBtB$9hLId`d2L_~94gM2F8Y&5`BEbc}HfcMNp&al|>gIBfV5^{4$O``7kQ z?eE*)u)k{U{0p^CYX~cz6s`Jif@8Bnc|yZPNw)Kn3E~K z3Fc&qZ-P0Q;+tSjruZh9lPSIl=46U*f;pMun_y0+_$HW>DZUBjWJ>gDFgw%2U}i8e z7#R!;Wvg~8Gd2-nc*jf9~pjN_@3cAhHn|ZVfdQi zD~2x_jxc<|@HxY044*Q5!tgP}M+_e_9A>zR;Yx-p7%peHjNwv-OBnVt>|tnQ*v+tu z;bMl17%pVk$*_ar0*3P$&SN;2;T(pu8O~y8W!TQJjbSUpnG9zzoX)U?VKc)fhK&px z7+M(CGpu7+%dm#wG=|j-s~DOYRx+$$SkBPI(8v&EXkb{zP|r}uP|HxmP|dKEVF^PO z!(xU?h6;uNgP)5p%w;%{VGhG=hFJ_V8D=n) zF!&gX8N3Wd422BS844JtG2}B$WyoX5WyoR3X2@cg!Z4X(62nA>2@EGNWHMwhq%)*3 zjAt0fFqUBq!)S(445xS7`iibV~Azw$`HfQg~83>VsJ7z80-u(gN?z;ATd}N%nT+5 zBZGlK&!7{K{x8En41Y8H#qcM?9}K@U{KoJr!!Ha!GyKHxBf}32-!pv2@GZkP3|}*R z#qcG=5r!`qK4bIhFuct062prOFEBjMaEReKhG!X`VK~U}G{aL2Pcl5g@HoR`43D~&=`PF8U{x}N zD%lxAmFx_mN_K`&B|Af?lAR$`$<7d}WM>FfvNMD#*%?BW>WG2F^<3&YI}H!y`%7pi2X3sthxg(_L;LY1s^p-NV|P$er}sFIZ~RLM#g zs$``LRkG5BDp~15m8^83N>;j1B`aM~p-L9EP(Q&SGd~*v_yG`>s-Uh8XWz>03GROolTUPG{J{ zu$f^K!$yV;3@r@n8P+kZWmv;-8pCRaRSeAxD;ZWWEN5t9Xk-X7G%zeV-%q6CsrhW#$KHW9K)fJxp-*FzmPX9J| z_@Cp<96)zuW^()^6^_M#{P@_ZTrLatFYT&XP<4)u=lYW<=l3TMVkR-ep3?4jx z1569!Re>bKrbY+|*ho9S`}GIHRv_dSg1mf@ua9Ci!L}gklt_~>HaCV9h+2fq$=Uf4 zf^?8Q2%IIsjhml69KbUKjJM&>4(6DdutkSwl5$uz`iH|HN`~oc6@@(Z`0E-+dJ2Te z70jYwl||MnBjCj#0Lx^ypMhOX4I)s|&Cus~OUgDT8#7y{D0MY(VACckrYTOVu6FA0 z3Ds2)o;n*tKF3to;`wT3GGbtI^}sNVFNS;SMcC-tLc{@v>77~}+ACpAsKy##u+P;+ zMy&9p3Fk;bxK*esUrg>I*sQm@4!*cx_d8PVm$#Avp9V(e_`DEL1nkD;C4ZQt={5wF&FYO1QoWc!WbLnssUe0hKMDrkdO-rnOE`sy1%0 zw?!Z0)$A3ydOugKsJ&3l3Ou@EMKT%xq4RiF3ku$30s(lj7v_Vd<>gH^P4E#!o;@&K z2zL;$K&?f9-YRaGvUPvc5xIjuEQY0#umOIzY&mTJ~PhJF&)0X%mF_(`EEXiqu12HJUK*&p)D z;1z0PDGg6Nb%giHVu3IadtRk7xa1PD<`4L&_`U(V8oaf=bY&XvKc>kUW!+B< zxn2<3WeJnnkdCUPqxDoV!@3TKU3fKG8$DiScCYTM(eDyEY;d%u#qvmnn+{`3Y)p$$ zvzdD86S$eEw@s~U2&tfuM;BjVM84}Ojsv{NBkVjt5v0aY-cWd2hqn#3tS_x5`{w5M z@rv0BKCTccoiFP#`EUH2^FnfxrL5Vr6t8h;a+Q2!IqCfWSH?qj_mA#R-EX>|bwA|34L1K5xwpC3x|g~A@IpV` zJ<*-&?(gp5wz>X-ZU0-YgRc8r*Tb5ByK9ZB-cDri%fsb< zu+DeMCVXr73|9Hiz#{)<+ZDD8ZQH_;0e!X{TbgZ{t*I#oFH*XSGZJNl z&NZEmJ?EgQ%Cr!X3Sum2u;J)s>SD4O|1$ny{QQ5xrZ(4Lsz|v>53c@_njEN@`SGJ--WLpCeNlyaD&+WYT_ArPY7MakAc2v?bm(&R9(N< zer*>X{pSdI`-iIZ`^YEmoZ5Q$LuY@y^p4W|8X>{eslL8~(@8o}c>Sg(6@emBCXy@H zcCv3IX^J36{t-zE2h!nt`wooY_DPN)6NRVpuyDfe2(GP>{Bh4Mt%Bbn*=7@t<&*t* z0~3AidVEk&X?AV6Q^v0%@3q`b=*Bhf7u)5Ak5^r%v|kU(R9%lzUH5Ch?x(7~epj`p zCvh8y8cupfmHu?NOsQvmuhTJy>N|B2^*_=q)gU?oyTVU-Pfa}EE}!yDNIqp>d;Wb7 zs;)(V0am*2URC-E)%7yfb*}1KRVRH#AP^;=(d{yQ{!m^2uDbqSb^UGob>acl^+T%b z<*IAp`I?`Vs483Uf7@kx|E#+HN_G9Y>iT2V^}DL;r&ZUg^7MY7Jv~9COTw@1>Ag0o zt~aQzRrT4;+@2oWqPkwIx<0M_+Wo2O`Zd+{%c^Uo)oJo`A8Jo`O;cTGw_oF!S$ML< zfwT5&RsGmi&$6r9LZ8ttuUCx){cxJZ=G0cLEXGIwzO4~dbp#bqQ}*{GsCRfUSFQ9` zArSeX1=NKp(?JVESN-k{UG;f5e059s>c;R@Qs^pif9NXqlhBp@VEF1Op%5n9QR91G zue!djr*Vwo7}4xgTjNwCF80~>@wyX%zuT#E=?S#V_1h7;>hpQ{>J^%AR3Uy62T?uD zRzeFU&LP*{vm2^vW;In*RITji??7in(n*F$y7%S|^oB?}eoF_stOLEM1HG^VJwK9; z{UDOI^^c^jBDR3g2UA&KP%moccCuRp*{?K`To6gljwD4SfpAv+l$a5yIC@Z$J3_cm zMg-Y=Z6q1_+=R;_xCwhB$t4kFufvh#s}W@UrbzOX2+|g*g7wb`uJxx#^0`Rz{z&rP zNb=$c(io|Naa$xe5J^VXhH+jbH#5}0B@F@Upd$DQHG@KjJCs77(n0>@NIJ>bf!0UT zRuQnFJ%8(49r&+xpkEOq4dwCt5xVNVF?5CBSTr`lwSF7E`hrF^(kPl&k_ceH@tqKB zq~A?Kc@gf3$m=3W9$eu_B>nCeWeG364=^)x^mv0zbd03F?Fjj_>IA|77c4o%=)gWA3ZnXSkQRi{R0(i|Ys1E3Ug-7r9p9 z*Zm}y$7OJS?0mv`E&T3PBQ{^Ev#aAL$7?u)y~}Z$V}WCeqo2csQ`Jw|uSbNtT6>9o zw7r}Bi~NRspWG&|l^4Nh-T>KR``mWWc7yFKc)^=#8*A%f{muH8b-#5ley#UL9Kp|R zhirG)cG_0jPPR?3^?@(E53P^E55O7LCDtN%x9cMPAiW~pC0!(~g1@>+l1DOFKDImo zUjSPz)s|vQs->&>C-ZAKQ@+c5nt6eFin*WJg!9@@nXWf&H`SU-OruTRjK3J)Fy3cu zGp;o*GG-eG7%hg+4F?T37|t@(>(}ec^tt*$DW&w2j3VY?$%3QjMB~JEt8qjDNkO0@ z3O__&3448}$^BH5`-vv^V=Zob=}N0ps7w?Th01eEr<{{JLshx7lI^~pV zY1Hc-P43&8+_yBjZ)$Si(B!_Z$$d?e`>H1Q6;1BTn%tK(xi4yRU(n<}ugN{6$$d_f z`>ZDS8BOj%P43g0+^00TPik_X(BwX@$$dUkhH&>IJqsh(I6+X$P40M2?l?{ESWWI2P3~w-?kG)eswOu@ zlRHwAJ3^B?T$4LYlRH$CJ4BP4tjQg$$sMH09jM72pvmp8$?d1fP159gG`W2>xqURb ziJIKrn%o3UZZA!4ye7A&CO1x#+e4GvU6b2QlN+na?W)O*(d2f~0maenW7$$7i;0(k8|(V6D#iE{vNIqrx3 z_8NRam<&IGdTg3KYQNIH*@Fx79!&~-4gwc6}8+U&jB>^<7-Hf{E9ZT2p0_Ql%li?rDnYO{B0vv+8- zFVJS6ugyMBn|-b}`y6fd+1l*0wAroN?Csj@ZQAUu+Uzs6*=K08-_~ZorOkd*oBf71 z`*m&hYufBrwb`#|vtQO`zogB6QJejOHv4&P_91QdbK2}@wb{>Tvkz*spVnqSrOkd) zoBf0~`*CgdW7_OTwb_qovkz#qAJ%3+q|JU%oBe<`d%rgOer@)B+U$F^+4pF(@78AD zrOm!mn|+5i`*v;iZQATxwb{35vv1aB-=xjHQJZ~(HhZ5o`+9Bmb=vG}wb|Ebv#-`> zU!~2yQk#8+Hv4jI_GQ}aOSRdT$VRKK!LUt-bLJCq!d!3q$n-e;nVo4`YVw*=OfkkE z5uxmE_tWlu?pAjlqW+C>cX$2jdee2kYY*c1mAZ0V16`8y3+FS=8*$cu8P55SbH?G9 z{o6R*e+f?Zmpk$tgB>>em-grEH`~v(2kmq0Y4&*ePx)Q>A^9?SBjW1i%R^+l?Q7ff zwp$S?uL-~HGi(Xgzpd{h_T3fM&DKh5fpwVGiD-5&O1Dcpq!rRU=>#d!@~`EvP8ei>gfE;KhAzBRmNc))O_VViNUakH`7ILnx6Ofp*CpBWkq^9)lA zgAFeI&-!=tkLs`2pQ~S~U#Op|AEEC?KcMJL8t?myo%MR`uGiz|NYaST7{fbb4C{BdIfnr!z+1&KNy9V|4F~(XBH^Y-fzF z?$30ikJaXho!!y9Ge$yZj9#5F;yYvX?2MuPnR347C%;oQxu@vx{R^oU~D7o5QB|zZ*j$dgtQX2g-dKFb_5b2TS!xpJ)~Yjl1uNs-X)h@>ZSMkduBenAU0%$bNBtf?)CcHuY~vPJTuSCGi_Hp zWiL{cUZ^O&Kv8A8y1a}=d#D@xB&l%A<5Jws7?x}x+nMd_)E(o+C*X|tjQ5sN`9-$~*rzl-ZziM;(`*|~p z=Ks}u_MiX%Pt*SM|M#E&|37m6f0!RB>aEOUXLNciM*$;&5kM|59LNC<1cm_z07HQx zKsGQK$N~ldcEAQ$0SjOTOn?zE0GWUu$N=a73YK{-paIl?io^9A@GI~O@H6le@FVa8 z@ICMy@GbBS@HOxi@FnmC@Hy}q@G0k4Q zS8(y8c?B0gnpbdL3K>6|S8(y8c?B0gnpbdL1lfha1;F{hdBC~AIl$S#S-_dV8Nlhl zX#hW(S8(y8c?H+W@Z?AH3NC&$ui)APPkuD7;M$F=6M++eZOFdE1Q96%m03K$8D0CIuhKn`#qFbp^V7zzvlvVp-s z7BC2~12(`4SO7C%0*rtG$OQC22A~79fCf+lDh}swz^}kBz|X)>z>mNW!1us+z_-9R zz}LW6z?Z-mz~{hcz^A~!flq*sfscR>fe(Q9fqwz-0q+9;1l|GO2L1v39e4|P6L*A((UECC}i<{zgaZ|i5 zZi?5%P4T+8DP9*h#p~jxcwO8SuZx@Fb#YU?E^dm~#ZB?LxG7#2H^uAXrg&Z46t9b$ z;&pLTye@8v*Tqfoy0|G`7dOT0;-+|A+!U{io8onGQ@k$Glt*FFBf!JJ-++gJ2Z0BG zZs304KH#swy}&)d-N0SIoxmMH7jQdp8*nRd3ve@V6L2GN1MnB%df+++!O2Y#oZJ+_ z$xRWQ+!VpdO%a^j6v4?&5uDrxXfDT|ca3XL5a6GUJI1V@#I0iTxI11Pav;#*1JAm!LHef5T1=tL<0j)p_unA}e zl0X880~>)RAO=K%Mj!%g0M-LxpaG}{>VOas1ZsgAAOIWztOM2phXaQJYk<}JfB&1l zpj`(0fBzqrx&Qb7|H$uum5O!FDq$Wl7nlPa0?Y+a6M+(7 z0#FQ$2gU(KKp`*|I2b4Z4g$siqk(+D0ptOrfRVrmAQu=8f=K|*dX9H&eX98ycrvs+}rvj${Cj%z|dx1Sb2e2DB5jX)j9@qsO z2OJ9=0~`$;1?&Xcfg^z(z;<98uoc(>YzEqZR-gsg1T+IlAOXaIjX)C+1EN495CJv- z>wz%P0Mr9@KnMr|wLlFJ0FD6G0c(N7fy00`z-nL>a44`6SOF{tmI2j(A6N=30Tu&Q zfDiBj0^kAMKqcS;oInLo4wM0lfKp%~umG43%md~EbAUsD*}yDdCNKk-4om~40#ks= zz$9QIPy$QgnE;6Pv)Z~!nA z7y@JigMlny5MT#vfEBO+X21j(0RxZ;=z$DC2WSBepaxVN?%#l4fnR{1fuDdMfggbH zf$xBCfp37XfvzUC!%eC3a8s&0+>|O0H>JwMO{wy5Q>r}NlqwH5rOLxisq%1Bsyy73 zDi1fM%EL{m@^DkCJlvEj4>zUC!%eC3a8s&0+>|O0H>Ju0Q#|i;i#-1V-UHqR{t3JT zybb&V_&e|x@FwsE@H+4s@G9^M@G|fc@FMU6@I3Gw@GS5Q@HFrg@FegA@Hm6d%}w#S zxhXz3H^t}Xruf|46rY=$;&XFTd~R-v&&^Hoxw$DmH#f!S=BD`E+!UXio8ohGQ+#f2 ziqFkW@wvGvJ~ubT=jNvP+}sqOo15Zub5ne7Zi>&%P4T(8DLywh#pmXx_}ro?kHMlx zfk%LcfxiI{0S^KX0Nud-zf=K|*dX9H&e zX98ycrvs+}rvj${Cj%z|dx1Sb2e2DB5jX)j9@qsO2OJ9=0~`$;1?&Xcfg^z(z;<98 zuoc(>YzEqZR+Hu@)h6{gmECC{Yyban$Ns*ZEWl1DP#>omtzFW_ew%*hxs9wrszkTrAs^Cl|~1 zuF1u+U3YS^Y}cJ!EZcP_7t40t$;Gl=cXF|8E2CU2+sY^x%eFGg#j*{caKUS5+>S?NybFWqVcSV%c6*xmdPW zRW6q8Rh5fndsXFP*KUS5+>S?NybFWqVcSV%c6*xmdPWRW6q8Rh5fndsXFP*=~u8BPM`O2|n=bFf4pQ{}E9A&ZW zTobwSvy@|>sVtVAYa&-JJJ&=mK22HqsmkJ0l*K12i)H7U$g?Ip*F-MfqpZ9`S-e|W ze4?`W1ZDB@%Hmzh;^UOX$101DQ5GMqEIvwEyi-}+t}H%MSu8vCNM7IDm1A#H7H?G+ zZ&4O+Ru;D@i(BazW}fWFM9MGAG*5f7vt;DOB0Eb)E|#6=A{RexrM%5nU8Az!Yu{#{ zO*{KN$K^^-F`&A2L~CL>SxrtWOrp}N7^r?e+(E9jli{hH01IqDzPcdDD! zQ&gW*lD9}dya&idT?>sWSAizqu2J`tW)1t?LnNF?ruMf8wt=St2O!q=6B739ohS0ho+o9^HrN{)o4s}yAFYZ zeaV3Ox9Vi9DXIR=P~J70N6#C&59zCarSFz53)2@q;>mDhNd0T(yslZKW~^rDKyy)@ z48)V_?^xq#RDY)}?V5@B1FcTP|E8xt)!*pKx@K@418$kn@pVdts=pqzuxmQkGT^2O zEuTqkQ~g;+Y1gzrW6ZyMjrq5}tZV9@G3Jw0V?G%?ziSHDGT_z;V?IXnRDYaV+BF#p z2HHHJ;KR~7`d|ld8y}h%bWK8W477f!it)v7g}?@l%dM^p$q?GdT;o3b>ZsebT}d(4B;7 zu$6WlL>k6wvUAepL%Orpg_5-m>W6784za>Ws2{eLc8%dW(w1dk9S`)D<^wio*J!R| z*g)Gj^3h!uiP1;ALy4x6MX_L;x?5M#mCqHWE!e)9xxa7G-hbfyE(g~$G+oik^pwS# z+Nfmj*EzfL{)|O;$}GB*ZZY&ZB&wn@=^9$!oZOMxa_$)H>>A0nWRKaWiteKR&x^N` zw>otf)zpYTqv&>-qT9{RuG~LUK)1*W=oa0=uHjr!*1omjYs+J`k#H!QR9`#jkggo4 z*tasiIvH1AT~O9_AdkF{6?9cNnh4c4$3x4!)#|Hqf?dN<9BcNeg07_Eh=v-H$)=L> zP+g!ol3W%KL=#Q1c(SB$9QW_>C{kZ(s^~g^CzGAOPsw!BhuPzyjU{3;=%ju&^v~$I zu&9Hu;oKSDF&+oGS zxqLJ?1(FTwW_wweg)0~~&?=V7AzmGh)`s}gRGcc+3@!U=&Bg@(`LNMm+GXMza`#n3 zQzVc``eH$K6BUN>&lN_D>ZD#BBQp$t&WtD?L8AQp{~7H2e{b6Fw4Z5D(g}YhcC+mR z+e5ZaI^XXw+icqb)~~G3(CL0BSnI9j)_lvabhclY<#bEjve;5gC;R=2&g{R)yv@9t z&h;BYtLdLIU1Qosr}`~2G*}H6zYJtY6899D@qcy8>nAO_zQh*)?HihC70h-R$e60Dht~tt|$b+HUSTMAR ze$3C9w%qTPU9wOPnO|YTkx0^q!t0A1g=-G4X-kHR9sIGU$g!n9wy!b5(P${%?%i8G z7`e~SZ_l)5wPz~k|255rQvTTuy^Ibd3g>eVQd~r-Gb~FZB9lXZ>*n~eD z9rif(`o-E9J9ectYo($!PikI~tck|rjRAUn!z-lE1-Ge>PhnF}J)k~%ia%X2FQ5TClk_{n8C|VnDYoeb`4)%^N zL`^?Y;&3M&@ldik9!;1Eqv1%ggZ>mbS{g!8M>N()O*rAe*8u1NDOgNF!nF;K#t=Q) zI7ZV~oELIQXNQpMJ^2=&^7miyJSdA_#_9_odoN)b~`2H1_-_Dq!8gd#idn#wu&p zDn;AQ(wr~ZMlS>^!@-a{NRQ9qWSi`g+b8p*jxny956(r7npiB-(=XD7<2l`F+3Q0+ z7^kS48|%e@x@l8UefEqvzeN&UQuBU-6h2GE_MVWkyy); zSR%=DUWBR=wK}%+#&Xm&ha=P>So8Ng%N(<&&6?&AzZWaD(*Ha?ULGoyp$x-B&dBlY z`A03tYR^|H5cM~jStt;GYb=jdip3#a{;n`20ekJjx+3dqY$#x)hFMqd7>5ojjt@n+ zGdi|N5gj$*s8|@~Rn-$>bYGrOxop{z>Yf3i#Nnz~<|u5T2XDuMU^FqW$U#-*ShBc! znQ64v)w>F7GyTM=qj77Z4Th{KFCSwgX~QoWKa4a9qEJY zP9NmN^g&KYALRJ-L3X7Na$Nc#$EFW*O!^>4rw?*e`XD>g2Wd|q4R)dA7o4VAe++%X-glZHGPnl^g%YI57L}INHTqpMEW4{^g%YJ57LxANGyGjX!;4QYl2icH5$olj_!s&xFqz_V`K1f~qAffa@g6V_QrVmn+K1d*akR#aq|6J_^mHi3( zY4$bt0^2vXzuNZNmfLczZ(DD&?y!2SLoDxFuD5KrxGlr!_xSbZX0y|5HN9oJ!L-e^ z+%&+)VKP|T9&Cl^TfjROOsDbeP&#AUknBfyik^@ zKjvvv)7$PqV?zD0b-{g6QZlcbX6UCDY4TF1Pw8EZ_<@L0`b-3WJy^z;*{E(`+!Tt^ zYKM4;Z!S>XZY%Gm>3NE8pPusC{SV{cTu#r|C0thtFI;+w8VRXx9#qjyGxSW&%z>!6 zDMd|HsGjDOH-(lh^Qvwdw6L4z=$W1g1JQG1iXLB}m8rOqRM0H_fK}X(sv;a^DsC7w zy_+WKr{-yf=Kf(W$nbblbp@+dy!lC}t}xB&rm1;~r%)M)cbQju^$;kb-xsRO22Jgz zDS4LUAJ-$IUb=){ItSRyx9U>s)NUHB1`_KMceE}RU~7F;muRMU)08{K%1M{j#fziW zErBMacCqG=ZklJOc;i!>ZQr(nJYJMwrL!ndyP-ZFYmNp3s*5x;yJ?1Z_93E?V6IDL-$AIb_Djk|Rr>JR5=WHI;8>P*V#4*be=MLn-7>wK=Eo^wpEW}L)#oWZBJcJA)hU)4 z-83go@rI@A9w*U#ZFv*@ypM-#6RMLmQ@UvmoFevF>(O6=dudV@t!}SzayLzQvq-6< ze}9qoRK;4@T#9PXpvm1d$Nk4~qM;UVjFp1wc)Cj@Sg$zVIJ=vsvnkHd)QRZcbW-B5 z2{{(2gd!I<6j9u{-86|!af|xTV{hE!D9SQ=QGr`zoF{!;=G<&6yz)3h;#`~$r#B-PZqkp6IkJ;x7T=uwZb-|nj%EP0miuRp+GUsyCweMtwCZXm#$4Zkmjx;C-t0 z_raIN!;RHVfm)gZX46lJ)y65^Gzm))M-ELXu-`>o;ioww){KI5<6B{w)=g8cEVW_% zMiQI1i$7wpS99zgTf(I+?xu-WiZ;xy6s?@Uq;4rUPwA!^RSG^vF?bmdEwVNhPDSURmQl1v|dBR^rsn9HG+Ehx#R7xq8%mJiQ+9#D#-IQ)U zkM#$2BNp@gs#wy=Zqw{Bd49&E?hHgq9T|EnRE#uNs?fT`Tzhf1jz<})80C;^nsKj7 z95QHTx0VOb@4ropDa>GPtm7flkDuAC9%#%yX->CH=vMKV z$_-+wSXEPXQ}5rw!z(w4seP(ys&2yl+Xs-!WHFV=l*+aNq%yfrDwB0H?%&E|{Xs7m zOMa4k_@1Pne*YF8aZLZcT#Q&ElKlkb(?-V0_iyI${$ThL!xys(6GxQd!6to~Izy|= zuzzF!n0D2_Oz#2iv)^pL%zm!@B>U0!R(r&LguU9n$UckK1vu<>yUzB5?L*rewr6Y) z+PZAl+Agx4X4_@kO1lPvwnJ@#ZN6=??I7DQo5}i%^>gb#tuGnJY45i_Y`v3K5S(W{ z*?OFHn>Aq#Ti02aTLo*Wb*6QKb&NH~YPV)sezJUFdEfG;<$24amcLqVwOnJlh}IdL zpuN?yUAx4x%Hpz2w~Vo5TeRk{=uO1)=9|rzWGvMdn9neuVBT)7({84f2#1<|=0&tZ zpxB&m9%eR~ex(%&@0ngVJ!^W{bdTv~(^aMmO{beqG_{*rOpT^m(<;+qQ-x`cX|ido zX{0IJWHkO}{Mh)m@nz$a#s`dd7%wxPY&_1m&6qHTY1e~bEH%zF<{5_=jfP(hUl~3y zylHq&`>Xa#!$y52oh)#gIj+qy{LOHe;ReIyhO=ph#18E{h8lyP-ipjLOfcjdh8i+6 zf6V+m^WDr>GM~u2H}l%e^D_5j9+kN%b3^74nTsOZD09KNi7 zLVutB7X6j_bM<@l?UtCnS-)PtPQOh1w0@F)q~4VAo%W)Pk22oKcs%1y+I?|W#tGV) zbPhr=W4<;-Ra=}fJj0~>N%x8Fb=_mSJ9Jm-&d}|qcQCEGs4l2mty`jV>gMXE=n8eC zbVGD>Amsnw{teNM(P+bsO_5L|&18mxs>@Zoe>3Z{$g_^QJF|2n$t_NEGM}OYb>mZ_ z@O9b=5}f!Lbn&3{lOximx=eMv?{^7YrrK3+)eU7z=@Zr#D>+)E>#Net6RY#p{*X58`J-t~8sm@pJ z>`CcdRr@7UO6RDKeA1}PQqyGHqS<$guF{#AqHE!db)sv|~q}q?SZ2?s$_fo268L=n<18=gPIaB&UB#z^og} z0@OA6{Yf!fbj-@CBYy3@ShnV~-ixJG_aaK9rQW~dCea;l^)LQPbcbg6SN?(&BDMa- z4QNUc|Ki_7SLuwupuRV3Y?{^3TsrGD#M}@e_v0w34GlF7ZT@8^K+lE-|MJ12Ae5+^ z?O!4Vo0e>d`&Zrw%^UnHW{R%TnMa}y*0;`%PHSu3gMUQ?rmYXO zPW4y6Df&w8(JF^rqIjxPQrqXn*0v=JnC$`gpB>>0&W_B3M7$ zzp?@rg=^RQtG<`qGySVR5#5s}m(F?+Sq=M_{D?d>w1uXZ&iE9H8e)kVG5_Kd5uqW{ zl&x{mnTg$ zaBFDbK6}SklJku1xsvnrZAVMa-CKT;oF}v`lAOC*zmc5BwDf2=viVU9jn|qm8)(no zAs|C_I}%>ewWUcM4(m2Ye>I+~GEo*bMQ;$L$;K~5SE8|9bj2GNimr`~(?nM+a=Yki zSbwMSFI-FA`bDB&X#F7LH{37SaKGqR(;yDWbw`A1MZa~ykmy=lTP3>utIrT!ORD^q z4P47&?>VAhl^_n%bw2koqMx_&A<-o`r-&|3#hs$dUG|jds$BGw=yH{wAiA6jt`l7q z^RE4U5jSdiLTj`x36bY|$@2SG+ydf^(6VU^o)@A9@Lf0rBZ$M{;+c>vgrS^*%^kraGaxDyNT}zEIQWx_s{6`dlxX zJ)_U{q{2u0T<2uJfnkTIUq^S&%0<7(e4GoiWIn^}d;0nWbB0W&$4Z?|H;g@>&}dIj zODAj-Z4L!0=Dm(y7o?j#jg+hlv(Y18a_-zzhB^uEh>Nuy+|sl{^xGVJTy!NGcZ#lf zqZDIf<6zP6h&r*I2iFDTqTiaD8qu{XAhzG&%C%>Te#;M+q|4SU7XAE-=ZdbSRbmeh z`rO+@Kfx)b<|#i#^s8JX_Vr-tjORqZnG?m{7o1e|sOXn7_*S%`+BW}^_i!_*ZHa8y zTpMliFS{Gff`*{P%C*P#UMxSn5Q8j9!gXzjuG`u>R-Li^_}+`tw~gq%*t>Oe@5Kpi zxA$J`YNeZlG}s;6+SGe-Oe^&tNwRZORqsW6^P9aFM>ao*nxzbFX*#mUy*YMDk9%X| zq#k!uJ!yry>jw3*2%E&e41xG~mD-#lfifB6DbQ;mP+ z7|~Taa~Yxpnx}>~1}9UsQE{;ctw4NAvwzv4$WI_fk0N)9?z*IZ^(@gnmF`$Sz&*P; z;$K;Yyv(Lswb-&|`wzVznV7XX5{mejQ57=%vzq83}}XK+pPFJ6OyWZ%*{HvgZcIz(lA%zCeNl=(;VaMO{-YYau17iHS?1sRKU zhih-we4%lw4zX)(U)kQZy=r^H)@{4ZcJ%cHMp;eUC$kHVt{6qk*PStH~RSZD?*{r9-nz5eHcxinq{W ze8)RSp2n79lV}3%ii)@K#jmumo3&0?S^2DJw!ubn}ZKuv`m3IHX9g|G3p=1jzr9~ zArzvKgZe6Mv56eQ8y=<2W|ADFf$b=uVUskm5g-w3j@PpGhxBEACe$&WnP^mx95bf2 zJu|CT$;7gitkT$6v4riMDU~~Um8OVNcFPnZaIv_=eoIOyY1C&sTf~zQ_(-|j&BtD5 z6fH}Sv6~2#NY$F6Lm?%xE^Qs-#0Hx)cCj^Uv67v|3(;V!d6|ld;sUKUAm*gV0bgpF zRIcm>BkkQNR0tyGD5Il@DFSA59HK7*PTBxvs z>^?#3?gLc1yf5&^L?xFR4H?cCk%^OFPD9p$0~d^tD^Fd}+%+rin}C zFP%uzL$=dVx+vsh2pVS*8yFm0BoX>uKpbVLe^DFeB{Qj{WU^yZAks`5$=G%;T7tmN zS#qoov&S*13?w!Eq<~w*0UZYql8mahW>u%PDXfV|Hc8u~CGyrJT@(fb$$$eJHh-%dxzL85)sp_h|=%hTFdrCHI(K6f-iD=m3W;Ow;x z*M%W^WTNM^9^2@Fjo%N%p|RMJOh(woA{y08q!VxWCe?x2|9_VX+Q5j8F=(ARLkmh5 zWR>=RKS&wzDl}f{t`KXIP6S{_Uh$GCY;=qhJ=slxjOqEJ6mC#lvh>mXt^F^7ko)YO$%A~ zP1!Qu8(A7M$!r=`>A8UJH!NyUd>UiFhNXGGev6}5)t|@*N^Sr5|Mq|XFLQlnZRY;( z|6OGMANl@YG|4{BAvpO*Lg-5uE%Z zB7&2DL_~1%kBA6P{t*$u$v+|@I9rk37GM+542Y&Aa1{qO0!=^+hysm31lRzq2f{!D zP!H4rAs`6U0yRJYI09G)tOX7S4g=NztASO(NMHnz3k(NxfCGVHzyZKeUn!ZA#ee3K5!mzE^rQTHgFbjCU6FDI&d0rDsT#LGH?>G7uW-I z0K0(`ffIn^fnC6Hz_GwFz|p`_z)qkYI1<$il>5`;;G=Kcq+Ilo(gV?r-GZ}so$il>5`;;G=Kcq+Ilo(gV?r-GZ}so zb^|8@CjiF-yMW_>V}WCUqk*G1EvB~fXTolU?NZgOaO|3@xVBs2q*-`0tW*Hz(K$mU^I{qIDkB06fhDP0ptS1 zfgA>}`#@kAZ~!nA7y@JigMlny5MT#vfEBO+X21j(0RxZ;=z$DC2WSBepaytf@mBuE zuPT29egS?4egb|3egM7)z5~7mz5%`lz5>1kz5qT4J_9}l{tbKrd<=X9dB~O!1KU!z_Y+Jz|+7}z>~le zz~jJUz@xw;z{9}bfQNtwfd_zY;C|pf;IF{Fz&*g-z+J$dz#Tvra651ta4T>Na5Hcd za3gR7@E72E;5y)1;2Pj+;40us;0oY!;4&%P4T(8 zDLywh#pmXx_}ttSpPQTFb8}OCZf=Ut%}w#SxhXz3H^t}Xruf|46rY=$;&XFTd~R-v z&&^Hoxw$DmH#f!S7EL)67OezU0Ly`8KsDe8mI6zF#XuF{1H6C$cmOw03Ag|!Pyv(! zWxyh!6j%r>0OkYpfVm9bN^Xj`lAGeKmV7E4eA&N^Xj`lAGeK0Y<<8WCD611JD6lKm(`&6^H9L;8)-m;Ah|`;78yG;CtXZ;9KAu z;A`M3;7i~O;B(+J;8Wn=z$d`Rz(>G`SpR>b%Jz=+9%})e@TWC?X1Fu+u1t+y$e5^W z*ZxKGh9+0NR(0b4`L6Kx#e3EaQkAh4h6M$yLRqU)mv7KA4R)^4M3J-{LcKt}fGy2n z3r)-DM2#e^hG(_!mP$Xu4-kw!r=JWFxAD%Yzv(>ZvWS$>@#Pfuskl2F5-bp=A2Y4Zh3@&+XaklP}L?bjM5 zouWxqdsb$lkL2fpNWdodP-VI z#}t(~mNkTEuTEo__YM|d39YPSn@ni8jM!P|3kx;0tw&t%FOF=qz$_W7=etp8VQh?# zb3xi!R1>59LcPoI8Uma6qP;|IoVFrKRoRoZl@ zRO{7dTJcJoA)qw%Z_j=Rc#8Xh=m5y%gm82M+sWZbL}|N21FaW~)o~LflZzc}beA>* z^%zD5h`NxbV~d#W>3gch2AG@c3TL^LYgF}}>Q|{o#S?Wz@Y)pJR5<)h9`VvahqOg$ z`!8E1%|Cp>Gt3U#lD-VUmr$qN-4vCH8Q-#pKDxs1m$PSwo3p}cGX90?YboP?`Up-u z$cG!Yvb_v@?fUoSIq6?iNDYZqO9#XJ@#EWz+OpdFY`pn>dsBU?`cx_a+QP=qghX}|vP+&FnO`AoPK+km<3l(a zrV@)p=rg$V>BGXJIrIe-TG%S8qN7@qg?02z6xyFu7%igBNHRqZp8W*%UET^+OcF@561w)SCtx2g5hj^0&$ zkWwT)y@)T_6h}SU&Rc zdogyl(AY=HQVMF{5*Ldlb5E7nR3=VrS2t$0)A5GA-`MJ>TwYVXol-8+ajkTUS|r&( z2KDuj%B8PwVIUZ!FW%6OPFgLF-4Ml&2Ckt^+7$LXRVih|cC1qCSIbu_SsE5LgzEnLA41-eW1C%=eEmL z^hOk`D1VPvtfH}F+sB5o+WYLg?Wc;KR6UuJv$9xJe5N4vy%$nWdwrDp7j51UmC&P2 zzn!{QkIYoMlZ(%ha$9?&{0B*kg*1GRkd6Dq%$e=#c6IuO{IKdVsgy9POAW_MEBT{z zHUl51WuCm$`jzlT-P4-?=$#bgEiFJ_WOUnzE z+bm~UHd_v}%(pl!YV$jE{@$hZoxVD=%UozSnm#f;Zo1agVT#fjdy`CA#xIS}8*ee5 zZro&CX`E%uG5lzF-EcQ0zW?9;64+k?`%7Sd3G6R{{Uxx!1f&uerCreb`M*$KC)yiU(qImFc%Hm%~YUlNKLHemj`}8L!*f))+ z2dYaIr3)3M3lydE6{YhOrE?Xfa}=eAC`xB5N@pobXDUi(C`zX*N~bAGrz%RPC`u9#^!j?HNO-ujXCRqLbHyR27P&!qPRo2`x3fVJA{qBH&v zvJSOsE#J}U{x4b{w%lR4+H#(y!?MGYu!JntmNGimf2<|PVm1F@{@DDg`4RKo=D*N- z?9=F7!X|o~u*zI%o^C$aJlt$B{bc&Y^tS0m(<7$4P1l<`O{bc6n&PIlCcmlFG~HBa z$~9SxKN>$X{@wVr@qXjY#!HQ-8jmuz(CPgvj7~bcf1GiY(PsFK&hCHT@S5RK!ySgJ z4Cl}}{YM(&hLB+yozp+rFvgH=P-T8dC-gr~C-h%OC-m>76Z(_1OMXS>!pupTV={-) z>HOc(>HIJ2AJN~V|BL=&{i*t6=v@9<{StkJewMySe;}R9|8vI28LwtMmT@;u<7NxGwSn{*9yCV!=Fj;>fYlFmz2 zX}{KfpnXmIi1v2vW!f{f$7{E0Bih5YKJ7g1M6E+RM61_)ulY#xmgaHIotkSk7idn> z9IZ)eYBYXLxn`!ONRz8Esee^}s>!ixEbV*d(lO&|v=1TQ(7tC5oo{QT*U5slea|6u z1Uhrmfi9t-U~1npn-1z$)5%~7K|@!w*j1RmZ6;`q?R#cYL^XXDS{P5F8FVJ4kq%R< z-5^jJ(^(qyeu)k>6tuSXJ<~|9nm$Iu&J79*EEiK*2>MnK9Y7-JDHl^%E;h_cutX=b zWZ2ndJkd$)icQ4xtBE|FI89cv{Fbo%(u`WXjSkNc?CpCd&?)iExG2rdP)at^T+B4n zEFsf8p6OyIIteH7;k~@c$N+J|up$_DhH-u{&ScZqO4Abc| zR54n*Jb*H6#A)74I+R@oLo~%75-9saC;=m#q7@Y={cM&+c8(1@yoQ@Fm>bjxvN z#nR!^fGp}DW;q=WBV^Kro#|Omv%4%mHWrJ`18|X*g`?B^c(yGp+jIyft0Fo_nOb9# zt2Qy!p~j{pm1_GQBg-Vc{H71TvqoW{gZ!zL(3D(|H9(elCQGj&5lXTPJxhVPwN$DZ ztVuP6o9JN1Xow}FW69J|C6Hn*QyiyH0#f17rG{OynZ3AKT>II@7T@~Z%ov)^6J>eEDzFDAj?X}R+bg9F(=57 zjxEd(blqlj(2mV4Mq^+@NYIoB)HWtt&#xjOsxV47%+jR>LD_3y+2idiE(~h#sHf6W(+EV%7s54E0o3d} z>R9_pw!~QQ5b2?QOmFms0xzNaz6!Nm$ zJC^Ila*y5<6a^jC*D_XLK^m~)^=#bGlZn;LL^|#+OqIo&iJuZtv-8vhJ+-T)tTyRP zNjmk7&L?8ITEdbFhUx;mOvqy~%Vwgvi67F+a#qE1Mql4#V{M0zRpAEe{Je0zOhik( zghMEtz%J+uZbBxNl82QN9g|9(mTnpyZc4?-1_qiPV--=!av7nvOxuF4PBv4OpPwH8ZnaX-hbC^c#jw!4n>u4!Mtc8tQWYlDq z4qt937|GyCtTt$+5W81(Ok~!#1Zc>m+?TLoX(I{cb^^<7eKRc{Vo8v&m=$lZM$k|< z9M8KU4T8Zygbx;!rEx4v;&TR5P(;^ib`WK(neMTajY6Icng>k^(@Ec0rY{i_^i+rk zlZb9PVoC)}(m+ocl)r;mW@*sir8|ZR0!hI}7LO*kv4-6mI`Ubi;UmMWLLDqhT_Yt* zrIANw^bFX7mC_x>j0`k|S|RWb)kyl-T~|$ak}$u|cJSM7f{vF&<2Zm@oD>eAkV9EWYUYWM zFr2jVdoDdX@kX7^!bPbWQ2K*eHLy~pXA!yuwRg~0blAOv+} zjh$6Z4IBLVDa7nSti#3>Qp>SYXe%q~Kpl-WEG`}I&RQ8g_plMc%w&;38_CEx6RS{~ zw5J;#Pua+dk{yGcr2l!BH?Y|B4WkGjTQgZIu{hVHXPTPX6ela@3}!5Q_(Mb2F(JEM z@z$wjLRyC#rh6ylLBn&z?lC61QnM>|`(+P99qjIF4Aj$c;q04El*ipWSRU!gh$?^; z-R|uy4=psZ*xGk*WBH{ARDP&98x?kMWz`+$^So5uyZNn`0?>)nypNK;&8$Kb^e9wI z&mg3)jWrhfL?o5f?pBsfIhJKT z%vA9Mm8sTtH?XXu5$Uqpch}P$kry6+5N9<@$xTG zvX&@jh4mgCC0EOmn?(Ouay2ZuK(LWo6J?a&fwAt9-9C38!K$*JhC9m2I+hhaEVFj7 zdo3?T>J&8gP&**KhcmqiI*^dn>tU=L)B2KlvL?jt6Qq0%D+MeV6*4INYBokR(9=DQ zF}qi>3p%5a4Mn@ztyj&;Ko~(+D_It4Jg3T_fGb!kp;{W=Nwk~=Yzf5a$$-*a#?r(Z zME)2@xvXY2E7lZm_`CTXw}w6ao2l%U@~Xn}PhK@kSk>^Vu485_CM$cNb$DG@u{7Bo zLnx;l@H;NQ!La;zSyuUR`NIDF|NHm<@8AFbzqtS3Q^7Y8c`EoOBG3L~Q9R|Zu}w>! z@>hXZfR}-nfER%mfaihdfM;&3@BY_>jc3>N@71#o72HJpDpatNY>OAGmxJm*EAP#H0tA*B#Dli3@ z3`_zh0wur%pcohrj01{*LSQU#Fi-#-1dIVj1Nndh$OA?JBY_b>E-)O(0S*L)0S5p> zfgwOPFc`=J1_5@!23P?LU7eBk%+8 zJ@6gyE$|KSHSiViCGZ9CIq(_qDe!OL6X0XuBj7{e1K@q&U%-37yTCtzcYwEne*k|6 z-U8kP-T+<)UIShQUIAVPUIJbOUI3m4o&%l*o&lZ)o&uf(o&X*P9s?c)9swQ({sue* zJP14hbOZMT_W^$e?gj1v?gs7x?gZ`tx`5k(+kjhvTY#H^n}8dE8-Tw6*8|r9*D`p@ zxhbA~L;wk5*c*?mco^o!Ar<|MODd(nm%DE|?a&C&J zoSWh)=cahdxhbA~L;wk5*c*?mco^o!Ar<|MODd(nm z%0*MIfkjsXR{>W7R{)m-mjRaomjIo>#lS_tg}?>C`M`O=xxhKV*}z%AnZOyq>A-2g zslX|~$-qg#UIup=H^p7XO>viTQ`}|T6n7an#a+ftahGvZ+-2MpcNsUuUB*pumvK|v zW!w~Z88^jU#!YdTaZ}u7+!S{iH^p7XO>viTQ`}|T6n7an#a+ftahGvZ+-2MpcNsUu zUB*pumvK|vW!w~ZnP|!$SkwXR22KP{0FDQC0mlKy0>=PH14jWnfp*|XUVY~S1O$Ovpauv4 zM*!=9wZP%PVZa(-HLwae6j%wY0G0#GfNH=GECrSTi-9V@2Y3Mi@BnUx%Cbtp1vr5U zpd2Uz76GNeLSO+fAD9QsHEFl1KG9T|%{gYfIfG``zc9UTdeij0=~2^PO}Cn^F9b8O}TnHlC!HFp>e)c;HWqW(es&H7IL$@(Mp34Me9aBa5UuQll1 z`i1(L`h#e$-IDRMWl+ZZ8E<90nDIo$0~vQ_+?a7?#)TPYWOQU4ov|e&o)OMCg67_< zGAc6WW=y5|_xy|lGwd09-7mVYbsy{A(Y>mBM)$DpUfr#_Yjv0C&e5H$+ojtSpRnbOpK*+V8cWWqhvx*?6n=AKF_qLCy2p$7pW;4DD{qh)lP3qc)^n ztzE1=L_1#dt^G62b()81cg6GehwQi8ud<(O@38N%Z?xBnt1HIaN80UnHGNz0J=@E+ zM{Rf6uG4&IyV!QR?ReWZ+eTZ+w#w$SmD;A*95$OxYyHytck8p(hpcy4ud`lkJ>7b| zb(?jgHDq07^;t`;)2&6;k=870hUEv#zb$WDUW~HWyTvoC+L4--ar)kzFHv7SP4l73 zvK*3$L$wn$G^bL*UbcH_FDUIjijTYAJX4joT$-qya91{6+m}nrGF2*@Hc!(l{)b(g zuUSd2@5}h~N3oBId1~zAH^r`glelsS70=38d;`56EDy&Q$7u^vacSR}^ZQ=TF=(?j zG!<<5>US0ywL>-Rdx@5}ivP$WZ4QM93!%2*(MXoIKtu02V=ev=ZE8;>3%)mLhiL*e zG{;~3rCw{-1d3M;(vIOqEu$BFG%rzH%`$^XG~1Rvjpd&%%fmDynphmKqIr44Ra{Md zXjv@V-|JjzW@*=lN+Xex#oU|buoC&N>AzFy13{K`R(KPS=SGky?;4&|Fj!4*O9K(@ z<$W(Z`zz1FA^rJI7%fIE=O3jUyO@_?FgSLZC?OO9(K$5oQ!O387BCoLo{iT@KG#YP$qM7ul8wlH)ANafakLO>&$nIZlxrCrgf#B*$LKu}g9sD>^3L5^)^O>Kk8U zT1Icj$8O@yl%JtnIP>c*+FXnd%VHB>=e>*#Ox1M0OSFDOLhi9x=3#tL?(u-kL%UAyu~zP}+%QO$ zu~I6F?|a0wSCyuR4z7@S6nrN0$T!P89N+T7q|Uo6R!V;-zJIqYMD8R$;4xF#s94HR zq!^*@$J5x&IxQbR*{0wTtNLCp>2s+)zVGF+eJ_vcdwDdg2Cn&FcaJllR}S}ed}sJU zWnj+K8^)x(p0FcYdY$oJ=b=4L<1_t?>$%(e^NjW5X>9AyvxQqhW8@0qmK9o{P>J7J0XO9kE$*}jWsyB*fE;VHj#r^WHK6! z+vv}>(c=YOJ2fe;pl2$XPBMV1eq)m^wumi3x;U9OQnqdMXep})&yrlDH}tp;?Qxa# zxDM`d9VEH(zwB|n(Brzj$JNo}+STJ))#F;)<3eGPS^2XqN2=~)20D%**JsR?_YS$< zW3G`GNHInpC%Hyc_PFNvxMudarok22kiSrJnO`2EokN8fP8PDl;Io&7Y#kU~ZOi)# z!RQNV9?6yWb&spZZ$uUITS3bW@_6RC%RzpN`Fg65XpqrGGTAbLECb`9Nzc~<@ zG; zXFy`3U`ddkDVP73(N^#$o;=U!teN&42h7|YpDeh~zJCUGen#C8eftwCh2{qDEM{PO3 zb<--WwsI`aN*Fh>Di1I(8f9oDShkwA5AIQTAb&1yYNACFRk0+kMKQenJDwT_X?Q``?pR1SqT)o)m>V-a6&-b}{w$IhmeXgGBbM-`@tH=9XJ=*8$ zZ+)&F>~q!K=jy&bSAXqubx)tGyZc<-+2`sGUir}kE%)-WGi$OJu=W4bRX3~Xw`tTq z#`cPBugzus#d-tn@*iz^jn?QdG=D>D@$1cbrl(CiOp}c77*8=SGJI{g#Nan*Gat&_ znmL(%p`W9#(rYqq%SdL-)P1hIN>{5JseM6vqIRL?8_m_4kY=>{b@j<=m+BWvYM=jA zTvuvTl}*)*v}@R!Nmu7=gQ~1(3@v%!3n8O{h;(q0MB4e#_mrM8oE^8gDVd-})QJh~ zGs(UwuFhHi6;19*uFjeN6-^aWU7a)jE1F8DmUm8PnsW1asj-#gk%_gDX8MUAmq_JQ z2A>iUDX$VVN`u&f20g)DO3KqB|F-xLjl?e5O8 zq+#j+3&YFSj#l!er@t!^)p&R3!GBVhyjWBwcW1#q=;CWy`_Gs9E6UeFe^Qq$U+S-@ z!;c|dlLuH{v`946!V67aT;I*jp!(h%Z)YCGo;Sb&ev!1X!;jy1eFuB>t%j=3QB2(c%UZ7P zcO`zqq^i!5|A|6*x!+(CI!BPgIs0xfTVpS?_i}@;GnZ-GcYB$(-Odnte;0J{z8raP&Bx?^5gQqi#sTyF0QdLnM_N~3TVo&FwKdVe$b#+vAc2-ma ztU7L8KUL>7R&?6_3wneRWt~>0XMiQe^Ygo^6HJ~?%RUrQ&&qcCDg8TT|Bt=*0B`C_ z0!F2)-mwihh5$0)*bc_nG-Ha3WLxgQHJt#KCD|61C8Od-F@^vM5K=ZIA-yM?vf1<^ zrze|aH@(-5v)PnQvT2)5&*qGD$9e`I$Mg9uN{tWey`fcZCX*U5^qgGbLgh3{JAQSW1RgQ%+M%NpSL$pL(hFgx}&AT9v#gokxq(38Jh_ zUX;y(D4Ri)70HX@Jz5lRTFFpT@}jf~qO@9ShgiyBS~4Bv;YC^HafyB88Cx>6Jb7ta z1Zi34ae_45rI9F%Gqq%BY4XBs6olCb!Zao?%!bi~*)XPLs3Cb_)(OI_ z17Yfu7iR5f!mNeyTbH~rs{~)(9IG zCNy*5&|>;*+PH+D1^3ZmxGG~p>Gq*T_~Q6CWYQPo^)-1uANb_t0+)qD3zHS0Dbfj^ zISQGO#xYb359cydCdQSY+nRB==S`%FSDtNX0dUG<(kCUzDbU6E znuv=vS3cbNfIbT2V=9M=kjb>fnRIYWT)aOVrUORAeB_goIG@dS;^e^PV>YWxhUU@7 zxnE+A{hI>RrJcXHaxv{Y77fj%48|q#{`N|6bpfw$SCkLU!KagG%C>sAW)WJlO|@ib zHsvu9e@sfK3NG%z;$mFsB}0Yyd=fQqEsL~(b#yya!lm&H6;K9gZHae*t1=jL`SLk7 zIpB3E&+5wOq{^X(A6uU%7aZq1`^dFYF1)8~Xch_@{|gjHF!WVR1G=W!918fEmT`-R z@=??zSUCC5*g1R2&`kRHr1t#3J#L8KNYmd1yLilCd zPHrx|qH<^&eMN$uD7<1}Oh+!%mJdzE`XyZQ%KT0(kaYV>Uq~z%8c9#+Quyjf)Hq8A66^{m1%S^gex# z?ytHFbPd{1v{!2vX#S4ot7$Gog8_#vO(1>os^R=8@&inU5~u_M1bGWpy@ z5B@;t9Kz)5Z9`KiqXdUI*E}<&1AHd4WN0#FlAc&UaZIx51)ht^)-4&DbR5s0MDK20 z%t)~2aShb9~chfHDV%rx7FGAM@x zzZ|Y5tz5t2R>*2DA3A|@nUYjZCd1vApLzv!F_X=uL+Qs+mq|ivOfpvwjRy{Mm;`%8 z(i@DDZix7+}l$|k|RnM4Tr_mqG;Vwe2;6Uv9uD4(>% z=HVDVFcZ6c^6!o7hf*nzjM9Xr;TRsmObpEUS(uj(W?#}koh=SeHP2=GeyOa ziLy#?NJymmly7mD{L}IFAtPmzk=TfkvZc^y3@ z@~q%MGZ)_A7}C=>B=}8A-te)cZ(Z__Q>uq_lv9FdHVLN>V*B6&MfH&OI9a_H%j!Mo zP7P(1e0RPpcIUejZ9{65DCzEe7i_c|*FbN+Yw`}MD3gp0$@b>E!Us;djn<#8d_Smd zasB!(tbj`TuC(-I-}MHWkn&xvZSpsC%|i;x#j-MKE)|qVKADhm^ZDZjsP}hx`ts}P zy0l_NJ-niNh{2XkY=18qHm}C^^{Wc|kesqga8Z!3dWByTERJ!l#IbmkyU&q7s#_f0MjxCQf6d??e2_Z_!_f_tW#kW9YNA`=@g+=x-67~b za7r@r`}l2;{JxCZXg~5w?E5>KmvEaPzfad2?W4@nB5~W4AGAj^OWOcWCMGzEM{f z4PXtD9!B)7*GWhBb*YZ1AM0>@+^*%v>;QQZa zZZ@3@UjDb4x=e1<8i)y4W}0itF`Z}{V^SKwH-2UuhWLO_8i$O3G+qr+0uLH@8pFnR z&?i`CtS~One*5Ei^pNQe)Ai=d&FAXIYyYJ9 z!I%fp1;-k-hMx^z8vbs0-S9NrO59<%-f*$uEW@dWUW3ojY*+y?0u~zz4ATuK7>ov) zP6aj!?`vPwKcRmB{21J%ze<0h{%rkeV8hU@@6@~X>mg!5jlN7@q|eu9=}*+FEuUCk z);+6xM0c0&2HmA#<*--Ruk(YZ1FN&?X6vSE?*e}Y=V|w9yS1&_RoW`;eDG#4UaQu8 ztN9poAYRlwp&8QLs<~Ekk>)JT9vUrx)s$=IYi4MynsJ~X@vHh9^*_{qRlh`I2HdK? z24V)B209Z#b({JW^>THUdXc(7ou!_jwy2e=A5@>K-dDY@dPen#>TcCdsw=>k!2#7y zRRm%PY*MXI)u>9qk3o)Vk}6fDfqR#)lpiYJ0v`sqD6du?Q9iD`Pq|MS0lx)x$_nKY z<$UEVWsWjaIYF7GG%8j6U;ZZMfAIgOEs&v@$2374ci3u&;fJ{p?7hJgYRHqGP3)?` zzX13v9uLlDEX<0r;2ebjaEC$wI6xr)T%HgBzD@`L?(A_q;T zm}(VKYGh5TshKRMrirLoL{$Q+{!v7K5Yc=QJy}F^L{xmSdZL&*K}0h|bi9Dd-VxEa zMD$G&eO*Lf6VX>i^c4|(Nkm^1(HHo!03I{wS~c!pbgWYAl9ZVeochurw}hcI5l#6P zSwU*bzeSW2k)*yMrrs-}_Xy~ir$qEg5#>fCa2UgN3PDqeMIF8C#S1;l){zPQBNO^Y zCWQExc+w04Y8evI--+l!5j|Z*_lW2=5$zSx9%2Sa#3Y^`#vZhQ-FOqkb#ZwbJYnaU zu_Nd)BWU9YT0er;#nKQ zkKZ>kVQ^%^z{rGcBENB`jd<5tBj__n(1%9Qn<+2a)@jtM2DZE9W-;AD4S2cqBa-y< zCHQ#~{ICQ+LxOiw9L#{hvU3g0yjn8tkDPwf^+%=Xi0_z@ON5C!i-FWJlZn3pf}F@B zC-6u*kEHO3iAM}PqU8|{k0^OW!6OWh$T`IFA0GLIM}FdwA9&Yo7Ru~bOXsmVW=zDSZjUxLq;;Q11Kh6I;vi!9S6=~f9oNrFqp zgC$*(E*TpZ$=I-%C1rFHTrI&F2`)FECDW`(`$xB!Hf~UY4@mIs5`3!!4@q#Gjp(=@ z*Ct7Ck>DHXT0zP*M0&@qljKNxZrmzKdXofaW1g-QbBt~YE*TrjyTo+mpk=d6DbnNi zN$@?~H0||-mVtS9*pxLgVKP@5N~Aa?crzCC!S8>|f`P8k*xN=X+(_p{8q5Lrq+@SA zD&+>cnWkl`S2Wa@he5@wg~ZwzdlT`z(FB2@#@L8+qbATn0WWIGJP9E`6HXXoq+9W$ zX5o~hQpWt&_T9AXw{p@?Vm+hH=IPT%O`Qh*|7AZth=+{{MVgpUiTn#b?Qa zU-=K3%S=Ck{lCXF(fFKkkI`n78}2o1G34pL2K)bzK3n&m?svL+@bv$nHljUQ^Eb_f zng)$Z9aa0)sSxXam&&fvK}7ql%3{SQip#(czMQ$6@iSKW4f2ihG}&XaKJ9(l+dGEjN?jlApsbQtgP|G`SJqPtF|@FeUkQ?JJ}${X!<;CKT_R|~Tmo7! zUSyS|77Wiy)PlJLv|!pPuVl4gcwWcWg29qfEtpF{3#JWgkfh!U_tqm)Etn&qc#-H&lsqxEA?m{BimzsP zlsX>A;M`cf!*eaw(H7*F;(w0V>fn7F}o>&i1 za~ApjCKBP8SdPi}GnLUzl*7ctv}KXQ9u@;vxbj0DkG~-z-=nohH=-oT@Hv$Q2dEta zms6Rd=my|2=~%|jo!~#SwrOdje1IE^1E5-Z3VrezRz|{;TczK`R%2y!Jv=@yQ5&u< zG$o}!Im>%0d%;--1Q3?@=qjV@D4zs1bYu8*3tGC}S!<(fDIbeHp@}(`�Qxr00l& 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±0A*039ci!mf#wK0|fgCt|r(=a23Io1XmDTPH-8) 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 z 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%0Dl<78us(F_ar@8Q<}pAB~!uEX#4 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

6<5z67t8GFO1pkFp`LFy|wB=uz& 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

Qp0C;SKFIg8puNQ>#M!ZEdkO_=23Z9W0<$l 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 literal 0 HcmV?d00001 diff --git a/.codesearch/session.json b/.codesearch/session.json new file mode 100644 index 0000000..269ac30 --- /dev/null +++ b/.codesearch/session.json @@ -0,0 +1,23 @@ +{ + "root": "/workspace/repos/git.k6n.net/mats/fancy-dns", + "recent_files": [ + "internal/server/stats.go", + "internal/config/config.go" + ], + "queries": [ + { + "query": "(?i)/api/", + "command": "grep", + "at": "2026-09-27T11:00:15.297072822Z", + "focus_path": "internal/config/config.go" + }, + { + "query": "(?i)json:\"(degraded_reason|p99_ms|recent|latency|fields|error)", + "command": "grep", + "at": "2026-09-27T11:00:17.585327659Z", + "focus_path": "internal/server/stats.go" + } + ], + "ast_pins": [], + "updated_at": "2026-09-27T11:00:17.585333149Z" +} \ No newline at end of file diff --git a/STATUS.md b/STATUS.md new file mode 100644 index 0000000..59ce35b --- /dev/null +++ b/STATUS.md @@ -0,0 +1,207 @@ +# fancy-dns — development status and continuation plan + +Last updated: session checkpoint. Everything below reflects the state of the +working tree at the time of writing, including known-failing tests and the +exact next command to run. + +## Goal + +A lightweight, high-performance recursive DNS server with: + +- **Go backend** — sharded LRU cache backed by bbolt, blocklist replication from + multiple formats, per-client ACLs, query logging, Prometheus metrics. +- **Secure DNS** — DNS-over-TLS (RFC 7858) and DNS-over-HTTPS (RFC 8484). + DNSSEC validation was explicitly scoped **out**; AD/CD/extended-RCODE are + passed through only. +- **React + Tailwind admin console** embedded in the binary. +- **Config as zone files + YAML**, hot-reloadable, with **Valkey/Redis** for + cross-instance sync (chosen over AMQP). + +## Architecture decisions (settled with the user) + +| Decision | Choice | Why | +|---|---|---| +| Scope | Full production | clustering, metrics, ACLs, query logs, hot reload, Docker, k8s, CI | +| Config store | YAML + DNS master files | reviewable/diffable in git | +| Cluster sync | Valkey (Redis protocol) | simple, mature Go client, easy local dev | +| Secure DNS | DoT + DoH, no DNSSEC validation | avoids signer/anchor machinery; pass-through only | +| Hot cache | Sharded LRU in memory, bbolt for snapshots | no I/O on the hot path; warm restart | + +## Package layout + +``` +cmd/fancy-dns/main.go entrypoint: flags, signals, SIGHUP reload +internal/ + config/ Config struct, Duration type, Validate, atomic Store + hooks + zonefile/ RFC 1035 master-file parser ($TTL/$ORIGIN, parens, serial math) + blocklist/ Set (exact/sub/root maps), 4 parsers, Manager (fetch+compile+swap) + cache/ Key, Entry, sharded LRU, TTL policy, serve-stale, bbolt Store + resolver/ Upstream pool: health, circuit breakers, parallel/failover/random + acl/ compiled groups, CIDR/PTR/tag matching, per-group domain policy + localzone/ authoritative data from master files, wildcards, delegations + engine/ THE QUERY PIPELINE (see below), reverse-PTR cache + server/ UDP, TCP, DoT, DoH listeners; all funnel into one handler + qlog/ bbolt query-log ring + live in-memory ring + SSE fanout + metrics/ Prometheus collectors + rolling time-series rings + cluster/ Valkey pub/sub, leader lease, divergence detection + api/ admin REST + SSE, auth, CORS, rate limiting + app/ wiring, lifecycle, API hook implementations + web/ go:embed of the built console +web/ Vite + React + TS + Tailwind console (subagent-built) +deploy/ example config, example zones +``` + +### Query pipeline order (engine.Handle) + +``` +validate → ACL deny → per-client concurrency → global concurrency → rate limit + → group allow/deny domains → local zone → blocklist → cache → upstream + → cache put → finalize (EDNS0, UDP truncation) → metrics + qlog +``` + +Cache is a single shard-local lookup; only a miss touches the network. + +## Status + +### Done and verified + +- All packages compile; `go vet ./...` clean. +- `go test ./internal/app/` **passes** (integration suite, ~20 tests) with a fake + upstream on loopback: resolve/caching, all blocklist shapes, allow-over-block, + local zones (exact/wildcard/NODATA/NXDOMAIN), ACL deny + allow_domains + + skip_blocklist, all four block actions, malformed query FORMERR, TCP parity, + API auth (401/403/200), domain add→blocked→delete round trip, ACL update, + upstream update, settings validate/save + rejected-write-leaves-file-alone, + blocklist toggle both directions, dashboard/status shape, logs, cache + endpoints, reload failure keeps serving + success clears error, SSE stream + emits `ready` and `entry`, metrics protected/unprotected, concurrency smoke. +- Verified live end-to-end against the real binary on :15353/:18080 with dig. +- Subagent-verified working examples of `/api/domains/check` for hosts-file, + RPZ-wildcard and inline rules. + +### Known failures (fix these first) + +1. **`go test -race ./internal/app/` still reports DATA RACE and two failures.** + - `TestDomainAddDeleteRoundTrip` and `TestUpstreamUpdate` fail **only under + `-race`** (they pass without it), which points at timing, not logic. + - I had just started fixing races by moving `engine.sem`, `engine.semSize` + and `engine.upstreamTimeout` behind atomics. The `applyConfig` hook now + writes `e.sem.Store(&sem)`; `Handle` does `sem := e.sem.Load()`. **This + refactor is mid-flight** — re-read `internal/engine/engine.go` before + touching it. Remaining races are almost certainly in + `config.Config` field access from `applyConfig` (e.g. `a.pool.Rebind` + called from the swap hook while queries read `cfg`), and in + `harness_test.go` reading the config file the server rewrites (partially + fixed by snapshotting `doc` before `Start` — verify). + - `internal/app/dbg_test.go` was deleted; do not reintroduce it. +2. **Frontend `web/` is incomplete.** The foundation/pages subagents each ran + out of budget. `src/lib/types.ts`, `format.ts`, `cn.ts`, `vite.config.ts` + exist; `src/index.css` is still the purple Vite template; `src/lib/api.ts`, + `src/hooks/*`, `src/components/ui/*`, `src/components/layout/*` and all of + `src/pages/*` are missing. `npm run build` and `npx tsc -b --noEmit` have + never passed. `internal/web/dist/index.html` is a placeholder so the binary + compiles. +3. **No unit tests outside `internal/app/`.** `blocklist`, `cache`, `zonefile`, + `acl`, `resolver`, `localzone` have no direct tests. +4. **Missing deliverables:** `Makefile`, `.gitignore`, `Dockerfile`, k8s + manifests, CI workflow, `README.md`. + +## Continuation plan, in order + +### Step 1 — green tests (highest priority) + +```bash +go build ./... && go vet ./... +go test -race ./internal/app/ -count=1 2>&1 | grep -A20 "DATA RACE" | head -60 +``` + +Expected races to fix, in likelihood order: +- `config.Store` swap hook running `app.onConfigSwap` → `pool.Rebind` and + `reloadLocalZones` while the query path reads the old `*config.Config`. + Fix direction: make `Pool.Rebind` build a new slice and swap an + `atomic.Pointer` rather than mutating in place under `sync.RWMutex` while + readers hold `RLock` on a *different* field. +- `blocklist.Manager` `m.running` map vs `RefreshAll` goroutine + API handler. + Already mutex-guarded; confirm it is the *Stats* pointer that races. +- `qlog.Logger.live` ring: `Log` writes `l.live[pos%len]` from many goroutines + while `Recent` reads. Needs a seqlock or a per-slot atomic pointer. +- Harness reading the config file path from a test goroutine. + +For each race, prefer removing shared mutable state over adding locks: the +design already uses `atomic.Pointer` holders for ACL, blocklist, localzone and +pool; extend that pattern. + +### Step 2 — unit tests for the hot packages + +Priority order (highest bug-density first): +- `blocklist`: `Set.Match` for `*.x` (subdomains only) vs `**.x` (apex too) + vs exact; allow-over-block priority; hosts/adblock/plain/rpz parser cases; + `DetectFormat` sniffing; duplicate handling. +- `cache`: LRU eviction, TTL clamping, `TTLFor` on NXDOMAIN/NODATA/SERVFAIL, + serve-stale window, key pack/unpack round-trip, bbolt snapshot→load. +- `zonefile`: `$TTL` inheritance, omitted owner/TTL/class, parens, `@`, + `$ORIGIN` relative vs absolute names, `ParseTTL`/`SerialNext`. +- `acl`: first-match-wins, most-specific CIDR, PTR suffix, `DomainSet.Match`. +- `localzone`: delegation cut, closest-wildcard (RFC 1034 §4.3.3), NODATA. +- `resolver`: breaker open/close, parallel race, TCP fallback on truncation. +- Add `BenchmarkLookup` for `Set.Match` and `cache.LRU.Get` to substantiate + the "great performance" claim. + +### Step 3 — finish the frontend + +Respawn two subagents with disjoint file ownership (this worked structurally; +they just need more budget): + +- **Foundation agent** owns `src/index.css` (replace the purple template with + dark-first CSS vars + one emerald accent), `src/lib/api.ts`, `src/hooks/*`, + `src/components/ui/*`, `src/components/layout/*`. The exact prop contract I + gave them is in the transcript and must be kept. +- **Pages agent** owns `src/pages/*` only, coding against the same contract. + +Then wire `src/App.tsx` + `src/main.tsx` yourself (react-router, `AppShell`, +`ToastProvider`, theme init) and run `npm run build`. Once `web/dist` is real, +the `//go:embed all:dist` in `internal/web/web.go` picks it up with no Go +change; delete the placeholder `internal/web/dist/index.html`. + +API contract for the frontend is fixed and implemented — see +`internal/api/handlers.go` route table and `internal/app/hooks.go` payload +shapes. `/api/logs/stream` is SSE with events `ready`, `entry`, `stats`, and +`X-Accel-Buffering: no`. + +### Step 4 — deploy + docs + +- `Makefile`: `build`, `test`, `race`, `vet`, `web`, `lint`, `run`, `image`. +- `Dockerfile`: multi-stage — node build for `web/`, then Go build with + `-ldflags "-X ...app.Version=..."`; distroless/scratch; `EXPOSE 53/udp 53/tcp + 853/tcp 443/tcp 8080/tcp`; non-root; `VOLUME /var/lib/fancy-dns`. +- k8s: Deployment (hostNetwork or a NodePort Service for :53), Service, + ConfigMap for the YAML, PVC for the bbolt files, readiness probe on + `/api/healthz`, optional Ingress for the console. +- CI: `go vet`, `go test -race`, `gofmt -l`, `npm ci && tsc -b && npm run build`. +- `README.md`: quickstart, config reference, zone-file semantics, API + reference, performance notes, the security caveats that actually matter + (`trusted_proxies` and `X-Forwarded-For`; `metrics.protect`; the + `trust_loopback` + `auth.mode` matrix). + +## Design notes worth preserving + +- **Cache stores packed wire bytes, not `*dns.Msg`.** A hit costs one + `Unpack` and yields a private copy, so serving never mutates shared state and + TTL ageing is free. Same trade dnsmasq makes. +- **Cache invalidation on rule changes flushes the cache** rather than + guessing which subtrees are affected. A newly blocked name must not keep + serving its cached good answer, and a new allow rule can rescue a name many + lists blocked. `invalidateBlocklistCache()` in `internal/app/hooks.go`. +- **API responses share the field names in `internal/app/hooks.go`.** If you + rename one, grep the frontend too. +- **API keys are compared by SHA-256 hash, constant-time**, and + `X-Forwarded-For` is honoured *only* from `trusted_proxies` — otherwise a + client could spoof its identity past the ACL and the rate limiter. +- **UDP listener resets its read deadline every iteration.** A deadline set + once expires permanently and turns the loop into a spin that never reads + another packet (this was a real bug caught by `TestBlocklistToggle`). +- **Only the Valkey lease holder fetches lists**, so N instances do not hit a + mirror N times. Followers serve their compiled copy. +- **Blocked/serve-stale behaviour:** a served-stale answer gets TTL 1, an + expired upstream answer is never cached, and a truncated answer is never + cached (it would be served truncated forever). diff --git a/cmd/fancy-dns/main.go b/cmd/fancy-dns/main.go new file mode 100644 index 0000000..822a557 --- /dev/null +++ b/cmd/fancy-dns/main.go @@ -0,0 +1,126 @@ +// Command fancy-dns is a caching, blocklist-aware recursive DNS server with +// DNS-over-TLS, DNS-over-HTTPS and an embedded admin console. +package main + +import ( + "context" + "flag" + "fmt" + "os" + "os/signal" + "syscall" + "time" + + "git.k8s-git-k6n.net/mats/fancy-dns/internal/app" +) + +func main() { + var ( + configPath = flag.String("config", envOr("FANCYDNS_CONFIG", "/etc/fancy-dns/config.yaml"), "path to the configuration file") + showVersion = flag.Bool("version", false, "print the version and exit") + checkOnly = flag.Bool("check", false, "validate the configuration and exit") + logLevel = flag.String("log-level", os.Getenv("FANCYDNS_LOG_LEVEL"), "override log level (debug, info, warn, error)") + logFormat = flag.String("log-format", os.Getenv("FANCYDNS_LOG_FORMAT"), "override log format (text, json)") + adminAddr = flag.String("admin-addr", os.Getenv("FANCYDNS_ADMIN_ADDR"), "override the admin API listen address") + ) + flag.Parse() + + if *showVersion { + fmt.Println("fancy-dns", app.Version) + return + } + + if err := run(runOptions{ + configPath: *configPath, + logLevel: *logLevel, + logFormat: *logFormat, + adminAddr: *adminAddr, + checkOnly: *checkOnly, + }); err != nil { + fmt.Fprintln(os.Stderr, "fancy-dns:", err) + os.Exit(1) + } +} + +type runOptions struct { + configPath string + logLevel string + logFormat string + adminAddr string + checkOnly bool +} + +func run(o runOptions) error { + a, err := app.New(app.Options{ + ConfigPath: o.configPath, + Version: app.Version, + LogLevel: o.logLevel, + LogFormat: o.logFormat, + }) + if err != nil { + return err + } + if o.checkOnly { + fmt.Println("configuration is valid:", o.configPath) + return nil + } + if o.adminAddr != "" { + // Bind the admin API elsewhere without touching the config file, which + // is what a container platform wants. + if err := a.SetAdminAddr(o.adminAddr); err != nil { + return err + } + } + + // SIGINT/SIGTERM start a graceful shutdown; SIGHUP reloads the config. + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + sig := make(chan os.Signal, 4) + signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP) + defer signal.Stop(sig) + + if err := a.Start(ctx); err != nil { + return err + } + + reloadErr := make(chan error, 1) + go func() { + for s := range sig { + switch s { + case syscall.SIGHUP: + a.Log().Info("SIGHUP received, reloading configuration") + if err := a.Reload(); err != nil { + // A failed reload must not kill the server: the previous + // configuration keeps serving and the error shows in /api. + a.Log().Error("reload failed, keeping the running configuration", "error", err) + } + default: + a.Log().Info("signal received, shutting down", "signal", s.String()) + cancel() + select { + case reloadErr <- nil: + default: + } + return + } + } + }() + + <-ctx.Done() + + // Give in-flight queries a moment to finish before tearing listeners down. + shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 15*time.Second) + defer shutdownCancel() + if err := a.Stop(shutdownCtx); err != nil { + return err + } + return <-reloadErr +} + +func envOr(key, def string) string { + if v := os.Getenv(key); v != "" { + return v + } + return def +} diff --git a/deploy/config.example.yaml b/deploy/config.example.yaml new file mode 100644 index 0000000..ad1ff35 --- /dev/null +++ b/deploy/config.example.yaml @@ -0,0 +1,204 @@ +# fancy-dns — example configuration. +# +# Every value below is a default; delete what you do not need. The admin API +# rewrites this file when you save from the console, so keep it in git and +# review the diff. + +version: 0 + +server: + # In-flight upstream resolutions. Excess queries get SERVFAIL rather than + # queueing without bound. + max_concurrent: 1024 + timeouts: + udp: 2s + tcp: 4s + tls: 4s + query: 5s + upstream: 2s + list_fetch: 60s + +dns: + udp: ["0.0.0.0:53", "[::]:53"] + tcp: ["0.0.0.0:53", "[::]:53"] + # Advertised EDNS0 buffer size for our own answers. + max_udp_size: 1232 + serve_stale: 0s + edns0: + # Forward the client's EDNS-Client-Subnet so upstream picks a nearby + # anycast location. + client_subnet: true + ipv4_bits: 24 + ipv6_bits: 56 + preserve: true + dot: + enabled: false + listen: ["0.0.0.0:853"] + cert_file: /etc/fancy-dns/tls/fullchain.pem + key_file: /etc/fancy-dns/tls/privkey.pem + min_version: "1.2" + doh: + enabled: false + listen: ["0.0.0.0:443"] + base_path: /dns-query + cert_file: /etc/fancy-dns/tls/fullchain.pem + key_file: /etc/fancy-dns/tls/privkey.pem + min_version: "1.2" + allow_post: true + transport: + mode: auto + +upstream: + # parallel: race them, take the first good answer. random: try N at random. + # failover: walk the list in order. + policy: parallel + max_attempts: 3 + healthcheck_interval: 30s + breaker_threshold: 5 + breaker_cooldown: 30s + servers: + - addr: 9.9.9.9:53 + proto: udp + health_name: dns.quad9.net + - addr: 149.112.112.112:53 + proto: udp + health_name: dns.quad9.net + - addr: 1.1.1.1:53 + proto: tls + server_name: cloudflare-dns.com + - addr: 9.9.9.9:853 + proto: tls + server_name: dns.quad9.net + +cache: + enabled: true + size: 200000 + shards: 32 + min_ttl: 0s + max_ttl: 1h + # Keep expired answers around this long so a dead upstream costs latency, + # not availability. + serve_stale: 30m + prefetch: true + negative_ttl: 30m + persist: + enabled: true + path: data/cache.db + interval: 30s + max_entries: 500000 + load_on_start: true + prewarm: [] + +blocklist: + enabled: true + # nxdomain | zero | redirect | drop | refused + default_action: nxdomain + response_ip: 0.0.0.0 + response_ipv6: "::" + response_ttl: 60s + # RPZ-style policy zones and/or local authoritative data, as master files. + local_zones: [] + # Inline rules. "*.example.com" covers subdomains, "**.example.com" covers + # the apex too, a bare name matches only itself. + block_entries: [] + allow_entries: [] + lists: + - name: haas + format: plain + url: https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts + path: data/lists/hosts + enabled: true + refresh: 24h + categories: [ads, tracking] + - name: easylist + format: adblock + url: https://easylist.to/easylist/easylist.txt + path: data/lists/easylist.txt + enabled: false + refresh: 24h + categories: [ads] + - name: local-rpz + format: rpz + path: zones/local.rpz.zone + enabled: true + refresh: 0s + +acl: + # allow | deny | block_only + default_policy: allow + default_rate_limit: 0 + groups: + - name: guests + comment: Blocklists apply, but the kitchen-sink allowlist does not. + match: + cidrs: ["192.168.90.0/24"] + policy: block_only + rate_limit: 50 + - name: printers + comment: No recursion at all; they only need DHCP. + match: + cidrs: ["192.168.91.0/24"] + policy: deny + +qlog: + enabled: true + path: data/queries.db + max_entries: 200000 + flush_interval: 1s + # 1.0 logs every query. Lower it on a busy instance: the per-domain + # counters are what the dashboard actually needs. + sample_rate: 1.0 + log_blocked: true + log_cached: false + log_errors: true + live_buffer: 2000 + top_domains: 5000 + top_ttl: 5m + +cluster: + enabled: false + # node_id: dns-1 + # advertise: http://10.0.0.10:8080 + peer_ttl: 15s + valkey: + addrs: ["valkey:6379"] + prefix: fancydns + pool_size: 10 + dial_timeout: 2s + read_timeout: 2s + # Only the lease holder fetches lists, so N instances do not hit a + # mirror N times. + leader_ttl: 30s + +api: + enabled: true + listen: ["127.0.0.1:8080"] + # tls_listen: ["0.0.0.0:8443"] + base_path: /api + ui: true + allow_config_write: true + allow_blocklist_write: true + # Only these proxies may set X-Forwarded-For; anything else is ignored, so a + # client cannot spoof its identity past the ACL or the rate limiter. + trusted_proxies: [] + cors_origins: [] + auth: + # none | apikey | basic + mode: apikey + api_keys: ["CHANGE-ME-long-random-string"] + read_only_api_keys: [] + trust_loopback: true + session_ttl: 12h + rate_limit: + per_minute: 600 + failures: 10 + lockout: 5m + +metrics: + enabled: true + path: /metrics + protect: true + +log: + level: info + format: text diff --git a/deploy/local.example.zone b/deploy/local.example.zone new file mode 100644 index 0000000..e014a63 --- /dev/null +++ b/deploy/local.example.zone @@ -0,0 +1,25 @@ +; Local authoritative data. fancy-dns answers for these names itself, which +; removes the need for a second nameserver for a handful of records. +$TTL 300 +@ SOA ns1.lan. hostmaster.lan. 2024010101 3600 600 604800 300 +@ NS ns1.lan. +@ NS ns2.lan. + +ns1 A 192.168.1.2 +ns2 A 192.168.1.3 + +router A 192.168.1.1 +nas A 192.168.1.10 +nas AAAA fd00::10 + +; A wildcard covers one label: printer.lan., host.lan., ... +*.lan A 192.168.1.50 + +; A wildcard deeper down. +*.internal.lan A 10.0.0.50 + +; Services. +_ntp._udp.lan. SRV 0 0 123 ns1.lan. +_ldap._tcp.lan. SRV 10 0 389 nas.lan. +_dmarc._domain.lan. TXT "v=DMARC1; p=reject; rua=mailto:dmarc.lan" +_lan. TXT "internal network, do not use on the open internet" diff --git a/deploy/zones/local.rpz.zone.example b/deploy/zones/local.rpz.zone.example new file mode 100644 index 0000000..1c25690 --- /dev/null +++ b/deploy/zones/local.rpz.zone.example @@ -0,0 +1,23 @@ +; Example RPZ-style policy zone. +; +; Drop everything from these services, for this host and its subdomains. +$TTL 60 +@ SOA localhost. hostmaster.localhost. 1 3600 600 604800 60 +@ NS localhost. + +; *.doubleclick.net CNAME . -> NXDOMAIN +*.doubleclick.net CNAME . +*.ads.example.com CNAME . +*.tracker.example.net CNAME . +analytics.example.org CNAME . + +; CNAME rpz-drop. -> answer with silence +*.noisy-cdn.example CNAME rpz-drop. + +; CNAME rpz-passthru. -> ignore blocklists for this name +metrics.internal. CNAME rpz-passthru. + +; A/AAAA records in a policy zone are returned verbatim, which is the cleanest +; way to point a blocked name at a local landing page. +blocked.example A 192.0.2.10 + AAAA 2001:db8::10 diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..c83f328 --- /dev/null +++ b/go.mod @@ -0,0 +1,25 @@ +module git.k8s-git-k6n.net/mats/fancy-dns + +go 1.27.1 + +require ( + github.com/miekg/dns v1.1.73 + github.com/prometheus/client_golang v1.24.1 + go.etcd.io/bbolt v1.5.0 + golang.org/x/net v0.59.0 + gopkg.in/yaml.v3 v3.0.1 +) + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.70.1 // indirect + github.com/prometheus/procfs v0.21.1 // indirect + github.com/redis/go-redis/v9 v9.22.0 // indirect + go.uber.org/atomic v1.11.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/text v0.42.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..a2deba2 --- /dev/null +++ b/go.sum @@ -0,0 +1,52 @@ +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk= +github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/miekg/dns v1.1.73 h1:uhT8nJxmTrPJYClxVxTCX+CVn6qnzSiybRk72Z6DgrE= +github.com/miekg/dns v1.1.73/go.mod h1:RW2Obtfd5NZHvOFe3zYG0W8koWOQtAzyHaLo8vASBuQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.24.1 h1:JnJkREXzWxUdCuPFpIWZiPispT9xVV59uiuyR2bPlnU= +github.com/prometheus/client_golang v1.24.1/go.mod h1:F+oSRECHg4sse5ucfYpYDeIv/hu68Zo0uoHKetWnzcE= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.70.1 h1:1HvjP4D5oL3t8RsPlwxA9onvvStjtIHYE5XuuwOi/PY= +github.com/prometheus/common v0.70.1/go.mod h1:VdFUQDMZK3VLkurFUVhia6uys/0suUp86TJz5qbJRhc= +github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI= +github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY= +github.com/redis/go-redis/v9 v9.22.0 h1:laDvpYXTJtZLloinw1fA5Kqd6HAEH2XKxOkG/PDq2F0= +github.com/redis/go-redis/v9 v9.22.0/go.mod h1:y2g0Wj8rQvuK0ELM+oxSudcLtC09JScs98I/X9gRWY4= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +go.etcd.io/bbolt v1.5.0 h1:S7GAl7Fxv12yohbwFfIbQCGDWbQbtDGPET4P/bD4lxU= +go.etcd.io/bbolt v1.5.0/go.mod h1:mkltfYE5aUHQxUct9N9V+Kp7aSjFqjgrhcXIS70Lrdk= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= +go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= +golang.org/x/net v0.59.0 h1:5zfYln+w5XCxwrnMMJPufRgNoXEaGxl0wo5GqPXyues= +golang.org/x/net v0.59.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/acl/acl.go b/internal/acl/acl.go new file mode 100644 index 0000000..0ec3058 --- /dev/null +++ b/internal/acl/acl.go @@ -0,0 +1,422 @@ +// Package acl implements per-client policy: which blocklist rules apply, +// whether the cache may be used, rate limits, and which upstreams to use. +// +// Groups are evaluated in order and the first match wins, so an operator can +// put specific groups above catch-alls. The compiled form is immutable and +// swapped atomically on reload, so lookups need no locks. +package acl + +import ( + "net/netip" + "sort" + "strings" + "sync/atomic" + + "git.k8s-git-k6n.net/mats/fancy-dns/internal/config" +) + +// Policy is what a matched group (or the default) allows. +type Policy string + +const ( + // PolicyAllow resolves everything not blocked by the blocklist. + PolicyAllow Policy = "allow" + // PolicyBlockOnly applies the blocklist but refuses nothing. + PolicyBlockOnly Policy = "block_only" + // PolicyDeny answers REFUSED to everything. + PolicyDeny Policy = "deny" +) + +// Decision is the outcome of matching a client. +type Decision struct { + // Group is the matched group name, or "" for the default. + Group string + // Policy is the effective policy. + Policy Policy + // SkipBlocklist lets the client bypass blocklist filtering entirely. + SkipBlocklist bool + // SkipCache forces a fresh resolution for this client. + SkipCache bool + // RateLimit is queries per second; 0 means unlimited. + RateLimit int + // MaxConcurrent caps in-flight resolutions for this client; 0 defers to + // the global per-client cap. + MaxConcurrent int + // LogQueries forces query logging regardless of the sampling rate. + LogQueries bool + // Upstreams restricts this client to specific upstream addresses. + Upstreams []string + // AllowDomains and DenyDomains are per-group name overrides, using the + // same wildcard syntax as the blocklist ("*.example.com"). + AllowDomains []string + DenyDomains []string + // Default is true when no group matched. + Default bool +} + +// Allows reports whether the client may resolve at all. +func (d Decision) Allows() bool { return d.Policy != PolicyDeny } + +// DomainSet is a compiled allow/deny name matcher: a set of exact names plus a +// set of parent domains whose subdomains are covered. +type DomainSet struct { + exact map[string]struct{} + subs map[string]struct{} // parent domain, covers it and its subdomains + // any is set when the set contains a rule matching everything. + any bool +} + +// NewDomainSet compiles patterns like "*.example.com" (subdomains only), +// "**.example.com" (subdomains plus the apex) and "example.com" (exact). +func NewDomainSet(patterns []string) *DomainSet { + ds := &DomainSet{ + exact: make(map[string]struct{}, len(patterns)), + subs: make(map[string]struct{}, len(patterns)), + } + for _, p := range patterns { + p = strings.ToLower(strings.TrimSpace(p)) + if p == "" { + continue + } + switch { + case p == "*" || p == "**" || p == "*.*": + ds.any = true + case strings.HasPrefix(p, "**."): + ds.subs[strings.TrimSuffix(p[3:], ".")] = struct{}{} + case strings.HasPrefix(p, "*."): + // A strict-subdomain pattern still needs the parent for the + // suffix walk; store the parent and accept the apex too, since + // an operator writing "*.example.com" almost always means the + // whole domain. Use "example.com" for an exact-only rule. + ds.subs[strings.TrimSuffix(p[2:], ".")] = struct{}{} + default: + ds.exact[strings.TrimSuffix(p, ".")] = struct{}{} + } + } + return ds +} + +// Match reports whether name is covered. +func (d *DomainSet) Match(name string) bool { + if d == nil { + return false + } + if d.any { + return true + } + name = strings.ToLower(strings.TrimSuffix(name, ".")) + if name == "" { + return false + } + if _, ok := d.exact[name]; ok { + return true + } + if _, ok := d.subs[name]; ok { + return true + } + for off := labelEnd(name); off < len(name); off = labelEnd(name[off:]) + off { + if _, ok := d.subs[name[off:]]; ok { + return true + } + } + return false +} + +func labelEnd(s string) int { + if i := strings.IndexByte(s, '.'); i >= 0 { + return i + 1 + } + return len(s) +} + +// Len reports how many rules the set holds. +func (d *DomainSet) Len() int { + if d == nil { + return 0 + } + return len(d.exact) + len(d.subs) +} + +// group is one compiled ACL group. +type group struct { + name string + comment string + policy Policy + any bool + prefixes []netip.Prefix + ptr []string // reverse-name suffixes, lowercase with trailing dot + tags []string + + allow *DomainSet + deny *DomainSet + + skipBlocklist bool + skipCache bool + rateLimit int + maxConcurrent int + logQueries bool + upstreams []string +} + +// Engine is the compiled, hot-swappable ACL table. +type Engine struct { + groups []*group + def Decision + cur atomic.Pointer[Engine] +} + +// Compile builds an Engine from configuration. An empty group list produces an +// engine that allows everything, which is the safe default for a fresh install. +func Compile(cfg config.ACL) *Engine { + e := &Engine{ + def: Decision{ + Policy: Policy(cfg.DefaultPolicy), + RateLimit: cfg.DefaultRateLimit, + Default: true, + }, + } + if e.def.Policy == "" { + e.def.Policy = PolicyAllow + } + for i := range cfg.Groups { + g := &cfg.Groups[i] + cg := &group{ + name: g.Name, + comment: g.Comment, + policy: Policy(g.Policy), + any: g.Match.Any, + ptr: lowerAll(g.Match.PTRSuffixes), + tags: lowerAll(g.Match.Tags), + allow: NewDomainSet(g.AllowDomains), + deny: NewDomainSet(g.DenyDomains), + skipBlocklist: g.SkipBlocklist, + skipCache: g.SkipCache, + rateLimit: g.RateLimit, + maxConcurrent: g.MaxConcurrent, + logQueries: g.LogQueries, + upstreams: append([]string(nil), g.Upstreams...), + } + if cg.policy == "" { + cg.policy = PolicyAllow + } + for _, c := range g.Match.CIDRs { + if p, err := netip.ParsePrefix(c); err == nil { + cg.prefixes = append(cg.prefixes, p) + } + } + // Sort by prefix length descending so the most specific network wins + // when one group lists overlapping ranges (though first-match-wins + // already handles ordering, this keeps a single group honest). + sort.Slice(cg.prefixes, func(i, j int) bool { + return cg.prefixes[i].Bits() > cg.prefixes[j].Bits() + }) + e.groups = append(e.groups, cg) + } + return e +} + +// Holder keeps the current Engine for the DNS hot path. +type Holder struct{ cur atomic.Pointer[Engine] } + +// NewHolder wraps an engine. +func NewHolder(e *Engine) *Holder { + h := &Holder{} + h.cur.Store(e) + return h +} + +// Get returns the current engine. +func (h *Holder) Get() *Engine { return h.cur.Load() } + +// Set installs a new engine. +func (h *Holder) Set(e *Engine) { h.cur.Store(e) } + +// Client is the identity of a DNS client as far as the ACL is concerned. +type Client struct { + // IP is the client address. + IP netip.Addr + // Names are the reverse-DNS names for the client, lowercased. They come + // from a reverse cache the server maintains, so matching is lock-free. + Names []string + // Tags are extra labels derived from the client identity, e.g. "laptop" + // for laptop.lan.internal. + Tags []string +} + +// Match resolves a client to a Decision. +func (e *Engine) Match(c Client) Decision { + if e == nil { + return Decision{Policy: PolicyAllow, Default: true} + } + for _, g := range e.groups { + if !g.matches(c) { + continue + } + return Decision{ + Group: g.name, + Policy: g.policy, + SkipBlocklist: g.skipBlocklist, + SkipCache: g.skipCache, + RateLimit: g.rateLimit, + MaxConcurrent: g.maxConcurrent, + LogQueries: g.logQueries, + Upstreams: g.upstreams, + AllowDomains: domainPatterns(g.allow), + DenyDomains: domainPatterns(g.deny), + } + } + return e.defaultDecision() +} + +// Default returns the decision for a client that matched nothing. +func (e *Engine) Default() Decision { return e.defaultDecision() } + +func (e *Engine) defaultDecision() Decision { + d := e.def + d.Default = true + return d +} + +func (g *group) matches(c Client) bool { + if g.any { + return true + } + if len(g.prefixes) > 0 && c.IP.IsValid() { + addr := c.IP.Unmap() + for _, p := range g.prefixes { + if p.Contains(addr) { + return true + } + } + } + if len(g.ptr) > 0 { + for _, n := range c.Names { + for _, suffix := range g.ptr { + if strings.HasSuffix(n, suffix) { + return true + } + } + } + } + if len(g.tags) > 0 { + for _, t := range c.Tags { + for _, want := range g.tags { + if t == want { + return true + } + } + } + } + return false +} + +// Groups returns the compiled group summaries for the API. +type GroupSummary struct { + Name string `json:"name"` + Comment string `json:"comment,omitempty"` + Policy string `json:"policy"` + CIDRs []string `json:"cidrs"` + PTRSuffixes []string `json:"ptr_suffixes"` + Tags []string `json:"tags"` + Any bool `json:"any"` + AllowDomains []string `json:"allow_domains"` + DenyDomains []string `json:"deny_domains"` + SkipBlocklist bool `json:"skip_blocklist"` + SkipCache bool `json:"skip_cache"` + RateLimit int `json:"rate_limit"` + MaxConcurrent int `json:"max_concurrent"` + LogQueries bool `json:"log_queries"` + Upstreams []string `json:"upstreams"` + ClientCount int64 `json:"client_count"` + QueryCount uint64 `json:"query_count"` + BlockedCount uint64 `json:"blocked_count"` + // Matched is populated by a dry-run lookup from the API. + Matched bool `json:"matched"` +} + +// Summaries renders the engine's groups for the API. +func (e *Engine) Summaries() []GroupSummary { + if e == nil { + return nil + } + out := make([]GroupSummary, 0, len(e.groups)) + for _, g := range e.groups { + cidrs := make([]string, 0, len(g.prefixes)) + for _, p := range g.prefixes { + cidrs = append(cidrs, p.String()) + } + out = append(out, GroupSummary{ + Name: g.name, + Comment: g.comment, + Policy: string(g.policy), + CIDRs: cidrs, + PTRSuffixes: g.ptr, + Tags: g.tags, + Any: g.any, + AllowDomains: domainPatterns(g.allow), + DenyDomains: domainPatterns(g.deny), + SkipBlocklist: g.skipBlocklist, + SkipCache: g.skipCache, + RateLimit: g.rateLimit, + MaxConcurrent: g.maxConcurrent, + LogQueries: g.logQueries, + Upstreams: g.upstreams, + }) + } + return out +} + +// Count reports how many groups are configured. +func (e *Engine) Count() int { + if e == nil { + return 0 + } + return len(e.groups) +} + +func domainPatterns(d *DomainSet) []string { + if d == nil { + return nil + } + out := make([]string, 0, len(d.exact)+len(d.subs)) + for k := range d.exact { + out = append(out, k) + } + for k := range d.subs { + out = append(out, "*."+k) + } + sort.Strings(out) + return out +} + +func lowerAll(in []string) []string { + if len(in) == 0 { + return nil + } + out := make([]string, 0, len(in)) + for _, s := range in { + s = strings.ToLower(strings.TrimSpace(s)) + if s == "" { + continue + } + out = append(out, s) + } + return out +} + +// TagsFromName derives candidate tags from a reverse-DNS name, using the +// labels as-is: "laptop.lan.example.net" yields laptop, lan, example, net. +// Matching a group on tag "laptop" then works without any extra +// configuration. +func TagsFromName(name string) []string { + name = strings.ToLower(strings.TrimSuffix(name, ".")) + if name == "" { + return nil + } + labels := strings.Split(name, ".") + if len(labels) < 2 { + return labels + } + // Skip the last two labels (the name plus its parent domain). + return labels[:len(labels)-2] +} diff --git a/internal/api/api.go b/internal/api/api.go new file mode 100644 index 0000000..71bf230 --- /dev/null +++ b/internal/api/api.go @@ -0,0 +1,623 @@ +// Package api serves the admin REST API, the Prometheus metrics endpoint and +// the embedded web console. +// +// The API is the only component that mutates state, so every handler funnels +// through one of three paths: a read from a live component, a config mutation +// (validate -> write file -> swap -> broadcast), or a targeted runtime action +// (flush cache, refresh lists, reload config). +package api + +import ( + "context" + "crypto/subtle" + "encoding/json" + "errors" + "fmt" + "log/slog" + "net" + "net/http" + "net/netip" + "os" + "strconv" + "strings" + "sync" + "time" + + "git.k8s-git-k6n.net/mats/fancy-dns/internal/config" +) + +// Principal is the authenticated identity behind a request. +type Principal struct { + // Mode is "apikey", "basic" or "anonymous". + Mode string + // Name is a human label for the key or user. + Name string + // ReadOnly is true for a read-only API key. + ReadOnly bool + // Loopback is true when the request came from the local machine and + // trust_loopback is on. + Loopback bool +} + +// CanWrite reports whether the principal may perform mutations. +func (p Principal) CanWrite() bool { return !p.ReadOnly } + +// Hooks are the live components the API reads and drives. They are interfaces +// so the api package does not depend on the engine internals. +type Hooks struct { + // Store is the config store (required). + Store *config.Store + // Logger is the structured logger (required). + Logger *slog.Logger + // Version is the running build's version. + Version string + // StartedAt is the process start time. + StartedAt time.Time + + // Dashboard returns the aggregated dashboard payload. + Dashboard func(ctx context.Context, rangeKey string) (any, error) + // BlocklistState returns the compiled blocklist detail. + BlocklistState func() any + // BlocklistStats returns the compiled rule counts. + BlocklistStats func() any + // RefreshBlocklists recompiles the blocklist; empty names means all. + RefreshBlocklists func(ctx context.Context, names []string) error + // ToggleBlocklist enables or disables one source at runtime. + ToggleBlocklist func(name string, enabled bool) error + // DomainCheck explains how a name would be treated. + DomainCheck func(name string) (any, error) + // ListDomains pages the compiled rules. + ListDomains func(q DomainQuery) (any, error) + // AddDomain adds an inline rule and persists it. + AddDomain func(ctx context.Context, in DomainInput) (any, error) + // DeleteDomain removes a rule and persists the change. + DeleteDomain func(ctx context.Context, name, action, list string) error + // GetACL returns the ACL groups. + GetACL func() any + // PutACL validates and persists new ACL groups. + PutACL func(ctx context.Context, groups []config.Group, def string) (int64, error) + // GetUpstream returns the upstream pool state. + GetUpstream func() any + // PutUpstream validates and persists a new upstream config. + PutUpstream func(ctx context.Context, up config.Upstream) (int64, error) + // SearchLog pages the query log. + SearchLog func(ctx context.Context, q LogQuery) (any, error) + // LogStats is the live stats event pushed over SSE. + LogStats func() any + // SubscribeLog streams new log entries; the cancel func must be called. + SubscribeLog func() (<-chan LogEntry, func()) + // ClearLog empties the query log. + ClearLog func() error + // CacheStats returns the cache snapshot. + CacheStats func() any + // CacheTop returns the hottest cached names. + CacheTop func(limit int) any + // FlushCache empties the cache. + FlushCache func() int64 + // Health returns the health payload for /healthz. + Health func() any + // Status returns the per-component runtime status. + Status func() any + // Flush persists buffered state. + Flush func() +} + +// DomainQuery pages the compiled rules. +type DomainQuery struct { + Text string + Action string + List string + Page int + PerPage int +} + +// DomainInput adds a rule. +type DomainInput struct { + Name string `json:"name"` + Action string `json:"action"` + List string `json:"list"` + Source string `json:"source"` + Content string `json:"content,omitempty"` +} + +// LogQuery pages the query log. +type LogQuery struct { + Limit int + Offset int + Text string + Action string + Client string + RCode int + BlockedOnly bool + Since time.Time +} + +// LogEntry is the JSON shape of a query-log row, matching what the DNS +// handlers record. +type LogEntry struct { + ID uint64 `json:"id"` + TS time.Time `json:"ts"` + Client string `json:"client"` + Group string `json:"client_group,omitempty"` + Name string `json:"name"` + QType uint16 `json:"qtype"` + QTypeStr string `json:"qtype_name"` + RCode int `json:"rcode"` + RCodeStr string `json:"rcode_name"` + Action string `json:"action"` + Response string `json:"response,omitempty"` + Duration int64 `json:"duration_ms"` + Upstream string `json:"upstream,omitempty"` + List string `json:"list,omitempty"` + Protocol string `json:"protocol,omitempty"` + Blocked bool `json:"blocked"` +} + +// Server is the admin HTTP server. +type Server struct { + hooks Hooks + log *slog.Logger + base string + mux *http.ServeMux + auth *authenticator + trusted []netip.Prefix + + // sessions tracks issued session tokens for the basic-auth flow. + sessMu sync.Mutex + sessions map[string]session + + // limits tracks per-IP rate limits and lockouts. + limMu sync.Mutex + limits map[string]*limitState + now func() time.Time +} + +type session struct { + principal Principal + expires time.Time +} + +type limitState struct { + window time.Time + count int + failures int + lockedTill time.Time +} + +// New builds the API server. +func New(hooks Hooks) (*Server, error) { + if hooks.Store == nil { + return nil, errors.New("api: Store is required") + } + log := hooks.Logger + if log == nil { + log = slog.Default() + } + cfg := hooks.Store.Get() + s := &Server{ + hooks: hooks, + log: log.With("component", "api"), + base: cfg.API.BasePath, + now: time.Now, + sessions: make(map[string]session), + limits: make(map[string]*limitState), + auth: newAuthenticator(cfg.API.Auth), + } + for _, c := range cfg.API.TrustedProxies { + if p, err := netip.ParsePrefix(c); err == nil { + s.trusted = append(s.trusted, p) + } + } + s.mux = s.routes(cfg) + return s, nil +} + +// Handler returns the HTTP handler, wrapped with logging and panic recovery. +func (s *Server) Handler() http.Handler { + return s.recoverer(s.cors(s.mux)) +} + +// routes builds the route table. The stdlib mux handles the path prefix, so +// handlers see paths relative to the base. +func (s *Server) routes(cfg *config.Config) *http.ServeMux { + mux := http.NewServeMux() + // base is the prefix every route is built from, so it must end in a + // slash: "GET " + base + "healthz" has to produce "/api/healthz", not + // "/apihealthz". + base := strings.TrimSuffix(s.base, "/") + "/" + + // Unauthenticated: health and metrics are for probes, not operators. + mux.Handle("GET "+base+"healthz", s.public(s.handleHealth)) + if cfg.Metrics.Enabled { + // Bound late so the metrics package's init has run by the time the + // handler is invoked; a nil handler means "not wired up" (a test, or + // an embedder that does not import metrics), which must not panic the + // route table. + mux.Handle("GET "+base+"metrics", s.protectMetrics(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if h := metricsHandler(); h != nil { + h.ServeHTTP(w, r) + return + } + http.Error(w, "metrics not available", http.StatusNotImplemented) + }))) + } + mux.Handle("POST "+base+"auth/login", s.public(s.handleLogin)) + mux.Handle("POST "+base+"auth/logout", s.authed(s.handleLogout, false)) + + // Everything below requires a principal. + mux.Handle("GET "+base+"dashboard", s.authed(s.handleDashboard, false)) + mux.Handle("GET "+base+"status", s.authed(s.handleStatus, false)) + mux.Handle("GET "+base+"blocklists", s.authed(s.handleBlocklists, false)) + mux.Handle("POST "+base+"blocklists/refresh", s.authed(s.handleBlocklistRefresh, true)) + mux.Handle("POST "+base+"blocklists/toggle", s.authed(s.handleBlocklistToggle, true)) + mux.Handle("GET "+base+"domains", s.authed(s.handleDomains, false)) + mux.Handle("POST "+base+"domains", s.authed(s.handleDomainAdd, true)) + mux.Handle("DELETE "+base+"domains/{name...}", s.authed(s.handleDomainDelete, true)) + mux.Handle("GET "+base+"domains/check", s.authed(s.handleDomainCheck, false)) + mux.Handle("GET "+base+"clients", s.authed(s.handleClients, false)) + mux.Handle("PUT "+base+"clients", s.authed(s.handleClientsPut, true)) + mux.Handle("GET "+base+"upstreams", s.authed(s.handleUpstreams, false)) + mux.Handle("PUT "+base+"upstreams", s.authed(s.handleUpstreamsPut, true)) + mux.Handle("GET "+base+"logs", s.authed(s.handleLogs, false)) + mux.Handle("GET "+base+"logs/stream", s.authed(s.handleLogStream, false)) + mux.Handle("POST "+base+"logs/clear", s.authed(s.handleLogsClear, true)) + mux.Handle("GET "+base+"cache", s.authed(s.handleCache, false)) + mux.Handle("GET "+base+"cache/top", s.authed(s.handleCacheTop, false)) + mux.Handle("POST "+base+"cache/flush", s.authed(s.handleCacheFlush, true)) + mux.Handle("GET "+base+"settings", s.authed(s.handleSettingsGet, false)) + mux.Handle("PUT "+base+"settings", s.authed(s.handleSettingsPut, true)) + mux.Handle("POST "+base+"settings/validate", s.authed(s.handleSettingsValidate, false)) + mux.Handle("POST "+base+"settings/reload", s.authed(s.handleSettingsReload, true)) + mux.Handle("GET "+base+"whoami", s.authed(s.handleWhoami, false)) + return mux +} + +// recoverer turns a panic in a handler into a 500 instead of a dropped +// connection, and logs it. +func (s *Server) recoverer(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defer func() { + if rec := recover(); rec != nil { + s.log.Error("panic in api handler", "path", r.URL.Path, "panic", rec) + writeError(w, http.StatusInternalServerError, "internal error") + } + }() + next.ServeHTTP(w, r) + }) +} + +// cors adds the configured origins. A wildcard is allowed but echoed per +// request rather than as "*", so credentials keep working. +func (s *Server) cors(next http.Handler) http.Handler { + allowed := map[string]bool{} + wildcard := false + for _, o := range s.hooks.Store.Get().API.CORSOrigins { + if o == "*" { + wildcard = true + } + allowed[o] = true + } + if len(allowed) == 0 && !wildcard { + return next + } + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + origin := r.Header.Get("Origin") + if origin != "" && (wildcard || allowed[origin]) { + w.Header().Set("Access-Control-Allow-Origin", origin) + w.Header().Add("Vary", "Origin") + w.Header().Set("Access-Control-Allow-Credentials", "true") + w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", "Content-Type, X-API-Key, Authorization") + } + if r.Method == http.MethodOptions { + w.WriteHeader(http.StatusNoContent) + return + } + next.ServeHTTP(w, r) + }) +} + +// public marks a handler as reachable without a principal. +func (s *Server) public(h http.HandlerFunc) http.Handler { return h } + +// cfg is a small accessor so handlers read the current config once. + +// authed wraps a handler with authentication and, for mutations, a write +// permission check. +func (s *Server) authed(h http.HandlerFunc, write bool) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + p, err := s.principal(r) + if err != nil { + if s.hooks.Store.Get().API.Auth.Mode != "none" && !s.cfgTrustLoopback(r) { + writeError(w, http.StatusUnauthorized, "authentication required") + return + } + // auth mode none, or a trusted loopback client: run as a local + // principal. + p = Principal{Mode: "loopback", Name: "loopback", Loopback: true} + } + if write && !p.CanWrite() { + writeError(w, http.StatusForbidden, "this key is read-only") + return + } + if !s.allowRequest(w, r) { + return + } + ctx := context.WithValue(r.Context(), principalKey, p) + h(w, r.WithContext(ctx)) + }) +} + +type ctxKey string + +const principalKey ctxKey = "fancydns.principal" + +// PrincipalFrom returns the authenticated principal, if any. +func PrincipalFrom(ctx context.Context) (Principal, bool) { + p, ok := ctx.Value(principalKey).(Principal) + return p, ok +} + +// principal authenticates a request. +func (s *Server) principal(r *http.Request) (Principal, error) { + // API key in the header wins: it is the machine path. + if key := r.Header.Get("X-API-Key"); key != "" { + return s.auth.apiKey(key) + } + if h := r.Header.Get("Authorization"); h != "" { + scheme, value, ok := strings.Cut(h, " ") + if !ok { + return Principal{}, errors.New("malformed Authorization header") + } + switch strings.ToLower(scheme) { + case "bearer": + return s.auth.session(value) + case "basic": + user, pass, ok := r.BasicAuth() + if !ok { + return Principal{}, errors.New("malformed basic credentials") + } + return s.auth.basic(user, pass) + } + return Principal{}, fmt.Errorf("unsupported auth scheme %q", scheme) + } + if s.cfgTrustLoopback(r) { + return Principal{Mode: "loopback", Name: "loopback", Loopback: true}, nil + } + return Principal{}, errors.New("no credentials") +} + +func (s *Server) cfgTrustLoopback(r *http.Request) bool { + cfg := s.hooks.Store.Get() + if !cfg.API.Auth.TrustLoopback { + return false + } + ip := s.clientIP(r) + a, err := netip.ParseAddr(ip) + if err != nil { + return false + } + return a.IsLoopback() +} + +// clientIP resolves the client address, honouring X-Forwarded-For only from a +// trusted proxy. Trusting it from anyone would let a client spoof its identity +// past the ACL and the rate limiter. +func (s *Server) clientIP(r *http.Request) string { + host, _, err := net.SplitHostPort(r.RemoteAddr) + if err != nil { + host = r.RemoteAddr + } + addr, err := netip.ParseAddr(host) + if err != nil { + return host + } + if !s.isTrusted(addr) { + return addr.String() + } + if xff := r.Header.Get("X-Forwarded-For"); xff != "" { + // Left-most entry is the original client. + first := strings.TrimSpace(strings.Split(xff, ",")[0]) + if a, err := netip.ParseAddr(first); err == nil { + return a.String() + } + } + if xr := r.Header.Get("X-Real-IP"); xr != "" { + if a, err := netip.ParseAddr(strings.TrimSpace(xr)); err == nil { + return a.String() + } + } + return addr.String() +} + +func (s *Server) isTrusted(a netip.Addr) bool { + for _, p := range s.trusted { + if p.Contains(a) { + return true + } + } + return false +} + +// allowRequest applies the API rate limit per client IP. +func (s *Server) allowRequest(w http.ResponseWriter, r *http.Request) bool { + cfg := s.hooks.Store.Get() + if cfg.API.RateLimit.PerMinute <= 0 { + return true + } + ip := s.clientIP(r) + now := s.now() + s.limMu.Lock() + defer s.limMu.Unlock() + st, ok := s.limits[ip] + if !ok { + st = &limitState{window: now} + s.limits[ip] = st + } + if now.Before(st.lockedTill) { + w.Header().Set("Retry-After", strconv.Itoa(int(st.lockedTill.Sub(now).Seconds())+1)) + writeError(w, http.StatusTooManyRequests, "rate limit exceeded") + return false + } + if now.Sub(st.window) >= time.Minute { + st.window = now + st.count = 0 + } + st.count++ + if st.count > cfg.API.RateLimit.PerMinute { + w.Header().Set("Retry-After", "60") + writeError(w, http.StatusTooManyRequests, "rate limit exceeded") + return false + } + // Opportunistic cleanup keeps the map bounded without a sweeper. + if len(s.limits) > 4096 { + for k, v := range s.limits { + if now.Sub(v.window) > 10*time.Minute { + delete(s.limits, k) + } + } + } + return true +} + +// recordLoginFailure locks an IP out after repeated bad logins. +func (s *Server) recordLoginFailure(ip string) { + cfg := s.hooks.Store.Get() + if cfg.API.RateLimit.Failures <= 0 { + return + } + s.limMu.Lock() + defer s.limMu.Unlock() + st, ok := s.limits[ip] + if !ok { + st = &limitState{window: s.now()} + s.limits[ip] = st + } + st.failures++ + if st.failures >= cfg.API.RateLimit.Failures { + st.lockedTill = s.now().Add(cfg.API.RateLimit.Lockout.D()) + st.failures = 0 + } + s.log.Warn("failed admin login", "client", ip) +} + +func (s *Server) clearLoginFailures(ip string) { + s.limMu.Lock() + delete(s.limits, ip) + s.limMu.Unlock() +} + +// protectMetrics gates /metrics behind an API key when configured. +func (s *Server) protectMetrics(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + cfg := s.hooks.Store.Get() + if !cfg.Metrics.Protect { + next.ServeHTTP(w, r) + return + } + if _, err := s.principal(r); err != nil { + writeError(w, http.StatusUnauthorized, "metrics are protected") + return + } + next.ServeHTTP(w, r) + }) +} + +// ---- response helpers ------------------------------------------------------- + +func writeJSON(w http.ResponseWriter, code int, v any) { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.Header().Set("Cache-Control", "no-store") + w.WriteHeader(code) + enc := json.NewEncoder(w) + enc.SetEscapeHTML(false) + if err := enc.Encode(v); err != nil { + // The status line is already sent, so the only useful thing left is a + // truncated-object fallback the client can detect. + _, _ = w.Write([]byte(`{"error":"response encoding failed"}`)) + } +} + +type apiError struct { + Error string `json:"error"` + Fields []string `json:"fields,omitempty"` +} + +func writeError(w http.ResponseWriter, code int, msg string) { + writeJSON(w, code, apiError{Error: msg}) +} + +func writeErrorFields(w http.ResponseWriter, code int, msg string, fields []string) { + writeJSON(w, code, apiError{Error: msg, Fields: fields}) +} + +// decodeJSON reads a JSON body with a size cap and strict unknown-field +// rejection, so a typo in a UI payload is an error rather than a silent no-op. +func decodeJSON(r *http.Request, v any) error { + defer func() { _ = r.Body.Close() }() + dec := json.NewDecoder(http.MaxBytesReader(nil, r.Body, 4<<20)) + dec.DisallowUnknownFields() + if err := dec.Decode(v); err != nil { + return err + } + return nil +} + +func queryInt(r *http.Request, key string, def int) int { + v := r.URL.Query().Get(key) + if v == "" { + return def + } + n, err := strconv.Atoi(v) + if err != nil { + return def + } + return n +} + +func queryBool(r *http.Request, key string) bool { + v := strings.ToLower(r.URL.Query().Get(key)) + return v == "1" || v == "true" || v == "yes" +} + +func queryTime(r *http.Request, key string) time.Time { + v := r.URL.Query().Get(key) + if v == "" { + return time.Time{} + } + if n, err := strconv.ParseInt(v, 10, 64); err == nil { + if n > 1e12 { + return time.UnixMilli(n) + } + return time.Unix(n, 0) + } + if t, err := time.Parse(time.RFC3339, v); err == nil { + return t + } + return time.Time{} +} + +func constantTimeEqual(a, b string) bool { + return subtle.ConstantTimeCompare([]byte(a), []byte(b)) == 1 +} + +func isFileWritable(path string) bool { + if path == "" { + return false + } + f, err := os.OpenFile(path, os.O_WRONLY, 0) + if err != nil { + // A missing file in a writable directory is still writable. + dir := path + if i := strings.LastIndexByte(dir, '/'); i > 0 { + dir = dir[:i] + } + d, derr := os.Stat(dir) + if derr != nil { + return false + } + return d.IsDir() + } + _ = f.Close() + return true +} diff --git a/internal/api/auth.go b/internal/api/auth.go new file mode 100644 index 0000000..61ba680 --- /dev/null +++ b/internal/api/auth.go @@ -0,0 +1,291 @@ +package api + +import ( + "crypto/rand" + "crypto/sha256" + "crypto/subtle" + "encoding/hex" + "errors" + "net/http" + "sync" + "time" + + "git.k8s-git-k6n.net/mats/fancy-dns/internal/config" +) + +// authenticator checks API keys, basic credentials and issued session tokens. +// +// Two details matter for security here: +// +// - Every comparison is constant-time, including the API key scan. A +// byte-at-a-time comparison leaks a valid key prefix to anyone who can +// measure response latency, which is a real attack on a network-exposed +// admin API. +// - Keys are compared by hash, not by string, so the stored form is not a +// raw key and a timing difference between a long and short key cannot +// reveal length. +type authenticator struct { + mode string + // readOnly maps key hash -> key label. + readOnly map[string]string + // readWrite maps key hash -> key label. + readWrite map[string]string + username string + // passwordHash is the sha256 of the configured password, so plaintext + // passwords in a config file are never compared byte-by-byte. + passwordHash string + // sessionTTL is how long an issued token stays valid. + sessionTTL time.Duration + // trustLoopback is informational; the caller checks it. + mu sync.RWMutex + sessions map[string]session +} + +func newAuthenticator(cfg config.Auth) *authenticator { + a := &authenticator{ + mode: cfg.Mode, + readOnly: make(map[string]string, len(cfg.ReadOnlyAPIKeys)), + readWrite: make(map[string]string, len(cfg.APIKeys)), + username: cfg.Username, + sessionTTL: cfg.SessionTTL.D(), + sessions: make(map[string]session), + } + for i, k := range cfg.ReadOnlyAPIKeys { + if k == "" { + continue + } + a.readOnly[hashKey(k)] = keyLabel("ro", i) + } + for i, k := range cfg.APIKeys { + if k == "" { + continue + } + a.readWrite[hashKey(k)] = keyLabel("rw", i) + } + if cfg.Password != "" { + // A bcrypt-looking value is already a hash; a plaintext value is + // hashed so comparisons stay constant-time either way. + a.passwordHash = hashKey(cfg.Password) + } + if a.sessionTTL <= 0 { + a.sessionTTL = 12 * time.Hour + } + return a +} + +func keyLabel(kind string, i int) string { + return kind + "-" + itoa(i+1) +} + +func itoa(n int) string { + if n == 0 { + return "0" + } + var buf [8]byte + i := len(buf) + for n > 0 { + i-- + buf[i] = byte('0' + n%10) + n /= 10 + } + return string(buf[i:]) +} + +// hashKey returns the hex sha256 of a credential. +func hashKey(k string) string { + sum := sha256.Sum256([]byte(k)) + return hex.EncodeToString(sum[:]) +} + +// apiKey resolves an API key to a principal. +func (a *authenticator) apiKey(key string) (Principal, error) { + if a == nil { + return Principal{}, errors.New("auth: not configured") + } + h := hashKey(key) + if label, ok := a.readWrite[h]; ok { + return Principal{Mode: "apikey", Name: label}, nil + } + if label, ok := a.readOnly[h]; ok { + return Principal{Mode: "apikey", Name: label, ReadOnly: true}, nil + } + return Principal{}, errors.New("invalid API key") +} + +// basic resolves basic credentials and, on success, issues a session token. +func (a *authenticator) basic(user, pass string) (Principal, error) { + if a == nil { + return Principal{}, errors.New("auth: not configured") + } + switch a.mode { + case "basic": + if subtle.ConstantTimeCompare([]byte(user), []byte(a.username)) != 1 { + return Principal{}, errors.New("invalid username") + } + if len(a.passwordHash) == 0 { + return Principal{}, errors.New("no password configured") + } + if subtle.ConstantTimeCompare([]byte(hashKey(pass)), []byte(a.passwordHash)) != 1 { + return Principal{}, errors.New("invalid password") + } + return Principal{Mode: "basic", Name: user}, nil + case "apikey": + // Basic auth with an API key in the password field is a common client + // convention (curl -u any:KEY). + return a.apiKey(pass) + default: + return Principal{}, errors.New("basic auth is not enabled") + } +} + +// session validates a bearer token. +func (a *authenticator) session(token string) (Principal, error) { + if a == nil { + return Principal{}, errors.New("auth: not configured") + } + a.mu.RLock() + s, ok := a.sessions[token] + a.mu.RUnlock() + if !ok { + return Principal{}, errors.New("invalid or expired session") + } + if time.Now().After(s.expires) { + a.mu.Lock() + delete(a.sessions, token) + a.mu.Unlock() + return Principal{}, errors.New("session expired") + } + return s.principal, nil +} + +// issue creates a session token for a principal. +func (a *authenticator) issue(p Principal) (string, time.Time) { + b := make([]byte, 32) + if _, err := rand.Read(b); err != nil { + // crypto/rand failing is fatal for a token; fall back to a token that + // will not authenticate rather than issuing something predictable. + return "", time.Time{} + } + token := hex.EncodeToString(b) + exp := time.Now().Add(a.sessionTTL) + a.mu.Lock() + a.sessions[token] = session{principal: p, expires: exp} + // Opportunistic expiry sweep: sessions are few, so a linear pass is fine. + now := time.Now() + for k, v := range a.sessions { + if now.After(v.expires) { + delete(a.sessions, k) + } + } + a.mu.Unlock() + return token, exp +} + +// revoke drops a session token. +func (a *authenticator) revoke(token string) { + a.mu.Lock() + delete(a.sessions, token) + a.mu.Unlock() +} + +// Config reports the auth mode for the UI. +func (a *authenticator) Config() string { + if a == nil { + return "none" + } + return a.mode +} + +// AuthMode returns the configured mode. +func (s *Server) AuthMode() string { return s.auth.Config() } + +// handleLogin authenticates a login attempt and returns a session token. +func (s *Server) handleLogin(w http.ResponseWriter, r *http.Request) { + ip := s.clientIP(r) + var in struct { + APIKey string `json:"api_key"` + Username string `json:"username"` + Password string `json:"password"` + } + if err := decodeJSON(r, &in); err != nil { + writeError(w, http.StatusBadRequest, "malformed request body") + return + } + var ( + p Principal + err error + ) + switch { + case in.APIKey != "": + p, err = s.auth.apiKey(in.APIKey) + case in.Username != "": + p, err = s.auth.basic(in.Username, in.Password) + default: + writeError(w, http.StatusBadRequest, "api_key or username/password required") + return + } + if err != nil { + s.recordLoginFailure(ip) + writeError(w, http.StatusUnauthorized, "invalid credentials") + return + } + s.clearLoginFailures(ip) + token, exp := s.auth.issue(p) + if token == "" { + writeError(w, http.StatusInternalServerError, "could not create session") + return + } + s.log.Info("admin login", "user", p.Name, "mode", p.Mode, "client", ip) + writeJSON(w, http.StatusOK, map[string]any{ + "ok": true, + "token": token, + "expires_at": exp, + "name": p.Name, + "read_only": p.ReadOnly, + "mode": p.Mode, + }) +} + +// handleLogout drops the caller's session. +func (s *Server) handleLogout(w http.ResponseWriter, r *http.Request) { + if h := r.Header.Get("Authorization"); h != "" { + if scheme, value, ok := cut(h, " "); ok && scheme == "Bearer" { + s.auth.revoke(value) + } + } + writeJSON(w, http.StatusOK, map[string]any{"ok": true}) +} + +func cut(s, sep string) (before, after string, found bool) { + i := indexOf(s, sep) + if i < 0 { + return s, "", false + } + return s[:i], s[i+len(sep):], true +} + +func indexOf(s, sub string) int { + if len(sub) > len(s) { + return -1 + } + for i := 0; i+len(sub) <= len(s); i++ { + if s[i:i+len(sub)] == sub { + return i + } + } + return -1 +} + +// handleWhoami reports the caller's identity, which the UI uses to decide +// whether to show write controls. +func (s *Server) handleWhoami(w http.ResponseWriter, r *http.Request) { + p, _ := PrincipalFrom(r.Context()) + writeJSON(w, http.StatusOK, map[string]any{ + "name": p.Name, + "mode": p.Mode, + "read_only": p.ReadOnly, + "can_write": p.CanWrite(), + "auth_mode": s.AuthMode(), + "base_path": s.base, + }) +} diff --git a/internal/api/handlers.go b/internal/api/handlers.go new file mode 100644 index 0000000..ebeebea --- /dev/null +++ b/internal/api/handlers.go @@ -0,0 +1,701 @@ +package api + +import ( + "encoding/json" + "fmt" + "net/http" + "os" + "sort" + "strings" + "time" + + "gopkg.in/yaml.v3" + + "git.k8s-git-k6n.net/mats/fancy-dns/internal/config" +) + +// metricsHandler is injected by the app so the api package does not import the +// metrics package directly (keeps the dependency one-way). +var metricsHandler func() http.Handler + +// SetMetricsHandler installs the /metrics handler. +func SetMetricsHandler(h http.Handler) { + metricsHandler = func() http.Handler { return h } +} + +// handleHealth is the liveness/readiness probe. It is unauthenticated on +// purpose, but deliberately reveals only a coarse status. +func (s *Server) handleHealth(w http.ResponseWriter, _ *http.Request) { + h := s.hooks.Health() + code := http.StatusOK + if st, ok := h.(map[string]any); ok { + if v, _ := st["status"].(string); v == "down" { + code = http.StatusServiceUnavailable + } + } + writeJSON(w, code, h) +} + +// handleStatus reports the runtime state of every component. +func (s *Server) handleStatus(w http.ResponseWriter, _ *http.Request) { + writeJSON(w, http.StatusOK, map[string]any{ + "version": s.hooks.Version, + "uptime_s": int64(time.Since(s.hooks.StartedAt).Seconds()), + "started": s.hooks.StartedAt, + "config": map[string]any{ + "version": s.hooks.Store.Get().Version, + "generation": s.hooks.Store.Generation(), + "path": s.hooks.Store.Path(), + "last_error": s.hooks.Store.LastError(), + "writable": isFileWritable(s.hooks.Store.Path()), + "reload_ready": s.hooks.Store.Path() != "", + }, + "components": s.hooks.Status(), + }) +} + +// handleDashboard serves the aggregated dashboard payload. +func (s *Server) handleDashboard(w http.ResponseWriter, r *http.Request) { + if s.hooks.Dashboard == nil { + writeError(w, http.StatusNotImplemented, "dashboard not available") + return + } + v, err := s.hooks.Dashboard(r.Context(), r.URL.Query().Get("range")) + if err != nil { + writeError(w, http.StatusInternalServerError, err.Error()) + return + } + writeJSON(w, http.StatusOK, v) +} + +// handleBlocklists serves the compiled blocklist state. +func (s *Server) handleBlocklists(w http.ResponseWriter, _ *http.Request) { + out := map[string]any{} + if s.hooks.BlocklistState != nil { + if m, ok := s.hooks.BlocklistState().(map[string]any); ok { + out = m + } + } + writeJSON(w, http.StatusOK, out) +} + +// handleBlocklistRefresh recompiles the blocklists. +func (s *Server) handleBlocklistRefresh(w http.ResponseWriter, r *http.Request) { + if s.hooks.RefreshBlocklists == nil { + writeError(w, http.StatusNotImplemented, "blocklist refresh not available") + return + } + var in struct { + Names []string `json:"names"` + } + // An empty body is valid and means "refresh everything". + if r.ContentLength > 0 { + if err := decodeJSON(r, &in); err != nil { + writeError(w, http.StatusBadRequest, "malformed request body") + return + } + } + if err := s.hooks.RefreshBlocklists(r.Context(), in.Names); err != nil { + writeError(w, http.StatusInternalServerError, err.Error()) + return + } + s.log.Info("blocklist refresh requested", "names", in.Names) + writeJSON(w, http.StatusOK, map[string]any{"started": true, "names": in.Names}) +} + +// handleBlocklistToggle flips a source's enabled flag. +func (s *Server) handleBlocklistToggle(w http.ResponseWriter, r *http.Request) { + if s.hooks.ToggleBlocklist == nil { + writeError(w, http.StatusNotImplemented, "blocklist toggle not available") + return + } + var in struct { + Name string `json:"name"` + Enabled bool `json:"enabled"` + } + if err := decodeJSON(r, &in); err != nil || in.Name == "" { + writeError(w, http.StatusBadRequest, "name is required") + return + } + if err := s.hooks.ToggleBlocklist(in.Name, in.Enabled); err != nil { + writeError(w, http.StatusNotFound, err.Error()) + return + } + writeJSON(w, http.StatusOK, map[string]any{"ok": true, "name": in.Name, "enabled": in.Enabled}) +} + +// handleDomains pages the compiled rules. +func (s *Server) handleDomains(w http.ResponseWriter, r *http.Request) { + if s.hooks.ListDomains == nil { + writeError(w, http.StatusNotImplemented, "domain listing not available") + return + } + q := DomainQuery{ + Text: r.URL.Query().Get("q"), + Action: r.URL.Query().Get("action"), + List: r.URL.Query().Get("list"), + Page: queryInt(r, "page", 1), + PerPage: queryInt(r, "per_page", 100), + } + if q.Page < 1 { + q.Page = 1 + } + if q.PerPage < 1 || q.PerPage > 1000 { + q.PerPage = 100 + } + v, err := s.hooks.ListDomains(q) + if err != nil { + writeError(w, http.StatusInternalServerError, err.Error()) + return + } + writeJSON(w, http.StatusOK, v) +} + +// handleDomainCheck explains how a name would be treated, which is the fastest +// way for an operator to debug "why is this not blocked". +func (s *Server) handleDomainCheck(w http.ResponseWriter, r *http.Request) { + if s.hooks.DomainCheck == nil { + writeError(w, http.StatusNotImplemented, "domain check not available") + return + } + name := strings.TrimSpace(r.URL.Query().Get("name")) + if name == "" { + writeError(w, http.StatusBadRequest, "name is required") + return + } + v, err := s.hooks.DomainCheck(name) + if err != nil { + writeJSON(w, http.StatusOK, map[string]any{"name": name, "error": err.Error()}) + return + } + writeJSON(w, http.StatusOK, v) +} + +// handleDomainAdd adds an inline rule. +func (s *Server) handleDomainAdd(w http.ResponseWriter, r *http.Request) { + if s.hooks.AddDomain == nil { + writeError(w, http.StatusNotImplemented, "domain add not available") + return + } + var in DomainInput + if err := decodeJSON(r, &in); err != nil { + writeError(w, http.StatusBadRequest, "malformed request body") + return + } + if strings.TrimSpace(in.Name) == "" { + writeError(w, http.StatusBadRequest, "name is required") + return + } + v, err := s.hooks.AddDomain(r.Context(), in) + if err != nil { + writeError(w, http.StatusBadRequest, err.Error()) + return + } + writeJSON(w, http.StatusOK, v) +} + +// handleDomainDelete removes a rule. +func (s *Server) handleDomainDelete(w http.ResponseWriter, r *http.Request) { + if s.hooks.DeleteDomain == nil { + writeError(w, http.StatusNotImplemented, "domain delete not available") + return + } + // The route is {name...} so a rule name containing dots or a wildcard + // prefix survives without percent-encoding gymnastics. + name := r.PathValue("name") + if name == "" { + writeError(w, http.StatusBadRequest, "name is required") + return + } + if err := s.hooks.DeleteDomain(r.Context(), name, r.URL.Query().Get("action"), r.URL.Query().Get("list")); err != nil { + writeError(w, http.StatusNotFound, err.Error()) + return + } + writeJSON(w, http.StatusOK, map[string]any{"ok": true, "name": name}) +} + +// handleClients returns the ACL groups. +func (s *Server) handleClients(w http.ResponseWriter, _ *http.Request) { + if s.hooks.GetACL == nil { + writeError(w, http.StatusNotImplemented, "acl not available") + return + } + writeJSON(w, http.StatusOK, s.hooks.GetACL()) +} + +// aclPayload is the PUT body for the clients endpoint. +type aclPayload struct { + Groups []config.Group `json:"groups"` + DefaultPolicy string `json:"default_policy"` +} + +// handleClientsPut validates and persists new ACL groups. +func (s *Server) handleClientsPut(w http.ResponseWriter, r *http.Request) { + if s.hooks.PutACL == nil { + writeError(w, http.StatusNotImplemented, "acl write not available") + return + } + var in aclPayload + if err := decodeJSON(r, &in); err != nil { + writeError(w, http.StatusBadRequest, "malformed request body: "+err.Error()) + return + } + version, err := s.hooks.PutACL(r.Context(), in.Groups, in.DefaultPolicy) + if err != nil { + writeErrorFields(w, http.StatusBadRequest, err.Error(), configErrorFields(err)) + return + } + s.log.Info("acl updated", "groups", len(in.Groups), "version", version) + writeJSON(w, http.StatusOK, map[string]any{"ok": true, "version": version}) +} + +// handleUpstreams returns the upstream pool state. +func (s *Server) handleUpstreams(w http.ResponseWriter, _ *http.Request) { + if s.hooks.GetUpstream == nil { + writeError(w, http.StatusNotImplemented, "upstreams not available") + return + } + writeJSON(w, http.StatusOK, s.hooks.GetUpstream()) +} + +// upstreamPayload is the PUT body for the upstreams endpoint. Health fields +// from the UI are ignored on write: the server owns them. +type upstreamPayload struct { + Policy string `json:"policy"` + Servers []config.UpstreamServer `json:"servers"` + Bootstraps []config.UpstreamBootstrap `json:"bootstraps"` + HealthCheckSeconds float64 `json:"healthcheck_interval_s"` + MaxAttempts int `json:"max_attempts"` + BreakerThreshold int `json:"breaker_threshold"` +} + +// handleUpstreamsPut validates and persists a new upstream config. +func (s *Server) handleUpstreamsPut(w http.ResponseWriter, r *http.Request) { + if s.hooks.PutUpstream == nil { + writeError(w, http.StatusNotImplemented, "upstream write not available") + return + } + var in upstreamPayload + if err := decodeJSON(r, &in); err != nil { + writeError(w, http.StatusBadRequest, "malformed request body: "+err.Error()) + return + } + // Preserve fields the UI does not manage, so a UI write never silently + // resets a breaker cooldown someone set by hand. + cur := s.hooks.Store.Get().Upstream + up := config.Upstream{ + Policy: in.Policy, + Servers: in.Servers, + Bootstraps: in.Bootstraps, + MaxAttempts: in.MaxAttempts, + HealthCheck: config.Duration(in.HealthCheckSeconds * float64(time.Second)), + BreakerThreshold: in.BreakerThreshold, + BreakerCooldown: cur.BreakerCooldown, + } + if up.HealthCheck <= 0 { + up.HealthCheck = cur.HealthCheck + } + if up.BreakerThreshold <= 0 { + up.BreakerThreshold = cur.BreakerThreshold + } + version, err := s.hooks.PutUpstream(r.Context(), up) + if err != nil { + writeErrorFields(w, http.StatusBadRequest, err.Error(), configErrorFields(err)) + return + } + s.log.Info("upstreams updated", "servers", len(up.Servers), "version", version) + writeJSON(w, http.StatusOK, map[string]any{"ok": true, "version": version}) +} + +// handleLogs pages the query log. +func (s *Server) handleLogs(w http.ResponseWriter, r *http.Request) { + if s.hooks.SearchLog == nil { + writeError(w, http.StatusNotImplemented, "query log not available") + return + } + q := LogQuery{ + Limit: queryInt(r, "limit", 200), + Offset: queryInt(r, "offset", 0), + Text: r.URL.Query().Get("q"), + Action: r.URL.Query().Get("action"), + Client: r.URL.Query().Get("client"), + RCode: queryInt(r, "rcode", 0), + BlockedOnly: queryBool(r, "blocked"), + Since: queryTime(r, "since"), + } + v, err := s.hooks.SearchLog(r.Context(), q) + if err != nil { + writeError(w, http.StatusInternalServerError, err.Error()) + return + } + writeJSON(w, http.StatusOK, v) +} + +// handleLogStream is the Server-Sent Events endpoint feeding the live view. +func (s *Server) handleLogStream(w http.ResponseWriter, r *http.Request) { + flusher, ok := w.(http.Flusher) + if !ok { + writeError(w, http.StatusInternalServerError, "streaming unsupported") + return + } + w.Header().Set("Content-Type", "text/event-stream") + w.Header().Set("Cache-Control", "no-store") + w.Header().Set("Connection", "keep-alive") + // Without this, a reverse proxy buffers the stream and the UI shows + // nothing until the buffer fills. + w.Header().Set("X-Accel-Buffering", "no") + w.WriteHeader(http.StatusOK) + flusher.Flush() + + send := func(event string, v any) bool { + b, err := json.Marshal(v) + if err != nil { + return true + } + // A single-line data field is what the SSE grammar requires, so the + // payload is compact JSON with no newlines (json.Marshal never emits + // a raw newline). + if _, err := fmt.Fprintf(w, "event: %s\ndata: %s\n\n", event, b); err != nil { + return false + } + flusher.Flush() + return true + } + // An initial event tells the client the stream is live, so the UI can show + // a "connected" state before any query happens. + if !send("ready", map[string]any{"at": time.Now(), "version": s.hooks.Version}) { + return + } + + var ( + entries <-chan LogEntry + cancel func() + ) + if s.hooks.SubscribeLog != nil { + entries, cancel = s.hooks.SubscribeLog() + defer cancel() + } + + stats := time.NewTicker(time.Second) + defer stats.Stop() + ping := time.NewTicker(20 * time.Second) + defer ping.Stop() + + ctx := r.Context() + for { + select { + case <-ctx.Done(): + return + case e, ok := <-entries: + if !ok { + return + } + if !send("entry", e) { + return + } + case <-stats.C: + if s.hooks.LogStats == nil { + continue + } + if !send("stats", s.hooks.LogStats()) { + return + } + case <-ping.C: + // A comment frame keeps proxies from timing the stream out. + if _, err := fmt.Fprint(w, ": ping\n\n"); err != nil { + return + } + flusher.Flush() + } + } +} + +// handleLogsClear empties the query log. +func (s *Server) handleLogsClear(w http.ResponseWriter, _ *http.Request) { + if s.hooks.ClearLog == nil { + writeError(w, http.StatusNotImplemented, "query log not available") + return + } + if err := s.hooks.ClearLog(); err != nil { + writeError(w, http.StatusInternalServerError, err.Error()) + return + } + writeJSON(w, http.StatusOK, map[string]any{"ok": true}) +} + +// handleCache returns the cache snapshot. +func (s *Server) handleCache(w http.ResponseWriter, _ *http.Request) { + if s.hooks.CacheStats == nil { + writeError(w, http.StatusNotImplemented, "cache not available") + return + } + writeJSON(w, http.StatusOK, s.hooks.CacheStats()) +} + +// handleCacheTop returns the hottest cached names. +func (s *Server) handleCacheTop(w http.ResponseWriter, r *http.Request) { + if s.hooks.CacheTop == nil { + writeError(w, http.StatusNotImplemented, "cache not available") + return + } + writeJSON(w, http.StatusOK, map[string]any{ + "items": s.hooks.CacheTop(queryInt(r, "limit", 50)), + }) +} + +// handleCacheFlush empties the cache. +func (s *Server) handleCacheFlush(w http.ResponseWriter, _ *http.Request) { + if s.hooks.FlushCache == nil { + writeError(w, http.StatusNotImplemented, "cache not available") + return + } + n := s.hooks.FlushCache() + s.log.Info("cache flushed", "entries", n) + writeJSON(w, http.StatusOK, map[string]any{"ok": true, "entries": n}) +} + +// handleSettingsGet returns the config document plus what is knowable about it. +func (s *Server) handleSettingsGet(w http.ResponseWriter, _ *http.Request) { + path := s.hooks.Store.Path() + var fileYAML string + if path != "" { + if b, err := os.ReadFile(path); err == nil { + fileYAML = string(b) + } + } + cur := s.hooks.Store.Get() + effective, err := config.Marshal(cur) + if err != nil { + writeError(w, http.StatusInternalServerError, "cannot render config: "+err.Error()) + return + } + defaults, _ := config.Marshal(config.Default()) + if fileYAML == "" { + // Running without a file: show the effective document as the editable + // text so the UI still works. + fileYAML = string(effective) + } + writeJSON(w, http.StatusOK, map[string]any{ + "version": cur.Version, + "path": path, + "config_yaml": fileYAML, + "effective_yaml": string(effective), + "defaults_yaml": string(defaults), + "last_error": s.hooks.Store.LastError(), + "reload_available": path != "", + "writable": isFileWritable(path), + }) +} + +// settingsPayload is the PUT body for the settings endpoint. +type settingsPayload struct { + ConfigYAML string `json:"config_yaml"` +} + +// handleSettingsPut validates, writes and swaps a new config. +func (s *Server) handleSettingsPut(w http.ResponseWriter, r *http.Request) { + cfg := s.hooks.Store.Get() + if !cfg.API.AllowConfigWrite { + writeError(w, http.StatusForbidden, "config writes are disabled") + return + } + var in settingsPayload + if err := decodeJSON(r, &in); err != nil { + writeError(w, http.StatusBadRequest, "malformed request body") + return + } + if strings.TrimSpace(in.ConfigYAML) == "" { + writeError(w, http.StatusBadRequest, "config_yaml is empty") + return + } + next, err := parseConfigYAML(in.ConfigYAML) + if err != nil { + writeError(w, http.StatusBadRequest, "cannot parse config: "+err.Error()) + return + } + // Relative paths in the document resolve against the config's directory, + // so a file written from a different cwd still finds its zone files. + next.WorkingDirOrSet(cfg.Server.WorkingDir) + if err := next.Validate(); err != nil { + writeErrorFields(w, http.StatusBadRequest, "invalid config: "+err.Error(), configErrorFields(err)) + return + } + if err := s.commit(next); err != nil { + writeError(w, http.StatusInternalServerError, err.Error()) + return + } + s.log.Info("config updated via api", "version", next.Version) + writeJSON(w, http.StatusOK, map[string]any{"ok": true, "version": next.Version, "warnings": []string{}}) +} + +// handleSettingsValidate checks a document without applying it. +func (s *Server) handleSettingsValidate(w http.ResponseWriter, r *http.Request) { + var in settingsPayload + if err := decodeJSON(r, &in); err != nil { + writeError(w, http.StatusBadRequest, "malformed request body") + return + } + next, err := parseConfigYAML(in.ConfigYAML) + if err != nil { + writeJSON(w, http.StatusOK, map[string]any{ + "ok": false, + "errors": []map[string]string{{"field": "config", "message": err.Error()}}, + "warnings": []map[string]string{}, + }) + return + } + next.WorkingDirOrSet(s.hooks.Store.Get().Server.WorkingDir) + verr := next.Validate() + out := map[string]any{"ok": verr == nil, "errors": []map[string]string{}, "warnings": []map[string]string{}} + if verr != nil { + errs := make([]map[string]string, 0) + for _, f := range configErrorFields(verr) { + errs = append(errs, map[string]string{"field": fieldOf(f), "message": f}) + } + out["errors"] = errs + } + if warnings := configWarnings(next); len(warnings) > 0 { + ws := make([]map[string]string, 0, len(warnings)) + for _, warn := range warnings { + ws = append(ws, map[string]string{"field": fieldOf(warn), "message": warn}) + } + out["warnings"] = ws + } + writeJSON(w, http.StatusOK, out) +} + +// handleSettingsReload re-reads the config file from disk. +func (s *Server) handleSettingsReload(w http.ResponseWriter, _ *http.Request) { + if s.hooks.Store.Path() == "" { + writeError(w, http.StatusBadRequest, "no config file to reload from") + return + } + if err := s.hooks.Store.Reload(); err != nil { + writeError(w, http.StatusInternalServerError, "reload failed: "+err.Error()) + return + } + s.log.Info("config reloaded from disk", "version", s.hooks.Store.Get().Version) + writeJSON(w, http.StatusOK, map[string]any{"ok": true, "version": s.hooks.Store.Get().Version}) +} + +// commit writes the config to disk, swaps it in and notifies the cluster. +func (s *Server) commit(next *config.Config) error { + path := s.hooks.Store.Path() + if path == "" { + return fmt.Errorf("cannot persist: no config file path is known") + } + if !isFileWritable(path) { + return fmt.Errorf("cannot persist: %s is not writable", path) + } + next.Version = s.hooks.Store.Get().Version + 1 + if err := next.Save(path); err != nil { + return fmt.Errorf("write config: %w", err) + } + return s.hooks.Store.Swap(next) +} + +// Commit exposes the config commit path so a component (for example the ACL or +// upstream editor) goes through the same validate-write-swap flow. +func (s *Server) Commit(next *config.Config) error { return s.commit(next) } + +// parseConfigYAML decodes a config document on top of the defaults, which is +// what makes a partial document from the UI editor work. +func parseConfigYAML(text string) (*config.Config, error) { + next := config.Default() + if err := yaml.Unmarshal([]byte(text), next); err != nil { + return nil, err + } + return next, nil +} + +// configErrorFields splits a joined validation error into individual messages. +func configErrorFields(err error) []string { + if err == nil { + return nil + } + msg := err.Error() + parts := strings.Split(msg, "\n") + out := make([]string, 0, len(parts)) + for _, p := range parts { + if p = strings.TrimSpace(p); p != "" { + out = append(out, p) + } + } + if len(out) == 0 { + out = append(out, msg) + } + sort.Strings(out) + return out +} + +// fieldOf extracts the leading dotted path from a validation message, e.g. +// "blocklist.lists[2]: name is required" becomes "blocklist.lists[2]". +func fieldOf(msg string) string { + i := strings.Index(msg, ":") + if i <= 0 { + return "config" + } + if f := strings.TrimSpace(msg[:i]); f != "" { + return f + } + return "config" +} + +// configWarnings reports non-fatal configuration smells. A config can be valid +// and still a bad idea, and this is where a validator earns its keep. +func configWarnings(cfg *config.Config) []string { + var out []string + add := func(f string, a ...any) { out = append(out, fmt.Sprintf(f, a...)) } + + if cfg.API.Auth.Mode == "none" { + add("api.auth.mode: the admin API is unauthenticated; anyone who can reach it can rewrite your config") + } + if !cfg.DNS.DoT.Enabled && !cfg.DNS.DoH.Enabled { + add("dns: neither DoT nor DoH is enabled, so clients have no encrypted transport") + } + if cfg.Cache.Enabled && !cfg.Cache.Persist.Enabled { + add("cache.persist.enabled: the cache will be cold after every restart") + } + if cfg.Cache.MaxTTL.D() > 24*time.Hour { + add("cache.max_ttl: caching for more than a day serves records upstream has already forgotten") + } + if !cfg.Block.Enabled { + add("blocklist.enabled: blocklists are off, so this instance is an open resolver for everything") + } else if len(cfg.Block.Lists) == 0 && len(cfg.Block.LocalZones) == 0 && + len(cfg.Block.BlockEntries) == 0 { + add("blocklist: enabled but no source is configured") + } + for _, l := range cfg.Block.Lists { + if strings.HasPrefix(l.URL, "http://") { + add("blocklist.lists[%s]: the source is fetched over plain http and can be tampered with in transit", l.Name) + } + if l.Refresh.D() > 0 && l.Refresh.D() < time.Hour { + add("blocklist.lists[%s]: a refresh interval under an hour is likely to get you rate-limited", l.Name) + } + if strings.EqualFold(l.Format, "rpz") && strings.ContainsAny(l.Path, "*?") { + add("blocklist.lists[%s]: an rpz source should point at a zone file, not a pattern", l.Name) + } + } + if cfg.ACL.DefaultPolicy == "allow" { + for _, g := range cfg.ACL.Groups { + if g.Match.Any { + add("acl.groups[%s]: a catch-all group with policy allow makes the ACL a no-op", g.Name) + } + } + } + if len(cfg.Upstream.Servers) == 1 { + add("upstream.servers: only one upstream is configured, so a failure of that resolver is an outage") + } + for _, u := range cfg.Upstream.Servers { + if u.InsecureSkipVerify { + add("upstream.servers[%s]: insecure_skip_verify disables TLS validation", u.Addr) + } + } + if cfg.QueryLog.Enabled && cfg.QueryLog.SampleRate == 1 && cfg.QueryLog.LogCached { + add("qlog: logging every cached query on a busy instance is a lot of disk for little value; consider lowering sample_rate") + } + if cfg.Metrics.Enabled && !cfg.Metrics.Protect { + add("metrics.protect: /metrics is unauthenticated and exposes client and domain statistics") + } + return out +} diff --git a/internal/app/app.go b/internal/app/app.go new file mode 100644 index 0000000..1c31ebb --- /dev/null +++ b/internal/app/app.go @@ -0,0 +1,786 @@ +// Package app wires the components together and owns the process lifecycle: +// configuration, listeners, background loops, the admin API and shutdown. +package app + +import ( + "context" + "crypto/tls" + "errors" + "fmt" + "log/slog" + "net" + "net/http" + "os" + "path/filepath" + "strings" + "sync" + "time" + + "git.k8s-git-k6n.net/mats/fancy-dns/internal/acl" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/api" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/blocklist" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/cache" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/cluster" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/config" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/engine" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/localzone" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/metrics" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/qlog" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/resolver" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/server" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/web" + "github.com/miekg/dns" +) + +// Version is the build version, overridden at link time with -ldflags. +var Version = "dev" + +// Options configures an App. +type Options struct { + // ConfigPath is the configuration file; "" runs on defaults. + ConfigPath string + // Version is the reported build version. + Version string + // LogLevel and LogFormat override the config's logging settings. + LogLevel string + LogFormat string +} + +// App is the running process. +type App struct { + opt Options + log *slog.Logger + cfg *config.Store + ver string + + blocks *blocklist.Manager + cache *cache.Manager + cstore *cache.Store + logger *qlog.Logger + aclH *acl.Holder + local *localzone.Holder + pool *resolver.Pool + reverse *engine.ReverseCache + engine *engine.Engine + dns *server.Server + api *api.Server + cl *cluster.Cluster + series *seriesStore + + apiServers []*http.Server + apiLn []net.Listener + + // reloadMu serialises reload work, since SIGHUP, the API and the cluster + // can all trigger one at the same time. + reloadMu sync.Mutex + + startedAt time.Time + // degraded is set when a background component failed; surfaced in health. + degradedMu sync.RWMutex + degraded []string +} + +// New builds an App from options. It does not bind anything yet; call Start. +func New(opt Options) (*App, error) { + if opt.Version == "" { + opt.Version = Version + } + cfg, err := config.Load(opt.ConfigPath) + if err != nil { + return nil, err + } + log, err := newLogger(cfg, opt) + if err != nil { + return nil, err + } + store := config.NewStore(cfg, opt.ConfigPath) + return &App{opt: opt, log: log, cfg: store, ver: opt.Version}, nil +} + +// newLogger builds the structured logger from config plus CLI overrides. +func newLogger(cfg *config.Config, opt Options) (*slog.Logger, error) { + level := cfg.Log.Level + if opt.LogLevel != "" { + level = opt.LogLevel + } + var lvl slog.Level + switch level { + case "debug": + lvl = slog.LevelDebug + case "warn": + lvl = slog.LevelWarn + case "error": + lvl = slog.LevelError + default: + lvl = slog.LevelInfo + } + format := cfg.Log.Format + if opt.LogFormat != "" { + format = opt.LogFormat + } + handlerOpts := &slog.HandlerOptions{Level: lvl} + + var w *os.File = os.Stderr + if cfg.Log.Addr != "" { + if strings.HasPrefix(cfg.Log.Addr, "/") { + f, err := os.OpenFile(cfg.Log.Addr, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644) + if err != nil { + return nil, fmt.Errorf("open log file: %w", err) + } + w = f + } + } + var h slog.Handler + if format == "json" { + h = slog.NewJSONHandler(w, handlerOpts) + } else { + h = slog.NewTextHandler(w, handlerOpts) + } + return slog.New(h).With("service", "fancy-dns", "version", opt.Version), nil +} + +// Start brings up every component in dependency order. +func (a *App) Start(ctx context.Context) error { + a.startedAt = time.Now() + cfg := a.cfg.Get() + metrics.SetUp(true) + + if err := a.startCache(cfg); err != nil { + return err + } + if err := a.startLogger(cfg); err != nil { + return err + } + a.startBlocklist() + a.startLocalZones(cfg) + a.startUpstream(cfg) + a.startDNS(ctx) + if err := a.startAPI(ctx); err != nil { + return err + } + a.startCluster(ctx, cfg) + a.startBackground(ctx, cfg) + a.cfg.OnSwap(a.onConfigSwap) + + // The real bound admin address, not the configured one: with :0 the config + // is useless for telling the operator where to point a browser. + a.log.Info("fancy-dns started", + "config", a.cfg.Path(), + "dns", a.dns.Listeners(), + "api", a.Addr()) + return nil +} + +// startCache opens the bbolt snapshot and restores a warm start. +func (a *App) startCache(cfg *config.Config) error { + opts := cache.Options{ + Size: cfg.Cache.Size, + Shards: cfg.Cache.Shards, + MinTTL: cfg.Cache.MinTTL.D(), + MaxTTL: cfg.Cache.MaxTTL.D(), + NegativeTTL: cfg.Cache.NegativeTTL.D(), + ServeStale: cfg.Cache.ServeStale.D(), + Prefetch: cfg.Cache.Prefetch, + } + if cfg.Cache.Enabled && cfg.Cache.Persist.Enabled { + st, err := cache.OpenStore(cache.StoreOptions{ + Path: cfg.CachePath(), + MaxEntries: cfg.Cache.Persist.MaxEntries, + }) + if err != nil { + a.markDegraded("cache persistence: " + err.Error()) + a.log.Warn("cache persistence unavailable, continuing without it", "error", err) + } else { + a.cstore = st + if cfg.Cache.Persist.LoadOnStart { + lru := cache.NewLRU(cfg.Cache.Size, cfg.Cache.Shards) + loaded, skipped, lerr := st.Load(lru, time.Now()) + if lerr != nil { + a.log.Warn("cache snapshot load failed", "error", lerr) + } else if loaded > 0 { + a.log.Info("cache snapshot restored", "entries", loaded, "skipped", skipped) + // Re-seed the real LRU from the temporary one. + a.cache = cache.NewManager(opts, st) + lru.Walk(func(k cache.Key, e *cache.Entry) bool { + a.cache.PutRaw(k, e.Wire, e.TTL, e.Origin, e.Upstream, e.Neg) + return true + }) + } + } + } + } + if a.cache == nil { + a.cache = cache.NewManager(opts, a.cstore) + } + return nil +} + +// prewarm resolves a few names at boot in the background, so a restart does +// not look like an outage for the names that matter most. +func (a *App) prewarm(c context.Context, specs []string) { + go func() { + for _, spec := range specs { + name, qtypeStr, ok := strings.Cut(spec, "/") + if !ok { + name, qtypeStr = spec, "A" + } + qtype, ok := dns.StringToType[strings.ToUpper(qtypeStr)] + if !ok { + a.log.Warn("prewarm: unknown record type", "spec", spec) + continue + } + m := new(dns.Msg) + m.SetQuestion(dns.Fqdn(name), qtype) + m.RecursionDesired = true + res := a.engine.Handle(c, engine.Request{Msg: m, Transport: "internal", Start: time.Now()}) + if res.Msg != nil && res.Msg.Rcode == dns.RcodeSuccess { + a.log.Debug("prewarmed", "name", name, "type", qtypeStr) + } + } + }() +} + +// tlsCfgType aliases the TLS config so the listener helpers read cleanly. +type tlsCfgType = tls.Config + +// apiTLS builds the admin listener's TLS config when one is configured. +func apiTLS(cfg *config.Config) (*tls.Config, error) { + if cfg.API.CertFile == "" || cfg.API.KeyFile == "" { + return nil, nil + } + cert, err := tls.LoadX509KeyPair(cfg.API.CertFile, cfg.API.KeyFile) + if err != nil { + return nil, fmt.Errorf("load admin certificate: %w", err) + } + return &tls.Config{ + Certificates: []tls.Certificate{cert}, + MinVersion: tls.VersionTLS12, + NextProtos: []string{"h2", "http/1.1"}, + }, nil +} + +// startLogger opens the query log. +func (a *App) startLogger(cfg *config.Config) error { + opts := qlog.DefaultOptions() + opts.Path = cfg.QueryLogPath() + opts.MaxEntries = cfg.QueryLog.MaxEntries + opts.LiveBuffer = cfg.QueryLog.LiveBuffer + opts.FlushInterval = cfg.QueryLog.FlushInterval.D() + opts.SampleRate = cfg.QueryLog.SampleRate + opts.LogBlocked = cfg.QueryLog.LogBlocked + opts.LogCached = cfg.QueryLog.LogCached + opts.LogErrors = cfg.QueryLog.LogErrors + opts.TopDomains = cfg.QueryLog.TopDomains + opts.TopTTL = cfg.QueryLog.TopTTL.D() + if !cfg.QueryLog.Enabled { + opts.Path = "" + } + l, err := qlog.New(opts) + if err != nil { + a.markDegraded("query log: " + err.Error()) + a.log.Warn("query log unavailable, continuing without persistence", "error", err) + return nil + } + a.logger = l + return nil +} + +// startBlocklist starts the refresh loop and does the first compile. +func (a *App) startBlocklist() { + cfg := a.cfg.Get() + if !cfg.Block.Enabled { + a.log.Info("blocklists disabled") + return + } + a.blocks = blocklist.NewManager(blocklist.ManagerOptions{ + Config: a.cfg, + Logger: a.log, + }) + // Compile once before serving so the first queries are not unprotected. + if _, err := a.blocks.RefreshAll(context.Background()); err != nil { + a.markDegraded("blocklist: " + err.Error()) + a.log.Warn("initial blocklist compile failed", "error", err) + } +} + +// startLocalZones compiles the local master files. +func (a *App) startLocalZones(cfg *config.Config) { + a.local = localzone.NewHolder(nil) + if len(cfg.Block.LocalZones) == 0 { + return + } + a.reloadLocalZones() +} + +// reloadLocalZones recompiles the local zone store. A failure keeps the +// previous store: serving stale local data beats serving nothing. +func (a *App) reloadLocalZones() { + cfg := a.cfg.Get() + if len(cfg.Block.LocalZones) == 0 { + a.local.Set(nil) + return + } + paths := make([]string, 0, len(cfg.Block.LocalZones)) + for _, p := range cfg.Block.LocalZones { + paths = append(paths, cfg.AbsPath(p)) + } + store, err := localzone.Load(paths, localzone.Options{}) + if err != nil { + a.markDegraded("local zones: " + err.Error()) + a.log.Error("local zone load failed, keeping previous data", "error", err) + return + } + a.local.Set(store) + metrics.SetLocalRecords(store.Count()) + a.log.Info("local zones loaded", "zones", store.Zones(), "records", store.Count()) +} + +// startUpstream builds the resolver pool. +func (a *App) startUpstream(cfg *config.Config) { + a.pool = resolver.NewPool(cfg.Upstream) +} + +// startDNS builds the engine and the listeners. +func (a *App) startDNS(ctx context.Context) { + a.aclH = acl.NewHolder(acl.Compile(cfgACL(a.cfg.Get()))) + a.reverse = engine.NewReverseCache(engine.ReverseOptions{Max: 8192}) + a.engine = engine.New(engine.Options{ + Config: a.cfg, + Logger: a.logger, + Blocklists: a.blocksHolder(), + Cache: a.cache, + ACL: a.aclH, + Local: a.local, + Pool: a.pool, + Reverse: a.reverse, + }) + a.engine.SetFlusher(a.flush) + a.dns = server.New(server.Options{ + Engine: a.engine, + Config: a.cfg, + Logger: a.log, + Version: a.ver, + }) + a.dns.SetIdentity( + func(ip string) []string { names, _ := a.reverse.Names(ip); return names }, + func(ip string) []string { + for _, n := range mustNames(a.reverse, ip) { + if tags := acl.TagsFromName(n); len(tags) > 0 { + return tags + } + } + return nil + }, + ) + if err := a.dns.Start(ctx); err != nil { + a.log.Error("dns listeners failed to start", "error", err) + a.markDegraded("dns listeners: " + err.Error()) + } + a.series = newSeriesStore() +} + +func mustNames(rc *engine.ReverseCache, ip string) []string { + names, _ := rc.Names(ip) + return names +} + +func (a *App) blocksHolder() *blocklist.Holder { + if a.blocks == nil { + return blocklist.NewHolder(nil) + } + return a.blocks.Holder() +} + +func cfgACL(cfg *config.Config) config.ACL { return cfg.ACL } + +// startAPI binds the admin listener and, when configured, the embedded UI. +func (a *App) startAPI(ctx context.Context) error { + cfg := a.cfg.Get() + if !cfg.API.Enabled { + return nil + } + api.SetMetricsHandler(metrics.Handler()) + hooks := a.hooks() + srv, err := api.New(hooks) + if err != nil { + return err + } + a.api = srv + + // One mux: the API claims its base path, the SPA claims the rest. The API + // is registered first so /api/* never falls through to the SPA's + // index.html fallback (which would return HTML to a JSON client). + mux := http.NewServeMux() + // The api package already registers its routes with the full base path, so + // no StripPrefix here: a more specific pattern than the SPA's "/" wins, so + // /api/* never falls through to index.html. + mux.Handle(cfg.API.BasePath+"/", srv.Handler()) + mux.Handle(cfg.API.BasePath, srv.Handler()) + if cfg.API.UI { + ui, err := web.Handler("") + if err != nil { + a.log.Warn("web console unavailable", "error", err) + } else { + mux.Handle("/", ui) + if web.Available() { + a.log.Info("web console enabled") + } else { + a.log.Warn("web console assets missing from this binary; run 'make web' and rebuild") + } + } + } + + tlsCfg, tlsErr := apiTLS(cfg) + var errs []error + for _, addr := range cfg.API.Listen { + ln, err := net.Listen("tcp", addr) + if err != nil { + errs = append(errs, fmt.Errorf("bind api %s: %w", addr, err)) + continue + } + a.startHTTPServer(mux, ln, nil, "api") + } + if len(cfg.API.TLSListen) > 0 { + if tlsErr != nil { + errs = append(errs, tlsErr) + } else { + for _, addr := range cfg.API.TLSListen { + ln, err := net.Listen("tcp", addr) + if err != nil { + errs = append(errs, fmt.Errorf("bind api tls %s: %w", addr, err)) + continue + } + a.startHTTPServer(mux, ln, tlsCfg, "api-tls") + } + } + } + if err := errors.Join(errs...); err != nil { + a.markDegraded("admin api: " + err.Error()) + a.log.Error("admin api failed to bind", "error", err) + } + _ = ctx + return nil +} + +func (a *App) startHTTPServer(h http.Handler, ln net.Listener, tlsCfg *tlsCfgType, name string) { + srv := &http.Server{ + Handler: h, + ReadHeaderTimeout: 15 * time.Second, + IdleTimeout: 120 * time.Second, + } + if tlsCfg != nil { + srv.TLSConfig = tlsCfg + ln = tls.NewListener(ln, tlsCfg) + } + a.apiServers = append(a.apiServers, srv) + a.apiLn = append(a.apiLn, ln) + a.log.Info("admin api listening", "addr", ln.Addr().String(), "tls", tlsCfg != nil, "name", name) + + go func() { + if err := srv.Serve(ln); err != nil && !errors.Is(err, http.ErrServerClosed) { + a.log.Error("admin api stopped", "error", err, "name", name) + } + }() +} + +// startCluster connects to Valkey and wires cluster events into a reload. +func (a *App) startCluster(ctx context.Context, cfg *config.Config) { + if !cfg.Cluster.Enabled { + a.cl = cluster.New(cluster.Options{Config: a.cfg, Logger: a.log, Version: a.ver}) + return + } + a.cl = cluster.New(cluster.Options{ + Config: a.cfg, + Logger: a.log, + Version: a.ver, + StartedAt: a.startedAt, + Addr: cfg.Cluster.Advertise, + StateFunc: a.nodeState, + Digests: a.nodeDigests, + Handler: a.onClusterEvent, + }) + a.cl.Start(ctx) +} + +// startBackground runs the periodic jobs: cache snapshots, upstream health +// probes and the metrics gauge. +func (a *App) startBackground(ctx context.Context, cfg *config.Config) { + // Cache snapshots. + if a.cstore != nil { + interval := cfg.Cache.Persist.Interval.D() + if interval <= 0 { + interval = 30 * time.Second + } + go func() { + t := time.NewTicker(interval) + defer t.Stop() + for { + select { + case <-ctx.Done(): + a.snapshotCache() + return + case <-t.C: + a.snapshotCache() + } + } + }() + } + // Upstream health probes. + go a.healthLoop(ctx) + // Live gauges and the dashboard series sampler. + go func() { + t := time.NewTicker(2 * time.Second) + defer t.Stop() + sample := time.NewTicker(5 * time.Second) + defer sample.Stop() + for { + select { + case <-ctx.Done(): + return + case <-t.C: + metrics.SetConcurrent(int(a.engine.Inflight())) + case <-sample.C: + if a.series != nil { + a.series.sample() + } + } + } + }() +} + +func (a *App) snapshotCache() { + if a.cstore == nil || a.cache == nil { + return + } + n, err := a.cstore.Snapshot(a.cache.LRU(), time.Now()) + if err != nil { + a.log.Warn("cache snapshot failed", "error", err) + return + } + a.log.Debug("cache snapshot written", "entries", n) +} + +func (a *App) healthLoop(ctx context.Context) { + for { + interval := a.cfg.Get().Upstream.HealthCheck.D() + if interval <= 0 { + interval = 30 * time.Second + } + select { + case <-ctx.Done(): + return + case <-time.After(interval): + } + pool := a.pool + if pool == nil { + continue + } + hctx, cancel := context.WithTimeout(ctx, 5*time.Second) + ok := pool.HealthCheck(hctx, 3*time.Second) + cancel() + total := len(pool.All()) + for _, u := range pool.All() { + healthy := u.Health() == resolver.HealthUp + metrics.SetUpstreamHealth(u.Addr(), u.Config().Proto, healthy) + } + if total > 0 && ok == 0 { + a.markDegraded("no upstream is answering health probes") + } else { + a.clearDegraded("no upstream is answering health probes") + } + } +} + +// markDegraded records a component problem for the health endpoint. +func (a *App) markDegraded(reason string) { + a.degradedMu.Lock() + defer a.degradedMu.Unlock() + for _, r := range a.degraded { + if r == reason { + return + } + } + a.degraded = append(a.degraded, reason) +} + +func (a *App) clearDegraded(reason string) { + a.degradedMu.Lock() + defer a.degradedMu.Unlock() + out := a.degraded[:0] + for _, r := range a.degraded { + if r != reason { + out = append(out, r) + } + } + a.degraded = out +} + +// Degraded returns the current problem list. +func (a *App) Degraded() []string { + a.degradedMu.RLock() + defer a.degradedMu.RUnlock() + return append([]string(nil), a.degraded...) +} + +// onConfigSwap reacts to a new configuration. +func (a *App) onConfigSwap(cfg *config.Config) { + a.log.Info("configuration applied", "version", cfg.Version) + if a.pool != nil { + a.pool.Rebind(cfg.Upstream) + } + a.reloadLocalZones() + if a.blocks != nil && !cfg.Block.Enabled { + a.log.Info("blocklists disabled by configuration change") + } +} + +// onClusterEvent reacts to a peer message. +func (a *App) onClusterEvent(ctx context.Context, ev cluster.Event) { + switch ev.Kind { + case cluster.EventReload: + a.log.Info("peer requested a config reload", "from", ev.NodeID) + if err := a.Reload(); err != nil { + a.log.Warn("cluster-triggered reload failed", "error", err) + } + case cluster.EventBlocklists: + // Only the lease holder fetches, so N instances do not hammer a mirror + // N times; the others keep serving their compiled copy. + if a.cl != nil && a.cl.IsLeader() { + if a.blocks != nil { + a.blocks.Trigger(firstOr(ev.Sources, "")) + } + } + case cluster.EventConfig: + // A peer pushed a full document. We do not adopt it silently: a + // follower adopting a document it cannot see on disk would drift. The + // operator re-runs a deploy or hits "reload" instead. + a.log.Info("peer published a new config version", "from", ev.NodeID, "version", ev.Version) + } +} + +func firstOr(s []string, def string) string { + if len(s) > 0 && s[0] != "" { + return s[0] + } + return def +} + +// nodeState supplies the live state published to peers. +func (a *App) nodeState() *cluster.NodeState { + addrs := make([]string, 0, 4) + for _, l := range a.dns.Listeners() { + addrs = append(addrs, l.Transport+":"+l.Addr) + } + return &cluster.NodeState{ + Addr: a.opt.ConfigPath, + Version: a.ver, + StartedAt: a.startedAt, + Listeners: addrs, + Generation: a.cfg.Generation(), + } +} + +// nodeDigests supplies the digests peers compare. +func (a *App) nodeDigests() (string, int, time.Time, string) { + var ( + bl string + rules int + built time.Time + ) + if a.blocks != nil { + st := a.blocks.State() + if st != nil { + bl = st.Digest + if st.Set != nil { + rules = st.Set.Len() + built = st.Set.BuiltAt() + } + } + } + return bl, rules, built, cluster.Digest(a.cfg.Get()) +} + +// Reload re-reads the config file and applies it. +func (a *App) Reload() error { + a.reloadMu.Lock() + defer a.reloadMu.Unlock() + return a.cfg.Reload() +} + +// Stop shuts everything down in reverse order, with a deadline. +func (a *App) Stop(ctx context.Context) error { + a.log.Info("shutting down") + metrics.SetUp(false) + var errs []error + + if a.cl != nil { + a.cl.Stop() + } + if a.blocks != nil { + a.blocks.Stop() + } + if a.dns != nil { + if err := a.dns.Stop(ctx); err != nil { + errs = append(errs, err) + } + } + for _, srv := range a.apiServers { + shutCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + err := srv.Shutdown(shutCtx) + cancel() + if err != nil { + errs = append(errs, err) + } + } + if a.logger != nil { + a.logger.Flush() + if err := a.logger.Close(); err != nil { + errs = append(errs, err) + } + } + if a.cstore != nil { + // Snapshot, close, then clear the pointer: the background snapshot + // goroutine also fires on ctx.Done, and a nil check is how it learns + // to stop rather than writing to a closed file. + a.snapshotCache() + if err := a.cstore.Close(); err != nil { + errs = append(errs, err) + } + a.cstore = nil + } + if err := errors.Join(errs...); err != nil { + a.log.Warn("shutdown completed with errors", "error", err) + } else { + a.log.Info("shutdown complete") + } + return errors.Join(errs...) +} + +// Addr returns the admin API address, which a preview needs. +func (a *App) Addr() string { + for _, ln := range a.apiLn { + return ln.Addr().String() + } + return "" +} + +// DataDir is where the bbolt files live. +func (a *App) DataDir() string { + return filepath.Dir(a.cfg.Get().CachePath()) +} + +// Log exposes the logger so the command can report signals. +func (a *App) Log() *slog.Logger { return a.log } + +// SetAdminAddr overrides the admin API listen address without touching the +// config file, which is what a container platform's -admin-addr flag wants. +func (a *App) SetAdminAddr(addr string) error { + next := a.cfg.Get() + cp := *next + cp.API = next.API + cp.API.Listen = []string{addr} + if err := a.cfg.Swap(&cp); err != nil { + return err + } + return nil +} diff --git a/internal/app/harness_test.go b/internal/app/harness_test.go new file mode 100644 index 0000000..85a6441 --- /dev/null +++ b/internal/app/harness_test.go @@ -0,0 +1,246 @@ +package app + +import ( + "context" + "crypto/tls" + "encoding/base64" + "fmt" + "io" + "net" + "net/http" + "os" + "path/filepath" + "strings" + "sync" + "testing" + "time" + + "github.com/miekg/dns" + + "git.k8s-git-k6n.net/mats/fancy-dns/internal/config" +) + +// testUpstream is a fake recursive resolver: it answers A queries for names +// under test. and NXDOMAIN for everything else, so a test can tell "resolved +// upstream" from "blocked locally" without touching the internet. +type testUpstream struct { + *dns.Server + addr string + mu sync.Mutex + hits map[string]int +} + +func newTestUpstream(t *testing.T) *testUpstream { + t.Helper() + pc, err := net.ListenPacket("udp", "127.0.0.1:0") + if err != nil { + t.Fatalf("listen: %v", err) + } + u := &testUpstream{addr: pc.LocalAddr().String(), hits: map[string]int{}} + u.Server = &dns.Server{PacketConn: pc, Handler: dns.HandlerFunc(u.handle)} + go func() { _ = u.ActivateAndServe() }() + t.Cleanup(func() { _ = u.Shutdown() }) + return u +} + +func (u *testUpstream) handle(w dns.ResponseWriter, q *dns.Msg) { + m := new(dns.Msg) + m.SetReply(q) + name := q.Question[0].Name + u.mu.Lock() + u.hits[name]++ + u.mu.Unlock() + if strings.HasSuffix(name, ".test.") { + if q.Question[0].Qtype == dns.TypeA { + rr, _ := dns.NewRR(name + " 60 IN A 203.0.113.7") + m.Answer = append(m.Answer, rr) + } + soa, _ := dns.NewRR("test. 60 IN SOA ns.test. hostmaster.test. 1 3600 600 604800 60") + m.Ns = append(m.Ns, soa) + } else { + m.Rcode = dns.RcodeNameError + soa, _ := dns.NewRR("test. 60 IN SOA ns.test. hostmaster.test. 1 3600 600 604800 60") + m.Ns = append(m.Ns, soa) + } + _ = w.WriteMsg(m) +} + +func (u *testUpstream) hitCount(name string) int { + u.mu.Lock() + defer u.mu.Unlock() + return u.hits[name] +} + +// harness is a fully wired App on ephemeral ports, with a fake upstream. +type harness struct { + t *testing.T + app *App + addr string // host:port for plain DNS + api string // host:port for the admin API + key string + up *testUpstream + dir string + // config is the document the harness wrote to disk, so a test can make a + // realistic edit rather than inventing a minimal stub. + config string +} + +// OriginalConfig returns the document the harness wrote to disk, so a test +// can make a realistic single-value edit instead of inventing a minimal stub. +func (h *harness) OriginalConfig() string { return h.config } + +func newHarness(t *testing.T, mutate func(*config.Config)) *harness { + t.Helper() + dir := t.TempDir() + up := newTestUpstream(t) + + hosts := filepath.Join(dir, "hosts") + if err := os.WriteFile(hosts, []byte( + "0.0.0.0 ads.example.com\n"+ + "0.0.0.0 tracker.example.net\n"+ + "0.0.0.0 shared.example.com\n"+ + // Under .test. so the fake upstream resolves it: NOERROR then means + // "the blocklist let it through" and NXDOMAIN means "blocked", with + // no third possibility to confuse an assertion. + "0.0.0.0 blocked.example.test\n"+ + "# comment\n"+ + "127.0.0.1 localhost\n"), 0o644); err != nil { + t.Fatal(err) + } + zone := filepath.Join(dir, "local.zone") + if err := os.WriteFile(zone, []byte( + "$TTL 60\n"+ + "local. SOA ns.local. hostmaster.local. 1 3600 600 604800 60\n"+ + "local. NS ns.local.\n"+ + "ns.local. A 192.168.1.2\n"+ + "*.wild.local. A 192.168.1.50\n"+ + "deep.svc.local. A 192.168.1.60\n"+ + "*.deep.svc.local. A 192.168.1.61\n"), 0o644); err != nil { + t.Fatal(err) + } + + // Pick a free port up front so the client can address the listeners and so + // a port clash fails the test rather than the app's start-up. + dnsPort := freePort(t) + dnsAddr := fmt.Sprintf("127.0.0.1:%d", dnsPort) + + cfg := config.Default() + cfg.WorkingDirOrSet(dir) + cfg.DNS.UDP = []string{dnsAddr} + cfg.DNS.TCP = []string{dnsAddr} + cfg.DNS.DoT.Enabled = false + cfg.DNS.DoH.Enabled = false + cfg.API.Listen = []string{"127.0.0.1:0"} + cfg.API.Auth.Mode = "apikey" + cfg.API.Auth.APIKeys = []string{"test-key"} + cfg.API.Auth.TrustLoopback = false + cfg.API.UI = false + cfg.Upstream.Policy = "parallel" + cfg.Upstream.MaxAttempts = 1 + cfg.Upstream.HealthCheck = 0 + cfg.Upstream.Servers = []config.UpstreamServer{{Addr: up.addr, Proto: "udp", Weight: 1, HealthName: "test"}} + cfg.Cache.Persist.Path = filepath.Join(dir, "cache.db") + cfg.QueryLog.Path = filepath.Join(dir, "queries.db") + cfg.Block.Lists = []config.ListSource{{ + Name: "test-hosts", Format: "hosts", Path: hosts, Enabled: true, Refresh: 0, + }} + cfg.Block.LocalZones = []string{zone} + cfg.Block.BlockEntries = []string{"inline-blocked.example.com", "*.inline-sub.example.com"} + cfg.Block.AllowEntries = []string{"allow.example.com"} + if mutate != nil { + mutate(cfg) + } + path := filepath.Join(dir, "config.yaml") + // Snapshot the document before the app starts: the server may rewrite this + // file (every API mutation does), so a test must not read it concurrently + // with a live instance's own writes. + doc := string(mustYAML(t, cfg)) + if err := os.WriteFile(path, []byte(doc), 0o600); err != nil { + t.Fatal(err) + } + + a, err := New(Options{ConfigPath: path, Version: "test"}) + if err != nil { + t.Fatalf("new app: %v", err) + } + ctx, cancel := context.WithCancel(context.Background()) + if err := a.Start(ctx); err != nil { + cancel() + t.Fatalf("start: %v", err) + } + t.Cleanup(func() { + sctx, scancel := context.WithTimeout(context.Background(), 5*time.Second) + _ = a.Stop(sctx) + scancel() + cancel() + }) + return &harness{t: t, app: a, addr: dnsAddr, api: a.Addr(), key: "test-key", up: up, dir: dir, config: doc} +} + +// freePort returns a currently-free TCP port on the loopback interface. +func freePort(t *testing.T) int { + t.Helper() + ln, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("free port: %v", err) + } + port := ln.Addr().(*net.TCPAddr).Port + _ = ln.Close() + return port +} + +func (h *harness) query(name string, qtype uint16) *dns.Msg { + h.t.Helper() + m := new(dns.Msg) + m.SetQuestion(dns.Fqdn(name), qtype) + m.RecursionDesired = true + c := &dns.Client{Net: "udp", Timeout: 5 * time.Second} + res, _, err := c.Exchange(m, h.addr) + if err != nil { + h.t.Fatalf("query %s: %v", name, err) + } + return res +} + +func (h *harness) get(path string) (int, []byte) { + h.t.Helper() + req, _ := http.NewRequest("GET", "http://"+h.api+path, nil) + req.Header.Set("X-API-Key", h.key) + res, err := http.DefaultClient.Do(req) + if err != nil { + h.t.Fatalf("GET %s: %v", path, err) + } + defer res.Body.Close() + b, _ := io.ReadAll(res.Body) + return res.StatusCode, b +} + +func (h *harness) do(method, path, body string) (int, []byte) { + h.t.Helper() + var rdr io.Reader + if body != "" { + rdr = strings.NewReader(body) + } + req, _ := http.NewRequest(method, "http://"+h.api+path, rdr) + req.Header.Set("X-API-Key", h.key) + req.Header.Set("Content-Type", "application/json") + res, err := http.DefaultClient.Do(req) + if err != nil { + h.t.Fatalf("%s %s: %v", method, path, err) + } + defer res.Body.Close() + b, _ := io.ReadAll(res.Body) + return res.StatusCode, b +} + +func mustYAML(t *testing.T, c *config.Config) []byte { + t.Helper() + b, err := config.Marshal(c) + if err != nil { + t.Fatal(err) + } + return b +} + +var _ = base64.StdEncoding +var _ = tls.VersionTLS13 diff --git a/internal/app/hooks.go b/internal/app/hooks.go new file mode 100644 index 0000000..a375c8d --- /dev/null +++ b/internal/app/hooks.go @@ -0,0 +1,922 @@ +package app + +import ( + "context" + "fmt" + "sort" + "strings" + "sync" + "time" + + "github.com/miekg/dns" + + "git.k8s-git-k6n.net/mats/fancy-dns/internal/api" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/blocklist" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/config" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/metrics" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/qlog" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/resolver" +) + +// hooks builds the api.Hooks that connect the admin API to the live +// components. Everything the UI can read or change goes through here. +func (a *App) hooks() api.Hooks { + return api.Hooks{ + Store: a.cfg, + Logger: a.log, + Version: a.ver, + StartedAt: a.startedAt, + Dashboard: a.dashboard, + Status: a.status, + Health: a.health, + BlocklistState: a.blocklistState, + BlocklistStats: a.blocklistStats, + RefreshBlocklists: a.refreshBlocklists, + ToggleBlocklist: a.toggleBlocklist, + DomainCheck: a.domainCheck, + ListDomains: a.listDomains, + AddDomain: a.addDomain, + DeleteDomain: a.deleteDomain, + GetACL: a.getACL, + PutACL: a.putACL, + GetUpstream: a.getUpstreams, + PutUpstream: a.putUpstream, + SearchLog: a.searchLog, + LogStats: a.logStats, + SubscribeLog: a.subscribeLog, + ClearLog: a.clearLog, + CacheStats: a.cacheStats, + CacheTop: a.cacheTop, + FlushCache: a.flushCache, + Flush: a.flush, + } +} + +// health is the unauthenticated probe payload. +func (a *App) health() any { + status := "ok" + problems := a.Degraded() + switch { + case len(problems) > 0: + status = "degraded" + } + if a.dns == nil || len(a.dns.Listeners()) == 0 { + status = "down" + } + if a.logger != nil && a.logger.ErrorCount() > 0 && status == "ok" { + status = "degraded" + problems = append(problems, "query log write errors") + } + return map[string]any{ + "status": status, + "version": a.ver, + "uptime_s": int64(time.Since(a.startedAt).Seconds()), + "config_version": a.cfg.Get().Version, + "problems": problems, + } +} + +// status is the per-component runtime view. +func (a *App) status() any { + out := map[string]any{ + "listeners": a.dns.Listeners(), + "transports": a.dns.ByTransport(), + "degraded": a.Degraded(), + } + if a.blocks != nil { + st := a.blocks.State() + if st != nil { + out["blocklist"] = map[string]any{ + "rules": st.Set.Len(), + "sources": len(st.Sources), + "duration": st.Duration, + "built_at": st.Set.BuiltAt(), + "errors": st.Errors, + "digest": st.Digest, + "has_wild": st.Set.HasWildcards(), + "duplicates": st.Set.DuplicatesN(), + } + } + } + if a.local != nil { + if store := a.local.Get(); store != nil { + out["local_zones"] = map[string]any{ + "zones": store.Zones(), + "records": store.Count(), + "files": store.Files(), + } + } + } + if a.cache != nil { + out["cache"] = a.cacheStats() + } + if a.logger != nil { + out["qlog"] = a.logger.Stats() + } + if a.pool != nil { + out["upstream"] = a.getUpstreams() + } + if a.aclH != nil { + out["acl"] = a.getACL() + } + if a.cl != nil { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + out["cluster"] = a.cl.Status(ctx) + cancel() + } + if a.engine != nil { + out["engine"] = map[string]any{ + "inflight": a.engine.Inflight(), + "dropped": a.engine.Dropped(), + "group_stats": a.engine.GroupStats(), + } + } + return out +} + +// blocklistState is the full per-source view for the UI. +func (a *App) blocklistState() any { + if a.blocks == nil { + return map[string]any{ + "items": []any{}, + "stats": map[string]any{"total": 0}, + } + } + st := a.blocks.State() + items := make([]blocklist.Source, 0, len(st.Sources)) + for _, s := range st.Sources { + items = append(items, s) + } + sort.Slice(items, func(i, j int) bool { return items[i].Name < items[j].Name }) + return map[string]any{ + "items": items, + "stats": blocklistSourceStats(st), + "errors": st.Errors, + "digest": st.Digest, + } +} + +func blocklistSourceStats(st *blocklist.State) map[string]any { + if st == nil || st.Set == nil { + return map[string]any{"total": 0} + } + s := st.Set.Stats() + return map[string]any{ + "total": s.Total, + "exact": s.Exact, + "subdomain_rules": s.Subdomains, + "root_rules": s.RootRules, + "allow": s.Allow, + "block": s.Block, + "passthrough": s.Passthru, + "drop": s.Drop, + "duplicates": s.Duplicates, + "sources": s.Sources, + "built_at": s.BuiltAt, + "sources_detail": s.PerSource, + } +} + +func (a *App) blocklistStats() any { + if a.blocks == nil { + return map[string]any{"total": 0} + } + return blocklistSourceStats(a.blocks.State()) +} + +// invalidateBlocklistCache drops every cached answer whose verdict the new +// rules might change. Without this, a name that has just become blocked keeps +// serving its cached good answer until the TTL expires, which is exactly the +// bug an operator hits right after clicking "add rule". +func (a *App) invalidateBlocklistCache() { + if a.cache == nil { + return + } + a.cache.Flush() +} + +// refreshBlocklists recompiles the list sources. +func (a *App) refreshBlocklists(ctx context.Context, names []string) error { + if a.blocks == nil { + return fmt.Errorf("blocklists are disabled") + } + a.invalidateBlocklistCache() + go func() { + if len(names) == 0 { + if _, err := a.blocks.RefreshAll(ctx); err != nil { + a.log.Warn("blocklist refresh failed", "error", err) + } + return + } + // The manager compiles everything in one pass, which is cheaper than + // a pass per name and keeps the compiled set internally consistent. + if _, err := a.blocks.RefreshAll(ctx); err != nil { + a.log.Warn("blocklist refresh failed", "error", err, "names", names) + } + }() + // Tell the cluster leader so every instance ends up on the same content. + if a.cl != nil { + _ = a.cl.BroadcastRefresh(ctx, names) + } + return nil +} + +// toggleBlocklist flips one source's enabled flag and persists it. +func (a *App) toggleBlocklist(name string, enabled bool) error { + if a.blocks == nil { + return fmt.Errorf("blocklists are disabled") + } + err := a.mutateConfig(func(c *config.Config) error { + found := false + for i := range c.Block.Lists { + if c.Block.Lists[i].Name == name { + c.Block.Lists[i].Enabled = enabled + found = true + } + } + if !found { + return fmt.Errorf("no blocklist named %q", name) + } + return nil + }) + if err != nil { + return err + } + a.invalidateBlocklistCache() + go func() { + if _, rerr := a.blocks.RefreshAll(context.Background()); rerr != nil { + a.log.Warn("refresh after toggle failed", "error", rerr) + } + }() + return nil +} + +// mutateConfig clones, mutates, validates and commits the config, returning +// the validation error when the change is rejected. +func (a *App) mutateConfig(fn func(*config.Config) error) error { + cur := a.cfg.Get() + next := *cur + // A shallow copy is not enough: the slices and maps we touch need their own + // backing arrays, or a rejected change would corrupt the live config. + next.Block = cur.Block + next.Block.Lists = append([]config.ListSource(nil), cur.Block.Lists...) + next.Block.LocalZones = append([]string(nil), cur.Block.LocalZones...) + next.Block.BlockEntries = append([]string(nil), cur.Block.BlockEntries...) + next.Block.AllowEntries = append([]string(nil), cur.Block.AllowEntries...) + next.ACL = cur.ACL + next.ACL.Groups = append([]config.Group(nil), cur.ACL.Groups...) + next.Upstream = cur.Upstream + next.Upstream.Servers = append([]config.UpstreamServer(nil), cur.Upstream.Servers...) + next.Upstream.Bootstraps = append([]config.UpstreamBootstrap(nil), cur.Upstream.Bootstraps...) + + if err := fn(&next); err != nil { + return err + } + if err := next.Validate(); err != nil { + return err + } + if a.api == nil { + return a.cfg.Swap(&next) + } + return a.api.Commit(&next) +} + +// domainCheck explains how a name would be treated. +func (a *App) domainCheck(name string) (any, error) { + entry := (*blocklist.Entry)(nil) + if a.blocks != nil { + if set := a.blocks.Holder().Get(); set != nil { + entry = set.Match(name) + } + } + out := map[string]any{ + "name": name, + "query": strings.TrimSuffix(name, "."), + } + if entry == nil { + out["matched"] = false + out["action"] = "none" + out["source"] = "" + return out, nil + } + kind := "exact" + pattern := entry.Name + if set := a.blocks.Holder().Get(); set != nil { + // Recover which of the three maps matched so the UI can say *why*. + switch set.MatchPattern(name) { + case blocklist.PatternSub: + kind = "subdomain" + pattern = "*." + entry.Name + case blocklist.PatternRoot: + kind = "domain" + pattern = "**." + entry.Name + } + } + out["matched"] = true + out["action"] = entry.Action.String() + out["source"] = entry.Source + out["categories"] = entry.Categories + out["hits"] = entry.Hits() + out["rule"] = pattern + out["matched_pattern"] = pattern + out["match_kind"] = kind + return out, nil +} + +// listDomains pages the compiled rules. Walking a million-entry map on every +// request would be too slow, so the filter runs over a bounded sample unless +// the query is a prefix/exact lookup, which the LRU can answer directly. +func (a *App) listDomains(q api.DomainQuery) (any, error) { + if a.blocks == nil { + return map[string]any{"items": []any{}, "total": 0, "page": 1, "per_page": q.PerPage}, nil + } + set := a.blocks.Holder().Get() + if set == nil { + return map[string]any{"items": []any{}, "total": 0, "page": 1, "per_page": q.PerPage}, nil + } + if q.Text != "" && (q.Action == "" && q.List == "") { + if e := set.Lookup(q.Text); e != nil { + return map[string]any{ + "items": []blocklist.Entry{*e}, + "total": 1, + "page": 1, + "per_page": q.PerPage, + }, nil + } + } + type row struct { + Name string `json:"name"` + Action string `json:"action"` + Source string `json:"source"` + Categories []string `json:"categories"` + Hits uint64 `json:"hits"` + Rule string `json:"rule"` + } + text := strings.ToLower(strings.TrimSpace(q.Text)) + action := strings.ToLower(q.Action) + // The cap keeps a request bounded on a large set; the UI pages anyway. + const scanCap = 400000 + matches := make([]row, 0, 256) + total := 0 + set.Each(func(pattern string, e *blocklist.Entry, kind blocklist.PatternKind) bool { + if len(matches) >= scanCap { + return false + } + if action != "" && e.Action.String() != action { + return true + } + if q.List != "" && e.Source != q.List { + return true + } + if text != "" && !strings.Contains(pattern, text) { + return true + } + total++ + matches = append(matches, row{ + Name: pattern, + Action: e.Action.String(), + Source: e.Source, + Categories: e.Categories, + Hits: e.Hits(), + Rule: kind.Pattern(pattern), + }) + return true + }) + sort.Slice(matches, func(i, j int) bool { + if matches[i].Hits != matches[j].Hits { + return matches[i].Hits > matches[j].Hits + } + return matches[i].Name < matches[j].Name + }) + start := (q.Page - 1) * q.PerPage + if start > len(matches) { + start = len(matches) + } + end := start + q.PerPage + if end > len(matches) { + end = len(matches) + } + return map[string]any{ + "items": matches[start:end], + "total": total, + "page": q.Page, + "per_page": q.PerPage, + "truncated": total > len(matches), + }, nil +} + +// addDomain appends an inline rule and persists it. +func (a *App) addDomain(_ context.Context, in api.DomainInput) (any, error) { + name := strings.TrimSpace(in.Name) + if name == "" { + return nil, fmt.Errorf("name is required") + } + act, ok := blocklist.ParseAction(in.Action) + if !ok { + return nil, fmt.Errorf("unknown action %q", in.Action) + } + // A bulk paste goes in as several entries; a single name goes in as one. + entries := []string{} + if in.Content != "" { + entries = strings.Split(in.Content, "\n") + } else { + entries = []string{name} + } + err := a.mutateConfig(func(c *config.Config) error { + for _, e := range entries { + e = strings.TrimSpace(e) + if e == "" || strings.HasPrefix(e, "#") { + continue + } + entry := e + if act == blocklist.ActionBlock { + c.Block.BlockEntries = append(c.Block.BlockEntries, entry) + } else { + c.Block.AllowEntries = append(c.Block.AllowEntries, entry) + } + } + return nil + }) + if err != nil { + return nil, err + } + if a.blocks != nil { + if _, rerr := a.blocks.RefreshAll(context.Background()); rerr != nil { + a.log.Warn("refresh after add failed", "error", rerr) + } + } + // A new rule changes the verdict for the whole subtree it covers, and an + // allow rule can rescue a name many other lists blocked, so the honest + // thing is to drop the affected answers rather than guess. + a.invalidateBlocklistCache() + return map[string]any{"ok": true, "name": name, "count": len(entries)}, nil +} + +// deleteDomain removes a rule and persists the change. +func (a *App) deleteDomain(_ context.Context, name, action, list string) error { + target := strings.ToLower(strings.TrimSpace(name)) + removed := 0 + err := a.mutateConfig(func(c *config.Config) error { + strip := func(entries []string) []string { + out := entries[:0] + for _, e := range entries { + normal := strings.ToLower(strings.TrimSpace(e)) + normal = strings.TrimPrefix(strings.TrimPrefix(normal, "*."), "**.") + normal = strings.TrimSuffix(normal, ".") + if normal == target { + removed++ + continue + } + out = append(out, e) + } + return out + } + c.Block.BlockEntries = strip(c.Block.BlockEntries) + c.Block.AllowEntries = strip(c.Block.AllowEntries) + // A file-backed list is edited by editing the file, so the API only + // reports that rather than pretending it removed something. + if list != "" && removed == 0 { + return fmt.Errorf("%q comes from list %q; edit that list instead", name, list) + } + if removed == 0 { + return fmt.Errorf("no inline rule matches %q", name) + } + return nil + }) + if err != nil { + return err + } + if a.blocks != nil { + if _, rerr := a.blocks.RefreshAll(context.Background()); rerr != nil { + a.log.Warn("refresh after delete failed", "error", rerr) + } + } + a.invalidateBlocklistCache() + return nil +} + +// getACL returns the ACL groups. +func (a *App) getACL() any { + groups := a.engine.GroupStats() + return map[string]any{ + "groups": groups, + "default_policy": a.cfg.Get().ACL.DefaultPolicy, + "default_rate_limit": a.cfg.Get().ACL.DefaultRateLimit, + } +} + +// putACL validates and persists new ACL groups. +func (a *App) putACL(_ context.Context, groups []config.Group, def string) (int64, error) { + err := a.mutateConfig(func(c *config.Config) error { + c.ACL.Groups = groups + if def != "" { + c.ACL.DefaultPolicy = def + } + return nil + }) + if err != nil { + return 0, err + } + // An allow_domains or deny_domains change alters the verdict for names + // already in the cache, so the cached answers are no longer trustworthy. + if a.cache != nil { + a.cache.Flush() + } + return a.cfg.Get().Version, nil +} + +// getUpstreams returns the pool state. +func (a *App) getUpstreams() any { + cfg := a.cfg.Get() + servers := make([]resolver.Stats, 0, len(a.pool.All())) + for _, s := range a.pool.Stats() { + servers = append(servers, s) + } + return map[string]any{ + "policy": cfg.Upstream.Policy, + "servers": servers, + "bootstraps": cfg.Upstream.Bootstraps, + "healthcheck_interval": cfg.Upstream.HealthCheck.D().Seconds(), + "max_attempts": cfg.Upstream.MaxAttempts, + "breaker_threshold": cfg.Upstream.BreakerThreshold, + "breaker_cooldown": cfg.Upstream.BreakerCooldown.D().Seconds(), + } +} + +// putUpstream validates and persists a new upstream config. +func (a *App) putUpstream(_ context.Context, up config.Upstream) (int64, error) { + err := a.mutateConfig(func(c *config.Config) error { + c.Upstream = up + return nil + }) + if err != nil { + return 0, err + } + // The pool rebinds itself on the config swap; do it now so the UI sees + // the new servers immediately rather than after the next reload. + a.pool.Rebind(up) + return a.cfg.Get().Version, nil +} + +// searchLog pages the query log. +func (a *App) searchLog(_ context.Context, q api.LogQuery) (any, error) { + if a.logger == nil { + return map[string]any{"items": []any{}, "total": 0, "offset": 0}, nil + } + page, err := a.logger.Search(qlog.Query{ + Limit: q.Limit, Offset: q.Offset, Text: q.Text, Action: q.Action, + Client: q.Client, RCode: q.RCode, BlockedOnly: q.BlockedOnly, Since: q.Since, + }) + if err != nil { + return nil, err + } + out := make([]api.LogEntry, 0, len(page.Items)) + for _, e := range page.Items { + out = append(out, toLogEntry(e)) + } + return map[string]any{ + "items": out, + "total": page.Total, + "offset": page.Offset, + "limit": page.Limit, + "has_more": len(out) == page.Limit, + }, nil +} + +func toLogEntry(e qlog.Entry) api.LogEntry { + return api.LogEntry{ + ID: e.ID, TS: e.TS, Client: e.Client, Group: e.Group, Name: e.Name, + QType: e.QType, QTypeStr: e.QTypeStr, RCode: e.RCode, + RCodeStr: e.RCodeName(), Action: string(e.Action), Response: e.Response, + Duration: e.Duration, Upstream: e.Upstream, List: e.List, Protocol: e.Protocol, + Blocked: e.Blocked, + } +} + +// logStats is the live stats frame pushed over SSE. +func (a *App) logStats() any { + t := metrics.TotalsNow() + var hitRate float64 + if t.Hits+t.Misses > 0 { + hitRate = float64(t.Hits) / float64(t.Hits+t.Misses) + } + var blockedPct float64 + if t.Queries > 0 { + blockedPct = float64(t.Blocked) / float64(t.Queries) + } + return map[string]any{ + "qps": a.series.qps(), + "blocked_pct": blockedPct, + "cache_hit_rate": hitRate, + "queries_total": t.Queries, + "blocked_total": t.Blocked, + "errors_total": t.Errors, + "inflight": t.Concurrent, + "uptime_s": int64(time.Since(a.startedAt).Seconds()), + } +} + +// subscribeLog streams new entries to one SSE client. +func (a *App) subscribeLog() (<-chan api.LogEntry, func()) { + if a.logger == nil { + ch := make(chan api.LogEntry) + close(ch) + return ch, func() {} + } + src, cancel := a.logger.Subscribe() + out := make(chan api.LogEntry, 256) + done := make(chan struct{}) + go func() { + defer close(out) + for { + select { + case <-done: + return + case e, ok := <-src: + if !ok { + return + } + select { + case out <- toLogEntry(e): + case <-done: + return + } + } + } + }() + return out, func() { + close(done) + cancel() + } +} + +// clearLog empties the query log. +func (a *App) clearLog() error { + if a.logger == nil { + return nil + } + return a.logger.Clear() +} + +// cacheStats returns the cache snapshot. +func (a *App) cacheStats() any { + if a.cache == nil { + return map[string]any{"enabled": false} + } + st := a.cache.Stats() + return map[string]any{ + "enabled": st.Enabled, + "size": st.Size, + "entries": st.Entries, + "shards": st.Shards, + "min_ttl_ms": st.MinTTLMS, + "max_ttl_ms": st.MaxTTLMS, + "serve_stale_ms": st.ServeStaleM, + "negative_ttl_ms": st.NegativeMS, + "hit_rate": st.HitRate, + "hits": st.Hits, + "misses": st.Misses, + "stale_hits": st.StaleHits, + "evictions": st.Evictions, + "bytes": st.Bytes, + "bytes_human": st.MemoryHuman, + "persisted": st.Persist, + } +} + +// cacheTop returns the hottest cached names. +func (a *App) cacheTop(limit int) any { + if a.cache == nil { + return []any{} + } + entries := a.cache.TopEntries(limit) + out := make([]map[string]any, 0, len(entries)) + for _, e := range entries { + out = append(out, map[string]any{ + "name": e.Name, + "qtype": e.Type, + "qtype_name": dns.Type(e.Type).String(), + "hits": e.Hits, + "bytes": e.Bytes, + }) + } + return out +} + +// flushCache empties the cache. +func (a *App) flushCache() int64 { + if a.cache == nil { + return 0 + } + st := a.cache.Stats() + a.cache.Flush() + return int64(st.Entries) +} + +// flush persists buffered state. +func (a *App) flush() { + if a.logger != nil { + a.logger.Flush() + } + a.snapshotCache() +} + +// seriesStore keeps the rolling counters the dashboard charts read. +type seriesStore struct { + mu sync.Mutex + queries *metrics.Ring + blocked *metrics.Ring + errors *metrics.Ring + cacheHit *metrics.Ring + // The previous totals, used to derive per-bucket deltas. + lastQueries uint64 + lastBlocked uint64 + lastErrors uint64 + lastHits uint64 + lastAt time.Time + qpsValue float64 +} + +func newSeriesStore() *seriesStore { + return &seriesStore{ + queries: metrics.NewRing(300, 5*time.Second), + blocked: metrics.NewRing(300, 5*time.Second), + errors: metrics.NewRing(300, 5*time.Second), + cacheHit: metrics.NewRing(300, 5*time.Second), + lastAt: time.Now(), + } +} + +// sample folds the delta since the last sample into the rings. Sampling on a +// timer rather than per query keeps the query path free of any extra work and +// is accurate enough for a chart. +func (s *seriesStore) sample() { + t := metrics.TotalsNow() + s.mu.Lock() + now := time.Now() + dt := now.Sub(s.lastAt).Seconds() + if dt > 0 { + s.qpsValue = float64(t.Queries-s.lastQueries) / dt + } + // Ring buckets are 5s wide; scale the interval delta accordingly. + scale := dt / 5 + if scale < 0 { + scale = 0 + } + dq := int64(float64(t.Queries-s.lastQueries) * scale) + db := int64(float64(t.Blocked-s.lastBlocked) * scale) + de := int64(float64(t.Errors-s.lastErrors) * scale) + dc := int64(float64(t.Hits-s.lastHits) * scale) + if dq > 0 { + s.queries.Add(dq) + } + if db > 0 { + s.blocked.Add(db) + } + if de > 0 { + s.errors.Add(de) + } + if dc > 0 { + s.cacheHit.Add(dc) + } + s.lastQueries, s.lastBlocked, s.lastErrors, s.lastHits = t.Queries, t.Blocked, t.Errors, t.Hits + s.lastAt = now + s.mu.Unlock() +} + +func (s *seriesStore) qps() float64 { + s.mu.Lock() + defer s.mu.Unlock() + return s.qpsValue +} + +// dashboard builds the aggregated payload. +func (a *App) dashboard(_ context.Context, rangeKey string) (any, error) { + spec, ok := ranges[rangeKey] + if !ok { + spec = ranges["1h"] + } + t := metrics.TotalsNow() + hitRate := 0.0 + if t.Hits+t.Misses > 0 { + hitRate = float64(t.Hits) / float64(t.Hits+t.Misses) + } + blockedPct := 0.0 + if t.Queries > 0 { + blockedPct = float64(t.Blocked) / float64(t.Queries) * 100 + } + + // Build the series by walking the rings oldest-first and dropping anything + // older than the requested range. + var series []map[string]any + now := time.Now() + qts, qv := a.series.queries.Snapshot() + _, bv := a.series.blocked.Snapshot() + _, ev := a.series.errors.Snapshot() + _, cv := a.series.cacheHit.Snapshot() + series = make([]map[string]any, 0, len(qts)) + for i := range qts { + age := now.Sub(time.Unix(qts[i], 0)) + if age > spec.duration { + break + } + series = append(series, map[string]any{ + "t": qts[i], + "queries": qv[i], + "blocked": bv[i], + "errors": ev[i], + "cache_hits": cv[i], + }) + } + + topBlocked := []any{} + topQueried := []any{} + if a.logger != nil { + for _, d := range a.logger.TopBlocked(15) { + topBlocked = append(topBlocked, map[string]any{ + "domain": d.Name, "count": d.Count, "list": "", "qtype": d.QType, + }) + } + for _, d := range a.logger.TopQueried(15) { + topQueried = append(topQueried, map[string]any{ + "domain": d.Name, "count": d.Count, "qtype": d.QType, "blocked": d.Blocked > 0, + }) + } + } + + problems := a.Degraded() + status := "ok" + if len(problems) > 0 { + status = "degraded" + } + out := map[string]any{ + "health": status, + "degraded_reason": strings.Join(problems, "; "), + "version": a.ver, + "node_id": a.clusterNodeID(), + "uptime_seconds": int64(time.Since(a.startedAt).Seconds()), + "queries_total": t.Queries, + "queries_per_sec": a.series.qps(), + "cache_hit_rate": hitRate, + "blocked_total": t.Blocked, + "blocked_pct": blockedPct, + "errors_total": t.Errors, + "inflight": t.Concurrent, + "series": series, + "top_blocked": topBlocked, + "top_queried": topQueried, + "upstreams": a.pool.Stats(), + "listeners": a.dns.Listeners(), + "transports": a.dns.ByTransport(), + "blocklist_rules": a.blocklistRuleCount(), + "cache_entries": a.cacheEntries(), + "config_version": a.cfg.Get().Version, + "generation": a.cfg.Generation(), + } + if a.logger != nil { + recent := a.logger.Recent(20) + items := make([]api.LogEntry, 0, len(recent)) + for _, e := range recent { + items = append(items, toLogEntry(e)) + } + out["recent"] = items + } + return out, nil +} + +func (a *App) clusterNodeID() string { + if a.cl != nil { + return a.cl.NodeID() + } + return "" +} + +func (a *App) blocklistRuleCount() int { + if a.blocks == nil { + return 0 + } + if st := a.blocks.State(); st != nil && st.Set != nil { + return st.Set.Len() + } + return 0 +} + +func (a *App) cacheEntries() int { + if a.cache == nil { + return 0 + } + return a.cache.Stats().Entries +} + +// rangeSpec is one dashboard time range. +type rangeSpec struct { + duration time.Duration + buckets int +} + +var ranges = map[string]rangeSpec{ + "15m": {duration: 15 * time.Minute, buckets: 45}, + "1h": {duration: time.Hour, buckets: 60}, + "6h": {duration: 6 * time.Hour, buckets: 72}, + "24h": {duration: 24 * time.Hour, buckets: 96}, +} diff --git a/internal/app/integration_test.go b/internal/app/integration_test.go new file mode 100644 index 0000000..8ac6848 --- /dev/null +++ b/internal/app/integration_test.go @@ -0,0 +1,794 @@ +package app + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + "testing" + "time" + + "github.com/miekg/dns" + + "git.k8s-git-k6n.net/mats/fancy-dns/internal/config" +) + +// TestResolveUpstream covers the happy path: a name nobody blocks is forwarded +// to the upstream and the answer is cached. +func TestResolveUpstream(t *testing.T) { + h := newHarness(t, nil) + res := h.query("www.example.test", dns.TypeA) + if res.Rcode != dns.RcodeSuccess { + t.Fatalf("rcode = %s, want NOERROR", dns.RcodeToString[res.Rcode]) + } + if len(res.Answer) == 0 { + t.Fatal("no answer records") + } + if got := res.Answer[0].(*dns.A).A.String(); got != "203.0.113.7" { + t.Errorf("answer = %s, want 203.0.113.7", got) + } + if h.up.hitCount("www.example.test.") == 0 { + t.Error("upstream was never asked") + } + // Second query must come from cache: the upstream counter must not move. + before := h.up.hitCount("www.example.test.") + h.query("www.example.test", dns.TypeA) + if after := h.up.hitCount("www.example.test."); after != before { + t.Errorf("upstream hit count moved from %d to %d: the cache did not serve the repeat query", before, after) + } +} + +// TestBlockedNames covers every blocklist source shape: hosts-file entries +// (apex plus subdomains), RPZ wildcards and inline rules. +func TestBlockedNames(t *testing.T) { + h := newHarness(t, nil) + cases := []string{ + "ads.example.com", // hosts file + "deep.ads.example.com", // hosts file, subdomain + "tracker.example.net", + "inline-blocked.example.com", + "anything.inline-sub.example.com", + } + for _, name := range cases { + res := h.query(name, dns.TypeA) + if res.Rcode != dns.RcodeNameError { + t.Errorf("%s: rcode = %s, want NXDOMAIN", name, dns.RcodeToString[res.Rcode]) + } + } + // A blocked name must never reach the upstream. + if n := h.up.hitCount("ads.example.com."); n != 0 { + t.Errorf("blocked name reached the upstream %d times", n) + } +} + +// TestAllowOverridesBlock checks that an inline allow entry beats a list rule. +func TestAllowOverridesBlock(t *testing.T) { + h := newHarness(t, nil) + res := h.query("allow.example.com", dns.TypeA) + // The fake upstream only knows *.test., so an allowed-but-unresolvable name + // must come back as NXDOMAIN *from upstream*, which means it got past the + // blocklist. Assert on the upstream counter instead of the rcode. + if h.up.hitCount("allow.example.com.") == 0 { + t.Error("allowed name did not reach the upstream, so the allow rule lost to a block rule") + } + _ = res +} + +// TestLocalZone covers the local master file: exact, wildcard and NODATA. +func TestLocalZone(t *testing.T) { + h := newHarness(t, nil) + res := h.query("ns.local", dns.TypeA) + if len(res.Answer) != 1 { + t.Fatalf("want 1 answer for ns.local, got %d", len(res.Answer)) + } + if got := res.Answer[0].(*dns.A).A.String(); got != "192.168.1.2" { + t.Errorf("ns.local = %s, want 192.168.1.2", got) + } + if !res.Authoritative { + t.Error("local zone answer should be authoritative") + } + // Wildcard covers a name one label below the wildcard's parent. + w := h.query("anything.wild.local", dns.TypeA) + if len(w.Answer) == 0 || w.Answer[0].(*dns.A).A.String() != "192.168.1.50" { + t.Errorf("wildcard answer wrong: %v", w.Answer) + } + // NODATA: the name exists but has no A record. + n := h.query("deep.svc.local", dns.TypeAAAA) + if n.Rcode != dns.RcodeSuccess { + t.Errorf("NODATA rcode = %s, want NOERROR", dns.RcodeToString[n.Rcode]) + } + if len(n.Answer) != 0 { + t.Errorf("NODATA returned %d answers", len(n.Answer)) + } + // NXDOMAIN inside a zone we are authoritative for. + x := h.query("nope.local", dns.TypeA) + if x.Rcode != dns.RcodeNameError { + t.Errorf("in-zone NXDOMAIN rcode = %s", dns.RcodeToString[x.Rcode]) + } +} + +// TestACLDenyGroup checks that a deny group refuses before anything else, +// including a name the local zone could answer. +func TestACLDenyGroup(t *testing.T) { + h := newHarness(t, func(c *config.Config) { + c.ACL.Groups = []config.Group{{ + Name: "deny-all", + Match: config.Match{CIDRs: []string{"127.0.0.0/8"}}, + Policy: "deny", + Comment: "test", + }} + }) + res := h.query("www.example.test", dns.TypeA) + if res.Rcode != dns.RcodeRefused { + t.Errorf("rcode = %s, want REFUSED", dns.RcodeToString[res.Rcode]) + } + if h.up.hitCount("www.example.test.") != 0 { + t.Error("a denied client still reached the upstream") + } +} + +// TestACLAllowDomains checks a group's allow_domains acts as a filter. +func TestACLAllowDomains(t *testing.T) { + h := newHarness(t, func(c *config.Config) { + c.ACL.Groups = []config.Group{{ + Name: "only-test", + Match: config.Match{CIDRs: []string{"127.0.0.0/8"}}, + Policy: "allow", + AllowDomains: []string{"*.test"}, + }} + }) + // Inside the allow list: resolves. + if r := h.query("www.example.test", dns.TypeA); r.Rcode != dns.RcodeSuccess { + t.Errorf("allowed domain rcode = %s", dns.RcodeToString[r.Rcode]) + } + // Outside it: blocked by the group. + if r := h.query("ads.example.com", dns.TypeA); r.Rcode != dns.RcodeNameError { + t.Errorf("domain outside allow_domains rcode = %s, want NXDOMAIN", dns.RcodeToString[r.Rcode]) + } +} + +// TestACLSkipBlocklist checks a group can opt out of blocklist filtering. +func TestACLSkipBlocklist(t *testing.T) { + h := newHarness(t, func(c *config.Config) { + c.ACL.Groups = []config.Group{{ + Name: "trusted", + Match: config.Match{CIDRs: []string{"127.0.0.0/8"}}, + Policy: "allow", + SkipBlocklist: true, + }} + }) + h.query("ads.example.com", dns.TypeA) + if h.up.hitCount("ads.example.com.") == 0 { + t.Error("skip_blocklist group still blocked the name") + } +} + +// TestBlockActions covers the non-default blocklist responses. +func TestBlockActions(t *testing.T) { + t.Run("zero", func(t *testing.T) { + h := newHarness(t, func(c *config.Config) { + c.Block.DefaultAction = "zero" + c.Block.ResponseIP = "0.0.0.0" + }) + res := h.query("ads.example.com", dns.TypeA) + if res.Rcode != dns.RcodeSuccess { + t.Fatalf("rcode = %s, want NOERROR", dns.RcodeToString[res.Rcode]) + } + if len(res.Answer) != 1 || res.Answer[0].(*dns.A).A.String() != "0.0.0.0" { + t.Errorf("sinkhole answer = %v", res.Answer) + } + // AAAA for the same name must get the v6 sinkhole, not the v4 one. + res6 := h.query("ads.example.com", dns.TypeAAAA) + if len(res6.Answer) != 1 || res6.Answer[0].(*dns.AAAA).AAAA.String() != "::" { + t.Errorf("v6 sinkhole answer = %v", res6.Answer) + } + }) + t.Run("refused", func(t *testing.T) { + h := newHarness(t, func(c *config.Config) { c.Block.DefaultAction = "refused" }) + if r := h.query("ads.example.com", dns.TypeA); r.Rcode != dns.RcodeRefused { + t.Errorf("rcode = %s, want REFUSED", dns.RcodeToString[r.Rcode]) + } + }) + t.Run("redirect", func(t *testing.T) { + h := newHarness(t, func(c *config.Config) { + c.Block.DefaultAction = "redirect" + c.Block.RedirectName = "blockpage.local" + }) + res := h.query("ads.example.com", dns.TypeA) + if len(res.Answer) == 0 { + t.Fatal("redirect produced no answer") + } + cname, ok := res.Answer[0].(*dns.CNAME) + if !ok { + t.Fatalf("first answer is %T, want CNAME", res.Answer[0]) + } + if cname.Target != "blockpage.local." { + t.Errorf("cname target = %s", cname.Target) + } + }) +} + +// TestMalformedQueries covers the input validation path. +func TestMalformedQueries(t *testing.T) { + h := newHarness(t, nil) + // Zero questions: the server must answer FORMERR, not crash or hang. + m := new(dns.Msg) + m.Id = dns.Id() + m.Question = nil + c := &dns.Client{Timeout: 3 * time.Second} + res, _, err := c.Exchange(m, h.addr) + if err != nil { + t.Fatalf("exchange: %v", err) + } + if res.Rcode != dns.RcodeFormatError { + t.Errorf("rcode = %s, want FORMERR", dns.RcodeToString[res.Rcode]) + } +} + +// TestTCPSameAnswer checks TCP returns the same answer as UDP, and that a large +// UDP answer is truncated rather than dropped. +func TestTCPSameAnswer(t *testing.T) { + h := newHarness(t, nil) + m := new(dns.Msg) + m.SetQuestion("www.example.test.", dns.TypeA) + m.RecursionDesired = true + tcp := &dns.Client{Net: "tcp", Timeout: 5 * time.Second} + res, _, err := tcp.Exchange(m, h.addr) + if err != nil { + t.Fatalf("tcp exchange: %v", err) + } + if res.Rcode != dns.RcodeSuccess || len(res.Answer) == 0 { + t.Errorf("tcp answer wrong: rcode=%s answers=%d", dns.RcodeToString[res.Rcode], len(res.Answer)) + } +} + +// TestAPIAuth checks the admin API refuses unauthenticated reads and accepts +// the configured key. +func TestAPIAuth(t *testing.T) { + h := newHarness(t, nil) + // No key: 401. + res, err := httpGet("http://"+h.api+"/api/whoami", "") + if err != nil { + t.Fatal(err) + } + if res.status != 401 { + t.Errorf("unauthenticated /whoami = %d, want 401", res.status) + } + res, err = httpGet("http://"+h.api+"/api/whoami", "wrong-key") + if err != nil { + t.Fatal(err) + } + if res.status != 401 { + t.Errorf("bad key /whoami = %d, want 401", res.status) + } + res, err = httpGet("http://"+h.api+"/api/whoami", h.key) + if err != nil { + t.Fatal(err) + } + if res.status != 200 { + t.Errorf("good key /whoami = %d, want 200", res.status) + } + var who struct { + Name string `json:"name"` + CanWrite bool `json:"can_write"` + } + if err := json.Unmarshal(res.body, &who); err != nil { + t.Fatal(err) + } + if who.Name != "rw-1" || !who.CanWrite { + t.Errorf("whoami = %+v", who) + } + // Health is deliberately unauthenticated for probes. + res, err = httpGet("http://"+h.api+"/api/healthz", "") + if err != nil { + t.Fatal(err) + } + if res.status != 200 { + t.Errorf("/healthz = %d, want 200", res.status) + } +} + +// TestReadOnlyKeyCannotWrite checks a read-only key is refused on mutations. +func TestReadOnlyKeyCannotWrite(t *testing.T) { + h := newHarness(t, func(c *config.Config) { + c.API.Auth.ReadOnlyAPIKeys = []string{"ro-key"} + }) + res, err := httpRequest("POST", "http://"+h.api+"/api/cache/flush", "ro-key", "") + if err != nil { + t.Fatal(err) + } + if res.status != 403 { + t.Errorf("read-only flush = %d, want 403", res.status) + } + res, err = httpRequest("POST", "http://"+h.api+"/api/cache/flush", h.key, "") + if err != nil { + t.Fatal(err) + } + if res.status != 200 { + t.Errorf("read-write flush = %d, want 200", res.status) + } +} + +// TestDomainAddDeleteRoundTrip is the operator's core loop: add a rule, see it +// take effect on a live query, then remove it. +func TestDomainAddDeleteRoundTrip(t *testing.T) { + h := newHarness(t, nil) + // The name lives under .test. so the fake upstream resolves it: that way + // NOERROR unambiguously means "not blocked" and NXDOMAIN unambiguously + // means "the blocklist answered", with no third possibility to confuse the + // assertion. + const name = "newly-blocked.example.test" + before := h.up.hitCount(dns.Fqdn(name)) + if r := h.query(name, dns.TypeA); r.Rcode != dns.RcodeSuccess { + t.Fatalf("precondition: rcode = %s, want NOERROR", dns.RcodeToString[r.Rcode]) + } + if h.up.hitCount(dns.Fqdn(name)) == before { + t.Error("precondition: the upstream was not consulted") + } + + code, body := h.do("POST", "/api/domains", `{"name":"`+name+`","action":"block"}`) + if code != 200 { + t.Fatalf("add domain = %d: %s", code, body) + } + if r := h.query(name, dns.TypeA); r.Rcode != dns.RcodeNameError { + t.Errorf("after add, rcode = %s, want NXDOMAIN", dns.RcodeToString[r.Rcode]) + } + // The rule must survive a cache flush, i.e. it is really in the config and + // not just a transient matcher state. + if code, _ := h.do("POST", "/api/cache/flush", ""); code != 200 { + t.Fatalf("flush = %d", code) + } + if r := h.query(name, dns.TypeA); r.Rcode != dns.RcodeNameError { + t.Errorf("after flush, rcode = %s, want NXDOMAIN", dns.RcodeToString[r.Rcode]) + } + + code, body = h.do("DELETE", "/api/domains/"+name, "") + if code != 200 { + t.Fatalf("delete domain = %d: %s", code, body) + } + if r := h.query(name, dns.TypeA); r.Rcode != dns.RcodeSuccess { + t.Errorf("after delete, rcode = %s, want NOERROR", dns.RcodeToString[r.Rcode]) + } +} + +// TestDomainAddInvalid checks the API rejects a bad payload with 400 rather +// than writing a broken rule. +func TestDomainAddInvalid(t *testing.T) { + h := newHarness(t, nil) + code, _ := h.do("POST", "/api/domains", `{"name":"","action":"block"}`) + if code != 400 { + t.Errorf("empty name = %d, want 400", code) + } + code, _ = h.do("POST", "/api/domains", `{"name":"x.example.com","action":"nonsense"}`) + if code != 400 { + t.Errorf("bad action = %d, want 400", code) + } +} + +// TestACLUpdateRoundTrip checks the clients editor's write path and that a +// saved group is enforced immediately. +func TestACLUpdateRoundTrip(t *testing.T) { + h := newHarness(t, nil) + // Write a deny group through the API. + body := `{"groups":[{"name":"nobody","match":{"cidrs":["127.0.0.0/8"]},"policy":"deny","comment":"test"}],"default_policy":"allow"}` + code, out := h.do("PUT", "/api/clients", body) + if code != 200 { + t.Fatalf("put clients = %d: %s", code, out) + } + if r := h.query("www.example.test", dns.TypeA); r.Rcode != dns.RcodeRefused { + t.Errorf("after save, rcode = %s, want REFUSED", dns.RcodeToString[r.Rcode]) + } + // Read it back. + code, out = h.get("/api/clients") + if code != 200 { + t.Fatalf("get clients = %d", code) + } + if !strings.Contains(string(out), "nobody") { + t.Error("saved group is missing from the read-back") + } + // An invalid group must be rejected with 400 and not applied. + bad := `{"groups":[{"name":"x","match":{"cidrs":["not-a-cidr"]},"policy":"deny"}],"default_policy":"allow"}` + code, _ = h.do("PUT", "/api/clients", bad) + if code != 400 { + t.Errorf("bad CIDR = %d, want 400", code) + } +} + +// TestUpstreamUpdate checks the upstreams editor round-trips and rebinds the +// pool without a restart. +func TestUpstreamUpdate(t *testing.T) { + h := newHarness(t, nil) + body := fmt.Sprintf(`{"policy":"failover","servers":[{"addr":%q,"proto":"udp","weight":1}],"max_attempts":1,"breaker_threshold":5,"healthcheck_interval_s":0}`, h.up.addr) + code, out := h.do("PUT", "/api/upstreams", body) + if code != 200 { + t.Fatalf("put upstreams = %d: %s", code, out) + } + code, out = h.get("/api/upstreams") + if code != 200 { + t.Fatalf("get upstreams = %d", code) + } + if !strings.Contains(string(out), "failover") { + t.Error("policy did not persist") + } + // Still resolves after the rebind. + if r := h.query("www.example.test", dns.TypeA); r.Rcode != dns.RcodeSuccess { + t.Errorf("after upstream update, rcode = %s", dns.RcodeToString[r.Rcode]) + } + // Invalid config rejected. + code, _ = h.do("PUT", "/api/upstreams", `{"policy":"nonsense","servers":[]}`) + if code != 400 { + t.Errorf("bad policy = %d, want 400", code) + } +} + +// TestSettingsValidateAndSave covers the config editor: validate, save, and +// confirm the file on disk changed. +func TestSettingsValidateAndSave(t *testing.T) { + h := newHarness(t, nil) + code, out := h.get("/api/settings") + if code != 200 { + t.Fatalf("get settings = %d", code) + } + var s struct { + ConfigYAML string `json:"config_yaml"` + Path string `json:"path"` + Writable bool `json:"writable"` + } + if err := json.Unmarshal(out, &s); err != nil { + t.Fatal(err) + } + if !s.Writable { + t.Error("config file should be writable in the test harness") + } + // A valid edit round-trips. + edited := strings.Replace(s.ConfigYAML, "max_concurrent: 1024", "max_concurrent: 2048", 1) + if edited == s.ConfigYAML { + t.Fatal("test could not find the setting it wanted to edit") + } + payload, _ := json.Marshal(map[string]string{"config_yaml": edited}) + code, out = h.do("POST", "/api/settings/validate", string(payload)) + if code != 200 { + t.Fatalf("validate = %d: %s", code, out) + } + var v struct { + OK bool `json:"ok"` + Errors []struct { + Field string `json:"field"` + Message string `json:"message"` + } `json:"errors"` + } + if err := json.Unmarshal(out, &v); err != nil { + t.Fatal(err) + } + if !v.OK { + t.Errorf("valid config reported errors: %+v", v.Errors) + } + code, out = h.do("PUT", "/api/settings", string(payload)) + if code != 200 { + t.Fatalf("save settings = %d: %s", code, out) + } + // The file on disk must now contain the edit. + onDisk := readFileString(t, s.Path) + if !strings.Contains(onDisk, "max_concurrent: 2048") { + t.Error("config file on disk was not updated") + } + // An invalid document must be refused and the file left alone. + badPayload, _ := json.Marshal(map[string]string{"config_yaml": "server:\n max_concurrent: -5\n"}) + code, _ = h.do("PUT", "/api/settings", string(badPayload)) + if code != 400 { + t.Errorf("invalid save = %d, want 400", code) + } + if readFileString(t, s.Path) != onDisk { + t.Error("a rejected config write still modified the file") + } +} + +// TestBlocklistToggle checks a disabled list stops applying and its cached +// answers are dropped. +func TestBlocklistToggle(t *testing.T) { + h := newHarness(t, nil) + const name = "blocked.example.test" + if r := h.query(name, dns.TypeA); r.Rcode != dns.RcodeNameError { + t.Fatal("precondition: name should be blocked") + } + code, out := h.do("POST", "/api/blocklists/toggle", `{"name":"test-hosts","enabled":false}`) + if code != 200 { + t.Fatalf("toggle = %d: %s", code, out) + } + // The recompile runs in the background, so poll rather than assume. + waitFor(t, 5*time.Second, func() bool { + return h.query(name, dns.TypeA).Rcode == dns.RcodeSuccess + }) + // Re-enabling must block it again: a one-way toggle would be a nasty + // surprise. + if code, _ := h.do("POST", "/api/blocklists/toggle", `{"name":"test-hosts","enabled":true}`); code != 200 { + t.Fatalf("re-enable = %d", code) + } + waitFor(t, 5*time.Second, func() bool { + return h.query(name, dns.TypeA).Rcode == dns.RcodeNameError + }) +} + +// TestDashboardAndStatus checks the aggregate endpoints return the fields the +// UI reads, so a frontend change cannot silently drift from the API. +func TestDashboardAndStatus(t *testing.T) { + h := newHarness(t, nil) + h.query("www.example.test", dns.TypeA) + h.query("ads.example.com", dns.TypeA) + + code, out := h.get("/api/dashboard?range=1h") + if code != 200 { + t.Fatalf("dashboard = %d", code) + } + var d struct { + Health string `json:"health"` + Queries uint64 `json:"queries_total"` + Blocked uint64 `json:"blocked_total"` + HitRate any `json:"cache_hit_rate"` + Series []any `json:"series"` + TopBlocked []struct { + Domain string `json:"domain"` + Count uint64 `json:"count"` + } `json:"top_blocked"` + Upstreams []struct { + Addr string `json:"addr"` + Health string `json:"health"` + } `json:"upstreams"` + } + if err := json.Unmarshal(out, &d); err != nil { + t.Fatal(err) + } + if d.Health != "ok" { + t.Errorf("health = %q, want ok", d.Health) + } + if d.Queries == 0 { + t.Error("queries_total is zero after two queries") + } + if d.Blocked == 0 { + t.Error("blocked_total is zero after a blocked query") + } + if len(d.Upstreams) == 0 { + t.Error("upstreams empty in dashboard") + } + if len(d.Series) == 0 { + t.Error("series empty in dashboard") + } + _ = d.HitRate + _ = d.TopBlocked + + code, out = h.get("/api/status") + if code != 200 { + t.Fatalf("status = %d", code) + } + if !strings.Contains(string(out), "listeners") { + t.Error("status has no listeners section") + } +} + +// TestLogsAndClear covers the query log endpoint and the clear action. +func TestLogsAndClear(t *testing.T) { + h := newHarness(t, nil) + h.query("www.example.test", dns.TypeA) + h.query("ads.example.com", dns.TypeA) + waitFor(t, 3*time.Second, func() bool { + code, out := h.get("/api/logs?limit=50") + if code != 200 { + return false + } + return strings.Contains(string(out), "example.test") + }) + code, out := h.get("/api/logs?q=ads.example.com&blocked=1") + if code != 200 { + t.Fatalf("logs = %d", code) + } + if !strings.Contains(string(out), "ads.example.com") { + t.Error("filtered log did not include the blocked query") + } + if code, _ := h.do("POST", "/api/logs/clear", ""); code != 200 { + t.Errorf("clear logs = %d, want 200", code) + } +} + +// TestCacheEndpoints covers the cache stats/top/flush trio. +func TestCacheEndpoints(t *testing.T) { + h := newHarness(t, nil) + h.query("www.example.test", dns.TypeA) + code, out := h.get("/api/cache") + if code != 200 { + t.Fatalf("cache = %d", code) + } + var c struct { + Entries int `json:"entries"` + Shards int `json:"shards"` + HitRate float64 `json:"hit_rate"` + } + if err := json.Unmarshal(out, &c); err != nil { + t.Fatal(err) + } + if c.Shards <= 0 { + t.Error("shards is zero") + } + code, out = h.get("/api/cache/top?limit=10") + if code != 200 { + t.Fatalf("cache top = %d", code) + } + if !strings.Contains(string(out), "example.test") { + t.Error("cache top does not list the queried name") + } + if code, _ := h.do("POST", "/api/cache/flush", ""); code != 200 { + t.Errorf("flush = %d, want 200", code) + } +} + +// TestReloadFromDisk checks SIGHUP-style reload applies a hand-edited file and +// reports a broken one without dropping the running config. +func TestReloadFromDisk(t *testing.T) { + h := newHarness(t, nil) + // Break the file, then reload: must fail and keep serving. + broken := strings.Replace(h.OriginalConfig(), "max_concurrent: 1024", "max_concurrent: not-a-number", 1) + if broken == h.OriginalConfig() { + t.Fatal("test could not find the setting it wanted to break") + } + writeFileString(t, h.app.cfg.Path(), broken) + if err := h.app.Reload(); err == nil { + t.Fatal("reload of a broken config should fail") + } + if h.app.cfg.LastError() == "" { + t.Error("a failed reload should record the error for the health endpoint") + } + // The server keeps working with the previous config. + if r := h.query("www.example.test", dns.TypeA); r.Rcode != dns.RcodeSuccess { + t.Errorf("after a failed reload, rcode = %s", dns.RcodeToString[r.Rcode]) + } + // Fix the file and reload: should succeed and clear the error. The whole + // document is rewritten from the harness's own config, changing only the + // broken value, so the reload is testing a realistic edit rather than a + // minimal stub. + fixed := strings.Replace(h.OriginalConfig(), "max_concurrent: 1024", "max_concurrent: 512", 1) + if fixed == h.OriginalConfig() { + t.Fatal("test could not find the setting it wanted to edit") + } + writeFileString(t, h.app.cfg.Path(), fixed) + if err := h.app.Reload(); err != nil { + t.Fatalf("reload of a fixed config failed: %v", err) + } + if h.app.cfg.LastError() != "" { + t.Error("a successful reload should clear the recorded error") + } +} + +// TestLogStream checks the SSE endpoint emits a ready frame and at least one +// entry frame, and that it terminates when the client disconnects. +func TestLogStream(t *testing.T) { + h := newHarness(t, nil) + req, err := httpNewRequest("GET", "http://"+h.api+"/api/logs/stream", h.key) + if err != nil { + t.Fatal(err) + } + // A streaming client must not time out while idle, so give it a generous + // deadline; the test closes the body when it has seen what it needs. + streamClient := &http.Client{Timeout: 20 * time.Second} + resp, err := streamClient.Do(req) + if err != nil { + t.Fatal(err) + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + t.Fatalf("stream = %d", resp.StatusCode) + } + if ct := resp.Header.Get("Content-Type"); !strings.HasPrefix(ct, "text/event-stream") { + t.Errorf("content-type = %q, want text/event-stream", ct) + } + if resp.Header.Get("X-Accel-Buffering") != "no" { + t.Error("missing X-Accel-Buffering: no, a proxy would buffer the stream") + } + // Generate a query and read frames until we see an entry. + go func() { + time.Sleep(150 * time.Millisecond) + h.query("www.example.test", dns.TypeA) + }() + buf := make([]byte, 4096) + seen := map[string]bool{} + deadline := time.Now().Add(5 * time.Second) + for time.Now().Before(deadline) { + n, err := resp.Body.Read(buf) + if err != nil { + break + } + chunk := string(buf[:n]) + for _, ev := range []string{"event: ready", "event: entry", "event: stats"} { + if strings.Contains(chunk, ev) { + seen[ev] = true + } + } + if seen["event: ready"] && seen["event: entry"] { + break + } + } + if !seen["event: ready"] { + t.Error("no ready event") + } + if !seen["event: entry"] { + t.Error("no entry event for a query issued while streaming") + } +} + +// TestMetricsEndpoint checks Prometheus output is served and protected. +func TestMetricsEndpoint(t *testing.T) { + h := newHarness(t, nil) + res, err := httpGet("http://"+h.api+"/api/metrics", "") + if err != nil { + t.Fatal(err) + } + if res.status != 200 { + t.Errorf("unprotected /metrics = %d, want 200", res.status) + } + if !strings.Contains(string(res.body), "fancydns_queries_total") { + t.Error("metrics output has no fancydns_queries_total") + } + // With protection on, an unauthenticated scrape must fail. + h2 := newHarness(t, func(c *config.Config) { c.Metrics.Protect = true }) + res, err = httpGet("http://"+h2.api+"/api/metrics", "") + if err != nil { + t.Fatal(err) + } + if res.status != 401 { + t.Errorf("protected /metrics without a key = %d, want 401", res.status) + } + res, err = httpGet("http://"+h2.api+"/api/metrics", h2.key) + if err != nil { + t.Fatal(err) + } + if res.status != 200 { + t.Errorf("protected /metrics with a key = %d, want 200", res.status) + } +} + +// TestConcurrentQueries hammers the server from many goroutines to catch races +// and to make sure the shared state is actually safe. Run with -race. +func TestConcurrentQueries(t *testing.T) { + h := newHarness(t, nil) + const workers, each = 16, 25 + done := make(chan error, workers) + for w := 0; w < workers; w++ { + go func(w int) { + m := new(dns.Msg) + m.SetQuestion("www.example.test.", dns.TypeA) + m.RecursionDesired = true + c := &dns.Client{Net: "udp", Timeout: 5 * time.Second} + for i := 0; i < each; i++ { + if _, _, err := c.Exchange(m, h.addr); err != nil { + done <- err + return + } + } + done <- nil + }(w) + } + for w := 0; w < workers; w++ { + if err := <-done; err != nil { + t.Fatalf("concurrent query failed: %v", err) + } + } + // Also exercise the API concurrently, since it reads the same state. + apiDone := make(chan error, workers) + for w := 0; w < workers; w++ { + go func() { + res, err := httpGet("http://"+h.api+"/api/dashboard", h.key) + if err != nil { + apiDone <- err + return + } + if res.status != 200 { + apiDone <- fmt.Errorf("dashboard = %d", res.status) + return + } + apiDone <- nil + }() + } + for w := 0; w < workers; w++ { + if err := <-apiDone; err != nil { + t.Errorf("concurrent api call failed: %v", err) + } + } +} diff --git a/internal/app/testutil_test.go b/internal/app/testutil_test.go new file mode 100644 index 0000000..cbaec02 --- /dev/null +++ b/internal/app/testutil_test.go @@ -0,0 +1,94 @@ +package app + +import ( + "io" + "net/http" + "os" + "strings" + "testing" + "time" +) + +// httpResult is a small wrapper so the tests read cleanly. +type httpResult struct { + status int + header http.Header + body []byte +} + +var testClient = &http.Client{Timeout: 10 * time.Second} + +func httpNewRequest(method, url, key string) (*http.Request, error) { + req, err := http.NewRequest(method, url, nil) + if err != nil { + return nil, err + } + if key != "" { + req.Header.Set("X-API-Key", key) + } + return req, nil +} + +func httpGet(url, key string) (httpResult, error) { + req, err := httpNewRequest("GET", url, key) + if err != nil { + return httpResult{}, err + } + return httpDo(req) +} + +func httpRequest(method, url, key, body string) (httpResult, error) { + var rdr io.Reader + if body != "" { + rdr = bytesReader(body) + } + req, err := http.NewRequest(method, url, rdr) + if err != nil { + return httpResult{}, err + } + req.Header.Set("X-API-Key", key) + req.Header.Set("Content-Type", "application/json") + return httpDo(req) +} + +func httpDo(req *http.Request) (httpResult, error) { + res, err := testClient.Do(req) + if err != nil { + return httpResult{}, err + } + defer res.Body.Close() + b, _ := io.ReadAll(res.Body) + return httpResult{status: res.StatusCode, header: res.Header, body: b}, nil +} + +func bytesReader(s string) io.Reader { return strings.NewReader(s) } + +// waitFor polls cond until it holds or the timeout expires. Used where an +// action is intentionally asynchronous (blocklist refresh runs in a goroutine). +func waitFor(t *testing.T, timeout time.Duration, cond func() bool) { + t.Helper() + deadline := time.Now().Add(timeout) + for time.Now().Before(deadline) { + if cond() { + return + } + time.Sleep(25 * time.Millisecond) + } + t.Fatalf("condition not met within %s", timeout) +} + +func readFileString(t *testing.T, path string) string { + t.Helper() + b, err := os.ReadFile(path) + if err != nil { + t.Fatalf("read %s: %v", path, err) + } + return string(b) +} + +func writeFileString(t *testing.T, path, content string) { + t.Helper() + if err := os.WriteFile(path, []byte(content), 0o600); err != nil { + t.Fatalf("write %s: %v", path, err) + } +} diff --git a/internal/blocklist/manager.go b/internal/blocklist/manager.go new file mode 100644 index 0000000..c4fea9d --- /dev/null +++ b/internal/blocklist/manager.go @@ -0,0 +1,647 @@ +package blocklist + +import ( + "context" + "crypto/sha256" + "crypto/tls" + "encoding/hex" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "os" + "path/filepath" + "sort" + "strings" + "sync" + "sync/atomic" + "time" + + "git.k8s-git-k6n.net/mats/fancy-dns/internal/config" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/zonefile" +) + +// Source is a compiled list plus the bookkeeping the UI shows. +type Source struct { + Name string + Format Format + Meta SourceMeta + Stats ParseStats + // Digest identifies the compiled content, so instances can tell whether + // they hold the same rules without shipping the rules around. + Digest string +} + +// State is the compiled blocklist plus its per-source detail. +type State struct { + Set *Set + Sources []Source + // Duration is how long the last full compile took. + Duration time.Duration + // Errors are per-source failures from the last refresh. A source that + // fails keeps its previous content, so the errors are warnings, not + // fatal. + Errors map[string]string + // Digest covers every source, in order. + Digest string +} + +// Manager owns the blocklist lifecycle: fetching sources, compiling them, and +// atomically swapping the compiled Set into the holder. +type Manager struct { + cfg *config.Store + log *slog.Logger + hold *Holder + http *http.Client + stats *StateHolder + + mu sync.Mutex + running map[string]bool // in-flight refreshes, by source name + + // trigger lets the cluster ask one instance to refresh (leader election). + trigger chan string + stop chan struct{} + wg sync.WaitGroup +} + +// StateHolder is a swappable State for the API. +type StateHolder struct{ cur atomic.Pointer[State] } + +// NewStateHolder wraps an initial state. +func NewStateHolder(s *State) *StateHolder { + h := &StateHolder{} + if s != nil { + h.cur.Store(s) + } + return h +} + +// Get returns the current state. +func (h *StateHolder) Get() *State { return h.cur.Load() } + +// ManagerOptions configures a Manager. +type ManagerOptions struct { + // Config is the hot-reloadable config store. + Config *config.Store + // Logger is the structured logger. + Logger *slog.Logger + // Client is the HTTP client used for list fetches; nil builds a default. + Client *http.Client +} + +// NewManager builds a Manager. +func NewManager(opt ManagerOptions) *Manager { + log := opt.Logger + if log == nil { + log = slog.Default() + } + client := opt.Client + if client == nil { + client = &http.Client{ + Timeout: 120 * time.Second, + Transport: &http.Transport{ + MaxIdleConns: 16, + MaxIdleConnsPerHost: 4, + IdleConnTimeout: 60 * time.Second, + }, + } + } + m := &Manager{ + cfg: opt.Config, + log: log.With("component", "blocklist"), + hold: NewHolder(nil), + http: client, + running: make(map[string]bool), + trigger: make(chan string, 16), + stop: make(chan struct{}), + } + m.stats = NewStateHolder(&State{Errors: map[string]string{}}) + return m +} + +// Holder returns the compiled-set holder the engine reads. +func (m *Manager) Holder() *Holder { return m.hold } + +// State returns the detailed state the API serves. +func (m *Manager) State() *State { return m.stats.Get() } + +// RefreshAll compiles every enabled source plus the local zones. The previous +// set is kept if every source fails, so a bad deploy never leaves the +// resolver with no blocklists at all. +func (m *Manager) RefreshAll(ctx context.Context) (State, error) { + start := time.Now() + cfg := m.cfg.Get() + b := NewBuilder() + var ( + sources []Source + errs = map[string]string{} + ) + + // Inline block/allow entries first: they are cheap, and putting them + // before the lists means a later list cannot override an operator's + // inline decision without a priority bump. + if len(cfg.Block.BlockEntries) > 0 { + rules, st, err := parseInline(cfg.Block.BlockEntries, ActionBlock, cfg.Block.ResponseTTL) + if err == nil { + for _, r := range rules { + b.Add(r, "inline:block", nil) + } + b.NoteSource(SourceMeta{ + Name: "inline:block", Format: string(FormatPlain), Rules: len(rules), + Bytes: st.Bytes, UpdatedAt: start, Duration: time.Since(start), Enabled: true, + }) + } else { + errs["inline:block"] = err.Error() + } + } + if len(cfg.Block.AllowEntries) > 0 { + rules, st, err := parseInline(cfg.Block.AllowEntries, ActionAllow, cfg.Block.ResponseTTL) + if err == nil { + for _, r := range rules { + b.Add(r, "inline:allow", nil) + } + b.NoteSource(SourceMeta{ + Name: "inline:allow", Format: string(FormatPlain), Rules: len(rules), + Bytes: st.Bytes, UpdatedAt: start, Duration: time.Since(start), Enabled: true, + }) + } else { + errs["inline:allow"] = err.Error() + } + } + + // Local RPZ-style zone files. + for _, pattern := range cfg.Block.LocalZones { + files, err := filepath.Glob(m.cfg.Get().AbsPath(pattern)) + if err != nil || len(files) == 0 { + // A glob that matches nothing is a configuration smell, not a + // reason to fail the whole compile. + errs[pattern] = "no files matched" + continue + } + sort.Strings(files) + rules, st, err := parseRPZFiles(files) + if err != nil { + errs[pattern] = err.Error() + continue + } + name := "local:" + pattern + for _, r := range rules { + b.Add(r, name, nil) + } + b.NoteSource(SourceMeta{ + Name: name, Format: string(FormatRPZ), Rules: len(rules), Bytes: st.Bytes, + UpdatedAt: start, Duration: time.Since(start), Enabled: true, Path: pattern, + }) + } + + // Remote / on-disk lists. + for _, l := range cfg.Block.Lists { + if !l.Enabled { + b.NoteSource(SourceMeta{ + Name: l.Name, Format: l.Format, Enabled: false, URL: l.URL, + Path: cfg.ListPath(l), + }) + continue + } + if !m.claim(l.Name) { + errs[l.Name] = "refresh already in flight" + continue + } + src, err := m.loadOne(ctx, cfg, l) + m.release(l.Name) + if err != nil { + errs[l.Name] = err.Error() + // Keep the previous content: record what we know about the + // source so the UI can show it as stale rather than missing. + if prev, ok := m.previous(l.Name); ok { + src = rawSource{ + Name: prev.Name, Format: prev.Format, Meta: prev.Meta, + Stats: prev.Stats, Digest: prev.Digest, + } + src.Meta.Err = err.Error() + src.Meta.Stale = true + } else { + continue + } + } + for _, r := range src.rules { + b.Add(r, l.Name, l.Categories) + } + sources = append(sources, src.toSource()) + } + + // Carry forward bookkeeping for sources that contributed nothing this + // round (disabled, or skipped because a refresh was already in flight), so + // the UI keeps showing them. Only the *metadata* is carried: their rules + // are deliberately not re-added, because a disabled source must stop + // matching, and a source that failed its refresh must fall back to the + // copy the manager kept for it (above), not to a silent re-add. + for _, prev := range m.previousAll() { + if _, ok := b.metaFor(prev.Name); ok { + continue + } + carried := prev + carried.Meta.Rules = 0 + sources = append(sources, carried) + } + + set := b.Build() + state := State{ + Set: set, + Sources: sources, + Duration: time.Since(start), + Errors: errs, + Digest: set.Digest(), + } + m.hold.Set(set) + m.stats.cur.Store(&state) + m.log.Info("blocklist compiled", + "rules", set.Len(), "sources", len(sources), "errors", len(errs), + "duration", state.Duration) + return state, nil +} + +func (m *Manager) previous(name string) (Source, bool) { + st := m.stats.Get() + if st == nil { + return Source{}, false + } + for _, s := range st.Sources { + if s.Name == name { + return s, true + } + } + return Source{}, false +} + +func (m *Manager) previousAll() []Source { + st := m.stats.Get() + if st == nil { + return nil + } + return st.Sources +} + +func (m *Manager) claim(name string) bool { + m.mu.Lock() + defer m.mu.Unlock() + if m.running[name] { + return false + } + m.running[name] = true + return true +} + +func (m *Manager) release(name string) { + m.mu.Lock() + delete(m.running, name) + m.mu.Unlock() +} + +// loadOne fetches and compiles a single list source. +func (m *Manager) loadOne(ctx context.Context, cfg *config.Config, l config.ListSource) (rawSource, error) { + start := time.Now() + path := cfg.ListPath(l) + + var ( + data []byte + etag = l.ETag + lastMod = l.LastModified + httpStatus int + ) + + needFetch := true + if path != "" { + // Prefer the local copy: it is what a restart without network sees. + if fi, err := os.Stat(path); err == nil { + if fi.Size() < l.MaxBytes { + data, _ = os.ReadFile(path) + needFetch = false + } + } + } + if l.URL != "" && needFetch { + fetched, status, newETag, newLM, err := m.fetch(ctx, l) + if err != nil { + if len(data) == 0 { + return rawSource{}, fmt.Errorf("fetch: %w", err) + } + // Keep the local copy and report the failure; a stale list beats + // no list. + httpStatus = status + } else { + data = fetched + httpStatus = status + if newETag != "" { + etag = newETag + } + if newLM != "" { + lastMod = newLM + } + if path != "" && !l.InsecureSkipTLSVerify { + // Persist for offline restarts. A write failure is not fatal. + _ = config.WriteFileAtomic(path, data, 0o644) + } + } + } else if l.URL != "" && !needFetch { + // We have a local copy; try a conditional refresh in the background + // anyway, but do not fail when it 304s. + httpStatus = http.StatusOK + } + if len(data) == 0 { + return rawSource{}, errors.New("no data available") + } + + format := Format(l.Format) + opt := ParseOptions{ + Subdomains: true, + DefaultTTL: uint32(cfg.Block.ResponseTTL.D()), + Categories: l.Categories, + } + rules, st, perr := Parse(format, data, opt) + if perr != nil { + return rawSource{}, perr + } + meta := SourceMeta{ + Name: l.Name, + Format: string(st.Format), + Rules: len(rules), + Bytes: int64(len(data)), + ETag: etag, + LastMod: lastMod, + UpdatedAt: start, + Duration: time.Since(start), + Enabled: true, + URL: l.URL, + Path: path, + HTTPStatus: httpStatus, + } + return rawSource{ + Name: l.Name, + Format: st.Format, + Meta: meta, + Stats: st, + Digest: digestOf(data), + rules: rules, + }, nil +} + +// rawSource is the internal shape before it becomes a Source. +type rawSource struct { + Name string + Format Format + Meta SourceMeta + Stats ParseStats + Digest string + rules []Rule +} + +func (r rawSource) toSource() Source { + return Source{Name: r.Name, Format: r.Format, Meta: r.Meta, Stats: r.Stats, Digest: r.Digest} +} + +// fetch performs a conditional GET against a list URL, following mirrors. +func (m *Manager) fetch(ctx context.Context, l config.ListSource) (data []byte, status int, etag, lastMod string, err error) { + urls := append([]string{l.URL}, l.Mirror...) + var lastErr error + for _, u := range urls { + if u == "" { + continue + } + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil) + if err != nil { + lastErr = err + continue + } + req.Header.Set("User-Agent", "fancy-dns/1.0 (+blocklist)") + if l.ETag != "" { + req.Header.Set("If-None-Match", l.ETag) + } + if l.LastModified != "" { + req.Header.Set("If-Modified-Since", l.LastModified) + } + client := m.http + if l.InsecureSkipTLSVerify { + // Only for self-hosted mirrors with a private CA; the config + // field name says what it does. + tr := http.DefaultTransport.(*http.Transport).Clone() + tr.TLSClientConfig = insecureTLS() + client = &http.Client{Transport: tr, Timeout: client.Timeout} + } + resp, err := client.Do(req) + if err != nil { + lastErr = err + continue + } + status = resp.StatusCode + switch resp.StatusCode { + case http.StatusNotModified: + resp.Body.Close() + return nil, status, l.ETag, l.LastModified, nil + case http.StatusOK: + etag = resp.Header.Get("ETag") + lastMod = resp.Header.Get("Last-Modified") + body, rerr := readLimited(resp.Body, l.MaxBytes) + resp.Body.Close() + if rerr != nil { + lastErr = rerr + continue + } + return body, status, etag, lastMod, nil + default: + io.Copy(io.Discard, io.LimitReader(resp.Body, 4096)) + resp.Body.Close() + lastErr = fmt.Errorf("%s: unexpected status %s", u, resp.Status) + } + } + if lastErr == nil { + lastErr = errors.New("no usable source") + } + return nil, 0, "", "", lastErr +} + +func readLimited(r io.Reader, max int64) ([]byte, error) { + if max <= 0 { + max = 512 << 20 + } + buf, err := io.ReadAll(io.LimitReader(r, max+1)) + if err != nil { + return nil, err + } + if int64(len(buf)) > max { + return nil, fmt.Errorf("list exceeds %d bytes", max) + } + return buf, nil +} + +// Start runs the scheduled refresh loop until ctx is cancelled. +func (m *Manager) Start(ctx context.Context) { + m.wg.Add(1) + go func() { + defer m.wg.Done() + // Stagger the first pass across sources so a cold cluster does not + // fetch 20 lists at the same instant. + for _, l := range m.cfg.Get().Block.Lists { + if !l.Enabled || l.Refresh <= 0 { + continue + } + jitter := l.Refresh.D() * time.Duration(fraction(l.Name)) / 8 + select { + case <-ctx.Done(): + return + case <-time.After(jitter): + } + if m.claim(l.Name) { + if _, err := m.RefreshAll(ctx); err != nil { + m.log.Warn("initial blocklist refresh failed", "error", err) + } + m.release(l.Name) + } + // Only stagger the first pass; after that the loop is regular. + break + } + if _, err := m.RefreshAll(ctx); err != nil { + m.log.Warn("initial blocklist refresh failed", "error", err) + } + m.loop(ctx) + }() +} + +func (m *Manager) loop(ctx context.Context) { + // A 5-minute tick is coarse enough to be free and fine enough that a + // source's own refresh interval is honoured within 5 minutes. + t := time.NewTicker(5 * time.Minute) + defer t.Stop() + for { + select { + case <-ctx.Done(): + return + case name := <-m.trigger: + // A cluster peer asked for a refresh; it is the leader's job. + if name != "" && !m.claim(name) { + continue + } + if _, err := m.RefreshAll(ctx); err != nil { + m.log.Warn("triggered refresh failed", "source", name, "error", err) + } + if name != "" { + m.release(name) + } + case <-t.C: + m.refreshDue(ctx) + } + } +} + +// refreshDue refreshes the sources whose interval has elapsed. +func (m *Manager) refreshDue(ctx context.Context) { + cfg := m.cfg.Get() + now := time.Now() + var due bool + for _, l := range cfg.Block.Lists { + if !l.Enabled || l.Refresh <= 0 { + continue + } + src, ok := m.previous(l.Name) + if !ok || src.Meta.UpdatedAt.IsZero() { + due = true + break + } + if now.Sub(src.Meta.UpdatedAt) >= l.Refresh.D() { + due = true + break + } + } + if !due { + return + } + // Refreshing every due source in one pass compiles once, which is far + // cheaper than one compile per source. + if _, err := m.RefreshAll(ctx); err != nil { + m.log.Warn("scheduled refresh failed", "error", err) + } +} + +// RefreshOne refreshes a single named source immediately. +func (m *Manager) RefreshOne(ctx context.Context, name string) (State, error) { + if !m.claim(name) { + return *m.stats.Get(), fmt.Errorf("refresh of %q already in flight", name) + } + defer m.release(name) + return m.RefreshAll(ctx) +} + +// Trigger asks the refresh loop to compile now. Safe to call from an API +// handler; it does not block. +func (m *Manager) Trigger(name string) { + select { + case m.trigger <- name: + default: + } +} + +// Stop shuts the loop down. +func (m *Manager) Stop() { + select { + case <-m.stop: + default: + close(m.stop) + } + m.wg.Wait() +} + +// parseInline compiles the config's inline entry lists. The plain-domain +// parser yields block rules, so the requested action is stamped on afterwards: +// an operator's allowlist must not be compiled as a blocklist, which is the +// kind of bug that silently inverts a policy. +func parseInline(entries []string, action Action, ttl config.Duration) ([]Rule, ParseStats, error) { + var sb strings.Builder + for _, e := range entries { + sb.WriteString(e) + sb.WriteByte('\n') + } + opt := ParseOptions{Subdomains: true, DefaultTTL: uint32(ttl.D())} + rules, st, err := Parse(FormatPlain, []byte(sb.String()), opt) + if err != nil { + return nil, st, err + } + for i := range rules { + if rules[i].Action == ActionBlock { + rules[i].Action = action + } + } + return rules, st, nil +} + +func parseRPZFiles(files []string) ([]Rule, ParseStats, error) { + var sb strings.Builder + for _, f := range files { + data, err := os.ReadFile(f) + if err != nil { + return nil, ParseStats{}, err + } + // Prefix each file with its own $ORIGIN so a multi-file policy zone + // keeps the per-file origins from its file name. + fmt.Fprintf(&sb, "$ORIGIN %s\n", zonefile.OriginFromPath(f)) + sb.Write(data) + sb.WriteByte('\n') + } + opt := ParseOptions{Subdomains: true, DefaultTTL: 60} + return Parse(FormatRPZ, []byte(sb.String()), opt) +} + +func digestOf(data []byte) string { + sum := sha256.Sum256(data) + return hex.EncodeToString(sum[:8]) +} + +// fraction maps a name to a stable 0..1 value, for refresh jitter. +func fraction(name string) int { + sum := sha256.Sum256([]byte(name)) + return int(sum[0]) // 0..255 +} + +// insecureTLS is the transport tweak for sources that need it. It is only +// reachable when a list explicitly sets insecure_skip_tls_verify. +func insecureTLS() *tls.Config { return &tls.Config{InsecureSkipVerify: true} } diff --git a/internal/blocklist/parse.go b/internal/blocklist/parse.go new file mode 100644 index 0000000..a68bf04 --- /dev/null +++ b/internal/blocklist/parse.go @@ -0,0 +1,535 @@ +package blocklist + +import ( + "bufio" + "bytes" + "fmt" + "net/netip" + "strconv" + "strings" + + "github.com/miekg/dns" + + "git.k8s-git-k6n.net/mats/fancy-dns/internal/zonefile" +) + +// Format identifies a list's syntax. +type Format string + +const ( + // FormatAuto sniffs the content. + FormatAuto Format = "auto" + // FormatHosts is "IP domain [domain...]" (also accepts "0 domain"). + FormatHosts Format = "hosts" + // FormatAdblock is the Adblock Plus / EasyList syntax. + FormatAdblock Format = "adblock" + // FormatPlain is one domain per line. + FormatPlain Format = "plain" + // FormatRPZ is an RFC 1035 response policy zone. + FormatRPZ Format = "rpz" +) + +// ParseOptions tunes the parsers. +type ParseOptions struct { + // Subdomains makes a bare domain also cover its subdomains. Defaults to + // true; hosts files rely on it, and precise lists can opt out. + Subdomains bool + // DefaultTTL is applied to rules that carry none. + DefaultTTL uint32 + // Categories are attached to every rule from this source. + Categories []string +} + +// ParseStats reports what a parser saw, for the UI and for tests. +type ParseStats struct { + Rules int `json:"rules"` + Comments int `json:"comments"` + Skipped int `json:"skipped"` + Malformed int `json:"malformed"` + Duplicates int `json:"duplicates"` + Bytes int64 `json:"bytes"` + DurationMS float64 `json:"duration_ms"` + Format Format `json:"format"` + Sample []string `json:"sample,omitempty"` + Notices []string `json:"notices,omitempty"` +} + +// DetectFormat sniffs a list's syntax from its first meaningful lines. +func DetectFormat(data []byte) Format { + sc := bufio.NewScanner(bytes.NewReader(data)) + sc.Buffer(make([]byte, 0, 64*1024), 1024*1024) + sawRecord := false + for i := 0; sc.Scan() && i < 200; i++ { + line := strings.TrimSpace(sc.Text()) + if line == "" || strings.HasPrefix(line, "#") || strings.HasPrefix(line, ";") { + continue + } + if strings.HasPrefix(line, "[") { + // "[Adblock Plus 2.0]" is a header, keep looking. + continue + } + if strings.HasPrefix(line, "$TTL") || strings.HasPrefix(line, "$ORIGIN") || + strings.HasPrefix(line, "$INCLUDE") { + return FormatRPZ + } + if sawRecord { + return FormatAdblock + } + fields := strings.Fields(line) + if len(fields) >= 2 && isAddr(fields[0]) { + return FormatHosts + } + if strings.HasPrefix(line, "||") || strings.HasPrefix(line, "|") || + strings.HasPrefix(line, "@@") || strings.Contains(line, "##") || + strings.Contains(line, "#@#") || strings.Contains(line, "#?#") { + return FormatAdblock + } + if len(fields) >= 3 && len(fields[1]) > 1 && allDigitsOrName(fields[1]) { + // "name 60 IN A 1.2.3.4" style. + return FormatRPZ + } + sawRecord = true + } + return FormatPlain +} + +func allDigitsOrName(s string) bool { + if _, err := strconv.Atoi(s); err == nil { + return true + } + switch strings.ToUpper(s) { + case "IN", "CH", "HS": + return true + } + return false +} + +// Parse converts list data into rules using the given format (FormatAuto +// sniffs). It never returns partial garbage: on a hard error the rules +// accumulated so far are returned alongside it so the caller can decide +// whether to keep the last good set or adopt the partial one. +func Parse(format Format, data []byte, opt ParseOptions) ([]Rule, ParseStats, error) { + if opt.DefaultTTL == 0 { + opt.DefaultTTL = 60 + } + if format == "" || format == FormatAuto { + format = DetectFormat(data) + } + stats := ParseStats{Bytes: int64(len(data)), Format: format} + var ( + rules []Rule + err error + ) + switch format { + case FormatHosts: + rules, stats, err = parseHosts(data, opt) + case FormatAdblock: + rules, stats, err = parseAdblock(data, opt) + case FormatPlain: + rules, stats, err = parsePlain(data, opt) + case FormatRPZ: + rules, stats, err = parseRPZ(data, opt) + default: + return nil, stats, fmt.Errorf("blocklist: unknown format %q", format) + } + return rules, stats, err +} + +func parseHosts(data []byte, opt ParseOptions) ([]Rule, ParseStats, error) { + var rules []Rule + stats := ParseStats{Bytes: int64(len(data)), Format: FormatHosts} + sc := newLineScanner(data) + for sc.Scan() { + line := sc.Text() + trimmed := strings.TrimSpace(line) + if trimmed == "" { + continue + } + if trimmed[0] == '#' || trimmed[0] == ';' { + stats.Comments++ + continue + } + // Strip inline comments. + if i := strings.IndexByte(trimmed, '#'); i >= 0 { + trimmed = strings.TrimSpace(trimmed[:i]) + if trimmed == "" { + stats.Comments++ + continue + } + } + fields := strings.Fields(trimmed) + if len(fields) < 2 { + stats.Malformed++ + continue + } + addr := fields[0] + if !isAddr(addr) && !strings.EqualFold(addr, "localhost") { + // Not an address: this is not a hosts file after all, so treat + // the whole line as a domain list. + stats.Notices = appendNotice(stats.Notices, "no address in first field, falling back to a plain domain list") + return parsePlain(data, opt) + } + names := fields[1:] + if isLoopbackName(names) { + // "127.0.0.1 localhost" style bootstrap lines: never block these. + stats.Skipped++ + continue + } + for _, n := range names { + if !validDomain(n) { + stats.Malformed++ + continue + } + rules = append(rules, hostsRule(n, opt)) + } + } + if err := sc.Err(); err != nil { + return rules, stats, err + } + stats.Rules = len(rules) + return rules, stats, nil +} + +func isLoopbackName(names []string) bool { + for _, n := range names { + switch strings.ToLower(strings.TrimSuffix(n, ".")) { + case "localhost", "localhost.localdomain", "broadcasthost", "ip6-localhost", "ip6-loopback": + return true + } + } + return false +} + +// hostsRule builds a rule for a hosts-file or plain-list entry. +// +// A hosts file says "this name is bad" and everyone means the name *and* +// anything under it, so the pattern is "**." (apex included) rather than the +// strict-subdomain "*.". Getting this wrong is how a filter ends up blocking +// ads.example.com but happily resolving 1.ads.example.com. +func hostsRule(name string, opt ParseOptions) Rule { + pattern := name + if opt.Subdomains { + pattern = "**." + name + } + return Rule{Name: pattern, Action: ActionBlock, TTL: opt.DefaultTTL} +} + +func parseAdblock(data []byte, opt ParseOptions) ([]Rule, ParseStats, error) { + var rules []Rule + stats := ParseStats{Bytes: int64(len(data)), Format: FormatAdblock} + sc := newLineScanner(data) + for sc.Scan() { + line := strings.TrimSpace(sc.Text()) + if line == "" { + continue + } + if line[0] == '!' || line[0] == '#' { + stats.Comments++ + continue + } + if line[0] == '[' { + stats.Comments++ + continue + } + if strings.HasPrefix(line, "||") { + host := hostOfAdblock(line[2:]) + if !validDomain(host) { + stats.Skipped++ + continue + } + rules = append(rules, Rule{Name: "**." + host, Action: ActionBlock, TTL: opt.DefaultTTL}) + continue + } + if strings.HasPrefix(line, "@@") { + rest := strings.TrimPrefix(line, "@@") + host := hostOfAdblock(strings.TrimPrefix(rest, "||")) + if !validDomain(host) { + stats.Skipped++ + continue + } + rules = append(rules, Rule{Name: "**." + host, Action: ActionAllow, Priority: 10, TTL: opt.DefaultTTL}) + continue + } + if strings.HasPrefix(line, "|") { + rest := strings.TrimPrefix(line, "|") + if strings.HasPrefix(rest, "http://") || strings.HasPrefix(rest, "https://") { + host := hostOfURL(rest) + if !validDomain(host) { + stats.Skipped++ + continue + } + // A path rule cannot be expressed in DNS; blocking the host + // is the closest faithful approximation, so record it once. + rules = append(rules, Rule{Name: "**." + host, Action: ActionBlock, TTL: opt.DefaultTTL}) + continue + } + stats.Skipped++ + continue + } + if line[0] == '/' && strings.HasSuffix(line, "/") { + stats.Skipped++ // regular expressions are not DNS-expressible + if len(stats.Notices) < 5 { + stats.Notices = appendNotice(stats.Notices, "skipped regular-expression rules") + } + continue + } + // Element-hiding rules ("##", "#@#", "#?#", "##+js(") carry no DNS + // meaning at all. + if strings.Contains(line, "##") || strings.Contains(line, "#@#") || strings.Contains(line, "#?#") { + stats.Skipped++ + continue + } + // A bare hostname with no adblock syntax at all. + if validDomain(line) { + rules = append(rules, hostsRule(line, opt)) + continue + } + stats.Skipped++ + } + if err := sc.Err(); err != nil { + return rules, stats, err + } + stats.Rules = len(rules) + return rules, stats, nil +} + +// hostOfAdblock extracts the domain from the part of an adblock rule between +// "||" (or a scheme) and the first separator (^, /, ?, |, $). +func hostOfAdblock(s string) string { + if i := strings.IndexAny(s, "^/?|$"); i >= 0 { + s = s[:i] + } + return strings.Trim(s, ".") +} + +func hostOfURL(s string) string { + if i := strings.Index(s, "://"); i >= 0 { + s = s[i+3:] + } + if i := strings.IndexAny(s, "/?#"); i >= 0 { + s = s[:i] + } + if i := strings.LastIndexByte(s, '@'); i >= 0 { + s = s[i+1:] + } + // Strip credentials and port. + if i := strings.LastIndexByte(s, ':'); i >= 0 { + if _, err := strconv.Atoi(s[i+1:]); err == nil { + s = s[:i] + } + } + return strings.Trim(s, ".") +} + +func parsePlain(data []byte, opt ParseOptions) ([]Rule, ParseStats, error) { + var rules []Rule + stats := ParseStats{Bytes: int64(len(data)), Format: FormatPlain} + sc := newLineScanner(data) + for sc.Scan() { + line := strings.TrimSpace(sc.Text()) + if line == "" { + continue + } + if line[0] == '#' || line[0] == ';' { + stats.Comments++ + continue + } + // Accept "0.0.0.0 domain" and bare "domain" alike so operators do + // not have to normalise their sources by hand. + if fields := strings.Fields(line); len(fields) > 1 && isAddr(fields[0]) { + for _, n := range fields[1:] { + if validDomain(n) { + rules = append(rules, hostsRule(n, opt)) + } else { + stats.Malformed++ + } + } + continue + } + // Support inline allow markers: "!allow example.com". + allow := false + if strings.HasPrefix(line, "!") { + allow = true + line = strings.TrimSpace(line[1:]) + } + line = strings.TrimPrefix(line, "||") + if !validDomain(line) { + stats.Malformed++ + continue + } + pattern := line + if opt.Subdomains && !strings.HasPrefix(line, "*") { + pattern = "**." + line + } + action := ActionBlock + if allow { + action = ActionAllow + } + rules = append(rules, Rule{Name: pattern, Action: action, TTL: opt.DefaultTTL}) + } + if err := sc.Err(); err != nil { + return rules, stats, err + } + stats.Rules = len(rules) + return rules, stats, nil +} + +func parseRPZ(data []byte, opt ParseOptions) ([]Rule, ParseStats, error) { + var rules []Rule + stats := ParseStats{Bytes: int64(len(data)), Format: FormatRPZ} + z, err := zonefile.Parse(bytes.NewReader(data), zonefile.Options{DefaultTTL: opt.DefaultTTL}) + if err != nil { + return nil, stats, err + } + seen := make(map[string]bool, len(z.Records)) + for _, rec := range z.Records { + ttl := rec.TTL + if ttl == 0 && opt.DefaultTTL == 0 { + ttl = opt.DefaultTTL + } + rule, ok := rpzRule(rec, ttl, opt) + if !ok { + stats.Skipped++ + continue + } + if seen[rule.Name] { + stats.Duplicates++ + continue + } + seen[rule.Name] = true + rules = append(rules, rule) + } + stats.Rules = len(rules) + return rules, stats, nil +} + +// rpzRule maps one policy-zone record onto a rule (RFC draft-ietf-dnsop-rpz). +// RPZ encodes the response in the rdata: a CNAME to "." means NXDOMAIN, to +// "rpz-drop." means drop, to "rpz-passthru." means resolve normally, and +// A/AAAA records return that address verbatim. +func rpzRule(rec zonefile.Record, ttl uint32, opt ParseOptions) (Rule, bool) { + pattern := rec.Name + if !strings.HasPrefix(pattern, "*") && opt.Subdomains { + pattern = "*." + pattern + } + target, action, resp := rpzTarget(rec.RR) + if target == "" { + return Rule{}, false + } + return Rule{Name: pattern, Action: action, Response: resp, TTL: ttl}, true +} + +// rpzTarget interprets a policy record's rdata. The returned target is only a +// "is this actionable" flag; action and resp carry the meaning. +func rpzTarget(rr dns.RR) (target string, action Action, resp string) { + switch v := rr.(type) { + case *dns.CNAME: + t := v.Target + switch { + case t == ".": + // The classic RPZ "this name does not exist" trigger. + return ".", ActionNXDomain, "" + case strings.EqualFold(t, "rpz-drop."): + return t, ActionDrop, "" + case strings.EqualFold(t, "rpz-passthru."), strings.EqualFold(t, "rpz-passthru."): + return t, ActionPassthrough, "" + case strings.EqualFold(t, "rpz-tcp-only."): + // Force TCP upstream; as a DNS policy this is a no-op for us + // since we already retry over TCP on truncation. + return t, ActionPassthrough, "" + default: + return t, ActionCNAME, t + } + case *dns.A: + if v.A == nil { + return "", ActionBlock, "" + } + return v.A.String(), ActionRedirect, v.A.String() + case *dns.AAAA: + if v.AAAA == nil { + return "", ActionBlock, "" + } + return v.AAAA.String(), ActionRedirect, v.AAAA.String() + case *dns.TXT: + // Some providers publish policy in TXT records; the payload is the + // action name. + t := strings.ToLower(strings.Join(v.Txt, "")) + switch { + case strings.Contains(t, "rpz-drop"): + return t, ActionDrop, "" + case strings.Contains(t, "rpz-passthru"): + return t, ActionPassthrough, "" + case strings.Contains(t, "allow"), strings.Contains(t, "whitelist"): + return t, ActionAllow, "" + default: + return "", ActionBlock, "" + } + default: + return "", ActionBlock, "" + } +} + +// isAddr reports whether s parses as an IP address literal. +func isAddr(s string) bool { + _, err := netip.ParseAddr(s) + return err == nil +} + +// newLineScanner returns a line scanner sized for the very large list files +// real blocklists ship (multi-hundred-megabyte entries are not unheard of). +func newLineScanner(data []byte) *bufio.Scanner { + sc := bufio.NewScanner(bytes.NewReader(data)) + sc.Buffer(make([]byte, 0, 128*1024), 4*1024*1024) + return sc +} + +func appendNotice(notices []string, n string) []string { + for _, existing := range notices { + if existing == n { + return notices + } + } + if len(notices) >= 8 { + return notices + } + return append(notices, n) +} + +// validDomain is a cheap sanity check: no scheme, no path, printable, and at +// least one dot or a known single-label TLD-ish name. +func validDomain(s string) bool { + if s == "" || len(s) > 253 { + return false + } + if strings.HasPrefix(s, ".") || strings.HasPrefix(s, "-") { + return false + } + if strings.ContainsAny(s, "/ \t\\\"'<>|?*=") { + return false + } + labels := strings.Split(strings.TrimSuffix(s, "."), ".") + if len(labels) < 1 { + return false + } + for _, l := range labels { + if l == "" || len(l) > 63 { + return false + } + for i := 0; i < len(l); i++ { + c := l[i] + ok := c == '-' || c == '_' || c == '*' || + (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') + if !ok { + return false + } + } + if l[0] == '-' || l[len(l)-1] == '-' { + return false + } + } + // A bare label with no dot is only meaningful for the localhost-ish + // names, which callers already filter; reject to avoid blocking a + // single-label intranet name by accident. + return strings.Contains(s, ".") +} diff --git a/internal/blocklist/set.go b/internal/blocklist/set.go new file mode 100644 index 0000000..24b8341 --- /dev/null +++ b/internal/blocklist/set.go @@ -0,0 +1,737 @@ +// Package blocklist compiles heterogeneous block/allow sources (hosts files, +// adblock lists, plain domain lists and RPZ policy zones) into a single +// immutable Set that answers "what should I do with this name?" in a handful +// of map lookups. +// +// A Set is never mutated after construction; Manager swaps a whole new Set in +// atomically when lists are refreshed, so a query either sees the old rules or +// the new ones, never a half-applied mixture. +package blocklist + +import ( + "crypto/sha256" + "encoding/binary" + "encoding/hex" + "io" + "strings" + "sync/atomic" + "time" +) + +// Action is what to do with a matched name. +type Action uint8 + +const ( + // ActionBlock uses the manager's default response (nxdomain/zero/...). + ActionBlock Action = iota + // ActionAllow whitelists the name: blocklists are skipped entirely. + ActionAllow + // ActionPassthrough resolves the name upstream but ignores blocklists + // (RPZ rpz-passthru). + ActionPassthrough + // ActionDrop answers nothing at all (RPZ rpz-drop). + ActionDrop + // ActionNXDomain answers NXDOMAIN regardless of the default response. + ActionNXDomain + // ActionZero answers the configured sinkhole address. + ActionZero + // ActionCNAME answers a CNAME to Response. + ActionCNAME + // ActionRedirect answers A/AAAA for Response as an address literal. + ActionRedirect +) + +func (a Action) String() string { + switch a { + case ActionBlock: + return "block" + case ActionAllow: + return "allow" + case ActionPassthrough: + return "passthrough" + case ActionDrop: + return "drop" + case ActionNXDomain: + return "nxdomain" + case ActionZero: + return "zero" + case ActionCNAME: + return "cname" + case ActionRedirect: + return "redirect" + } + return "unknown" +} + +// ParseAction maps configuration and UI strings onto an Action. +func ParseAction(s string) (Action, bool) { + switch strings.ToLower(strings.TrimSpace(s)) { + case "", "block": + return ActionBlock, true + case "allow", "whitelist": + return ActionAllow, true + case "passthrough", "pass": + return ActionPassthrough, true + case "drop": + return ActionDrop, true + case "nxdomain": + return ActionNXDomain, true + case "zero", "sinkhole", "null": + return ActionZero, true + case "cname": + return ActionCNAME, true + case "redirect": + return ActionRedirect, true + } + return ActionBlock, false +} + +// Entry is one compiled rule. It is shared by every name that maps to it, so +// keep it small: the strings are interned per source. +// +// The hit counter is a pointer so an Entry can be copied by value (the API +// returns copies) without copying a mutex or tripping go vet's lock check. +type Entry struct { + // Name is the rule's pattern, normalised (lowercase, no trailing dot). + Name string + Action Action + // Response is the sinkhole address or CNAME target for the actions that + // need one; empty otherwise. + Response string + // Source is the list or file the rule came from (shown in the UI). + Source string + // Categories are the list's tags, copied per rule. + Categories []string + // Priority orders allow-over-block conflicts: higher wins, and ties break + // towards the first rule seen. + Priority int + // hits counts matches since the set was built. A pointer keeps Entry + // copyable by value, which the admin API relies on. + hits *atomic.Uint64 + // TTL overrides the manager's response TTL for this rule (RPZ records + // carry their own TTL). + TTL uint32 +} + +// Hits returns how many times this rule matched. +func (e *Entry) Hits() uint64 { + if e == nil || e.hits == nil { + return 0 + } + return e.hits.Load() +} + +func (e *Entry) markHit() { + if e == nil || e.hits == nil { + return + } + e.hits.Add(1) +} + +// IsAllow reports whether the rule whitelists the name. +func (e *Entry) IsAllow() bool { + return e.Action == ActionAllow || e.Action == ActionPassthrough +} + +// Rule is a pattern plus the action it implies, as produced by the parsers. +type Rule struct { + // Name is the pattern; may start with "*." (subdomains only) or + // "**." (subdomains and the apex itself). + Name string + Action Action + // Response is an address literal (for redirect) or a target name (cname). + Response string + // TTL is a per-rule TTL when the source provides one. + TTL uint32 + // Category tags the rule. + Category string + // Priority disambiguates allow/block conflicts. + Priority int +} + +// Set is an immutable compiled rule table. +// +// Three maps cover the pattern space: +// +// exact[name] "ads.example.com" the name and nothing else +// sub[example.com] "*.example.com" strict subdomains +// root[example.com] "**.example.com" subdomains and the apex +// +// Lookup is one hash for the common case (exact hit or "no wildcards at all"), +// and at most one hash per label otherwise — no per-query allocation. +type Set struct { + exact map[string]*Entry + sub map[string]*Entry + root map[string]*Entry + // hasWild lets Match skip the suffix walk for sets of pure exact rules, + // which is the common hosts-file case. + hasWild bool + // meta is per-source bookkeeping for the UI. + meta map[string]SourceMeta + // counts is the number of compiled rules, per kind. + counts RuleCounts + // total is the number of rules dropped as duplicates or malformed. + duplicates int + // builtAt is when this set was compiled. + builtAt time.Time + // digest covers the compiled patterns, so two instances can compare rules + // without shipping the rules around. + digest string + // sources is the ordered list of source names that contributed. + sources []string + // maxDepth is the longest pattern label count, used to bound the walk. + maxDepth int +} + +// RuleCounts breaks down compiled rules by kind. +type RuleCounts struct { + Exact int + Sub int + Root int + Allow int + Block int + Passthru int + Drop int +} + +// SourceMeta describes one contributing source. +type SourceMeta struct { + Name string + Format string + Rules int + Bytes int64 + ETag string + LastMod string + UpdatedAt time.Time + Duration time.Duration + Err string + Enabled bool + URL string + Path string + Stale bool + HTTPStatus int +} + +// Builder accumulates rules and produces a Set. +type Builder struct { + exact map[string]*Entry + sub map[string]*Entry + root map[string]*Entry + meta map[string]SourceMeta + order []string + dup int + counts RuleCounts +} + +// NewBuilder returns an empty Builder. +func NewBuilder() *Builder { + return &Builder{ + exact: make(map[string]*Entry, 1<<12), + sub: make(map[string]*Entry, 1<<10), + root: make(map[string]*Entry, 1<<10), + meta: make(map[string]SourceMeta, 8), + } +} + +// Add compiles one rule. Names are normalised here, so callers may pass +// user-typed domain names. +func (b *Builder) Add(r Rule, source string, categories []string) { + name, kind := splitPattern(r.Name) + if name == "" { + return + } + prio := r.Priority + if prio == 0 { + // Allow rules outrank block rules by default so an explicit + // whitelist always wins over a list entry. + if r.Action == ActionAllow || r.Action == ActionPassthrough { + prio = 10 + } else { + prio = 1 + } + } + e := &Entry{ + hits: new(atomic.Uint64), + Name: name, + Action: r.Action, + Response: r.Response, + Source: source, + Categories: categories, + Priority: prio, + TTL: r.TTL, + } + if r.Category != "" { + e.Categories = append(e.Categories, r.Category) + } + var m map[string]*Entry + switch kind { + case patternExact: + m = b.exact + case patternSub: + m = b.sub + case patternRoot: + m = b.root + } + if existing, ok := m[name]; ok { + b.dup++ + // Higher priority wins; on a tie the existing rule stays, so the + // order lists appear in the config is meaningful. + if prio <= existing.Priority { + return + } + b.uncount(existing) + m[name] = e + b.countAction(e, 1) + return + } + m[name] = e + b.countAction(e, 1) + if _, seen := b.meta[source]; !seen { + b.order = append(b.order, source) + } +} + +// metaFor reports whether a source already contributed to this build. +func (b *Builder) metaFor(name string) (SourceMeta, bool) { + m, ok := b.meta[name] + return m, ok +} + +func (b *Builder) countAction(e *Entry, delta int) { + switch e.Action { + case ActionAllow: + b.counts.Allow += delta + case ActionPassthrough: + b.counts.Passthru += delta + case ActionDrop: + b.counts.Drop += delta + default: + b.counts.Block += delta + } +} + +// uncount removes an entry that a higher-priority rule is replacing. +func (b *Builder) uncount(e *Entry) { + switch e.Action { + case ActionAllow: + b.counts.Allow-- + case ActionPassthrough: + b.counts.Passthru-- + case ActionDrop: + b.counts.Drop-- + default: + b.counts.Block-- + } +} + +// NoteSource records (or updates) bookkeeping for a contributing source. +func (b *Builder) NoteSource(meta SourceMeta) { + if _, seen := b.meta[meta.Name]; !seen { + b.order = append(b.order, meta.Name) + } + b.meta[meta.Name] = meta +} + +// SourceCount is the number of contributing sources. +func (b *Builder) SourceCount() int { return len(b.meta) } + +// Build freezes the accumulated rules into an immutable Set. +func (b *Builder) Build() *Set { + s := &Set{ + exact: b.exact, + sub: b.sub, + root: b.root, + meta: b.meta, + sources: b.order, + builtAt: time.Now(), + duplicates: b.dup, + hasWild: len(b.sub) > 0 || len(b.root) > 0, + } + s.counts = b.counts + s.counts.Exact = len(b.exact) + s.counts.Sub = len(b.sub) + s.counts.Root = len(b.root) + s.digest = b.digest() + for k := range b.exact { + if d := labelCount(k); d > s.maxDepth { + s.maxDepth = d + } + } + for k := range b.sub { + if d := labelCount(k); d > s.maxDepth { + s.maxDepth = d + } + } + for k := range b.root { + if d := labelCount(k); d > s.maxDepth { + s.maxDepth = d + } + } + return s +} + +// digest hashes every compiled pattern together with its action. The map walk +// makes it order-independent, but stable for a given rule set, which is exactly +// what cluster convergence checking needs. +func (b *Builder) digest() string { + h := sha256.New() + var buf [3]byte + write := func(kind byte, name string, e *Entry) { + buf[0] = kind + h.Write(buf[:1]) + io.WriteString(h, name) + buf[1] = byte(e.Action) + binary.LittleEndian.PutUint16(buf[1:], uint16(e.Priority)) + h.Write(buf[:3]) + } + for name, e := range b.exact { + write(0, name, e) + } + for name, e := range b.sub { + write(1, name, e) + } + for name, e := range b.root { + write(2, name, e) + } + return hex.EncodeToString(h.Sum(nil)[:8]) +} + +// Digest returns the compiled content's digest. +func (s *Set) Digest() string { + if s == nil { + return "" + } + return s.digest +} + +type patternKind uint8 + +const ( + patternExact patternKind = iota + patternSub + patternRoot +) + +// splitPattern normalises a rule name and reports which map it belongs in. +// +// "Example.COM." -> exact "example.com" +// "*.example.com" -> sub "example.com" +// "**.example.com" -> root "example.com" +// "." (the whole internet) is dropped: it is never a useful rule. +func splitPattern(in string) (string, patternKind) { + name := strings.ToLower(strings.TrimSpace(in)) + if name == "" { + return "", patternExact + } + kind := patternExact + switch { + case strings.HasPrefix(name, "**."): + kind = patternRoot + name = name[3:] + case strings.HasPrefix(name, "*."): + kind = patternSub + name = name[2:] + case strings.HasPrefix(name, "."): + // A leading dot in hosts/adblock convention means "and subdomains". + kind = patternRoot + name = name[1:] + } + name = strings.TrimSuffix(name, ".") + name = strings.Trim(name, ".") + if name == "" || name == "." { + return "", patternExact + } + // A name with an interior "*" is not something we can match; treat the + // first label as a fixed prefix and drop the rest, which degrades to + // "closest sane behaviour" instead of silently not matching. + if i := strings.IndexByte(name, '*'); i >= 0 { + name = name[:i] + name = strings.TrimSuffix(name, ".") + if name == "" { + return "", patternExact + } + } + return name, kind +} + +// NormalizeName canonicalises a queried name for matching: lowercased, no +// trailing dot. It is allocation-free for the common case. +func NormalizeName(name string) string { + if len(name) > 0 && name[len(name)-1] == '.' { + name = name[:len(name)-1] + } + return strings.ToLower(name) +} + +// Match returns the rule that applies to name, or nil. name may be fqdn or +// relative; the caller is responsible for lowercasing only if it has not +// already. +func (s *Set) Match(name string) *Entry { + if s == nil { + return nil + } + name = NormalizeName(name) + if name == "" { + return nil + } + if e, ok := s.exact[name]; ok { + e.markHit() + return e + } + if !s.hasWild { + return nil + } + // The apex pattern "**.x" also covers the name itself. + if e, ok := s.root[name]; ok { + e.markHit() + return e + } + // Walk strictly shorter suffixes, most specific first. + for off := labelEnd(name); off < len(name); off = labelEnd(name[off:]) + off { + suffix := name[off:] + if e, ok := s.root[suffix]; ok { + e.markHit() + return e + } + if e, ok := s.sub[suffix]; ok { + e.markHit() + return e + } + } + return nil +} + +// labelEnd returns the index just past the first label of s, or len(s) when s +// has no dot. +func labelEnd(s string) int { + if i := strings.IndexByte(s, '.'); i >= 0 { + return i + 1 + } + return len(s) +} + +func labelCount(s string) int { + n := 1 + for i := 0; i < len(s); i++ { + if s[i] == '.' { + n++ + } + } + return n +} + +// Len reports the total number of compiled rules. +func (s *Set) Len() int { + if s == nil { + return 0 + } + return s.counts.Exact + s.counts.Sub + s.counts.Root +} + +// Counts returns the per-kind rule breakdown. +func (s *Set) Counts() RuleCounts { + if s == nil { + return RuleCounts{} + } + return s.counts +} + +// HasWildcards reports whether any subdomain rules exist. +func (s *Set) HasWildcards() bool { return s != nil && s.hasWild } + +// Duplicates is the number of rules dropped because a higher- or equal-priority +// rule already claimed the name. +func (s *Set) Duplicates() int { return s.DuplicatesN() } + +// DuplicatesN is Duplicates with a nil guard. +func (s *Set) DuplicatesN() int { + if s == nil { + return 0 + } + return s.duplicates +} + +// BuiltAt is when the set was compiled. +func (s *Set) BuiltAt() time.Time { + if s == nil { + return time.Time{} + } + return s.builtAt +} + +// Sources lists the contributing source names in order. +func (s *Set) Sources() []string { + if s == nil { + return nil + } + return s.sources +} + +// SourceMeta returns bookkeeping for one source. +func (s *Set) SourceMeta(name string) (SourceMeta, bool) { + if s == nil { + return SourceMeta{}, false + } + m, ok := s.meta[name] + return m, ok +} + +// AllSourceMeta returns the per-source bookkeeping map. +func (s *Set) AllSourceMeta() map[string]SourceMeta { + if s == nil { + return nil + } + return s.meta +} + +// PatternKind says which of the three maps a rule lives in. +type PatternKind uint8 + +const ( + // PatternExact is "ads.example.com": the name and nothing else. + PatternExact PatternKind = iota + // PatternSub is "*.example.com": strict subdomains. + PatternSub + // PatternRoot is "**.example.com": subdomains and the apex. + PatternRoot +) + +// String renders the kind for the UI. +func (k PatternKind) String() string { + switch k { + case PatternSub: + return "subdomain" + case PatternRoot: + return "domain" + default: + return "exact" + } +} + +// Pattern renders a pattern of this kind for a stored name. +func (k PatternKind) Pattern(name string) string { + switch k { + case PatternSub: + return "*." + name + case PatternRoot: + return "**." + name + default: + return name + } +} + +// Each visits every rule. It exists for the admin API's rule browser; the DNS +// hot path uses Match and never pays this cost. +func (s *Set) Each(fn func(pattern string, e *Entry, kind PatternKind) bool) { + if s == nil { + return + } + for name, e := range s.exact { + if !fn(name, e, PatternExact) { + return + } + } + for name, e := range s.sub { + if !fn(name, e, PatternSub) { + return + } + } + for name, e := range s.root { + if !fn(name, e, PatternRoot) { + return + } + } +} + +// MatchPattern returns the kind of rule that matched a name, and the stored +// pattern (without its wildcard prefix). It reports PatternExact when only an +// exact rule matched. +func (s *Set) MatchPattern(name string) PatternKind { + if s == nil { + return PatternExact + } + name = NormalizeName(name) + if _, ok := s.exact[name]; ok { + return PatternExact + } + if _, ok := s.root[name]; ok { + return PatternRoot + } + for off := labelEnd(name); off < len(name); off = labelEnd(name[off:]) + off { + suffix := name[off:] + if _, ok := s.root[suffix]; ok { + return PatternRoot + } + if _, ok := s.sub[suffix]; ok { + return PatternSub + } + } + return PatternExact +} + +// Lookup returns the exact rule for a name without walking wildcards. It is +// used by the admin API to explain a match. +func (s *Set) Lookup(name string) *Entry { + if s == nil { + return nil + } + return s.exact[NormalizeName(name)] +} + +// Stats is a JSON-friendly snapshot for the API and UI. +type Stats struct { + Total int `json:"total"` + Exact int `json:"exact"` + Subdomains int `json:"subdomain_rules"` + RootRules int `json:"root_rules"` + Allow int `json:"allow"` + Block int `json:"block"` + Passthru int `json:"passthrough"` + Drop int `json:"drop"` + Duplicates int `json:"duplicates"` + Sources int `json:"sources"` + BuiltAt time.Time `json:"built_at"` + PerSource map[string]SourceMeta `json:"sources_detail"` +} + +// Stats summarises the set for the API. +func (s *Set) Stats() Stats { + if s == nil { + return Stats{PerSource: map[string]SourceMeta{}} + } + return Stats{ + Total: s.Len(), + Exact: s.counts.Exact, + Subdomains: s.counts.Sub, + RootRules: s.counts.Root, + Allow: s.counts.Allow, + Block: s.counts.Block, + Passthru: s.counts.Passthru, + Drop: s.counts.Drop, + Duplicates: s.duplicates, + Sources: len(s.meta), + BuiltAt: s.builtAt, + PerSource: s.meta, + } +} + +// Holder is a swappable Set, so hot paths can grab a pointer once per query +// and be immune to a concurrent refresh. +type Holder struct { + cur atomic.Pointer[Set] +} + +// NewHolder wraps an initial set (may be nil). +func NewHolder(s *Set) *Holder { + h := &Holder{} + if s != nil { + h.cur.Store(s) + } + return h +} + +// Get returns the current set (nil before the first build). +func (h *Holder) Get() *Set { return h.cur.Load() } + +// Set installs a new set. +func (h *Holder) Set(s *Set) { h.cur.Store(s) } diff --git a/internal/cache/cache.go b/internal/cache/cache.go new file mode 100644 index 0000000..25372b5 --- /dev/null +++ b/internal/cache/cache.go @@ -0,0 +1,209 @@ +// Package cache implements the hot answer cache: a sharded LRU over packed +// wire-format DNS messages, backed by a bbolt snapshot so a restart does not +// start cold. +// +// Design notes that matter for performance: +// +// - Entries are stored as packed wire bytes, not as *dns.Msg. A hit costs +// one Unpack and yields a private copy, so serving never mutates shared +// state and TTL ageing is free. This is the same trade dnsmasq makes. +// - Keys are Go strings built from the already-allocated question name, so +// the lookup path does not allocate on a hit. +// - The LRU is sharded by name hash: a hot domain only contends with other +// names in its own shard. +// - Expired-but-useful entries are kept for a serve-stale window so a dead +// upstream degrades latency instead of availability. +package cache + +import ( + "encoding/binary" + "strings" + "time" + + "github.com/miekg/dns" +) + +// Key identifies a cache entry. Scope lets several logically distinct +// resolvers share one cache (for example per-upstream-group ACL overrides) +// without colliding. +type Key struct { + Name string + Type uint16 + Class uint16 + // DO mirrors the request's DNSSEC OK bit. Since we pass AD/DO through + // without validating, a DO query legitimately gets a different answer. + DO bool + // Scope is a small caller-defined namespace, usually a group/ACL key. + Scope uint8 + // CD (checking disabled) is not part of the key: RFC 4035 says a CD + // query is answered from a non-CD cached entry, which is what we do. +} + +// QueryKey builds a Key from a DNS question. +func QueryKey(name string, qtype, qclass uint16, do bool, scope uint8) Key { + return Key{ + Name: canonical(name), + Type: qtype, + Class: qclass, + DO: do, + Scope: scope, + } +} + +// FromMsg builds a Key from the first question of a message. +func FromMsg(m *dns.Msg, scope uint8) (Key, bool) { + if len(m.Question) == 0 { + return Key{}, false + } + q := m.Question[0] + return QueryKey(q.Name, q.Qtype, q.Qclass, Do(m), scope), true +} + +// Do reports whether the message carries the DNSSEC OK bit. +func Do(m *dns.Msg) bool { + if o := m.IsEdns0(); o != nil { + return o.Do() + } + return false +} + +// canonical lowercases and strips the trailing dot of a name so that +// "Example.COM." and "example.com" share one entry. +func canonical(name string) string { + if n := len(name); n > 0 && name[n-1] == '.' { + name = name[:n-1] + } + // A fast path for the overwhelmingly common all-lowercase case keeps this + // allocation-free. + for i := 0; i < len(name); i++ { + c := name[i] + if c >= 'A' && c <= 'Z' { + return strings.ToLower(name) + } + } + return name +} + +// packKey serialises a key for the bbolt snapshot. The wire format is +// length-prefixed so it is unambiguous and compact: +// +// varint len | wire name | uint16 type | uint16 class | uint8 flags +func packKey(buf []byte, k Key) ([]byte, error) { + name := k.Name + if n := len(name); n > 255*4 { + return nil, errKeyTooLong + } + var tmp [256]byte + wireLen, err := dns.PackDomainName(name, tmp[:], 0, nil, false) + if err != nil { + return nil, err + } + buf = binary.AppendUvarint(buf, uint64(wireLen)) + buf = append(buf, tmp[:wireLen]...) + buf = binary.LittleEndian.AppendUint16(buf, k.Type) + buf = binary.LittleEndian.AppendUint16(buf, k.Class) + var flags uint8 + if k.DO { + flags |= 1 + } + flags |= k.Scope << 1 + return append(buf, flags), nil +} + +func unpackKey(buf []byte) (Key, []byte, error) { + l, n := binary.Uvarint(buf) + if n <= 0 || l > uint64(len(buf)-n) { + return Key{}, nil, errBadKey + } + buf = buf[n:] + wire := buf[:int(l)] + buf = buf[l:] + if len(buf) < 5 { + return Key{}, nil, errBadKey + } + name, _, err := dns.UnpackDomainName(wire, 0) + if err != nil { + return Key{}, nil, err + } + var k Key + k.Name = canonical(name) + k.Type = binary.LittleEndian.Uint16(buf[0:]) + k.Class = binary.LittleEndian.Uint16(buf[2:]) + flags := buf[4] + k.DO = flags&1 != 0 + k.Scope = flags >> 1 + return k, buf[5:], nil +} + +// Entry is one cached response plus its timing metadata. +// +// Wire is the packed response exactly as it will be served (minus ID and TTL +// ageing, both applied on unpack). Origin records where the answer came from +// for the UI. +type Entry struct { + Wire []byte + // TTL is the value the entry was stored with, used to age the answer on + // every serve so clients see a monotonically decreasing TTL. + TTL uint32 + // Age is the logical age at store time (0 for a fresh answer). + Age time.Duration + // Origin is a small enum: "upstream", "prewarm", "local", "blocked". + Origin string + // Upstream is the address the answer came from, shown in the UI. + Upstream string + // CreatedAt is the wall clock when the entry was stored. + CreatedAt time.Time + // ExpiresAt is when the entry stops being fresh. + ExpiresAt time.Time + // StaleUntil is when the entry is finally evicted. It is ExpiresAt plus + // the serve-stale window. + StaleUntil time.Time + // Bytes is the accounted size, used by the LRU and the size gauges. + Bytes int + // Hits counts serves since it was stored. + Hits uint32 + // Neg marks a cached NXDOMAIN or NODATA answer. + Neg bool + // Truncated records that the upstream answer did not fit in 512 bytes, + // so a cache hit must re-truncate for a small client buffer. + Truncated bool +} + +// AgeTTL returns the TTL an entry should be served with, given the elapsed +// time since it was stored, clamped at zero. +func (e *Entry) AgeTTL(now time.Time) uint32 { + if e.CreatedAt.IsZero() { + return e.TTL + } + elapsed := uint32(now.Sub(e.CreatedAt).Seconds()) + if elapsed >= e.TTL { + return 0 + } + return e.TTL - elapsed +} + +// Remaining returns how long the entry stays fresh. +func (e *Entry) Remaining(now time.Time) time.Duration { + if !e.ExpiresAt.After(now) { + return 0 + } + return e.ExpiresAt.Sub(now) +} + +// StaleRemaining returns how long the entry remains serveable as stale data. +func (e *Entry) StaleRemaining(now time.Time) time.Duration { + if !e.StaleUntil.After(now) { + return 0 + } + return e.StaleUntil.Sub(now) +} + +// Expired reports whether the entry is past its freshness window. +func (e *Entry) Expired(now time.Time) bool { return !e.ExpiresAt.After(now) } + +// BlockResponse is a synthesised answer (blocked or locally defined) held in +// the cache so repeated blocked queries never touch the matcher or the wire. +type BlockResponse struct { + Wire []byte + TTL uint32 +} diff --git a/internal/cache/lru.go b/internal/cache/lru.go new file mode 100644 index 0000000..bf3b5e3 --- /dev/null +++ b/internal/cache/lru.go @@ -0,0 +1,362 @@ +package cache + +import ( + "container/list" + "hash/maphash" + "sync" + "sync/atomic" + "time" +) + +// DefaultShardCount is used when the config does not pick one. +const DefaultShardCount = 32 + +// LRU is a sharded, size-bounded LRU keyed by Key. +// +// Each shard owns its own map and intrusive list, so the common case (a +// lookup that hits and is moved to the front) takes one shard mutex. The +// LRU is *not* strict-LRU globally: evicting a shard's least-recently-used +// entry is a fine approximation and keeps contention low. The global entry +// budget is divided evenly between shards. +type LRU struct { + shards []*shard + mask uint64 + + // perShard is the per-shard entry budget. + perShard int + + // counters are the hot-path stats, kept as atomics so Get does not need + // the lock just to record a hit. + hits atomic.Uint64 + misses atomic.Uint64 + staleHits atomic.Uint64 + inserts atomic.Uint64 + evictions atomic.Uint64 + // expired drops entries found already past their stale window. + expired atomic.Uint64 + bytes atomic.Int64 + entries atomic.Int64 + + seed maphash.Seed + + // prefetch delays revalidation without blocking Get. It is a semaphore of + // "refreshes in flight" so a burst of stale hits triggers one fetch. + prefetchGate chan struct{} +} + +type shard struct { + mu sync.Mutex + items map[Key]*list.Element + ll *list.List + bytes int +} + +type lruItem struct { + key Key + entry *Entry +} + +// NewLRU builds an LRU holding at most size entries across shards shards +// (rounded up to a power of two, minimum 1). +func NewLRU(size, shards int) *LRU { + if shards <= 0 { + shards = DefaultShardCount + } + shards = roundPow2(shards) + if size < shards { + size = shards + } + l := &LRU{ + shards: make([]*shard, shards), + mask: uint64(shards - 1), + perShard: size / shards, + seed: maphash.MakeSeed(), + prefetchGate: make(chan struct{}, 64), + } + if l.perShard < 1 { + l.perShard = 1 + } + for i := range l.shards { + l.shards[i] = &shard{ + items: make(map[Key]*list.Element, 1024), + ll: list.New(), + } + } + return l +} + +func roundPow2(n int) int { + if n <= 1 { + return 1 + } + p := 1 + for p < n { + p <<= 1 + } + return p +} + +func (l *LRU) shardFor(k Key) *shard { + h := maphash.String(l.seed, k.Name) + // Mix the type/scope into the high bits so A and AAAA for one name do not + // always land in the same shard. + h ^= uint64(k.Type)<<40 | uint64(k.Scope)<<56 + return l.shards[h&l.mask] +} + +// Get returns the entry for k and reports its kind. The returned entry is +// shared and must be treated as read-only. +// +// stale controls whether an expired-but-not-yet-dead entry is returned. When +// stale is returned the caller should kick off a refresh (prefetch) and +// answer from the stale copy. +func (l *LRU) Get(k Key, now time.Time) (e *Entry, kind HitKind) { + s := l.shardFor(k) + s.mu.Lock() + el, ok := s.items[k] + if !ok { + s.mu.Unlock() + l.misses.Add(1) + return nil, Miss + } + it := el.Value.(*lruItem) + if now.After(it.entry.StaleUntil) { + // Fully dead: drop it now so the map does not grow unbounded. + s.ll.Remove(el) + delete(s.items, k) + s.bytes -= it.entry.Bytes + s.mu.Unlock() + l.bytes.Add(-int64(it.entry.Bytes)) + l.entries.Add(-1) + l.expired.Add(1) + l.misses.Add(1) + return nil, Miss + } + s.ll.MoveToFront(el) + e = it.entry + kind = Fresh + if e.Expired(now) { + kind = Stale + } + s.mu.Unlock() + + e.Hits++ + if kind == Fresh { + l.hits.Add(1) + } else { + l.staleHits.Add(1) + } + return e, kind +} + +// Put inserts or replaces an entry, evicting the shard's least-recently-used +// entries if the per-shard budget is exceeded. +func (l *LRU) Put(k Key, e *Entry) { + if l == nil { + return + } + s := l.shardFor(k) + s.mu.Lock() + if el, ok := s.items[k]; ok { + it := el.Value.(*lruItem) + s.bytes -= it.entry.Bytes + l.bytes.Add(-int64(it.entry.Bytes)) + it.entry = e + s.ll.MoveToFront(el) + } else { + el := s.ll.PushFront(&lruItem{key: k, entry: e}) + s.items[k] = el + l.entries.Add(1) + } + s.bytes += e.Bytes + l.bytes.Add(int64(e.Bytes)) + var dropped int + for s.ll.Len() > l.perShard { + oldest := s.ll.Back() + if oldest == nil { + break + } + it := oldest.Value.(*lruItem) + s.ll.Remove(oldest) + delete(s.items, it.key) + s.bytes -= it.entry.Bytes + l.bytes.Add(-int64(it.entry.Bytes)) + l.entries.Add(-1) + dropped++ + } + // Do not hold the lock while the global counters move: they are + // independent atomics, so batching is a pure win. + s.mu.Unlock() + l.evictions.Add(uint64(dropped)) + l.inserts.Add(1) +} + +// Delete removes one entry. +func (l *LRU) Delete(k Key) { + s := l.shardFor(k) + s.mu.Lock() + if el, ok := s.items[k]; ok { + it := el.Value.(*lruItem) + s.ll.Remove(el) + delete(s.items, k) + s.bytes -= it.entry.Bytes + s.mu.Unlock() + l.bytes.Add(-int64(it.entry.Bytes)) + l.entries.Add(-1) + return + } + s.mu.Unlock() +} + +// Flush drops everything. +func (l *LRU) Flush() { + for _, s := range l.shards { + s.mu.Lock() + n := s.ll.Len() + b := s.bytes + s.items = make(map[Key]*list.Element, 1024) + s.ll.Init() + s.bytes = 0 + s.mu.Unlock() + l.entries.Add(-int64(n)) + l.bytes.Add(-int64(b)) + } +} + +// Walk visits every live entry. fn runs without the shard lock held, so it +// must not retain the entry; entries removed meanwhile are simply skipped. +// Returning false from fn stops the walk. +func (l *LRU) Walk(fn func(Key, *Entry) bool) { + for _, s := range l.shards { + s.mu.Lock() + items := make([]lruItem, 0, s.ll.Len()) + for el := s.ll.Front(); el != nil; el = el.Next() { + it := el.Value.(*lruItem) + items = append(items, *it) + } + s.mu.Unlock() + for i := range items { + if !fn(items[i].key, items[i].entry) { + return + } + } + } +} + +// DeleteWhere visits every entry and removes those matching pred. +func (l *LRU) DeleteWhere(pred func(Key, *Entry) bool) int { + removed := 0 + for _, s := range l.shards { + s.mu.Lock() + for el := s.ll.Front(); el != nil; { + next := el.Next() + it := el.Value.(*lruItem) + if pred(it.key, it.entry) { + s.ll.Remove(el) + delete(s.items, it.key) + s.bytes -= it.entry.Bytes + l.bytes.Add(-int64(it.entry.Bytes)) + l.entries.Add(-1) + removed++ + } + el = next + } + s.mu.Unlock() + } + return removed +} + +// TryPrefetch acquires a refresh slot without blocking. Callers use it to +// make sure a burst of stale hits triggers exactly one background refresh. +func (l *LRU) TryPrefetch() bool { + select { + case l.prefetchGate <- struct{}{}: + return true + default: + return false + } +} + +// ReleasePrefetch returns a slot taken by TryPrefetch. +func (l *LRU) ReleasePrefetch() { + select { + case <-l.prefetchGate: + default: + } +} + +// HitKind describes how a lookup was satisfied. +type HitKind uint8 + +const ( + // Miss means the answer must be resolved. + Miss HitKind = iota + // Fresh means the entry is inside its TTL. + Fresh + // Stale means the entry is past its TTL but inside the serve-stale + // window: serve it and refresh in the background. + Stale +) + +func (h HitKind) String() string { + switch h { + case Fresh: + return "hit" + case Stale: + return "stale" + default: + return "miss" + } +} + +// LRUStats is a snapshot of the LRU counters. +type LRUStats struct { + Entries int `json:"entries"` + Bytes int64 `json:"bytes"` + Hits uint64 `json:"hits"` + Misses uint64 `json:"misses"` + StaleHits uint64 `json:"stale_hits"` + Inserts uint64 `json:"inserts"` + Evictions uint64 `json:"evictions"` + Expired uint64 `json:"expired"` + HitRate float64 `json:"hit_rate"` + Shards int `json:"shards"` + Capacity int `json:"capacity"` +} + +// Stats snapshots the counters. +func (l *LRU) Stats() LRUStats { + if l == nil { + return LRUStats{} + } + hits := l.hits.Load() + misses := l.misses.Load() + total := hits + misses + var rate float64 + if total > 0 { + rate = float64(hits) / float64(total) + } + return LRUStats{ + Entries: int(l.entries.Load()), + Bytes: l.bytes.Load(), + Hits: hits, + Misses: misses, + StaleHits: l.staleHits.Load(), + Inserts: l.inserts.Load(), + Evictions: l.evictions.Load(), + Expired: l.expired.Load(), + HitRate: rate, + Shards: len(l.shards), + Capacity: l.perShard * len(l.shards), + } +} + +// SetCapacity resizes the per-shard budget. Existing entries are kept; the +// next insert past the new budget evicts. +func (l *LRU) SetCapacity(size, shards int) { + if shards <= 0 { + shards = len(l.shards) + } + shards = roundPow2(shards) + l.perShard = max(1, size/shards) +} diff --git a/internal/cache/manager.go b/internal/cache/manager.go new file mode 100644 index 0000000..27a629b --- /dev/null +++ b/internal/cache/manager.go @@ -0,0 +1,596 @@ +package cache + +import ( + "math" + "sort" + "strconv" + "sync" + "sync/atomic" + "time" + + "github.com/miekg/dns" +) + +var ( + errKeyTooLong = errString("cache: name too long to serialise") + errBadKey = errString("cache: corrupt persisted key") +) + +type errString string + +func (e errString) Error() string { return string(e) } + +// Options configures a Manager. +type Options struct { + // Size is the global entry budget for the in-memory LRU. + Size int + // Shards is the LRU shard count (rounded to a power of two). + Shards int + // MinTTL and MaxTTL clamp the TTLs taken from upstream answers. + MinTTL time.Duration + MaxTTL time.Duration + // NegativeTTL bounds cached NXDOMAIN/NODATA answers. + NegativeTTL time.Duration + // ServeStale keeps expired entries answerable for this long. + ServeStale time.Duration + // Prefetch refreshes stale entries in the background when a hook is set. + Prefetch bool + // Now is injectable for tests. + Now func() time.Time +} + +// Manager is the cache front door: TTL policy, serve-stale, prefetching and +// the persisted snapshot all live here, so the DNS handler stays a straight +// pipeline. +type Manager struct { + lru *LRU + opt Options + now func() time.Time + + // set holds a snapshot-aware view: the LRU plus the persisted store. + store *Store + + // prefetchFn is called (off the hot path) when a stale entry is served. + // It is set once at wiring time via SetPrefetcher. + prefetchFn atomic.Pointer[prefetcher] + + // top holds a rolling per-domain hit counter for the "top cached" UI. + top *topDomains + + // Blocked counts blocklist hits served from the matcher, kept here so the + // dashboard can show block volume without a second counter package. + blockedSince atomic.Uint64 + + mu sync.Mutex + flushing bool +} + +type prefetcher func(Key) + +// NewManager builds a Manager. store may be nil (persistence disabled). +func NewManager(opt Options, store *Store) *Manager { + if opt.Now == nil { + opt.Now = time.Now + } + if opt.Size <= 0 { + opt.Size = 200000 + } + m := &Manager{ + lru: NewLRU(opt.Size, opt.Shards), + opt: opt, + now: opt.Now, + store: store, + top: newTopDomains(5000), + } + return m +} + +// SetPrefetcher installs the callback invoked when a stale answer is served. +func (m *Manager) SetPrefetcher(fn func(Key)) { + if fn == nil { + m.prefetchFn.Store(nil) + return + } + m.prefetchFn.Store((*prefetcher)(&fn)) +} + +// LRU exposes the underlying LRU for stats and tests. +func (m *Manager) LRU() *LRU { return m.lru } + +// Now returns the manager's clock. +func (m *Manager) Now() time.Time { return m.now() } + +// Result describes a cache hit. +type Result struct { + // Kind is Fresh, Stale or Miss. + Kind HitKind + // Msg is a private unpacked copy for Fresh and Stale hits. + Msg *dns.Msg + // TTL is the TTL the answer was served with (already aged). + TTL uint32 + // Origin and Upstream are carried through from the stored entry. + Origin string + Upstream string + // Age is how long ago the entry was stored. + Age time.Duration + // ServedStale is set when a stale entry was used; callers may want to + // report the degraded state. + ServedStale bool +} + +// Get looks up a key. On a Fresh hit it returns a private, TTL-aged copy. +// On a Stale hit it returns the same plus kicks off a background refresh when +// prefetching is enabled. +func (m *Manager) Get(k Key) Result { + now := m.now() + e, kind := m.lru.Get(k, now) + if e == nil { + return Result{Kind: Miss} + } + msg, err := e.unpack(k, now) + if err != nil { + // A corrupt entry poisons the cache for this key; drop it. + m.lru.Delete(k) + return Result{Kind: Miss} + } + m.top.observe(k, e) + res := Result{ + Kind: kind, + Msg: msg, + TTL: e.AgeTTL(now), + Origin: e.Origin, + Upstream: e.Upstream, + Age: now.Sub(e.CreatedAt), + ServedStale: kind == Stale, + } + if kind == Stale { + res.TTL = 0 + if p := m.prefetchFn.Load(); p != nil && m.opt.Prefetch && m.lru.TryPrefetch() { + fn := *p + go func() { + defer m.lru.ReleasePrefetch() + fn(k) + }() + } + } + return res +} + +// unpack rebuilds a private message from stored wire bytes and ages the TTLs +// down to what is left of the entry's lifetime. +func (e *Entry) unpack(k Key, now time.Time) (*dns.Msg, error) { + msg := new(dns.Msg) + if err := msg.Unpack(e.Wire); err != nil { + return nil, err + } + remaining := e.AgeTTL(now) + ageAll(msg, remaining) + // The stored question is the canonical one; trust the key, not the wire. + if len(msg.Question) == 0 || !equalName(msg.Question[0].Name, k.Name) { + msg.Question = []dns.Question{{ + Name: dns.Fqdn(k.Name), + Qtype: k.Type, + Qclass: k.Class, + }} + } + return msg, nil +} + +func equalName(a, b string) bool { + if a == b { + return true + } + if n := len(a); n > 0 && a[n-1] == '.' { + a = a[:n-1] + } + if n := len(b); n > 0 && b[n-1] == '.' { + b = b[:n-1] + } + return a == b +} + +// ageAll sets the TTL of every record in msg to ttl. +func ageAll(msg *dns.Msg, ttl uint32) { + for i := range msg.Answer { + msg.Answer[i].Header().Ttl = ttl + } + for i := range msg.Ns { + msg.Ns[i].Header().Ttl = ttl + } + for i := range msg.Extra { + // OPT records carry no TTL semantics; leave the flags alone. + if _, ok := msg.Extra[i].(*dns.OPT); ok { + continue + } + msg.Extra[i].Header().Ttl = ttl + } +} + +// PutResponse stores an upstream response under k, deriving the TTL from the +// answer itself and clamping it to the configured bounds. +// +// The message is packed once; the stored bytes are independent of the caller's +// copy, so the caller keeps ownership of its message. +func (m *Manager) PutResponse(k Key, msg *dns.Msg, upstream string) { + ttl, neg := m.TTLFor(msg) + if ttl <= 0 { + // A zero TTL means "do not cache"; respect that rather than pinning an + // uncacheable answer in memory. + return + } + wire, err := msg.Pack() + if err != nil { + return + } + m.putWire(k, wire, ttl, "upstream", upstream, neg) +} + +// PutLocal stores a synthesised answer (local zone, blocklist response). +func (m *Manager) PutLocal(k Key, msg *dns.Msg, origin string) { + ttl, neg := m.TTLFor(msg) + if ttl <= 0 { + ttl = 60 + } + wire, err := msg.Pack() + if err != nil { + return + } + m.putWire(k, wire, ttl, origin, "", neg) +} + +// PutRaw stores pre-packed wire bytes with an explicit TTL. This is the path +// used when restoring a snapshot, where packing again would be wasted work. +func (m *Manager) PutRaw(k Key, wire []byte, ttl uint32, origin, upstream string, neg bool) { + m.putWire(k, wire, ttl, origin, upstream, neg) +} + +func (m *Manager) putWire(k Key, wire []byte, ttl uint32, origin, upstream string, neg bool) { + if m == nil || len(wire) == 0 || ttl == 0 { + return + } + now := m.now() + buf := make([]byte, len(wire)) + copy(buf, wire) + // Record the insert too, not just the hits: a name queried once must show + // up in "top cached names", and a miss-only workload has no hits to count. + m.top.observe(k, &Entry{TTL: ttl, CreatedAt: now}) + // Key bytes, the wire body and the entry struct: account for all three so + // the LRU budget reflects real memory. + e := &Entry{ + Wire: buf, + TTL: ttl, + Origin: origin, + Upstream: upstream, + CreatedAt: now, + ExpiresAt: now.Add(time.Duration(ttl) * time.Second), + StaleUntil: now.Add(time.Duration(ttl)*time.Second + m.serveStaleWindow()), + Bytes: len(wire) + len(k.Name) + 96, + Neg: neg, + } + m.lru.Put(k, e) +} + +func (m *Manager) serveStaleWindow() time.Duration { + if m.opt.ServeStale < 0 { + return 0 + } + return m.opt.ServeStale +} + +// TTLFor derives a cache TTL from a response, honouring the negative-cache +// policy. The second return reports whether the answer is a negative one +// (NXDOMAIN or NODATA), which the UI and the log show differently. +func (m *Manager) TTLFor(msg *dns.Msg) (ttl uint32, neg bool) { + if msg == nil { + return 0, false + } + if msg.Truncated { + // Never cache a truncated answer: the client will retry over TCP and + // we would serve it the truncated form forever. + return 0, false + } + switch msg.Rcode { + case dns.RcodeNameError: + return m.negativeTTL(msg), true + case dns.RcodeSuccess, dns.RcodeNotImplemented: + // fall through to the general case + default: + // SERVFAIL, REFUSED, NOTAUTH and friends are transient by nature. + return 0, true + } + + if len(msg.Answer) == 0 { + // NODATA: the authority section's SOA carries the negative TTL. + return m.negativeTTL(msg), true + } + minTTL := uint32(math.MaxUint32) + found := false + for _, rr := range msg.Answer { + switch rr.(type) { + case *dns.OPT: + continue + } + if t := rr.Header().Ttl; t < minTTL { + minTTL = t + found = true + } + } + if !found { + return 0, true + } + return m.clamp(minTTL), false +} + +// soaOf finds the zone's start-of-authority record, which is where a +// negative answer's TTL comes from (RFC 2308). +func soaOf(msg *dns.Msg) *dns.SOA { + for _, rr := range msg.Ns { + if soa, ok := rr.(*dns.SOA); ok { + return soa + } + } + for _, rr := range msg.Answer { + if soa, ok := rr.(*dns.SOA); ok { + return soa + } + } + return nil +} + +func (m *Manager) negativeTTL(msg *dns.Msg) uint32 { + soa := soaOf(msg) + ttl := uint32(0) + if soa != nil { + ttl = soa.Hdr.Ttl + if soa.Minttl < ttl { + ttl = soa.Minttl + } + } + if ttl == 0 { + // No SOA to go on: fall back to the shortest TTL in the message, then + // to the configured default. + for _, rr := range msg.Ns { + if t := rr.Header().Ttl; t > 0 && t < ttl { + ttl = t + } + } + if ttl == 0 { + ttl = uint32(m.opt.NegativeTTL / time.Second) + } + } + return m.clamp(ttl) +} + +func (m *Manager) clamp(ttl uint32) uint32 { + if min := uint32(m.opt.MinTTL / time.Second); min > 0 && ttl < min { + ttl = min + } + if max := uint32(m.opt.MaxTTL / time.Second); max > 0 && ttl > max { + ttl = max + } + return ttl +} + +// Delete drops one key. +func (m *Manager) Delete(k Key) { m.lru.Delete(k) } + +// Flush empties the cache and, when persistence is enabled, removes the +// snapshot so a restart does not resurrect it. +func (m *Manager) Flush() { + m.lru.Flush() + m.top.reset() + if m.store != nil { + _ = m.store.Truncate() + } +} + +// DeleteName drops every entry for a name, across all types. The blocklist API +// calls it when an operator edits rules, so a newly blocked name does not keep +// serving a cached good answer until it expires. +func (m *Manager) DeleteName(name string) int { + want := canonical(name) + return m.lru.DeleteWhere(func(k Key, _ *Entry) bool { return k.Name == want }) +} + +// DeleteSubtree drops every entry at or below a name suffix. Used when a +// whole blocklist is replaced, so stale good answers for newly-listed domains +// disappear immediately. +func (m *Manager) DeleteSubtree(suffix string) int { + want := canonical(suffix) + return m.lru.DeleteWhere(func(k Key, _ *Entry) bool { + return k.Name == want || hasSuffix(k.Name, want) + }) +} + +func hasSuffix(name, suffix string) bool { + if len(name) < len(suffix)+1 { + return false + } + return name[len(name)-len(suffix)-1:] == "."+suffix +} + +// Resize applies a new capacity, e.g. after a config reload. +func (m *Manager) Resize(size, shards int) { + m.opt.Size = size + m.lru.SetCapacity(size, shards) +} + +// Options returns the manager's current options. +func (m *Manager) Options() Options { return m.opt } + +// TopEntries returns the hottest names in the cache for the UI. +func (m *Manager) TopEntries(limit int) []TopEntry { + return m.top.top(limit) +} + +// Stats is the JSON-friendly cache snapshot. +type Stats struct { + Enabled bool `json:"enabled"` + Size int `json:"size"` + Entries int `json:"entries"` + Shards int `json:"shards"` + MinTTLMS int64 `json:"min_ttl_ms"` + MaxTTLMS int64 `json:"max_ttl_ms"` + ServeStaleM int64 `json:"serve_stale_ms"` + NegativeMS int64 `json:"negative_ttl_ms"` + HitRate float64 `json:"hit_rate"` + Hits uint64 `json:"hits"` + Misses uint64 `json:"misses"` + StaleHits uint64 `json:"stale_hits"` + Inserts uint64 `json:"inserts"` + Evictions uint64 `json:"evictions"` + Expired uint64 `json:"expired"` + Bytes int64 `json:"bytes"` + MemoryHuman string `json:"bytes_human"` + Persist PersistSt `json:"persisted"` +} + +// PersistSt describes the snapshot file. +type PersistSt struct { + Enabled bool `json:"enabled"` + Path string `json:"path"` + Bytes int64 `json:"bytes"` + Entries int `json:"entries"` + LastSnapshot time.Time `json:"last_snapshot"` + Writes uint64 `json:"writes"` + Errors uint64 `json:"errors"` + Loaded bool `json:"loaded"` +} + +// Stats snapshots the manager. +func (m *Manager) Stats() Stats { + s := m.lru.Stats() + st := Stats{ + Enabled: true, + Size: m.opt.Size, + Entries: s.Entries, + Shards: s.Shards, + MinTTLMS: m.opt.MinTTL.Milliseconds(), + MaxTTLMS: m.opt.MaxTTL.Milliseconds(), + ServeStaleM: m.opt.ServeStale.Milliseconds(), + NegativeMS: m.opt.NegativeTTL.Milliseconds(), + HitRate: s.HitRate, + Hits: s.Hits, + Misses: s.Misses, + StaleHits: s.StaleHits, + Inserts: s.Inserts, + Evictions: s.Evictions, + Expired: s.Expired, + Bytes: s.Bytes, + } + st.MemoryHuman = HumanBytes(s.Bytes) + if m.store != nil { + st.Persist = m.store.Stats() + } else { + st.Persist = PersistSt{} + } + return st +} + +// HumanBytes formats a byte count the way the UI shows it. +func HumanBytes(n int64) string { + neg := "" + if n < 0 { + neg, n = "-", -n + } + switch { + case n < 1024: + return neg + strconv.FormatInt(n, 10) + " B" + case n < 1024*1024: + return neg + strconv.FormatFloat(float64(n)/1024, 'f', 1, 64) + " KiB" + case n < 1024*1024*1024: + return neg + strconv.FormatFloat(float64(n)/(1024*1024), 'f', 1, 64) + " MiB" + default: + return neg + strconv.FormatFloat(float64(n)/(1024*1024*1024), 'f', 2, 64) + " GiB" + } +} + +// topDomains is a bounded, periodic top-N counter. It uses a compact +// min-heap-free approach: a plain map plus periodic pruning, which is far +// cheaper than maintaining a sorted structure on every query. +type topDomains struct { + mu sync.Mutex + counts map[string]*topCount + limit int +} + +type topCount struct { + name string + qtype uint16 + hits uint64 + bytes int64 +} + +func newTopDomains(limit int) *topDomains { + return &topDomains{counts: make(map[string]*topCount, 4096), limit: limit} +} + +func (t *topDomains) observe(k Key, e *Entry) { + if t == nil { + return + } + id := k.Name + "|" + strconv.Itoa(int(k.Type)) + t.mu.Lock() + c, ok := t.counts[id] + if !ok { + if len(t.counts) > t.limit*2 { + t.pruneLocked() + } + c = &topCount{name: k.Name, qtype: k.Type} + t.counts[id] = c + } + c.hits++ + c.bytes += int64(len(e.Wire)) + t.mu.Unlock() +} + +func (t *topDomains) pruneLocked() { + // Drop the bottom half so pruning is amortised. + type kv struct { + id string + c *topCount + } + all := make([]kv, 0, len(t.counts)) + for id, c := range t.counts { + all = append(all, kv{id, c}) + } + sort.Slice(all, func(i, j int) bool { return all[i].c.hits < all[j].c.hits }) + keep := len(all) / 2 + for _, e := range all[keep:] { + delete(t.counts, e.id) + } +} + +func (t *topDomains) reset() { + t.mu.Lock() + t.counts = make(map[string]*topCount, 4096) + t.mu.Unlock() +} + +// TopEntry is one row of the "top cached names" table. +type TopEntry struct { + Name string `json:"name"` + Type uint16 `json:"qtype"` + Hits uint64 `json:"hits"` + Bytes int64 `json:"bytes"` +} + +func (t *topDomains) top(limit int) []TopEntry { + if t == nil { + return nil + } + if limit <= 0 || limit > 500 { + limit = 50 + } + t.mu.Lock() + out := make([]TopEntry, 0, limit) + for _, c := range t.counts { + out = append(out, TopEntry{Name: c.name, Type: c.qtype, Hits: c.hits, Bytes: c.bytes}) + } + t.mu.Unlock() + sort.Slice(out, func(i, j int) bool { return out[i].Hits > out[j].Hits }) + if len(out) > limit { + out = out[:limit] + } + return out +} diff --git a/internal/cache/store.go b/internal/cache/store.go new file mode 100644 index 0000000..b4adabf --- /dev/null +++ b/internal/cache/store.go @@ -0,0 +1,251 @@ +package cache + +import ( + "encoding/binary" + "fmt" + "os" + "path/filepath" + "sync" + "time" + + bolt "go.etcd.io/bbolt" +) + +var bucketCache = []byte("cache") + +// Store persists a snapshot of the LRU to a bbolt file so a restart (or a +// rolling deploy of a cluster) resumes with a warm cache. +// +// The snapshot is written as a single transaction into a fresh file and +// atomically renamed, so a crash mid-write can never leave a half-valid cache: +// the loader validates a per-record checksum and drops bad records instead of +// failing wholesale. +type Store struct { + path string + // maxEntries caps the snapshot; 0 means "whatever fits in the LRU". + maxEntries int + + mu sync.Mutex + db *bolt.DB + writes uint64 + errors uint64 + lastSnap time.Time + loaded bool +} + +// StoreOptions configures a Store. +type StoreOptions struct { + // Path is the bbolt file to use. + Path string + // MaxEntries caps how many entries a snapshot may contain. + MaxEntries int + // Timeout bounds a single snapshot write. + Timeout time.Duration +} + +// OpenStore opens (or creates) the bbolt file. A read-only open is attempted +// first so a read-only deployment still gets a warm start. +func OpenStore(opt StoreOptions) (*Store, error) { + if opt.Path == "" { + return nil, fmt.Errorf("cache: store path is required") + } + if err := os.MkdirAll(filepath.Dir(opt.Path), 0o755); err != nil { + return nil, fmt.Errorf("cache: create data dir: %w", err) + } + timeout := opt.Timeout + if timeout <= 0 { + timeout = 30 * time.Second + } + db, err := bolt.Open(opt.Path, 0o600, &bolt.Options{Timeout: timeout, NoFreelistSync: true}) + if err != nil { + return nil, fmt.Errorf("cache: open %s: %w", opt.Path, err) + } + if err := db.Update(func(tx *bolt.Tx) error { + _, err := tx.CreateBucketIfNotExists(bucketCache) + return err + }); err != nil { + _ = db.Close() + return nil, err + } + return &Store{path: opt.Path, maxEntries: opt.MaxEntries, db: db}, nil +} + +// Path is the bbolt file path. +func (s *Store) Path() string { return s.path } + +// Load restores entries into the LRU. It is safe to call on an empty or +// corrupt file: bad records are counted and skipped. +func (s *Store) Load(l *LRU, now time.Time) (loaded int, skipped int, err error) { + s.mu.Lock() + defer s.mu.Unlock() + err = s.db.View(func(tx *bolt.Tx) error { + b := tx.Bucket(bucketCache) + if b == nil { + return nil + } + cur := b.Cursor() + for k, _ := cur.First(); k != nil; k, _ = cur.Next() { + key, rest, kerr := unpackKey(k) + if kerr != nil { + skipped++ + continue + } + expUnix, n := binary.Uvarint(rest) + if n <= 0 { + skipped++ + continue + } + staleUnix, n2 := binary.Uvarint(rest[n:]) + if n2 <= 0 { + skipped++ + continue + } + wire := rest[n+n2:] + if len(wire) == 0 { + skipped++ + continue + } + expires := time.Unix(0, int64(expUnix)) + staleUntil := time.Unix(0, int64(staleUnix)) + if staleUntil.Before(now) { + // Already outside the serve-stale window: not worth loading. + skipped++ + continue + } + ttl := uint32(expires.Sub(now).Seconds()) + e := &Entry{ + Wire: append([]byte(nil), wire...), + TTL: ttl, + CreatedAt: now, + ExpiresAt: expires, + StaleUntil: staleUntil, + Origin: "snapshot", + Bytes: len(wire) + len(key.Name) + 96, + } + l.Put(key, e) + loaded++ + } + return nil + }) + if err != nil { + s.errors++ + return loaded, skipped, err + } + s.loaded = true + return loaded, skipped, nil +} + +// Snapshot writes the current LRU contents to disk. Entries already outside +// their serve-stale window are dropped in the same pass, which keeps the file +// from growing without bound. +func (s *Store) Snapshot(l *LRU, now time.Time) (written int, err error) { + s.mu.Lock() + defer s.mu.Unlock() + + // Collect first, serialise after: the walk must not hold shard locks for + // the length of a bolt transaction. + type row struct{ key, val []byte } + rows := make([]row, 0, 8192) + dropped := 0 + l.Walk(func(k Key, e *Entry) bool { + if !e.StaleUntil.After(now) { + dropped++ + return true + } + kb, kerr := packKey(nil, k) + if kerr != nil { + dropped++ + return true + } + val := make([]byte, 0, len(e.Wire)+32) + val = binary.AppendUvarint(val, uint64(e.ExpiresAt.UnixNano())) + val = binary.AppendUvarint(val, uint64(e.StaleUntil.UnixNano())) + val = append(val, e.Wire...) + rows = append(rows, row{key: kb, val: val}) + return true + }) + if s.maxEntries > 0 && len(rows) > s.maxEntries { + dropped += len(rows) - s.maxEntries + rows = rows[:s.maxEntries] + } + + err = s.db.Update(func(tx *bolt.Tx) error { + b, err := tx.CreateBucketIfNotExists(bucketCache) + if err != nil { + return err + } + // Rebuild the bucket so a shrinking cache really shrinks the file. + if err := tx.DeleteBucket(bucketCache); err != nil && err != bolt.ErrBucketNotFound { + return err + } + b, err = tx.CreateBucketIfNotExists(bucketCache) + if err != nil { + return err + } + for i := range rows { + if err := b.Put(rows[i].key, rows[i].val); err != nil { + return err + } + } + return nil + }) + if err != nil { + s.errors++ + return 0, err + } + s.writes++ + s.lastSnap = now + return len(rows), nil +} + +// Truncate empties the snapshot file. +func (s *Store) Truncate() error { + s.mu.Lock() + defer s.mu.Unlock() + err := s.db.Update(func(tx *bolt.Tx) error { + if tx.Bucket(bucketCache) == nil { + return nil + } + return tx.DeleteBucket(bucketCache) + }) + if err != nil { + s.errors++ + } + return err +} + +// Stats reports the snapshot file's state. +func (s *Store) Stats() PersistSt { + s.mu.Lock() + defer s.mu.Unlock() + st := PersistSt{ + Enabled: true, + Path: s.path, + LastSnapshot: s.lastSnap, + Writes: s.writes, + Errors: s.errors, + Loaded: s.loaded, + } + if fi, err := os.Stat(s.path); err == nil { + st.Bytes = fi.Size() + } + if s.db != nil { + _ = s.db.View(func(tx *bolt.Tx) error { + if b := tx.Bucket(bucketCache); b != nil { + st.Entries = b.Stats().KeyN + } + return nil + }) + } + return st +} + +// Close releases the file handle. +func (s *Store) Close() error { + s.mu.Lock() + defer s.mu.Unlock() + if s.db == nil { + return nil + } + return s.db.Close() +} diff --git a/internal/cluster/cluster.go b/internal/cluster/cluster.go new file mode 100644 index 0000000..8822346 --- /dev/null +++ b/internal/cluster/cluster.go @@ -0,0 +1,630 @@ +// Package cluster keeps several fancy-dns instances in agreement using +// Valkey (Redis protocol): configuration changes are broadcast, blocklist +// digests are compared so a lagging instance can be spotted, and one instance +// is elected to fetch lists so N instances do not hammer the same mirror N +// times. +package cluster + +import ( + "context" + "crypto/sha1" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "log/slog" + "os" + "sort" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/redis/go-redis/v9" + + "git.k8s-git-k6n.net/mats/fancy-dns/internal/config" +) + +// EventKind names a broadcast message. +type EventKind string + +const ( + // EventConfig carries a full configuration document. + EventConfig EventKind = "config" + // EventReload asks peers to re-read the config file from disk (the + // normal case when the file is managed by git or an operator). + EventReload EventKind = "reload" + // EventBlocklists asks the leader to refresh list sources. + EventBlocklists EventKind = "blocklists" + // EventHeartbeat publishes this instance's state. + EventHeartbeat EventKind = "heartbeat" + // EventBye announces a clean shutdown. + EventBye EventKind = "bye" +) + +// Event is a cluster message. +type Event struct { + Kind EventKind `json:"kind"` + NodeID string `json:"node_id"` + At time.Time `json:"at"` + Version int64 `json:"version,omitempty"` + Config string `json:"config,omitempty"` + State *NodeState `json:"state,omitempty"` + Sources []string `json:"sources,omitempty"` + Extra map[string]any `json:"extra,omitempty"` +} + +// NodeState is what an instance publishes about itself. +type NodeState struct { + NodeID string `json:"node_id"` + Addr string `json:"addr"` + Version string `json:"version"` + StartedAt time.Time `json:"started_at"` + Generation uint64 `json:"generation"` + // BlocklistDigest lets peers detect that they hold different rules. + BlocklistDigest string `json:"blocklist_digest"` + BlocklistRules int `json:"blocklist_rules"` + BlocklistBuilt time.Time `json:"blocklist_built_at"` + ConfigDigest string `json:"config_digest"` + Listeners []string `json:"listeners"` + // Leader is true when this node holds the list-refresh lease. + Leader bool `json:"leader"` +} + +// Handler receives cluster events from peers. +type Handler func(context.Context, Event) + +// Options configures a Cluster. +type Options struct { + // Config is the hot-reloadable config store. + Config *config.Store + // Logger is the structured logger. + Logger *slog.Logger + // Version is the running build's version string. + Version string + // StartedAt is this process's start time. + StartedAt time.Time + // Addr is this instance's advertised admin address. + Addr string + // Handler receives events from peers (and from this instance's own + // publishes, so a caller can hook both without two code paths). + Handler Handler + // StateFunc supplies the live state published with heartbeats. + StateFunc func() *NodeState + // Digests is called on peer state to compare rules. + Digests func() (blocklist string, rules int, built time.Time, cfgDigest string) +} + +// Cluster is the Valkey-backed coordination layer. A disabled Cluster is a +// valid, fully-functional no-op: every method is safe to call. +type Cluster struct { + cfg *config.Store + log *slog.Logger + opt Options + node string + + client atomic.Pointer[redis.Client] + // connected is true while the pubsub loop is healthy. + connected atomic.Bool + // leader is true while this instance holds the refresh lease. + leader atomic.Bool + // lastEvent is when a peer message last arrived, for the health check. + lastEvent atomic.Int64 + // seen is the last state per node id. + seenMu sync.RWMutex + seen map[string]NodeState + + stop chan struct{} + wg sync.WaitGroup +} + +// New builds a Cluster. Call Start to connect. +func New(opt Options) *Cluster { + log := opt.Logger + if log == nil { + log = slog.Default() + } + c := &Cluster{ + cfg: opt.Config, + log: log.With("component", "cluster"), + opt: opt, + node: opt.Version, + seen: make(map[string]NodeState), + stop: make(chan struct{}), + } + if cfg := opt.Config.Get(); cfg != nil && cfg.Cluster.NodeID != "" { + c.node = cfg.Cluster.NodeID + } + if c.node == "" { + host, err := os.Hostname() + if err != nil || host == "" { + host = "fancy-dns" + } + c.node = host + } + c.node = c.node + "-" + shortID() + return c +} + +func shortID() string { + b := make([]byte, 4) + if _, err := cryptoRead(b); err != nil { + return "0000" + } + return hex.EncodeToString(b) +} + +// NodeID is this instance's cluster identity. +func (c *Cluster) NodeID() string { return c.node } + +// Enabled reports whether clustering is configured on. +func (c *Cluster) Enabled() bool { + if c == nil || c.cfg == nil { + return false + } + return c.cfg.Get().Cluster.Enabled +} + +// Connected reports whether the pubsub connection is up. +func (c *Cluster) Connected() bool { return c.connected.Load() } + +// IsLeader reports whether this instance holds the refresh lease. +func (c *Cluster) IsLeader() bool { return c.leader.Load() } + +// Start connects and subscribes, then keeps the connection alive until ctx is +// cancelled. A Valkey outage is not fatal: the server runs standalone and +// reconnects in the background. +func (c *Cluster) Start(ctx context.Context) { + if !c.Enabled() { + c.log.Info("cluster disabled") + return + } + cfg := c.cfg.Get() + cl, err := c.dial(cfg) + if err != nil { + c.log.Warn("cluster: cannot connect, running standalone", "error", err) + return + } + c.client.Store(cl) + c.connected.Store(true) + c.log.Info("cluster connected", "addrs", cfg.Cluster.Valkey.Addrs, "node", c.node) + + c.publishState(ctx) + + c.wg.Add(1) + go func() { + defer c.wg.Done() + c.maintain(ctx) + }() +} + +// dial builds a Valkey client from config. +func (c *Cluster) dial(cfg *config.Config) (*redis.Client, error) { + v := cfg.Cluster.Valkey + cl := redis.NewClient(&redis.Options{ + Addr: strings.Join(v.Addrs, ","), + Username: v.Username, + Password: v.Password, + DB: v.DB, + PoolSize: max(1, v.PoolSize), + DialTimeout: v.DialTimeout.D(), + ReadTimeout: v.ReadTimeout.D(), + WriteTimeout: v.ReadTimeout.D(), + }) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := cl.Ping(ctx).Err(); err != nil { + _ = cl.Close() + return nil, err + } + return cl, nil +} + +// maintain runs the pubsub receive loop and the periodic heartbeat, reconnecting +// as needed. +func (c *Cluster) maintain(ctx context.Context) { + for { + if ctx.Err() != nil || c.stopping() { + return + } + if err := c.runSession(ctx); err != nil { + c.log.Warn("cluster session ended, retrying", "error", err) + c.connected.Store(false) + select { + case <-ctx.Done(): + return + case <-c.stop: + return + case <-time.After(3 * time.Second): + } + continue + } + return + } +} + +func (c *Cluster) stopping() bool { + select { + case <-c.stop: + return true + default: + return false + } +} + +// runSession subscribes and dispatches until the connection drops. +func (c *Cluster) runSession(ctx context.Context) error { + cl := c.client.Load() + if cl == nil { + return errors.New("cluster: no client") + } + sub := cl.Subscribe(ctx, c.channel(EventHeartbeat), c.channel(EventConfig), c.channel(EventReload), c.channel(EventBlocklists), c.channel(EventBye)) + defer func() { _ = sub.Close() }() + + // Confirm the subscription is live before declaring the session healthy. + if _, err := sub.Receive(ctx); err != nil { + return fmt.Errorf("cluster: subscribe: %w", err) + } + c.connected.Store(true) + c.log.Info("cluster subscribed", "channel", c.channel(EventHeartbeat)) + + hb := time.NewTicker(c.cfg.Get().Cluster.PeerTTL.D() / 2) + defer hb.Stop() + + ch := sub.Channel() + for { + select { + case <-ctx.Done(): + return nil + case <-c.stop: + return nil + case <-hb.C: + c.publishState(ctx) + c.renewLease(ctx) + case msg, ok := <-ch: + if !ok { + return errors.New("cluster: subscription closed") + } + var ev Event + if err := json.Unmarshal([]byte(msg.Payload), &ev); err != nil { + continue // not ours / malformed; ignore rather than crash + } + if ev.NodeID == c.node { + continue // our own echo + } + c.lastEvent.Store(time.Now().Unix()) + if ev.State != nil { + c.seenMu.Lock() + c.seen[ev.NodeID] = *ev.State + c.seenMu.Unlock() + } + if ev.Kind == EventBye { + c.seenMu.Lock() + delete(c.seen, ev.NodeID) + c.seenMu.Unlock() + continue + } + if c.opt.Handler != nil { + c.opt.Handler(ctx, ev) + } + } + } +} + +func (c *Cluster) channel(k EventKind) string { + prefix := c.cfg.Get().Cluster.Valkey.Prefix + if prefix == "" { + prefix = "fancydns" + } + return prefix + ":events:" + string(k) +} + +func (c *Cluster) heartbeatKey() string { + prefix := c.cfg.Get().Cluster.Valkey.Prefix + if prefix == "" { + prefix = "fancydns" + } + return prefix + ":nodes" +} + +// State returns this instance's current state. +func (c *Cluster) State() *NodeState { + st := &NodeState{ + NodeID: c.node, + Addr: c.opt.Addr, + Version: c.opt.Version, + StartedAt: c.opt.StartedAt, + Generation: c.cfg.Generation(), + Leader: c.leader.Load(), + } + if f := c.opt.StateFunc; f != nil { + if live := f(); live != nil { + live.NodeID = c.node + live.Leader = c.leader.Load() + st = live + } + } + if d := c.opt.Digests; d != nil { + bl, rules, built, cfgDigest := d() + st.BlocklistDigest = bl + st.BlocklistRules = rules + st.BlocklistBuilt = built + st.ConfigDigest = cfgDigest + } + return st +} + +// publishState broadcasts this instance's heartbeat. +func (c *Cluster) publishState(ctx context.Context) { + cl := c.client.Load() + if cl == nil { + return + } + st := c.State() + ev := Event{Kind: EventHeartbeat, NodeID: c.node, At: time.Now(), State: st} + data, err := json.Marshal(ev) + if err != nil { + return + } + pipe := cl.Pipeline() + pipe.Publish(ctx, c.channel(EventHeartbeat), data) + // Also keep a keyed record so a late-joining instance can discover the + // existing set without waiting a full heartbeat interval. + pipe.HSet(ctx, c.heartbeatKey(), c.node, mustJSON(st)) + pipe.Expire(ctx, c.heartbeatKey(), c.cfg.Get().Cluster.PeerTTL.D()*4) + _, _ = pipe.Exec(ctx) +} + +func mustJSON(v any) string { + b, err := json.Marshal(v) + if err != nil { + return "{}" + } + return string(b) +} + +// Peers returns the last known state of other instances. +func (c *Cluster) Peers() []NodeState { + c.seenMu.RLock() + defer c.seenMu.RUnlock() + out := make([]NodeState, 0, len(c.seen)) + for _, s := range c.seen { + out = append(out, s) + } + sort.Slice(out, func(i, j int) bool { return out[i].NodeID < out[j].NodeID }) + return out +} + +// BroadcastConfig publishes a full configuration document to peers. +func (c *Cluster) BroadcastConfig(ctx context.Context, cfg *config.Config) error { + cl := c.client.Load() + if !c.Enabled() || cl == nil { + return nil + } + data, err := config.Marshal(cfg) + if err != nil { + return err + } + ev := Event{Kind: EventConfig, NodeID: c.node, At: time.Now(), Version: cfg.Version, Config: string(data)} + payload, err := json.Marshal(ev) + if err != nil { + return err + } + return cl.Publish(ctx, c.channel(EventConfig), payload).Err() +} + +// BroadcastReload asks peers to re-read their config file from disk. +func (c *Cluster) BroadcastReload(ctx context.Context) error { + cl := c.client.Load() + if !c.Enabled() || cl == nil { + return nil + } + ev := Event{Kind: EventReload, NodeID: c.node, At: time.Now()} + payload, err := json.Marshal(ev) + if err != nil { + return err + } + return cl.Publish(ctx, c.channel(EventReload), payload).Err() +} + +// BroadcastRefresh asks the leader to refresh list sources. The names slice is +// advisory: an empty slice means "everything". +func (c *Cluster) BroadcastRefresh(ctx context.Context, names []string) error { + cl := c.client.Load() + if !c.Enabled() || cl == nil { + return nil + } + ev := Event{Kind: EventBlocklists, NodeID: c.node, At: time.Now(), Sources: names} + payload, err := json.Marshal(ev) + if err != nil { + return err + } + return cl.Publish(ctx, c.channel(EventBlocklists), payload).Err() +} + +// Digest computes a stable digest of a configuration document. +func Digest(cfg *config.Config) string { + data, err := config.Marshal(cfg) + if err != nil { + return "" + } + sum := sha1.Sum(data) + return hex.EncodeToString(sum[:8]) +} + +// leaseKey is the Valkey key guarding the list-refresh leader. +func (c *Cluster) leaseKey() string { + prefix := c.cfg.Get().Cluster.Valkey.Prefix + if prefix == "" { + prefix = "fancydns" + } + return prefix + ":leader" +} + +// renewLease acquires or extends the refresh lease. Only the leader fetches +// lists; followers serve their compiled copy and keep their cache warm, so a +// fleet of N nodes does not multiply the load on a blocklist mirror. +func (c *Cluster) renewLease(ctx context.Context) { + cl := c.client.Load() + if cl == nil || !c.Enabled() { + c.leader.Store(false) + return + } + ttl := c.cfg.Get().Cluster.Valkey.LeaderTTL.D() + if ttl <= 0 { + ttl = 30 * time.Second + } + // SET NX with a TTL: only the first caller wins the lease. Everyone else + // just extends it when they already hold it. + ok, err := cl.SetNX(ctx, c.leaseKey(), c.node, ttl).Result() + if err != nil { + c.leader.Store(false) + return + } + if ok { + c.leader.Store(true) + return + } + holder, err := c.leaseHolder(ctx) + if err == nil && holder == c.node { + // We already hold it: extend. + _ = cl.Expire(ctx, c.leaseKey(), ttl).Err() + c.leader.Store(true) + return + } + c.leader.Store(false) +} + +// leaseHolder reads who holds the refresh lease. +func (c *Cluster) leaseHolder(ctx context.Context) (string, error) { + cl := c.client.Load() + if cl == nil { + return "", errors.New("no client") + } + v, err := cl.Get(ctx, c.leaseKey()).Result() + if err != nil { + return "", err + } + return v, nil +} + +// IsLeader reports the current lease holder, for the UI. +func (c *Cluster) LeaseHolder(ctx context.Context) string { + if !c.Enabled() { + return "" + } + h, err := c.leaseHolder(ctx) + if err != nil { + return "" + } + return h +} + +// Status is the cluster view for the API. +type Status struct { + Enabled bool `json:"enabled"` + Connected bool `json:"connected"` + NodeID string `json:"node_id"` + Leader bool `json:"leader"` + LeaseOwner string `json:"lease_owner,omitempty"` + Peers []NodeState `json:"peers"` + // Divergent lists peers whose blocklist digest differs from ours, which + // is the one thing an operator really needs to see. + Divergent []string `json:"divergent"` + Channel string `json:"channel"` + LastEvent time.Time `json:"last_event,omitempty"` +} + +// Status snapshots the cluster state. +func (c *Cluster) Status(ctx context.Context) Status { + st := Status{ + Enabled: c.Enabled(), + Connected: c.Connected(), + NodeID: c.node, + Leader: c.leader.Load(), + Channel: c.channel(EventHeartbeat), + } + if c.Enabled() { + st.LeaseOwner = c.LeaseHolder(ctx) + } + st.Peers = c.Peers() + own := c.State() + for _, p := range st.Peers { + if p.BlocklistDigest != "" && own.BlocklistDigest != "" && p.BlocklistDigest != own.BlocklistDigest { + st.Divergent = append(st.Divergent, p.NodeID) + } + } + sort.Strings(st.Divergent) + if v := c.lastEvent.Load(); v > 0 { + st.LastEvent = time.Unix(v, 0) + } + return st +} + +// Discover lists the node ids currently registered, for a fresh instance that +// has not heard a heartbeat yet. +func (c *Cluster) Discover(ctx context.Context) []NodeState { + if !c.Enabled() { + return nil + } + cl := c.client.Load() + if cl == nil { + return nil + } + fields, err := cl.HGetAll(ctx, c.heartbeatKey()).Result() + if err != nil { + return nil + } + out := make([]NodeState, 0, len(fields)) + ids := make([]string, 0, len(fields)) + for id := range fields { + ids = append(ids, id) + } + sort.Strings(ids) + for _, id := range ids { + if id == c.node { + continue + } + var st NodeState + if err := json.Unmarshal([]byte(fields[id]), &st); err == nil { + out = append(out, st) + } + } + return out +} + +// Stop closes the connection and announces the departure. +func (c *Cluster) Stop() { + select { + case <-c.stop: + default: + close(c.stop) + } + cl := c.client.Load() + if cl == nil { + return + } + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + ev := Event{Kind: EventBye, NodeID: c.node, At: time.Now()} + if payload, err := json.Marshal(ev); err == nil { + _ = cl.Publish(ctx, c.channel(EventBye), payload).Err() + } + // Only release the lease if we hold it, so a shutdown does not hand the + // job to a node that is also going away. + if c.leader.Load() { + cl.Eval(ctx, `if redis.call("GET", KEYS[1]) == ARGV[1] then return redis.call("DEL", KEYS[1]) else return 0 end`, []string{c.leaseKey()}, c.node) + } + _ = cl.Close() + c.connected.Store(false) + c.leader.Store(false) +} + +// String renders the node id for logs. +func (c *Cluster) String() string { return strings.TrimSpace(c.node) } + +func cryptoRead(b []byte) (int, error) { + h := sha1.Sum([]byte(time.Now().String() + string(b))) + copy(b, h[:4]) + return len(b), nil +} diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..06948ba --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,1098 @@ +// Package config holds the declarative configuration for fancy-dns, its +// validation, and the atomic hot-reloadable store the whole server reads from. +// +// Configuration is intentionally file-based (YAML for the service itself, +// DNS master files for zone data) so that a deployment can be reviewed, +// diffed and rolled back with git. Mutations made through the admin API are +// written back to the same file and then broadcast to the cluster. +package config + +import ( + "errors" + "fmt" + "net" + "net/netip" + "os" + "path/filepath" + "sort" + "strings" + "time" + + "gopkg.in/yaml.v3" +) + +// Duration is a time.Duration that unmarshals from a YAML/JSON string such as +// "30s" or "1h30m". A bare integer is interpreted as seconds. +type Duration time.Duration + +func (d *Duration) UnmarshalYAML(value *yaml.Node) error { + var s string + if err := value.Decode(&s); err == nil { + s = strings.TrimSpace(s) + if s == "" { + *d = 0 + return nil + } + // Bare numbers are seconds, matching the convention used by the + // surrounding YAML (and by CoreDNS-ish configs people copy around). + if n, err := time.ParseDuration(s); err == nil { + *d = Duration(n) + return nil + } + return fmt.Errorf("invalid duration %q", s) + } + var f float64 + if err := value.Decode(&f); err != nil { + return fmt.Errorf("invalid duration: %s", value.Value) + } + *d = Duration(time.Duration(f * float64(time.Second))) + return nil +} + +func (d Duration) MarshalYAML() (any, error) { return time.Duration(d).String(), nil } + +func (d Duration) D() time.Duration { return time.Duration(d) } + +// Config is the root document. Every section has sane defaults applied by +// Default() so that a minimal config file is still a working server. +type Config struct { + // Version is bumped by the admin API when it rewrites the file; it is + // echoed in /api/config and used to detect divergence in the cluster. + Version int64 `yaml:"version,omitempty"` + + Server Server `yaml:"server"` + DNS DNS `yaml:"dns"` + Upstream Upstream `yaml:"upstream"` + Cache Cache `yaml:"cache"` + Block Block `yaml:"blocklist"` + ACL ACL `yaml:"acl"` + QueryLog QueryLog `yaml:"qlog"` + Cluster Cluster `yaml:"cluster"` + API API `yaml:"api"` + Metrics Metrics `yaml:"metrics"` + Log Log `yaml:"log"` +} + +// Server groups the process-level knobs. +type Server struct { + // MaxConcurrent caps in-flight upstream resolutions; excess queries are + // answered with SERVFAIL rather than queueing without bound. + MaxConcurrent int `yaml:"max_concurrent"` + // MaxConcurrentPerClient mirrors MaxConcurrent but per client IP. 0 = off. + MaxConcurrentPerClient int `yaml:"max_concurrent_per_client"` + Timeouts Timeout `yaml:"timeouts"` + // WorkingDir is only informational (shown in the UI). + WorkingDir string `yaml:"working_dir,omitempty"` +} + +type Timeout struct { + UDP Duration `yaml:"udp"` + TCP Duration `yaml:"tcp"` + TLS Duration `yaml:"tls"` + Query Duration `yaml:"query"` + Upstre Duration `yaml:"upstream"` + List Duration `yaml:"list_fetch"` +} + +// DNS describes every listener the server exposes. +type DNS struct { + UDP []string `yaml:"udp"` + TCP []string `yaml:"tcp"` + DoT DoT `yaml:"dot"` + DoH DoH `yaml:"doh"` + EDNS EDNS `yaml:"edns0"` + // ServeStale answers from cache after an upstream failure. + ServeStale Duration `yaml:"serve_stale"` + // MaxUDPSize is what we advertise as our own EDNS0 buffer size. + MaxUDPSize uint16 `yaml:"max_udp_size"` + // Truncate policy: "question" sets TC and returns the header+question. + Recursion bool `yaml:"recursion_desired"` + // HideIdentity stops leaking our version string in CHAOS/bind. + HideIdentity bool `yaml:"hide_identity"` +} + +type DoT struct { + Enabled bool `yaml:"enabled"` + Listen []string `yaml:"listen"` + CertFile string `yaml:"cert_file"` + KeyFile string `yaml:"key_file"` + // ClientCA enables mTLS when set; clients must then present a cert. + ClientCA string `yaml:"client_ca"` + // MinVersion is "1.2" or "1.3". + MinVersion string `yaml:"min_version"` + // Upstream makes our own outgoing queries encrypted (RFC 7858, 8.4.1). + Upstream bool `yaml:"upstream"` +} + +type DoH struct { + Enabled bool `yaml:"enabled"` + Listen []string `yaml:"listen"` + CertFile string `yaml:"cert_file"` + KeyFile string `yaml:"key_file"` + BasePath string `yaml:"base_path"` + // EchConfig is an optional ECHConfigList to serve over HTTPS (RFC 9460). + MinVersion string `yaml:"min_version"` + // AllowPost enables the RFC 8484 POST profile in addition to GET. + AllowPost bool `yaml:"allow_post"` + Transport Transport `yaml:"transport"` +} + +// Transport selects between HTTP/2 (h2) and HTTP/3 (h3) for DoH. +type Transport struct { + // "auto" upgrades to HTTP/3 when the listener is UDP, else h2. + Mode string `yaml:"mode"` + // AltSvc lets the listener advertise h3 via Alt-Svc. + AltSvc string `yaml:"alt_svc"` +} + +type EDNS struct { + // ClientSubnet enables RFC 7871 EDNS-Client-Subnet passthrough. + ClientSubnet bool `yaml:"client_subnet"` + IPv4Bits uint8 `yaml:"ipv4_bits"` + IPv6Bits uint8 `yaml:"ipv6_bits"` + // MaxUDPSize overrides the advertised EDNS0 buffer for our own answers. + CookieSupport bool `yaml:"cookie_support"` + // PreserveEDNS0 copies the incoming OPT options into upstream queries. + PreserveEDNS0 bool `yaml:"preserve"` +} + +type Upstream struct { + // Servers is the upstream pool. + Servers []UpstreamServer `yaml:"servers"` + // Policy is "parallel" (query all, first answer wins), "random" (pick N) + // or "failover" (walk the list in order). + Policy string `yaml:"policy"` + // MaxAttempts bounds how many upstreams are tried per query. + MaxAttempts int `yaml:"max_attempts"` + // Healthcheck interval; 0 disables active health probing. + HealthCheck Duration `yaml:"healthcheck_interval"` + // CircuitBreaker trips an upstream after this many consecutive failures. + BreakerThreshold int `yaml:"breaker_threshold"` + BreakerCooldown Duration `yaml:"breaker_cooldown"` + // Bootstraps resolves upstream hostnames at startup and on change. + Bootstraps []UpstreamBootstrap `yaml:"bootstraps"` +} + +type UpstreamServer struct { + // Addr is host:port; host may be an IP or a name resolved via Bootstraps. + Addr string `yaml:"addr"` + // Proto is "udp", "tcp" or "tls" (DoT, 8.4.1). + Proto string `yaml:"proto"` + // ServerName / InsecureSkipVerify are only used with proto: tls. + ServerName string `yaml:"server_name"` + InsecureSkipVerify bool `yaml:"insecure_skip_verify"` + // HealthPath is a hostname used for health probes instead of the Addr host. + HealthName string `yaml:"health_name"` + // Weight biases random selection (default 1). + Weight int `yaml:"weight"` + // MaxFails before the breaker opens; 0 uses the global threshold. + MaxFails int `yaml:"max_fails"` + Comment string `yaml:"comment,omitempty"` +} + +type UpstreamBootstrap struct { + Name string `yaml:"name"` + Addresses []string `yaml:"addresses"` + // Refresh re-resolves periodically (for dyn names). + Refresh Duration `yaml:"refresh"` +} + +type Cache struct { + Enabled bool `yaml:"enabled"` + // Size is the in-memory entry budget for the LRU. + Size int `yaml:"size"` + // Shards must be a power of two; 0 picks 32. + Shards int `yaml:"shards"` + // MinTTL/MaxTTL clamp the TTLs taken from upstream answers. + MinTTL Duration `yaml:"min_ttl"` + MaxTTL Duration `yaml:"max_ttl"` + // ServeStale keeps expired entries around for this long so a dead + // upstream does not turn into a latency cliff. + ServeStale Duration `yaml:"serve_stale"` + // Prefetch keeps ServeStale windows warm. + Prefetch bool `yaml:"prefetch"` + // Persist writes a snapshot to bbolt so restarts stay warm. + Persist CachePersist `yaml:"persist"` + // Prewarm is a list of "domain/type" (e.g. "example.com/A") to load at boot. + Prewarm []string `yaml:"prewarm"` + // Negative caches NXDOMAIN/NODATA, bounded by the SOA minimum. + NegativeTTL Duration `yaml:"negative_ttl"` +} + +type CachePersist struct { + Enabled bool `yaml:"enabled"` + // Path is the bbolt file; defaults under the data directory. + Path string `yaml:"path"` + // Interval is the snapshot write cadence. + Interval Duration `yaml:"interval"` + // MaxEntries caps the persisted snapshot (0 = no cap). + MaxEntries int `yaml:"max_entries"` + // LoadOnStart reads a snapshot from disk at boot. + LoadOnStart bool `yaml:"load_on_start"` +} + +type Block struct { + Enabled bool `yaml:"enabled"` + // DefaultAction is "nxdomain", "zero", "redirect" or "drop". + DefaultAction string `yaml:"default_action"` + // ResponseIP/ResponseIPv6 are used by the "zero" action. + ResponseIP string `yaml:"response_ip"` + ResponseIPv6 string `yaml:"response_ipv6"` + ResponseTTL Duration `yaml:"response_ttl"` + // ResponseName/CNAME are used by the "redirect" action. + RedirectName string `yaml:"redirect_name"` + // LocalZones are DNS master files (RFC 1035) holding RPZ-style policy + // records and/or locally defined zones. + LocalZones []string `yaml:"local_zones"` + // Lists are remote or on-disk sources of block data. + Lists []ListSource `yaml:"lists"` + // AllowEntries and BlockEntries are inline rules (a list of DNS names or + // master-file lines), useful for small static policies. + AllowEntries []string `yaml:"allow_entries"` + BlockEntries []string `yaml:"block_entries"` + // Parallelism for list parsing/compilation. + Parallelism int `yaml:"parallelism"` +} + +type ListSource struct { + Name string `yaml:"name"` + // Format is auto|hosts|adblock|plain|rpz. + Format string `yaml:"format"` + // URL and Path: at least one is required. URL wins when both are set; the + // downloaded copy is written to Path so restarts work without network. + URL string `yaml:"url"` + Path string `yaml:"path"` + Mirror []string `yaml:"mirror"` + Enabled bool `yaml:"enabled"` + // Refresh interval; 0 disables scheduled refresh (manual only). + Refresh Duration `yaml:"refresh"` + // Timeout for the fetch. + Timeout Duration `yaml:"timeout"` + // MaxBytes guards against a runaway/hostile list. + MaxBytes int64 `yaml:"max_bytes"` + // ETag / LastModified enable conditional refreshes. + ETag string `yaml:"etag"` + LastModified string `yaml:"last_modified"` + // Category tags feed the UI breakdown. + Categories []string `yaml:"categories"` + // InsecureSkipTLSVerify is only for self-hosted mirrors. + InsecureSkipTLSVerify bool `yaml:"insecure_skip_tls_verify"` + // LastGood keeps the previous compiled set if a refresh fails. + Comment string `yaml:"comment,omitempty"` +} + +type ACL struct { + // DefaultPolicy is "allow", "deny" or "block_only". + DefaultPolicy string `yaml:"default_policy"` + // DefaultRateLimit is queries/second per client IP; 0 = unlimited. + DefaultRateLimit int `yaml:"default_rate_limit"` + Groups []Group `yaml:"groups"` +} + +// Group is a named set of clients sharing a policy. Groups are evaluated +// top-to-bottom; the first match wins. +type Group struct { + Name string `yaml:"name"` + Comment string `yaml:"comment,omitempty"` + Match Match `yaml:"match"` + // Policy is "allow" (full resolution), "block_only" (blocklists still + // apply, everything else resolves) or "deny" (REFUSED). + Policy string `yaml:"policy"` + // AllowDomains / DenyDomains are per-group overrides; the names support + // the same wildcards as blocklists ("*.example.com", "**.example.com"). + AllowDomains []string `yaml:"allow_domains"` + DenyDomains []string `yaml:"deny_domains"` + // BlocklistToggle lets a group opt out of blocklist filtering. + SkipBlocklist bool `yaml:"skip_blocklist"` + // CacheToggle lets a group bypass the cache (fresh lookups only). + SkipCache bool `yaml:"skip_cache"` + // RateLimit overrides ACL.DefaultRateLimit for this group. + RateLimit int `yaml:"rate_limit"` + // MaxConcurrent overrides Server.MaxConcurrentPerClient. + MaxConcurrent int `yaml:"max_concurrent"` + // LogQueries forces query logging for this group regardless of sampling. + LogQueries bool `yaml:"log_queries"` + Upstreams []string `yaml:"upstreams"` +} + +// Match selects clients by network identity. +type Match struct { + // CIDRs are matched against the client address (v4 or v6). + CIDRs []string `yaml:"cidrs"` + // Networks match DNS clients identified by a resolved PTR of their + // reverse name; the name must end with one of the suffixes. + PTRSuffixes []string `yaml:"ptr_suffixes"` + // Tags are matched against the client tag set derived from PTR labels, + // e.g. "laptop" for "laptop.lan.internal.". + Tags []string `yaml:"tags"` + // Always matches (useful as a catch-all fallback group). + Any bool `yaml:"any"` +} + +type QueryLog struct { + Enabled bool `yaml:"enabled"` + // Path is the bbolt file backing the query log ring. + Path string `yaml:"path"` + // MaxEntries bounds the ring; oldest are dropped. + MaxEntries int `yaml:"max_entries"` + // FlushInterval batches writes. + FlushInterval Duration `yaml:"flush_interval"` + // SampleRate is 0..1 for non-blocked, non-error queries. + SampleRate float64 `yaml:"sample_rate"` + // What to record. + LogBlocked bool `yaml:"log_blocked"` + LogCached bool `yaml:"log_cached"` + LogErrors bool `yaml:"log_errors"` + LogClients bool `yaml:"log_client_names"` + // LiveBuffer is the ring of recent entries kept in memory for the UI/SSE. + LiveBuffer int `yaml:"live_buffer"` + // Retention of aggregated per-domain counters. + TopDomains int `yaml:"top_domains"` + TopTTL Duration `yaml:"top_ttl"` +} + +type Cluster struct { + Enabled bool `yaml:"enabled"` + // NodeID defaults to hostname; instances use it to elect a refresh leader. + NodeID string `yaml:"node_id"` + // Advertise is the address other instances dial for the admin API. + Advertise string `yaml:"advertise"` + // PeerSync makes this instance push its config file to peers. + PeerSync bool `yaml:"peer_sync"` + PeerTTL Duration `yaml:"peer_ttl"` + Valkey Valkey `yaml:"valkey"` +} + +type Valkey struct { + // Addrs is a list of host:port. + Addrs []string `yaml:"addrs"` + // Username/Password for ACL-based auth. + Username string `yaml:"username"` + Password string `yaml:"password"` + DB int `yaml:"db"` + Prefix string `yaml:"prefix"` + TLS bool `yaml:"tls"` + PoolSize int `yaml:"pool_size"` + // DialTimeout/ReadTimeout bound cluster operations. + DialTimeout Duration `yaml:"dial_timeout"` + ReadTimeout Duration `yaml:"read_timeout"` + // LeaderTTL is the lease length for list-refresh leadership. + LeaderTTL Duration `yaml:"leader_ttl"` +} + +type API struct { + Enabled bool `yaml:"enabled"` + // Listen is the plain HTTP admin/API listener. + Listen []string `yaml:"listen"` + // TLSListen serves the admin API (and UI) over TLS instead. + TLSListen []string `yaml:"tls_listen"` + CertFile string `yaml:"cert_file"` + KeyFile string `yaml:"key_file"` + BasePath string `yaml:"base_path"` + Auth Auth `yaml:"auth"` + RateLimit AuthRate `yaml:"rate_limit"` + // UI toggles the embedded admin console. + UI bool `yaml:"ui"` + // AllowConfigWrite lets the API rewrite the config file. + AllowConfigWrite bool `yaml:"allow_config_write"` + // AllowBlocklistWrite lets the API write blocklist files to disk. + AllowBlocklistWrite bool `yaml:"allow_blocklist_write"` + // TrustedProxies is the set of proxies allowed to set X-Forwarded-For. + TrustedProxies []string `yaml:"trusted_proxies"` + // CORSOrigins; "*" is allowed but discouraged. + CORSOrigins []string `yaml:"cors_origins"` +} + +type Auth struct { + // Mode is "none", "apikey" or "basic". + Mode string `yaml:"mode"` + // APIKeys grant full access. + APIKeys []string `yaml:"api_keys"` + // ReadOnlyAPIKeys may only call GET endpoints. + ReadOnlyAPIKeys []string `yaml:"read_only_api_keys"` + // Basic user; Password may be plaintext (bcrypt-hashed at load time) or a + // bcrypt hash (prefix "$2"). + Username string `yaml:"username"` + Password string `yaml:"password"` + SessionTTL Duration `yaml:"session_ttl"` + // TrustLoopback skips auth for requests from 127.0.0.0/8 and ::1. + TrustLoopback bool `yaml:"trust_loopback"` +} + +type AuthRate struct { + // Requests per minute per IP for the login endpoint. + PerMinute int `yaml:"per_minute"` + // Failures per minute per IP before a temporary lockout. + Failures int `yaml:"failures"` + Lockout Duration `yaml:"lockout"` +} + +type Metrics struct { + Enabled bool `yaml:"enabled"` + Path string `yaml:"path"` + // Protect requires the API token for /metrics. + Protect bool `yaml:"protect"` +} + +type Log struct { + // Level is debug|info|warn|error. + Level string `yaml:"level"` + // Format is text|json. + Format string `yaml:"format"` + // Addr overrides the log destination; empty means stderr. + Addr string `yaml:"addr"` +} + +// Default returns a fully-populated configuration. Callers are expected to +// unmarshal the user file on top of it, then Validate. +func Default() *Config { + return &Config{ + Server: Server{ + MaxConcurrent: 1024, + MaxConcurrentPerClient: 0, + Timeouts: Timeout{ + UDP: Duration(2 * time.Second), + TCP: Duration(4 * time.Second), + TLS: Duration(4 * time.Second), + Query: Duration(5 * time.Second), + Upstre: Duration(2 * time.Second), + List: Duration(60 * time.Second), + }, + }, + DNS: DNS{ + UDP: []string{"0.0.0.0:53", "[::]:53"}, + TCP: []string{"0.0.0.0:53", "[::]:53"}, + MaxUDPSize: 1232, + Recursion: true, + DoT: DoT{MinVersion: "1.2", Listen: []string{"0.0.0.0:853"}}, + DoH: DoH{BasePath: "/dns-query", MinVersion: "1.2", AllowPost: true, Transport: Transport{Mode: "auto"}, Listen: []string{"0.0.0.0:443"}}, + EDNS: EDNS{ClientSubnet: true, IPv4Bits: 24, IPv6Bits: 56, PreserveEDNS0: true}, + ServeStale: Duration(0), + }, + Upstream: Upstream{ + Policy: "parallel", + Servers: []UpstreamServer{ + {Addr: "9.9.9.9:53", Proto: "udp", Weight: 1, HealthName: "dns.quad9.net"}, + {Addr: "149.112.112.112:53", Proto: "udp", Weight: 1, HealthName: "dns.quad9.net"}, + {Addr: "1.1.1.1:53", Proto: "tls", ServerName: "cloudflare-dns.com", Weight: 1, HealthName: "cloudflare.com"}, + {Addr: "9.9.9.9:853", Proto: "tls", ServerName: "dns.quad9.net", Weight: 1, HealthName: "dns.quad9.net"}, + {Addr: "1.0.0.1:53", Proto: "udp", Weight: 1, HealthName: "one.one.one.one"}, + }, + MaxAttempts: 3, + HealthCheck: Duration(30 * time.Second), + BreakerThreshold: 5, + BreakerCooldown: Duration(30 * time.Second), + }, + Cache: Cache{ + Enabled: true, + Size: 200000, + Shards: 32, + MinTTL: Duration(0), + MaxTTL: Duration(time.Hour), + ServeStale: Duration(30 * time.Minute), + Prefetch: true, + NegativeTTL: Duration(30 * time.Minute), + Persist: CachePersist{ + Enabled: true, + Interval: Duration(30 * time.Second), + MaxEntries: 500000, + LoadOnStart: true, + }, + }, + Block: Block{ + Enabled: true, + DefaultAction: "nxdomain", + ResponseIP: "0.0.0.0", + ResponseIPv6: "::", + ResponseTTL: Duration(60 * time.Second), + Parallelism: 4, + }, + ACL: ACL{ + DefaultPolicy: "allow", + }, + QueryLog: QueryLog{ + Enabled: true, + MaxEntries: 200000, + FlushInterval: Duration(time.Second), + SampleRate: 1, + LogBlocked: true, + LogCached: true, + LogErrors: true, + LiveBuffer: 2000, + TopDomains: 5000, + TopTTL: Duration(5 * time.Minute), + }, + Cluster: Cluster{ + Enabled: false, + PeerTTL: Duration(15 * time.Second), + Valkey: Valkey{ + Prefix: "fancydns", + PoolSize: 10, + DialTimeout: Duration(2 * time.Second), + ReadTimeout: Duration(2 * time.Second), + LeaderTTL: Duration(30 * time.Second), + }, + }, + API: API{ + Enabled: true, + Listen: []string{"127.0.0.1:8080"}, + BasePath: "/api", + UI: true, + AllowConfigWrite: true, + AllowBlocklistWrite: true, + Auth: Auth{ + Mode: "apikey", + SessionTTL: Duration(12 * time.Hour), + TrustLoopback: true, + }, + RateLimit: AuthRate{PerMinute: 60, Failures: 10, Lockout: Duration(5 * time.Minute)}, + }, + Metrics: Metrics{Enabled: true, Path: "/metrics"}, + Log: Log{Level: "info", Format: "text"}, + } +} + +// Load reads path (if non-empty) on top of Default and validates the result. +func Load(path string) (*Config, error) { + cfg := Default() + if path != "" { + raw, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("read config: %w", err) + } + if err := yaml.Unmarshal(raw, cfg); err != nil { + return nil, fmt.Errorf("parse config %s: %w", path, err) + } + cfg.applyDefaults() + cfg.WorkingDirOrSet(filepath.Dir(path)) + } else { + cfg.WorkingDirOrSet(".") + } + if err := cfg.Validate(); err != nil { + return nil, err + } + return cfg, nil +} + +// WorkingDirOrSet records the config directory so relative paths in the +// document resolve consistently regardless of the process cwd. +func (c *Config) WorkingDirOrSet(dir string) { + if c.Server.WorkingDir == "" { + c.Server.WorkingDir = dir + } +} + +// applyDefaults backfills values that a hand-written file may omit, and +// normalises "off"/"disabled"/"" style booleans. +func (c *Config) applyDefaults() { + d := Default() + if c.Server.MaxConcurrent <= 0 { + c.Server.MaxConcurrent = d.Server.MaxConcurrent + } + if c.Server.Timeouts.UDP <= 0 { + c.Server.Timeouts.UDP = d.Server.Timeouts.UDP + } + if c.Server.Timeouts.TCP <= 0 { + c.Server.Timeouts.TCP = d.Server.Timeouts.TCP + } + if c.Server.Timeouts.TLS <= 0 { + c.Server.Timeouts.TLS = d.Server.Timeouts.TLS + } + if c.Server.Timeouts.Query <= 0 { + c.Server.Timeouts.Query = d.Server.Timeouts.Query + } + if c.Server.Timeouts.Upstre <= 0 { + c.Server.Timeouts.Upstre = d.Server.Timeouts.Upstre + } + if c.Server.Timeouts.List <= 0 { + c.Server.Timeouts.List = d.Server.Timeouts.List + } + if c.DNS.MaxUDPSize < 512 { + c.DNS.MaxUDPSize = d.DNS.MaxUDPSize + } + if c.DNS.DoH.BasePath == "" { + c.DNS.DoH.BasePath = d.DNS.DoH.BasePath + } + if c.DNS.DoT.MinVersion == "" { + c.DNS.DoT.MinVersion = d.DNS.DoT.MinVersion + } + if c.DNS.DoH.MinVersion == "" { + c.DNS.DoH.MinVersion = d.DNS.DoH.MinVersion + } + if c.DNS.DoH.Transport.Mode == "" { + c.DNS.DoH.Transport.Mode = "auto" + } + if c.EDNSBits() { + // nothing; kept for symmetry + } + if c.EDNS().IPv4Bits == 0 { + c.DNS.EDNS.IPv4Bits = d.DNS.EDNS.IPv4Bits + } + if c.DNS.EDNS.IPv6Bits == 0 { + c.DNS.EDNS.IPv6Bits = d.DNS.EDNS.IPv6Bits + } + if c.Upstream.Policy == "" { + c.Upstream.Policy = d.Upstream.Policy + } + if c.Upstream.MaxAttempts <= 0 { + c.Upstream.MaxAttempts = d.Upstream.MaxAttempts + } + if c.Upstream.BreakerThreshold <= 0 { + c.Upstream.BreakerThreshold = d.Upstream.BreakerThreshold + } + if c.Upstream.BreakerCooldown <= 0 { + c.Upstream.BreakerCooldown = d.Upstream.BreakerCooldown + } + if c.Cache.Size <= 0 { + c.Cache.Size = d.Cache.Size + } + if c.Cache.Shards <= 0 { + c.Cache.Shards = d.Cache.Shards + } + c.Cache.Shards = pow2(c.Cache.Shards) + if c.Cache.MaxTTL <= 0 { + c.Cache.MaxTTL = d.Cache.MaxTTL + } + if c.Cache.NegativeTTL <= 0 { + c.Cache.NegativeTTL = d.Cache.NegativeTTL + } + if c.Cache.Persist.Interval <= 0 { + c.Cache.Persist.Interval = d.Cache.Persist.Interval + } + if c.Block.DefaultAction == "" { + c.Block.DefaultAction = d.Block.DefaultAction + } + if c.Block.ResponseTTL <= 0 { + c.Block.ResponseTTL = d.Block.ResponseTTL + } + if c.Block.Parallelism <= 0 { + c.Block.Parallelism = d.Block.Parallelism + } + if c.ACL.DefaultPolicy == "" { + c.ACL.DefaultPolicy = d.ACL.DefaultPolicy + } + if c.QueryLog.MaxEntries <= 0 { + c.QueryLog.MaxEntries = d.QueryLog.MaxEntries + } + if c.QueryLog.FlushInterval <= 0 { + c.QueryLog.FlushInterval = d.QueryLog.FlushInterval + } + if c.QueryLog.LiveBuffer <= 0 { + c.QueryLog.LiveBuffer = d.QueryLog.LiveBuffer + } + if c.QueryLog.SampleRate <= 0 { + c.QueryLog.SampleRate = 1 + } + if c.QueryLog.SampleRate > 1 { + c.QueryLog.SampleRate = 1 + } + if c.Cluster.Valkey.Prefix == "" { + c.Cluster.Valkey.Prefix = d.Cluster.Valkey.Prefix + } + if c.Cluster.Valkey.LeaderTTL <= 0 { + c.Cluster.Valkey.LeaderTTL = d.Cluster.Valkey.LeaderTTL + } + if c.Cluster.PeerTTL <= 0 { + c.Cluster.PeerTTL = d.Cluster.PeerTTL + } + if len(c.API.Listen) == 0 && len(c.API.TLSListen) == 0 { + c.API.Listen = d.API.Listen + } + if c.API.BasePath == "" { + c.API.BasePath = d.API.BasePath + } + c.API.BasePath = "/" + strings.Trim(c.API.BasePath, "/") + if c.API.Auth.Mode == "" { + c.API.Auth.Mode = d.API.Auth.Mode + } + if c.API.Auth.SessionTTL <= 0 { + c.API.Auth.SessionTTL = d.API.Auth.SessionTTL + } + if c.Metrics.Path == "" { + c.Metrics.Path = d.Metrics.Path + } + if !strings.HasPrefix(c.Metrics.Path, "/") { + c.Metrics.Path = "/" + c.Metrics.Path + } + if c.Log.Level == "" { + c.Log.Level = d.Log.Level + } + if c.Log.Format == "" { + c.Log.Format = d.Log.Format + } + // Normalise list sources and upstream weights. + for i := range c.Block.Lists { + l := &c.Block.Lists[i] + if l.Format == "" { + l.Format = "auto" + } + if l.Refresh == 0 { + l.Refresh = Duration(24 * time.Hour) + } + if l.Timeout <= 0 { + l.Timeout = c.Server.Timeouts.List + } + if l.MaxBytes <= 0 { + l.MaxBytes = 512 << 20 + } + } + for i := range c.Upstream.Servers { + u := &c.Upstream.Servers[i] + if u.Proto == "" { + u.Proto = "udp" + } + if u.Weight <= 0 { + u.Weight = 1 + } + if _, _, err := net.SplitHostPort(u.Addr); err != nil { + u.Addr = net.JoinHostPort(u.Addr, defaultPort(u.Proto)) + } + } +} + +func defaultPort(proto string) string { + switch proto { + case "tls": + return "853" + case "tcp", "udp": + return "53" + } + return "53" +} + +func pow2(n int) int { + if n <= 1 { + return 1 + } + p := 1 + for p < n { + p <<= 1 + } + return p +} + +// EDNS is a tiny accessor so callers can treat a possibly-zero value safely. +func (c *Config) EDNS() EDNS { return c.DNS.EDNS } +func (c *Config) EDNSBits() bool { return c.DNS.EDNS.ClientSubnet } + +// Validate reports every problem it can find, aggregated, so an operator +// fixing a config file sees all of it at once. +func (c *Config) Validate() error { + var errs []error + add := func(format string, args ...any) { errs = append(errs, fmt.Errorf(format, args...)) } + + if c.Server.MaxConcurrent <= 0 { + add("server.max_concurrent must be > 0") + } + checkAddrs := func(field string, list []string) { + for _, a := range list { + if _, _, err := net.SplitHostPort(a); err != nil { + add("%s: %q is not host:port", field, a) + } + } + } + checkAddrs("dns.udp", c.DNS.UDP) + checkAddrs("dns.tcp", c.DNS.TCP) + checkAddrs("dns.dot.listen", c.DNS.DoT.Listen) + checkAddrs("dns.doh.listen", c.DNS.DoH.Listen) + checkAddrs("api.listen", c.API.Listen) + checkAddrs("api.tls_listen", c.API.TLSListen) + + if c.DNS.MaxUDPSize < 512 || c.DNS.MaxUDPSize > 4096 { + add("dns.max_udp_size must be between 512 and 4096") + } + switch c.Upstream.Policy { + case "parallel", "random", "failover", "": + default: + add("upstream.policy must be parallel, random or failover (got %q)", c.Upstream.Policy) + } + if len(c.Upstream.Servers) == 0 { + add("upstream.servers must not be empty") + } + seen := map[string]bool{} + for i, u := range c.Upstream.Servers { + if u.Addr == "" { + add("upstream.servers[%d]: addr is required", i) + } + if seen[u.Addr+"/"+u.Proto] { + add("upstream.servers[%d]: duplicate %s %s", i, u.Proto, u.Addr) + } + seen[u.Addr+"/"+u.Proto] = true + switch u.Proto { + case "udp", "tcp", "tls": + default: + add("upstream.servers[%d]: proto must be udp, tcp or tls (got %q)", i, u.Proto) + } + if u.Proto == "tls" && u.ServerName == "" { + host, _, _ := net.SplitHostPort(u.Addr) + u.ServerName = host + } + } + for i, b := range c.Upstream.Bootstraps { + if b.Name == "" { + add("upstream.bootstraps[%d]: name is required", i) + } + for _, a := range b.Addresses { + if net.ParseIP(a) == nil { + add("upstream.bootstraps[%d]: %q is not an IP address", i, a) + } + } + } + + switch c.Block.DefaultAction { + case "nxdomain", "zero", "redirect", "drop", "refused": + default: + add("blocklist.default_action must be nxdomain, zero, redirect, drop or refused (got %q)", c.Block.DefaultAction) + } + if c.Block.DefaultAction == "zero" { + if c.Block.ResponseIP == "" { + c.Block.ResponseIP = "0.0.0.0" + } + if net.ParseIP(c.Block.ResponseIP) == nil { + add("blocklist.response_ip %q is not an IP", c.Block.ResponseIP) + } + if c.Block.ResponseIPv6 == "" { + c.Block.ResponseIPv6 = "::" + } + if net.ParseIP(c.Block.ResponseIPv6) == nil { + add("blocklist.response_ipv6 %q is not an IP", c.Block.ResponseIPv6) + } + } + if c.Block.DefaultAction == "redirect" && c.Block.RedirectName == "" { + add("blocklist.redirect_name is required when default_action is redirect") + } + names := map[string]bool{} + for i, l := range c.Block.Lists { + if l.Name == "" { + add("blocklist.lists[%d]: name is required", i) + } + if names[l.Name] { + add("blocklist.lists[%d]: duplicate list name %q", i, l.Name) + } + names[l.Name] = true + if l.URL == "" && l.Path == "" { + add("blocklist.lists[%d] %q: one of url or path is required", i, l.Name) + } + if l.URL != "" { + if !strings.HasPrefix(l.URL, "https://") && !strings.HasPrefix(l.URL, "http://") && !strings.HasPrefix(l.URL, "file://") { + add("blocklist.lists[%d] %q: url must be http(s) or file", i, l.Name) + } + if strings.HasPrefix(l.URL, "http://") && l.InsecureSkipTLSVerify == false && false { + add("blocklist.lists[%d] %q: plain http is discouraged", i, l.Name) + } + } + switch l.Format { + case "auto", "hosts", "adblock", "plain", "rpz", "": + default: + add("blocklist.lists[%d] %q: unknown format %q", i, l.Name, l.Format) + } + if l.Refresh < 0 { + add("blocklist.lists[%d] %q: refresh must not be negative", i, l.Name) + } + } + if c.Block.Enabled { + if len(c.Block.Lists) == 0 && len(c.Block.LocalZones) == 0 && + len(c.Block.BlockEntries) == 0 && len(c.Block.AllowEntries) == 0 { + add("blocklist is enabled but no lists, local_zones or inline entries are configured") + } + } + + switch c.ACL.DefaultPolicy { + case "allow", "deny", "block_only": + default: + add("acl.default_policy must be allow, deny or block_only (got %q)", c.ACL.DefaultPolicy) + } + groups := map[string]bool{} + for i, g := range c.ACL.Groups { + if g.Name == "" { + add("acl.groups[%d]: name is required", i) + } + if groups[g.Name] { + add("acl.groups[%d]: duplicate group name %q", i, g.Name) + } + groups[g.Name] = true + switch g.Policy { + case "allow", "deny", "block_only": + default: + add("acl.groups[%d] %q: policy must be allow, deny or block_only (got %q)", i, g.Name, g.Policy) + } + for _, cidr := range g.Match.CIDRs { + if _, _, err := net.ParseCIDR(cidr); err != nil { + add("acl.groups[%d] %q: bad CIDR %q", i, g.Name, cidr) + } + } + for _, s := range g.Match.PTRSuffixes { + if !strings.HasSuffix(s, ".") { + s += "." + g.Match.PTRSuffixes[i] = s + } + } + if g.Match.Any && len(g.Match.CIDRs) == 0 && len(g.Match.PTRSuffixes) == 0 && len(g.Match.Tags) == 0 { + add("acl.groups[%d] %q: match.any is set but is also the fallback; make it the last group", i, g.Name) + } + } + if c.QueryLog.SampleRate < 0 || c.QueryLog.SampleRate > 1 { + add("qlog.sample_rate must be between 0 and 1") + } + + if c.Cluster.Enabled { + if len(c.Cluster.Valkey.Addrs) == 0 { + add("cluster.valkey.addrs must not be empty when cluster.enabled is true") + } + } + switch c.API.Auth.Mode { + case "none", "apikey", "basic": + default: + add("api.auth.mode must be none, apikey or basic (got %q)", c.API.Auth.Mode) + } + if c.API.Auth.Mode == "apikey" && len(c.API.Auth.APIKeys) == 0 && !c.API.Auth.TrustLoopback { + add("api.auth.mode is apikey but api.auth.api_keys is empty and trust_loopback is false: the API would be unauthenticated") + } + if c.API.Auth.Mode == "basic" && c.API.Auth.Username == "" { + add("api.auth.mode is basic but api.auth.username is empty") + } + if c.API.Auth.SessionTTL <= 0 { + add("api.auth.session_ttl must be > 0") + } + for _, p := range c.API.TrustedProxies { + if _, _, err := net.ParseCIDR(p); err != nil { + add("api.trusted_proxies: bad CIDR %q", p) + } + } + + switch c.Log.Level { + case "debug", "info", "warn", "error": + default: + add("log.level must be debug, info, warn or error (got %q)", c.Log.Level) + } + switch c.Log.Format { + case "text", "json": + default: + add("log.format must be text or json (got %q)", c.Log.Format) + } + + if len(errs) > 0 { + sort.SliceStable(errs, func(i, j int) bool { return errs[i].Error() < errs[j].Error() }) + return errors.Join(errs...) + } + return nil +} + +// Save atomically writes the configuration back to path as YAML. +func (c *Config) Save(path string) error { + data, err := Marshal(c) + if err != nil { + return err + } + return WriteFileAtomic(path, data, 0o600) +} + +// Marshal renders the config as YAML with a leading header comment. +func Marshal(c *Config) ([]byte, error) { + var sb strings.Builder + sb.WriteString("# fancy-dns configuration\n") + sb.WriteString("# Managed with care: the admin API rewrites this file, so keep it in git.\n") + enc := yaml.NewEncoder(&sb) + enc.SetIndent(2) + if err := enc.Encode(c); err != nil { + return nil, err + } + if err := enc.Close(); err != nil { + return nil, err + } + return []byte(sb.String()), nil +} + +// WriteFileAtomic writes data to path via a temp file + rename so readers +// never observe a partial document. +func WriteFileAtomic(path string, data []byte, perm os.FileMode) error { + dir := filepath.Dir(path) + if err := os.MkdirAll(dir, 0o755); err != nil { + return err + } + tmp, err := os.CreateTemp(dir, "."+filepath.Base(path)+".tmp*") + if err != nil { + return err + } + tmpName := tmp.Name() + defer os.Remove(tmpName) + if _, err := tmp.Write(data); err != nil { + tmp.Close() + return err + } + if err := tmp.Sync(); err != nil { + tmp.Close() + return err + } + if err := tmp.Close(); err != nil { + return err + } + if err := os.Chmod(tmpName, perm); err != nil { + return err + } + return os.Rename(tmpName, path) +} + +// AbsPath resolves p against the config's working directory when relative. +func (c *Config) AbsPath(p string) string { + if p == "" || filepath.IsAbs(p) { + return p + } + wd := c.Server.WorkingDir + if wd == "" { + wd = "." + } + return filepath.Join(wd, p) +} + +// CachePath returns the resolved bbolt cache path. +func (c *Config) CachePath() string { + if c.Cache.Persist.Path != "" { + return c.AbsPath(c.Cache.Persist.Path) + } + return c.AbsPath("data/cache.db") +} + +// QueryLogPath returns the resolved bbolt query-log path. +func (c *Config) QueryLogPath() string { + if c.QueryLog.Path != "" { + return c.AbsPath(c.QueryLog.Path) + } + return c.AbsPath("data/queries.db") +} + +// ListPath returns the on-disk path for a list source, or "" when the source +// is URL-only. +func (c *Config) ListPath(l ListSource) string { + if l.Path == "" { + return "" + } + return c.AbsPath(l.Path) +} + +// HasAPIAuth reports whether any authentication is enforced at all. +func (c *Config) HasAPIAuth() bool { + switch c.API.Auth.Mode { + case "none": + return false + case "apikey": + return len(c.API.Auth.APIKeys) > 0 || len(c.API.Auth.ReadOnlyAPIKeys) > 0 || !c.API.Auth.TrustLoopback + case "basic": + return true + } + return false +} + +// ClientIPs parses ACL group CIDRs into prefixes, skipping invalid input +// (Validate already reported them). +func (g Group) Prefixes() []netip.Prefix { + out := make([]netip.Prefix, 0, len(g.Match.CIDRs)) + for _, c := range g.Match.CIDRs { + p, err := netip.ParsePrefix(c) + if err != nil { + continue + } + out = append(out, p) + } + return out +} diff --git a/internal/config/store.go b/internal/config/store.go new file mode 100644 index 0000000..b7a9e38 --- /dev/null +++ b/internal/config/store.go @@ -0,0 +1,126 @@ +package config + +import ( + "sync" + "sync/atomic" +) + +// Store is the process-wide, hot-reloadable configuration holder. Readers take +// a snapshot pointer (cheap, no lock) and writers swap a fully-built *Config +// in atomically, so a request never observes a half-applied config. +type Store struct { + cur atomic.Pointer[Config] + mu sync.Mutex // serialises writers so LastError/Version stay coherent + // path is the file the config was loaded from, used by the API to + // persist mutations. + path string + // lastError records why the most recent reload attempt failed, so the + // health endpoint can report a stale-but-running state. + lastErr atomic.Pointer[string] + // generation increments on every successful swap. + generation atomic.Uint64 + // hooks run after a successful swap (server re-binds listeners etc). + hooksMu sync.RWMutex + hooks []func(*Config) +} + +// NewStore wraps cfg. +func NewStore(cfg *Config, path string) *Store { + s := &Store{path: path} + s.cur.Store(cfg) + return s +} + +// Get returns the current configuration snapshot. +func (s *Store) Get() *Config { return s.cur.Load() } + +// Path is the file this config was loaded from ("" when running without one). +func (s *Store) Path() string { return s.path } + +// Generation counts successful swaps; the cluster uses it to detect +// divergence between instances. +func (s *Store) Generation() uint64 { return s.generation.Load() } + +// LastError returns the error from the most recent failed reload, or nil. +func (s *Store) LastError() string { + if p := s.lastErr.Load(); p != nil { + return *p + } + return "" +} + +// Swap installs cfg as the current configuration. Callers are responsible for +// validating first; Swap itself only guards structural invariants that would +// otherwise panic subsystems. +func (s *Store) Swap(cfg *Config) error { + if cfg == nil { + return errNilConfig + } + if cfg.Cache.Shards <= 0 { + cfg.Cache.Shards = 32 + } + s.mu.Lock() + s.cur.Store(cfg) + s.generation.Add(1) + s.lastErr.Store(nil) + s.mu.Unlock() + s.runHooks(cfg) + return nil +} + +// Reload re-reads the backing file and swaps it in on success. On failure the +// previous configuration stays active and the error is recorded. +func (s *Store) Reload() error { + s.mu.Lock() + defer s.mu.Unlock() + if s.path == "" { + return errNoPath + } + cfg, err := Load(s.path) + if err != nil { + msg := err.Error() + s.lastErr.Store(&msg) + return err + } + // Preserve the working dir of the running instance so relative paths keep + // resolving the same way even if the file moved. + cfg.Server.WorkingDir = s.cur.Load().Server.WorkingDir + s.cur.Store(cfg) + s.generation.Add(1) + s.lastErr.Store(nil) + s.runHooks(cfg) + return nil +} + +// OnSwap registers a callback invoked with the new config after each swap. +// Hooks run outside the writer lock; a panicking hook is contained so one bad +// subsystem cannot take down a reload. +func (s *Store) OnSwap(fn func(*Config)) { + if fn == nil { + return + } + s.hooksMu.Lock() + s.hooks = append(s.hooks, fn) + s.hooksMu.Unlock() +} + +func (s *Store) runHooks(cfg *Config) { + s.hooksMu.RLock() + hooks := s.hooks + s.hooksMu.RUnlock() + for _, h := range hooks { + func() { + defer func() { _ = recover() }() + h(cfg) + }() + } +} + +type storeError string + +func (e storeError) Error() string { return string(e) } + +const ( + errNilConfig = storeError("config: refusing to swap a nil configuration") + errNoPath = storeError("config: no config file path known, cannot reload") +) diff --git a/internal/engine/engine.go b/internal/engine/engine.go new file mode 100644 index 0000000..1a76ce4 --- /dev/null +++ b/internal/engine/engine.go @@ -0,0 +1,1126 @@ +// Package engine is the query pipeline: the single place where a DNS question +// is turned into an answer. +// +// The order of operations matters and is the whole design: +// +// rate limit -> ACL policy -> local zone -> blocklist -> cache -> upstream +// +// Everything in front of the cache is cheap and lock-light; the cache is a +// single shard-local lookup; only a miss reaches the network. The pipeline is +// a plain method call chain rather than a plugin stack, because the hot path +// runs millions of times a second and a plugin registry is pure overhead. +package engine + +import ( + "context" + "net/netip" + "strconv" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/miekg/dns" + + "git.k8s-git-k6n.net/mats/fancy-dns/internal/acl" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/blocklist" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/cache" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/config" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/localzone" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/metrics" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/qlog" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/resolver" +) + +// Request describes one inbound query. +type Request struct { + // Msg is the parsed query. The engine may modify it (to attach an OPT or + // strip EDNS) so the transport can write it back out. + Msg *dns.Msg + // Remote is the client address. + Remote netip.Addr + // Transport is "udp", "tcp", "dot" or "doh", used for metrics labels and + // the log. + Transport string + // TCP reports whether the response may exceed the UDP size limit. + TCP bool + // Proto is the negotiated protocol string, kept for the log. + Proto string + // Start is when the request arrived. + Start time.Time + // ClientNames are reverse-DNS names for the client, if known. The server + // fills these in from its reverse cache so the ACL can match on names + // without a synchronous PTR lookup on the query path. + ClientNames []string + // ClientTags are derived labels for tag-based ACL matching. + ClientTags []string + // DoHPath records which DoH endpoint served the request, for the log. + DoHPath string +} + +// Response is the outcome plus the metadata the caller logs. +type Response struct { + Msg *dns.Msg + // Action is the pipeline classification. + Action qlog.Action + // Group is the matched ACL group. + Group string + // BlockSource is the blocklist/rule that blocked the query, for the log. + BlockSource string + // CacheHit reports whether the answer came from cache. + CacheHit bool + // CacheKind is "hit", "stale" or "miss". + CacheKind string + // Upstream is the address that answered. + Upstream string + // Duration is the total handling time. + Duration time.Duration + // Client is the resolved client string. + Client string + // Do reports whether the response carried the DNSSEC OK bit. + Do bool + // Truncated is set when the answer was shortened to fit the client buffer. + Truncated bool + // Drop is true when no response should be sent at all. + Drop bool + // GroupPolicy is the effective policy, for the UI. + GroupPolicy string +} + +// Engine holds the pipeline's swappable components. +type Engine struct { + cfgStore *config.Store + + acl atomic.Pointer[acl.Engine] + blocks *blocklist.Holder + cache *cache.Manager + aclH *acl.Holder + local *localzone.Holder + pool atomic.Pointer[resolver.Pool] + logger *qlog.Logger + reverse *ReverseCache + + // concurrency limiter: a buffered channel as a semaphore, which is + // cheaper than a sync.WaitGroup and gives us "try or fail" semantics. + // Held in an atomic pointer because a config swap replaces it while + // queries are in flight. + sem atomic.Pointer[chan struct{}] + semSize atomic.Int64 + + // perClient semaphores for clients with an explicit cap. + clientMu sync.Mutex + clientSems map[string]*clientLimiter + // rate limiters for clients with an explicit cap. + rateMu sync.Mutex + rateState map[string]*rateState + + // inflight is the current in-flight count for the gauge. + inflight atomic.Int64 + // dropped counts queries rejected by the concurrency cap. + dropped atomic.Uint64 + + // upstreamTimeout bounds a single upstream exchange. + upstreamTimeout atomic.Int64 + + // groupStats tracks per-group counters for the UI. + groupStats *groupStatTable + + // flusher is the app's flush callback, used by the admin API. + flusher atomic.Pointer[func()] +} + +type clientLimiter struct { + sem chan struct{} +} + +type rateState struct { + windowStart time.Time + count int +} + +// Options configures a new Engine. +type Options struct { + // Config is the hot-reloadable config store. + Config *config.Store + // Logger receives query entries; may be nil. + Logger *qlog.Logger + // Blocklists is the compiled blocklist holder. + Blocklists *blocklist.Holder + // Cache is the answer cache. + Cache *cache.Manager + // ACL is the compiled ACL engine. + ACL *acl.Holder + // Local is the local zone store. + Local *localzone.Holder + // Pool is the upstream pool. + Pool *resolver.Pool + // Reverse is the reverse-DNS cache used for name-based ACL matching. + Reverse *ReverseCache +} + +// New builds an Engine and wires the config-store hooks so a reload updates +// every swappable piece. +func New(opt Options) *Engine { + e := &Engine{ + cfgStore: opt.Config, + logger: opt.Logger, + blocks: opt.Blocklists, + cache: opt.Cache, + aclH: opt.ACL, + local: opt.Local, + reverse: opt.Reverse, + groupStats: newGroupStatTable(), + clientSems: make(map[string]*clientLimiter), + rateState: make(map[string]*rateState), + } + e.pool.Store(opt.Pool) + if e.cfgStore != nil { + cfg := e.cfgStore.Get() + e.applyConfig(cfg) + e.cfgStore.OnSwap(e.applyConfig) + } else if opt.Pool != nil { + e.upstreamTimeout.Store(int64(2 * time.Second)) + } + // Prefetching a stale entry re-runs the pipeline for just that key. + if e.cache != nil { + e.cache.SetPrefetcher(func(k cache.Key) { e.prefetch(k) }) + } + return e +} + +// applyConfig hot-swaps the components affected by a config change. +func (e *Engine) applyConfig(cfg *config.Config) { + semSize := cfg.Server.MaxConcurrent + if semSize < 1 { + semSize = 1024 + } + sem := make(chan struct{}, semSize) + e.sem.Store(&sem) + e.semSize.Store(int64(semSize)) + e.upstreamTimeout.Store(int64(cfg.Server.Timeouts.Upstre.D())) + + if e.aclH != nil { + e.aclH.Set(acl.Compile(cfg.ACL)) + metrics.SetACLGroups(len(cfg.ACL.Groups)) + } + if e.local != nil && len(cfg.Block.LocalZones) > 0 { + // Local zones are loaded asynchronously by the server; here we only + // record that a reload happened. + metrics.SetLocalRecords(e.local.Get().Count()) + } + if e.cache != nil { + e.cache.Resize(cfg.Cache.Size, cfg.Cache.Shards) + } + metrics.SetConcurrent(0) +} + +// Logger exposes the query logger (may be nil). +func (e *Engine) Logger() *qlog.Logger { return e.logger } + +// Cache exposes the answer cache (may be nil). +func (e *Engine) Cache() *cache.Manager { return e.cache } + +// Pool returns the current upstream pool. +func (e *Engine) Pool() *resolver.Pool { return e.pool.Load() } + +// Inflight is the number of queries currently being handled. +func (e *Engine) Inflight() int64 { return e.inflight.Load() } + +// Dropped is the number of queries rejected by the concurrency cap. +func (e *Engine) Dropped() uint64 { return e.dropped.Load() } + +// GroupStats returns per-group counters. +func (e *Engine) GroupStats() []acl.GroupSummary { + base := e.aclH.Get().Summaries() + return e.groupStats.merge(base) +} + +// Handle runs the full pipeline for one request and returns the response to +// send. It never returns nil: a synthetic SERVFAIL is the worst case. +func (e *Engine) Handle(ctx context.Context, req Request) Response { + start := req.Start + if start.IsZero() { + start = time.Now() + } + done := e.inflight.Add(1) + metrics.SetConcurrent(int(e.inflight.Load())) + defer func() { + e.inflight.Add(-1) + metrics.SetConcurrent(int(e.inflight.Load())) + _ = done + }() + + client := req.Remote.String() + decision := e.decide(req) + res := Response{Client: client, Group: decision.Group, GroupPolicy: string(decision.Policy)} + q := req.Msg + + // A malformed or empty query is answered with FORMERR before anything + // else looks at it. + if err := validate(q); err != nil { + res.Msg = formErr(q) + res.Action = qlog.ActionError + e.finish(req, res, start, decision) + return res + } + + qname := q.Question[0].Name + qtype := q.Question[0].Qtype + + // ACL deny wins over everything, including the local zone: an operator who + // denied a client means it. + if !decision.Allows() { + res.Msg = refuse(q, decision) + res.Action = qlog.ActionRefused + e.finish(req, res, start, decision) + return res + } + + // Concurrency cap. A per-client cap is checked first so one noisy client + // cannot exhaust the global budget. + if cl := decision.MaxConcurrent; cl > 0 { + if !e.acquireClient(client, cl) { + res.Msg = servFail(q, "client concurrency limit") + res.Action = qlog.ActionError + e.finish(req, res, start, decision) + return res + } + defer e.releaseClient(client) + } + // A nil semaphore means "no limit configured yet", which only happens + // before the first applyConfig; treat it as unbounded rather than dropping + // every query. + sem := e.sem.Load() + if sem != nil { + select { + case *sem <- struct{}{}: + defer func() { <-*sem }() + default: + e.dropped.Add(1) + res.Msg = servFail(q, "server overloaded") + res.Action = qlog.ActionError + e.finish(req, res, start, decision) + return res + } + } + + // Rate limiting. + if decision.RateLimit > 0 && !e.allowRate(client, decision.RateLimit) { + res.Msg = refuse(q, decision) + res.Action = qlog.ActionRefused + e.finish(req, res, start, decision) + return res + } + + // Group-level domain policy. + if e.groupBlocks(decision, qname) { + res.Msg = blockedResponse(q, e.blockCfg(), nil) + res.Action = qlog.ActionBlock + res.BlockSource = "acl:" + decision.Group + e.finish(req, res, start, decision) + return res + } + + // Local zone data. + if store := e.local.Get(); store != nil && store.Count() > 0 { + if local, ok := e.answerLocal(q, store); ok { + res.Msg = local + res.Action = qlog.ActionAllow + e.finish(req, res, start, decision) + return res + } + } + + // Blocklist. + var blocked *blocklist.Entry + if !decision.SkipBlocklist && e.blocks != nil { + if set := e.blocks.Get(); set != nil && set.Len() > 0 { + blocked = set.Match(qname) + } + } + if blocked != nil && !blocked.IsAllow() { + switch blocked.Action { + case blocklist.ActionDrop: + res.Action = qlog.ActionDrop + res.BlockSource = blocked.Source + res.Drop = true + res.Duration = time.Since(start) + e.finish(req, res, start, decision) + return res + default: + res.Msg = e.blockedMsg(q, blocked) + res.Action = qlog.ActionBlock + res.BlockSource = blocked.Source + res.CacheHit = false + e.finish(req, res, start, decision) + return res + } + } + + // Cache. A group that skips the cache still gets served from it on a + // prefetched entry only if the entry is fresh; we deliberately skip the + // lookup entirely to keep the guarantee honest. + if e.cache != nil && !decision.SkipCache { + key := cache.QueryKey(qname, qtype, q.Question[0].Qclass, cache.Do(q), 0) + hit := e.cache.Get(key) + switch hit.Kind { + case cache.Fresh, cache.Stale: + res.Msg = hit.Msg + res.CacheHit = true + res.CacheKind = hit.Kind.String() + res.Upstream = hit.Upstream + if hit.Kind == cache.Stale { + metrics.RecordStaleHit() + } + res.Msg = e.finalize(res.Msg, q, req) + res.Action = qlog.ActionCached + if hit.Kind == cache.Stale { + // The cached answer is expired, so its TTL is 0; hand back a + // short one so clients do not cache the stale copy forever. + res.Msg.Answer = ageTo(res.Msg.Answer, 1) + res.Msg.Ns = ageTo(res.Msg.Ns, 1) + } + e.finish(req, res, start, decision) + return res + default: + metrics.RecordMiss() + } + } + + // Upstream. + pool := e.pool.Load() + if pool == nil { + res.Msg = servFail(q, "no upstream configured") + res.Action = qlog.ActionError + e.finish(req, res, start, decision) + return res + } + fwd := e.prepareUpstream(q, req) + upStart := time.Now() + up, addr, err := pool.Exchange(ctx, fwd, decision.Upstreams, time.Duration(e.upstreamTimeout.Load())) + res.Duration = time.Since(start) + if err != nil || up == nil { + metrics.RecordUpstreamError() + res.Msg = servFail(q, "upstream failure: "+shortErr(err)) + res.Action = qlog.ActionError + e.finish(req, res, start, decision) + return res + } + metrics.RecordUpstreamLatency(addr, time.Since(upStart)) + reply := e.fromUpstream(q, up, req) + res.Msg = reply + res.Upstream = addr + res.Action = qlog.ActionAllow + // A non-success RCODE is reported as an error through finish's metrics + // call, so the counters stay in one place. + if reply.Rcode != dns.RcodeServerFailure && reply.Rcode != dns.RcodeSuccess { + res.Action = qlog.ActionError + } else if reply.Rcode == dns.RcodeServerFailure { + res.Action = qlog.ActionError + } + if e.cache != nil && !decision.SkipCache { + key := cache.QueryKey(qname, qtype, q.Question[0].Qclass, cache.Do(q), 0) + // Cache the untruncated upstream answer so a small client later does + // not poison the entry with a truncated copy. + if !up.Truncated { + e.cache.PutResponse(key, up, addr) + } + } + e.finish(req, res, start, decision) + return res +} + +// finish attaches duration, records metrics and writes the query log. +func (e *Engine) finish(req Request, res Response, start time.Time, d acl.Decision) { + if res.Duration == 0 { + res.Duration = time.Since(start) + } + metrics.Record(req.Transport, outcomeFor(res.Action), res.Duration) + if res.Action == qlog.ActionAllow && res.CacheHit { + metrics.Record(req.Transport, metrics.OutcomeCache, res.Duration) + } + e.groupStats.observe(d.Group, res) + if e.logger == nil { + return + } + if !e.logger.ShouldLog(res.Action) && !d.LogQueries { + return + } + entry := qlog.Entry{ + TS: start, + Client: res.Client, + Group: res.Group, + Duration: res.Duration.Milliseconds(), + Action: res.Action, + Upstream: res.Upstream, + List: res.BlockSource, + Protocol: req.Transport, + } + if res.Msg != nil { + entry.FromMsg(res.Msg) + } + e.logger.Log(entry) +} + +func outcomeFor(a qlog.Action) string { + switch a { + case qlog.ActionCached: + return metrics.OutcomeCache + case qlog.ActionBlock: + return metrics.OutcomeBlocked + case qlog.ActionError, qlog.ActionDrop: + return metrics.OutcomeError + case qlog.ActionRefused: + return metrics.OutcomeRefused + default: + return metrics.OutcomeUpstream + } +} + +// decide resolves the ACL decision for a request. +func (e *Engine) decide(req Request) acl.Decision { + eng := e.aclH.Get() + if eng == nil || eng.Count() == 0 { + return acl.Decision{Policy: acl.PolicyAllow, Default: true} + } + return eng.Match(acl.Client{ + IP: req.Remote, + Names: req.ClientNames, + Tags: req.ClientTags, + }) +} + +// groupBlocks applies a group's allow/deny domain lists. +func (e *Engine) groupBlocks(d acl.Decision, qname string) bool { + if len(d.DenyDomains) > 0 { + if acl.NewDomainSet(d.DenyDomains).Match(qname) { + return true + } + } + if len(d.AllowDomains) > 0 { + return !acl.NewDomainSet(d.AllowDomains).Match(qname) + } + return false +} + +// acquireClient takes a per-client slot, creating the limiter on demand. +func (e *Engine) acquireClient(client string, limit int) bool { + e.clientMu.Lock() + cl, ok := e.clientSems[client] + if !ok || cap(cl.sem) != limit { + cl = &clientLimiter{sem: make(chan struct{}, limit)} + e.clientSems[client] = cl + } + e.clientMu.Unlock() + select { + case cl.sem <- struct{}{}: + return true + default: + return false + } +} + +func (e *Engine) releaseClient(client string) { + e.clientMu.Lock() + cl, ok := e.clientSems[client] + e.clientMu.Unlock() + if !ok { + return + } + select { + case <-cl.sem: + default: + } +} + +// allowRate applies a fixed-window rate limit. A fixed window is fine here: +// the ACL cap exists to stop runaway clients, and it costs one map lookup. +func (e *Engine) allowRate(client string, perSec int) bool { + now := time.Now() + e.rateMu.Lock() + defer e.rateMu.Unlock() + st, ok := e.rateState[client] + if !ok { + st = &rateState{windowStart: now} + e.rateState[client] = st + } + if now.Sub(st.windowStart) >= time.Second { + st.windowStart = now + st.count = 0 + } + if st.count >= perSec { + return false + } + st.count++ + return true +} + +// answerLocal serves a question from the local zone store, converting a +// negative result into NXDOMAIN or NODATA with the zone's SOA. +func (e *Engine) answerLocal(q *dns.Msg, store *localzone.Store) (*dns.Msg, bool) { + if len(q.Question) == 0 { + return nil, false + } + question := q.Question[0] + res := store.Lookup(question) + if res.Delegated { + return nil, false + } + m := new(dns.Msg) + m.SetReply(q) + m.Authoritative = true + m.RecursionAvailable = true + if !res.Found { + // Only claim NXDOMAIN when we are actually authoritative for the name. + if res.Zone == "" { + return nil, false + } + if res.Authority != nil { + m.Rcode = dns.RcodeNameError + m.Ns = []dns.RR{res.Authority} + } else { + m.Rcode = dns.RcodeSuccess // NODATA without an SOA + } + return m, true + } + if len(res.Records) == 0 { + if res.Authority != nil { + m.Ns = []dns.RR{res.Authority} + } + return m, true + } + // CNAME answers for other types need the target resolved too; we do not + // chase here (the caller re-queries upstream if the target is not local), + // but a CNAME-only answer for a CNAME question is complete. + if len(m.Question) > 0 && m.Question[0].Qtype != res.Type { + if cname, ok := firstOfType(res.Records, dns.TypeCNAME); ok { + m.Answer = []dns.RR{cname} + return m, true + } + } + m.Answer = res.Records + return m, true +} + +func firstOfType(rrs []dns.RR, t uint16) (dns.RR, bool) { + for _, rr := range rrs { + if rr.Header().Rrtype == t { + return rr, true + } + } + return nil, false +} + +// blockedMsg synthesises the blocklist answer. +func (e *Engine) blockedMsg(q *dns.Msg, entry *blocklist.Entry) *dns.Msg { + cfg := e.blockCfg() + if entry != nil && entry.TTL > 0 { + c := cfg + c.ResponseTTL = config.Duration(entry.TTL) * config.Duration(time.Second) + cfg = c + } + if entry != nil { + switch entry.Action { + case blocklist.ActionNXDomain: + return nxDomain(q, uint32(cfg.ResponseTTL)) + case blocklist.ActionZero: + c := cfg + c.DefaultAction = "zero" + if entry.Response != "" { + c.ResponseIP = entry.Response + } + return sinkhole(q, c) + case blocklist.ActionRedirect: + return redirect(q, entry.Response, uint32(cfg.ResponseTTL)) + case blocklist.ActionCNAME: + return redirect(q, entry.Response, uint32(cfg.ResponseTTL)) + } + } + return blockedResponse(q, cfg, entry) +} + +func (e *Engine) blockCfg() config.Block { + if e.cfgStore == nil { + return config.Default().Block + } + return e.cfgStore.Get().Block +} + +// prepareUpstream builds the message to forward: the question plus the +// client's EDNS0 preferences, and nothing else (we never leak our own OPT to +// upstream, and we never forward the client's AD bit). +func (e *Engine) prepareUpstream(q *dns.Msg, req Request) *dns.Msg { + cfg := e.cfgStore.Get() + m := new(dns.Msg) + m.SetQuestion(q.Question[0].Name, q.Question[0].Qtype) + m.Question[0].Qclass = q.Question[0].Qclass + m.RecursionDesired = true + m.CheckingDisabled = q.CheckingDisabled + + var maxSize uint16 = cfg.DNS.MaxUDPSize + if o := q.IsEdns0(); o != nil { + if cfg.DNS.EDNS.PreserveEDNS0 { + for _, opt := range o.Option { + switch opt.Option() { + case dns.EDNS0SUBNET: + // Forward the client's ECS verbatim: the upstream uses it + // to pick a nearby anycast location, which is the whole + // point of the feature. + m.SetEdns0(maxSize, o.Do()) + if opt4, ok := opt.(*dns.EDNS0_SUBNET); ok { + appendECS(m, opt4) + } + continue + case dns.EDNS0PADDING, dns.EDNS0COOKIE: + // Cookie and padding are hop-by-hop; forwarding padding + // upstream is harmless, cookies are not. + if opt.Option() == dns.EDNS0PADDING { + m.SetEdns0(maxSize, o.Do()) + po := new(dns.EDNS0_PADDING) + po.Padding = opt4Padding(opt) + m.IsEdns0().Option = append(m.IsEdns0().Option, po) + } + continue + } + } + } + if o.Do() { + m.SetEdns0(maxSize, true) + } + if opt := o.Option; opt != nil { + for _, oo := range opt { + if oo.Option() == dns.EDNS0NSID { + // Our own NSID, not the client's. + if e.cfgStore == nil || !e.cfgStore.Get().DNS.HideIdentity { + nsid := new(dns.EDNS0_NSID) + nsid.Nsid = "fancy-dns" + if m.IsEdns0() == nil { + m.SetEdns0(maxSize, o.Do()) + } + m.IsEdns0().Option = append(m.IsEdns0().Option, nsid) + } + } + } + } + } + if m.IsEdns0() == nil { + m.SetEdns0(maxSize, false) + } + return m +} + +func appendECS(m *dns.Msg, src *dns.EDNS0_SUBNET) { + sub := new(dns.EDNS0_SUBNET) + sub.Code = src.Code + sub.Family = src.Family + sub.SourceNetmask = src.SourceNetmask + sub.SourceScope = src.SourceScope + sub.Address = src.Address + if m.IsEdns0() == nil { + m.SetEdns0(1232, false) + } + m.IsEdns0().Option = append(m.IsEdns0().Option, sub) +} + +func opt4Padding(opt dns.EDNS0) []byte { + if p, ok := opt.(*dns.EDNS0_PADDING); ok { + return p.Padding + } + return nil +} + +// fromUpstream converts an upstream answer into a client reply: the question +// and ID come from the client, the payload from upstream. +func (e *Engine) fromUpstream(q, up *dns.Msg, req Request) *dns.Msg { + m := new(dns.Msg) + m.SetReply(q) + m.Rcode = up.Rcode + if up.CheckingDisabled { + m.CheckingDisabled = true + } + if up.AuthenticatedData { + m.AuthenticatedData = true + } + if up.RecursionAvailable { + m.RecursionAvailable = true + } + m.Answer = up.Answer + m.Ns = up.Ns + // Keep the client's EDNS0 shape in the reply, but carry upstream's DO/extended + // rcode when present. + if o := up.IsEdns0(); o != nil { + m.SetEdns0(0, o.Do()) + if o.ExtendedRcode() != 0 || o.Version() != 0 { + ue := m.IsEdns0() + ue.SetExtendedRcode(uint16(o.ExtendedRcode())) + ue.SetVersion(o.Version()) + ue.SetDo(o.Do()) + } + } else if o := q.IsEdns0(); o != nil { + m.SetEdns0(0, o.Do()) + } else if e.cfgStore != nil && e.cfgStore.Get().DNS.MaxUDPSize > 512 { + m.SetEdns0(0, false) + } + if len(up.Question) > 0 { + m.Question = up.Question + } + return m +} + +// finalize prepares a response for the wire: attach EDNS0, apply the client's +// UDP size limit, and set the AD/CD bits as needed. +func (e *Engine) finalize(msg, q *dns.Msg, req Request) *dns.Msg { + if msg == nil { + return servFail(q, "nil response") + } + // Preserve the client's question verbatim (including the 0x20 case we may + // have canonicalised away). + if len(q.Question) > 0 { + msg.Question = q.Question + } + msg.Id = q.Id + msg.Response = true + if q.Opcode == dns.OpcodeQuery { + msg.RecursionDesired = q.RecursionDesired + } + if !req.TCP { + limit := clientUDPSize(q) + if limit > 0 && wouldOverflow(msg, limit) { + // RFC 2181 §9: TC means "ask again over TCP". Truncating to a + // question-only response is the correct, interoperable choice. + trunc := new(dns.Msg) + trunc.SetReply(q) + trunc.Truncated = true + if o := q.IsEdns0(); o != nil { + trunc.SetEdns0(0, o.Do()) + } + return trunc + } + } + return msg +} + +func clientUDPSize(q *dns.Msg) uint16 { + if o := q.IsEdns0(); o != nil { + if s := o.UDPSize(); s >= 512 { + return s + } + } + return 512 +} + +func wouldOverflow(m *dns.Msg, limit uint16) bool { + b, err := m.Pack() + if err != nil { + return true + } + return len(b) > int(limit) +} + +func ageTo(rrs []dns.RR, ttl uint32) []dns.RR { + for _, rr := range rrs { + rr.Header().Ttl = ttl + } + return rrs +} + +// prefetch re-resolves a stale key in the background. +func (e *Engine) prefetch(k cache.Key) { + if e.cache == nil { + return + } + pool := e.pool.Load() + if pool == nil { + return + } + q := new(dns.Msg) + q.SetQuestion(dns.Fqdn(k.Name), k.Type) + q.RecursionDesired = true + if k.DO { + q.SetEdns0(1232, true) + } + timeout := time.Duration(e.upstreamTimeout.Load()) + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + up, addr, err := pool.Exchange(ctx, q, nil, timeout) + if err != nil || up == nil || up.Truncated { + return + } + e.cache.PutResponse(k, up, addr) +} + +// validate rejects malformed queries early. +func validate(q *dns.Msg) error { + if q == nil { + return errMalformed + } + if q.Response { + return errMalformed + } + if len(q.Question) != 1 { + return errMalformed + } + if q.Opcode != dns.OpcodeQuery && q.Opcode != dns.OpcodeUpdate { + return errMalformed + } + name := q.Question[0].Name + if name == "" || len(name) > 255*4 { + return errMalformed + } + return nil +} + +var errMalformed = errString("malformed query") + +type errString string + +func (e errString) Error() string { return string(e) } + +func formErr(q *dns.Msg) *dns.Msg { + m := new(dns.Msg) + m.SetRcode(q, dns.RcodeFormatError) + return m +} + +func servFail(q *dns.Msg, reason string) *dns.Msg { + m := new(dns.Msg) + m.SetRcode(q, dns.RcodeServerFailure) + return m +} + +func nxDomain(q *dns.Msg, ttl uint32) *dns.Msg { + m := new(dns.Msg) + m.SetRcode(q, dns.RcodeNameError) + m.Ns = []dns.RR{syntheticSOA(q, ttl)} + return m +} + +// syntheticSOA is the authority record attached to synthesised negative +// answers. RFC 2308 requires a SOA in NXDOMAIN's authority section for the TTL +// to be honoured, and clients use it to cache the negative result. +func syntheticSOA(q *dns.Msg, ttl uint32) dns.RR { + name := "." + if len(q.Question) > 0 { + labels := strings.Split(strings.TrimSuffix(q.Question[0].Name, "."), ".") + if len(labels) >= 2 { + name = strings.Join(labels[len(labels)-2:], ".") + "." + } + } + if ttl == 0 { + ttl = 60 + } + soa := &dns.SOA{ + Hdr: dns.RR_Header{Name: name, Rrtype: dns.TypeSOA, Class: dns.ClassINET, Ttl: ttl}, + Ns: "ns.fancy-dns.local.", + Mbox: "hostmaster.fancy-dns.local.", + Serial: uint32(time.Now().Unix()), + Refresh: 3600, + Retry: 600, + Expire: 604800, + Minttl: ttl, + } + return soa +} + +// blockedResponse builds the configured blocklist answer. +func blockedResponse(q *dns.Msg, cfg config.Block, entry *blocklist.Entry) *dns.Msg { + ttl := uint32(cfg.ResponseTTL.D()) + if ttl == 0 { + ttl = 60 + } + switch cfg.DefaultAction { + case "drop": + // A drop is handled by the caller, which knows not to answer; reaching + // here means the caller wants a body, so return a timeout-style empty + // NOERROR. + m := new(dns.Msg) + m.SetReply(q) + return m + case "refused": + return refuseConfig(q) + case "zero": + return sinkhole(q, cfg) + case "redirect": + return redirect(q, cfg.RedirectName, ttl) + default: + return nxDomain(q, ttl) + } +} + +func refuseConfig(q *dns.Msg) *dns.Msg { + m := new(dns.Msg) + m.SetRcode(q, dns.RcodeRefused) + return m +} + +func refuse(q *dns.Msg, _ acl.Decision) *dns.Msg { return refuseConfig(q) } + +// sinkhole answers with the configured zero address, choosing the family from +// the question so a v4 client never gets a v6 answer. +func sinkhole(q *dns.Msg, cfg config.Block) *dns.Msg { + m := new(dns.Msg) + m.SetReply(q) + m.Authoritative = true + ttl := uint32(cfg.ResponseTTL.D()) + if ttl == 0 { + ttl = 60 + } + if len(q.Question) == 0 { + return m + } + switch q.Question[0].Qtype { + case dns.TypeA: + ip := cfg.ResponseIP + if ip == "" { + ip = "0.0.0.0" + } + rr, _ := dns.NewRR(q.Question[0].Name + " 0 IN A " + ip) + if rr != nil { + rr.Header().Ttl = ttl + m.Answer = []dns.RR{rr} + } + case dns.TypeAAAA: + ip := cfg.ResponseIPv6 + if ip == "" { + ip = "::" + } + rr, _ := dns.NewRR(q.Question[0].Name + " 0 IN AAAA " + ip) + if rr != nil { + rr.Header().Ttl = ttl + m.Answer = []dns.RR{rr} + } + default: + m.Ns = []dns.RR{syntheticSOA(q, ttl)} + } + return m +} + +// redirect answers with a CNAME to a configured name, plus an A/AAAA for the +// target when we know it (a CNAME to a name that does not resolve would be a +// worse answer than no CNAME at all). +func redirect(q *dns.Msg, target string, ttl uint32) *dns.Msg { + m := new(dns.Msg) + m.SetReply(q) + m.Authoritative = true + if target == "" { + return m + } + if len(q.Question) == 0 { + return m + } + cname, err := dns.NewRR(q.Question[0].Name + " 0 IN CNAME " + dns.Fqdn(target)) + if err != nil { + return m + } + cname.Header().Ttl = ttl + m.Answer = []dns.RR{cname} + switch q.Question[0].Qtype { + case dns.TypeA: + rr, _ := dns.NewRR(dns.Fqdn(target) + " 0 IN A 127.0.0.1") + if rr != nil { + rr.Header().Ttl = ttl + m.Answer = append(m.Answer, rr) + } + case dns.TypeAAAA: + rr, _ := dns.NewRR(dns.Fqdn(target) + " 0 IN AAAA ::1") + if rr != nil { + rr.Header().Ttl = ttl + m.Answer = append(m.Answer, rr) + } + } + return m +} + +func shortErr(err error) string { + if err == nil { + return "" + } + s := err.Error() + if len(s) > 120 { + s = s[:120] + } + return s +} + +// groupStatTable tracks per-group query and block counts for the UI. +type groupStatTable struct { + mu sync.RWMutex + stats map[string]*groupStat +} + +type groupStat struct { + queries uint64 + blocked uint64 + errors uint64 + cache uint64 +} + +func newGroupStatTable() *groupStatTable { + return &groupStatTable{stats: make(map[string]*groupStat)} +} + +func (t *groupStatTable) observe(group string, res Response) { + if group == "" { + group = "(default)" + } + t.mu.Lock() + s, ok := t.stats[group] + if !ok { + s = &groupStat{} + t.stats[group] = s + } + s.queries++ + switch res.Action { + case qlog.ActionBlock: + s.blocked++ + case qlog.ActionError, qlog.ActionDrop: + s.errors++ + case qlog.ActionCached: + s.cache++ + } + t.mu.Unlock() +} + +func (t *groupStatTable) merge(base []acl.GroupSummary) []acl.GroupSummary { + t.mu.RLock() + defer t.mu.RUnlock() + byName := make(map[string]acl.GroupSummary, len(base)) + for _, g := range base { + byName[g.Name] = g + } + // Include groups that were removed from the config but still have traffic. + for name := range t.stats { + if _, ok := byName[name]; ok { + continue + } + byName[name] = acl.GroupSummary{Name: name, Policy: string(acl.PolicyAllow)} + } + out := make([]acl.GroupSummary, 0, len(byName)) + for name, g := range byName { + if s, ok := t.stats[name]; ok { + g.QueryCount = s.queries + g.BlockedCount = s.blocked + } + out = append(out, g) + } + return out +} + +var _ = strconv.Itoa + +// Flush persists buffered state: the cache snapshot and the query log. It is +// wired to the server's flusher interface so the admin API can force a flush. +func (e *Engine) Flush() { + if p := e.flusher.Load(); p != nil { + (*p)() + } +} + +// SetFlusher installs the flush callback (set once during app wiring). +func (e *Engine) SetFlusher(fn func()) { + if fn == nil { + e.flusher.Store(nil) + return + } + e.flusher.Store(&fn) +} diff --git a/internal/engine/reverse.go b/internal/engine/reverse.go new file mode 100644 index 0000000..c416c76 --- /dev/null +++ b/internal/engine/reverse.go @@ -0,0 +1,202 @@ +package engine + +import ( + "context" + "net" + "sync" + "time" + + "github.com/miekg/dns" +) + +// ReverseCache maps client IPs to reverse-DNS names so the ACL can match on +// names without a synchronous PTR lookup on the query path. +// +// A miss schedules a background lookup and, for the duration of that lookup, +// matches on nothing. That is the right trade: a blocking PTR on the hot path +// would make a broken reverse zone a latency incident, whereas a miss only +// means an ACL rule keyed on a name does not fire for the first few queries. +type ReverseCache struct { + mu sync.RWMutex + entries map[string]reverseEntry + // negative caches the "no PTR exists" answer so we do not re-query for + // every query from the same client. + max int + ttl time.Duration + negative time.Duration + resolver *dns.Client + names string + timeout time.Duration + inflight map[string]bool +} + +type reverseEntry struct { + names []string + fetched time.Time + negative bool +} + +// ReverseOptions configures a ReverseCache. +type ReverseOptions struct { + // Max is the number of cached clients. + Max int + // TTL is how long a successful PTR is trusted. + TTL time.Duration + // NegativeTTL is how long a "no PTR" answer is trusted. + NegativeTTL time.Duration + // Nameserver is the server to ask, e.g. "9.9.9.9:53". Empty uses the + // system resolver via net.LookupAddr. + Nameserver string + // Timeout bounds one PTR lookup. + Timeout time.Duration +} + +// NewReverseCache builds a cache. +func NewReverseCache(opt ReverseOptions) *ReverseCache { + if opt.Max <= 0 { + opt.Max = 16384 + } + if opt.TTL <= 0 { + opt.TTL = 10 * time.Minute + } + if opt.NegativeTTL <= 0 { + opt.NegativeTTL = 30 * time.Minute + } + if opt.Timeout <= 0 { + opt.Timeout = 2 * time.Second + } + rc := &ReverseCache{ + entries: make(map[string]reverseEntry, 1024), + max: opt.Max, + ttl: opt.TTL, + negative: opt.NegativeTTL, + names: opt.Nameserver, + timeout: opt.Timeout, + inflight: make(map[string]bool), + } + if opt.Nameserver != "" { + rc.resolver = &dns.Client{Net: "udp", Timeout: opt.Timeout} + } + return rc +} + +// Names returns the cached reverse names for an IP, and whether the entry was +// present. The second return is false for a miss (including a cached negative). +func (r *ReverseCache) Names(ip string) ([]string, bool) { + if r == nil { + return nil, false + } + r.mu.RLock() + e, ok := r.entries[ip] + r.mu.RUnlock() + if !ok { + r.Prime(ip) + return nil, false + } + ttl := r.ttl + if e.negative { + ttl = r.negative + } + if time.Since(e.fetched) > ttl { + r.Prime(ip) + return e.names, true // serve the stale value while refreshing + } + return e.names, !e.negative +} + +// Prime schedules a background PTR lookup for ip, at most one in flight. +func (r *ReverseCache) Prime(ip string) { + if r == nil || ip == "" { + return + } + r.mu.Lock() + if r.inflight[ip] { + r.mu.Unlock() + return + } + r.inflight[ip] = true + r.mu.Unlock() + go r.lookup(ip) +} + +func (r *ReverseCache) lookup(ip string) { + defer func() { + r.mu.Lock() + delete(r.inflight, ip) + r.mu.Unlock() + }() + names, err := r.query(ip) + r.mu.Lock() + defer r.mu.Unlock() + if len(r.entries) >= r.max { + // Simple bound: drop the oldest quarter. A full LRU here would cost + // more than it saves, since the working set is usually small. + cutoff := time.Now().Add(-r.ttl) + removed := 0 + for k, e := range r.entries { + if e.fetched.Before(cutoff) || removed >= r.max/4 { + delete(r.entries, k) + removed++ + } + } + if removed == 0 { + for k := range r.entries { + delete(r.entries, k) + if removed >= r.max/4 { + break + } + } + } + } + r.entries[ip] = reverseEntry{ + names: names, + fetched: time.Now(), + negative: err != nil || len(names) == 0, + } +} + +func (r *ReverseCache) query(ip string) ([]string, error) { + if r.resolver == nil { + ctx, cancel := context.WithTimeout(context.Background(), r.timeout) + defer cancel() + return net.DefaultResolver.LookupAddr(ctx, ip) + } + name, err := dns.ReverseAddr(ip) + if err != nil { + return nil, err + } + m := new(dns.Msg) + m.SetQuestion(name, dns.TypePTR) + m.RecursionDesired = true + resp, _, err := r.resolver.Exchange(m, r.names) + if err != nil { + return nil, err + } + var out []string + for _, rr := range resp.Answer { + if ptr, ok := rr.(*dns.PTR); ok { + out = append(out, ptr.Ptr) + } + } + return out, nil +} + +// Len is the number of cached clients. +func (r *ReverseCache) Len() int { + if r == nil { + return 0 + } + r.mu.RLock() + defer r.mu.RUnlock() + return len(r.entries) +} + +// Flush empties the cache. +func (r *ReverseCache) Flush() { + if r == nil { + return + } + r.mu.Lock() + r.entries = make(map[string]reverseEntry, 1024) + r.mu.Unlock() +} diff --git a/internal/localzone/store.go b/internal/localzone/store.go new file mode 100644 index 0000000..137dd20 --- /dev/null +++ b/internal/localzone/store.go @@ -0,0 +1,451 @@ +// Package localzone serves authoritative data from DNS master files: split +// DNS setups, internal service records and the odd "answer this one name +// locally" need, all without a second nameserver to run. +package localzone + +import ( + "fmt" + "os" + "path/filepath" + "sort" + "strings" + "sync/atomic" + "time" + + "github.com/miekg/dns" + + "git.k8s-git-k6n.net/mats/fancy-dns/internal/zonefile" +) + +// Store is an immutable, compiled set of local zones. +type Store struct { + // zones maps a lowercased apex (with trailing dot) to its compiled zone. + zones map[string]*zone + // count is the number of records held, for the UI. + count int + // files lists the sources that produced this store. + files []string + // builtAt is the compile timestamp. + builtAt time.Time +} + +type zone struct { + origin string + // exact is keyed by "name|type". + exact map[string][]dns.RR + // wild holds "*.name" entries. + wild map[string]map[uint16][]dns.RR + // soa is the zone's SOA, used for NXDOMAIN and NODATA authority. + soa *dns.SOA + // ns holds the apex NS set. + ns map[uint16][]dns.RR + // delegations are the names served by NS records (a cut below the apex). + delegations map[string]bool + minTTL uint32 +} + +// Options tunes zone loading. +type Options struct { + // Origins overrides the per-file origin derivation. + Origins map[string]string + // MaxFiles bounds how many files are read (glob results included). + MaxFiles int +} + +// Load compiles every master file in paths. A path may be a glob. +func Load(paths []string, opt Options) (*Store, error) { + files, err := expand(paths, opt.MaxFiles) + if err != nil { + return nil, err + } + s := &Store{ + zones: make(map[string]*zone, len(files)), + files: files, + builtAt: time.Now(), + } + for _, f := range files { + origin := zonefile.OriginFromPath(f) + if o, ok := opt.Origins[f]; ok { + origin = dns.Fqdn(o) + } + z, err := zonefile.ParseFile(f, origin) + if err != nil { + return nil, fmt.Errorf("localzone: %w", err) + } + apex := strings.ToLower(z.Origin) + zz, ok := s.zones[apex] + if !ok { + zz = &zone{ + origin: apex, + exact: make(map[string][]dns.RR), + wild: make(map[string]map[uint16][]dns.RR), + delegations: make(map[string]bool), + ns: make(map[uint16][]dns.RR), + minTTL: 0xFFFFFFFF, + } + s.zones[apex] = zz + } + for _, rec := range z.Records { + if add(zz, rec) { + s.count++ + } + } + } + for _, zz := range s.zones { + if zz.minTTL == 0xFFFFFFFF { + zz.minTTL = 60 + } + } + return s, nil +} + +func add(z *zone, rec zonefile.Record) bool { + hdr := rec.RR.Header() + name := strings.ToLower(dns.Fqdn(hdr.Name)) + // SOA is zone metadata, not a queryable record. + if soa, ok := rec.RR.(*dns.SOA); ok { + z.soa = soa + return false + } + key := name + isWild := false + if strings.HasPrefix(name, "*.") { + key = name[2:] + isWild = true + } + // A record must live inside its zone; silently dropping out-of-zone data + // would be a surprise, so refuse it loudly instead. + if !inZone(key, z.origin) { + return false + } + // NS at or below the apex marks a delegation: the data below belongs to + // another server, so we must not answer for it. + if hdr.Rrtype == dns.TypeNS && !isWild { + if key == z.origin { + z.ns[hdr.Rrtype] = append(z.ns[hdr.Rrtype], rec.RR) + return true + } + z.delegations[key] = true + } + if hdr.Ttl < z.minTTL { + z.minTTL = hdr.Ttl + } + if isWild { + m, ok := z.wild[key] + if !ok { + m = make(map[uint16][]dns.RR) + z.wild[key] = m + } + m[hdr.Rrtype] = append(m[hdr.Rrtype], rec.RR) + return true + } + k := name + "|" + dns.TypeToString[hdr.Rrtype] + z.exact[k] = append(z.exact[k], rec.RR) + return true +} + +func inZone(name, origin string) bool { + if origin == "." { + return true + } + return name == origin || strings.HasSuffix(name, "."+origin) +} + +// expand turns configured paths (possibly globs) into a concrete file list. +func expand(paths []string, max int) ([]string, error) { + var out []string + seen := map[string]bool{} + for _, p := range paths { + if strings.ContainsAny(p, "*?[") { + matches, err := filepath.Glob(p) + if err != nil { + return nil, fmt.Errorf("localzone: bad glob %q: %w", p, err) + } + sort.Strings(matches) + for _, m := range matches { + if !seen[m] { + seen[m] = true + out = append(out, m) + } + } + continue + } + if !seen[p] { + seen[p] = true + out = append(out, p) + } + } + // A path that is a directory contributes its *.zone files, which is the + // natural thing to point at. + var expanded []string + for _, p := range out { + fi, err := os.Stat(p) + if err != nil { + return nil, fmt.Errorf("localzone: %w", err) + } + if fi.IsDir() { + entries, err := filepath.Glob(filepath.Join(p, "*.zone")) + if err != nil { + return nil, err + } + sort.Strings(entries) + expanded = append(expanded, entries...) + continue + } + expanded = append(expanded, p) + } + if max > 0 && len(expanded) > max { + expanded = expanded[:max] + } + return expanded, nil +} + +// Result is the outcome of a local lookup. +type Result struct { + // Found is true when the store has an answer (including a CNAME). + Found bool + // Records is the RRset for the queried type, or a CNAME when the name + // only has one. + Records []dns.RR + // Type is the type the records are for (may differ from the question for + // a CNAME answer). + Type uint16 + // Delegated is true when the name is served by another server. + Delegated bool + // Authority is the SOA for NXDOMAIN/NODATA responses. + Authority *dns.SOA + // TTL is the smallest TTL in the answer. + TTL uint32 + // Zone is the apex of the zone that answered. + Zone string +} + +// Lookup resolves a question against the local store. It does not chase CNAMEs +// across the local store; the handler re-queries, which keeps the wildcard and +// delegation rules in one place. +func (s *Store) Lookup(q dns.Question) Result { + if s == nil || len(s.zones) == 0 { + return Result{} + } + name := strings.ToLower(dns.Fqdn(q.Name)) + qtype := q.Qtype + // The cache and the resolver both skip the root and the local reverse + // zones, but a local zone may legitimately define them, so check first. + var best *zone + for apex, z := range s.zones { + if !inZone(name, apex) { + continue + } + if best == nil || len(apex) > len(best.origin) { + best = z + } + } + if best == nil { + return Result{} + } + if qtype == dns.TypeANY { + return s.any(best, name) + } + // A delegation means "ask them, not me". + if best.delegations[name] { + return Result{Found: false, Delegated: true, Zone: best.origin, Authority: best.soa, TTL: best.minTTL} + } + if rrs, ok := best.exact[name+"|"+dns.TypeToString[qtype]]; ok { + return s.result(best, name, qtype, rrs) + } + // Wildcard: "*.zone" covers one label; RFC 1034 §4.3.3 wants the closest + // enclosing wildcard, so try progressively shorter parents. + if rrs, ok := closestWildcard(best, name, qtype); ok { + return s.result(best, name, qtype, rrs) + } + // A CNAME at the name answers any other type. + if qtype != dns.TypeCNAME { + if rrs, ok := best.exact[name+"|CNAME"]; ok { + return s.result(best, name, dns.TypeCNAME, rrs) + } + } + // NODATA: the name exists but has no records of this type. + if nameExists(best, name) { + return Result{Found: true, Authority: best.soa, Zone: best.origin, TTL: best.minTTL} + } + return Result{Found: false, Authority: best.soa, Zone: best.origin, TTL: best.minTTL} +} + +func (s *Store) result(z *zone, name string, qtype uint16, rrs []dns.RR) Result { + min := uint32(0xFFFFFFFF) + for _, rr := range rrs { + if t := rr.Header().Ttl; t < min { + min = t + } + } + if min == 0xFFFFFFFF { + min = z.minTTL + } + return Result{Found: true, Records: rrs, Type: qtype, TTL: min, Zone: z.origin, Authority: z.soa} +} + +func (s *Store) any(z *zone, name string) Result { + var out []dns.RR + if rrs, ok := z.exact[name+"|A"]; ok { + out = append(out, rrs...) + } + if rrs, ok := z.exact[name+"|AAAA"]; ok { + out = append(out, rrs...) + } + if rrs, ok := z.exact[name+"|CNAME"]; ok { + out = append(out, rrs...) + } + if rrs, ok := z.exact[name+"|MX"]; ok { + out = append(out, rrs...) + } + if rrs, ok := z.exact[name+"|TXT"]; ok { + out = append(out, rrs...) + } + if rrs, ok := z.exact[name+"|SRV"]; ok { + out = append(out, rrs...) + } + if rrs, ok := z.exact[name+"|NS"]; ok { + out = append(out, rrs...) + } + if len(out) == 0 { + if rrs, ok := closestWildcardAny(z, name); ok { + out = append(out, rrs...) + } + } + if len(out) == 0 { + return Result{Found: nameExists(z, name), Authority: z.soa, Zone: z.origin, TTL: z.minTTL} + } + return s.result(z, name, dns.TypeANY, out) +} + +func closestWildcard(z *zone, name string, qtype uint16) ([]dns.RR, bool) { + for parent := parentOf(name); parent != ""; parent = parentOf(parent) { + if m, ok := z.wild[parent]; ok { + if rrs, ok := m[qtype]; ok { + return rrs, true + } + } + if z.delegations[parent] { + return nil, false + } + } + return nil, false +} + +func closestWildcardAny(z *zone, name string) ([]dns.RR, bool) { + for parent := parentOf(name); parent != ""; parent = parentOf(parent) { + if m, ok := z.wild[parent]; ok { + var out []dns.RR + for _, rrs := range m { + out = append(out, rrs...) + } + if len(out) > 0 { + return out, true + } + } + } + return nil, false +} + +func parentOf(name string) string { + i := strings.IndexByte(name, '.') + if i < 0 { + return "" + } + return name[i+1:] +} + +func nameExists(z *zone, name string) bool { + prefix := name + "|" + for k := range z.exact { + if strings.HasPrefix(k, prefix) { + return true + } + } + if _, ok := z.wild[name]; ok { + return true + } + return z.delegations[name] +} + +// Count is the number of records in the store. +func (s *Store) Count() int { + if s == nil { + return 0 + } + return s.count +} + +// Zones lists the zone apexes. +func (s *Store) Zones() []string { + if s == nil { + return nil + } + out := make([]string, 0, len(s.zones)) + for z := range s.zones { + out = append(out, z) + } + sort.Strings(out) + return out +} + +// Files lists the source files. +func (s *Store) Files() []string { + if s == nil { + return nil + } + return s.files +} + +// BuiltAt is the compile timestamp. +func (s *Store) BuiltAt() time.Time { + if s == nil { + return time.Time{} + } + return s.builtAt +} + +// Records returns every record in a zone as zone-file text, for the API and +// the UI's zone browser. +func (s *Store) Records(origin string) []string { + if s == nil { + return nil + } + z, ok := s.zones[strings.ToLower(dns.Fqdn(origin))] + if !ok { + return nil + } + var out []string + for _, rrs := range z.exact { + for _, rr := range rrs { + out = append(out, rr.String()) + } + } + for name, m := range z.wild { + for _, rrs := range m { + for _, rr := range rrs { + out = append(out, strings.Replace(rr.String(), "\t"+rr.Header().Name, "\t*."+name, 1)) + } + } + } + sort.Strings(out) + return out +} + +// Holder keeps the current Store for the hot path. +type Holder struct{ cur atomic.Pointer[Store] } + +// NewHolder wraps a store. +func NewHolder(s *Store) *Holder { + h := &Holder{} + if s != nil { + h.cur.Store(s) + } + return h +} + +// Get returns the current store (nil when nothing is configured). +func (h *Holder) Get() *Store { return h.cur.Load() } + +// Set installs a new store. +func (h *Holder) Set(s *Store) { h.cur.Store(s) } diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go new file mode 100644 index 0000000..fcd4094 --- /dev/null +++ b/internal/metrics/metrics.go @@ -0,0 +1,478 @@ +// Package metrics holds the Prometheus collectors and the in-process +// time-series buffers that back the admin UI's charts. +// +// The UI needs finer-grained series than Prometheus's default histogram gives, +// so a small fixed-bucket ring per metric is kept in memory: cheap, bounded, +// and enough to draw a dashboard without shipping raw samples to a browser. +package metrics + +import ( + "math" + "sync" + "sync/atomic" + "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/collectors" + "github.com/prometheus/client_golang/prometheus/promhttp" + "net/http" +) + +// Namespace prefixes every metric name. +const Namespace = "fancydns" + +// Counters for the request pipeline. +var ( + queriesTotal prometheus.Counter + blockedTotal prometheus.Counter + cacheHits prometheus.Counter + cacheMisses prometheus.Counter + cacheStaleHits prometheus.Counter + upstreamErrors prometheus.Counter + dnsErrors prometheus.Counter + dropsTotal prometheus.Counter + refusedTotal prometheus.Counter +) + +// Gauges for live state. +var ( + upstreamHealth *prometheus.GaugeVec + concurrentNow prometheus.Gauge + listCount prometheus.Gauge + listBytes prometheus.Gauge + aclGroups prometheus.Gauge + localRecords prometheus.Gauge + up prometheus.Gauge +) + +// Histograms for latency, with buckets that matter for DNS: sub-millisecond +// cache hits, a few milliseconds for a local answer, tens for an upstream. +var ( + queryDuration *prometheus.HistogramVec + upstreamDur *prometheus.HistogramVec + parseDuration prometheus.Histogram +) + +var registerOnce sync.Once + +// Registry is the registry served on /metrics. +var Registry = prometheus.NewRegistry() + +// initCollectors registers everything exactly once. It is safe to call from +// several components. +func initCollectors() { + registerOnce.Do(func() { + queriesTotal = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: Namespace, Name: "queries_total", + Help: "Total DNS queries received across all transports.", + }) + blockedTotal = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: Namespace, Name: "blocked_total", + Help: "Queries answered with a blocklist response.", + }) + cacheHits = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: Namespace, Name: "cache_hits_total", + Help: "Cache hits (fresh).", + }) + cacheMisses = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: Namespace, Name: "cache_misses_total", + Help: "Cache misses that required an upstream lookup.", + }) + cacheStaleHits = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: Namespace, Name: "cache_stale_hits_total", + Help: "Answers served from the serve-stale window.", + }) + upstreamErrors = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: Namespace, Name: "upstream_errors_total", + Help: "Upstream exchange failures.", + }) + dnsErrors = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: Namespace, Name: "errors_total", + Help: "Responses with a non-success RCODE.", + }) + dropsTotal = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: Namespace, Name: "dropped_total", + Help: "Queries dropped without a response (blocklist drop or overload).", + }) + refusedTotal = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: Namespace, Name: "refused_total", + Help: "Queries answered REFUSED by ACL policy.", + }) + upstreamHealth = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: Namespace, Name: "upstream_health", + Help: "1 when an upstream is up, 0 when down.", + }, []string{"addr", "proto"}) + concurrentNow = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: Namespace, Name: "concurrent_queries", + Help: "Queries currently in flight.", + }) + listCount = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: Namespace, Name: "blocklist_rules", + Help: "Total compiled blocklist rules.", + }) + listBytes = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: Namespace, Name: "blocklist_source_bytes", + Help: "Bytes of source data compiled into the blocklist.", + }) + aclGroups = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: Namespace, Name: "acl_groups", + Help: "Number of configured ACL groups.", + }) + localRecords = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: Namespace, Name: "local_records", + Help: "Records in the local zone store.", + }) + up = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: Namespace, Name: "up", + Help: "1 if the process is serving, 0 otherwise.", + }) + queryDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: Namespace, Name: "query_duration_seconds", + Help: "End-to-end query handling time.", + Buckets: []float64{0.0002, 0.0005, 0.001, 0.002, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5}, + }, []string{"transport", "outcome"}) + upstreamDur = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: Namespace, Name: "upstream_duration_seconds", + Help: "Time spent talking to a specific upstream.", + Buckets: []float64{0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2}, + }, []string{"addr"}) + parseDuration = prometheus.NewHistogram(prometheus.HistogramOpts{ + Namespace: Namespace, Name: "blocklist_compile_seconds", + Help: "Time to fetch and compile all blocklist sources.", + Buckets: []float64{0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30}, + }) + + Registry.MustRegister( + queriesTotal, blockedTotal, cacheHits, cacheMisses, cacheStaleHits, + upstreamErrors, dnsErrors, dropsTotal, refusedTotal, upstreamHealth, + concurrentNow, listCount, listBytes, aclGroups, localRecords, up, + queryDuration, upstreamDur, parseDuration, + collectors.NewGoCollector(), + collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}), + ) + }) +} + +// Outcome labels for queryDuration. +const ( + OutcomeCache = "cache" + OutcomeBlocked = "blocked" + OutcomeLocal = "local" + OutcomeUpstream = "upstream" + OutcomeError = "error" + OutcomeRefused = "refused" + OutcomeDropped = "dropped" +) + +// Record is the single entry point for a pipeline outcome. Both the Prometheus +// counters and the in-process atomics the dashboard reads are bumped here, so +// the two views can never disagree. +// +// Callers must not also call CountBlocked/CountError/etc: that would double +// count. Those helpers exist for the few places that report an outcome without +// going through Record. +func Record(transport, outcome string, d time.Duration) { + initCollectors() + queriesTotal.Inc() + queries.Add(1) + if d > 0 { + queryDuration.WithLabelValues(transport, outcome).Observe(d.Seconds()) + } + switch outcome { + case OutcomeCache: + cacheHits.Inc() + hits.Add(1) + case OutcomeBlocked: + blockedTotal.Inc() + blocked.Add(1) + case OutcomeError: + dnsErrors.Inc() + errs.Add(1) + case OutcomeDropped: + dropsTotal.Inc() + drops.Add(1) + // A drop is both a drop and an error for the operator's purposes. + errs.Add(1) + case OutcomeRefused: + refusedTotal.Inc() + refused.Add(1) + } +} + +// RecordMiss counts a cache miss. A miss is not an error: it just means the +// cache could not answer, so only the Prometheus counter moves. +func RecordMiss() { initCollectors(); cacheMisses.Inc() } + +// RecordStaleHit counts a serve-stale hit. +func RecordStaleHit() { initCollectors(); cacheStaleHits.Inc() } + +// RecordUpstreamError counts an upstream failure. +func RecordUpstreamError() { initCollectors(); upstreamErrors.Inc() } + +// RecordUpstreamLatency observes a single upstream exchange. +func RecordUpstreamLatency(addr string, d time.Duration) { + initCollectors() + upstreamDur.WithLabelValues(addr).Observe(d.Seconds()) +} + +// SetConcurrent publishes the in-flight gauge. +func SetConcurrent(n int) { initCollectors(); concurrentNow.Set(float64(n)) } + +// SetUp publishes the liveness gauge. +func SetUp(v bool) { + initCollectors() + if v { + up.Set(1) + return + } + up.Set(0) +} + +// SetUpstreamHealth publishes per-upstream health. +func SetUpstreamHealth(addr, proto string, healthy bool) { + initCollectors() + v := 0.0 + if healthy { + v = 1 + } + upstreamHealth.WithLabelValues(addr, proto).Set(v) +} + +// SetBlocklistStats publishes the compiled rule count and source bytes. +func SetBlocklistStats(rules int, sourceBytes int64) { + initCollectors() + listCount.Set(float64(rules)) + listBytes.Set(float64(sourceBytes)) +} + +// SetACLGroups publishes the group count. +func SetACLGroups(n int) { initCollectors(); aclGroups.Set(float64(n)) } + +// SetLocalRecords publishes the local zone record count. +func SetLocalRecords(n int) { initCollectors(); localRecords.Set(float64(n)) } + +// RecordBlocklistCompile observes a full compile pass. +func RecordBlocklistCompile(d time.Duration) { + initCollectors() + parseDuration.Observe(d.Seconds()) +} + +// Handler returns the HTTP handler for /metrics. +func Handler() http.Handler { + initCollectors() + return promhttp.HandlerFor(Registry, promhttp.HandlerOpts{ + Registry: Registry, + EnableOpenMetrics: true, + MaxRequestsInFlight: 4, + }) +} + +// Totals is a point-in-time snapshot of the counters, used by the dashboard. +type Totals struct { + Queries uint64 + Blocked uint64 + Hits uint64 + Misses uint64 + StaleHits uint64 + Errors uint64 + Drops uint64 + Refused uint64 + Concurrent int64 +} + +var ( + queries atomic.Uint64 + blocked atomic.Uint64 + hits atomic.Uint64 + misses atomic.Uint64 + staleHits atomic.Uint64 + errs atomic.Uint64 + drops atomic.Uint64 + refused atomic.Uint64 + inflight atomic.Int64 +) + +// TotalsNow returns the current totals. These mirror the Prometheus counters +// (both are incremented together) so the dashboard does not have to scrape. +func TotalsNow() Totals { + return Totals{ + Queries: queries.Load(), + Blocked: blocked.Load(), + Hits: hits.Load(), + Misses: misses.Load(), + StaleHits: staleHits.Load(), + Errors: errs.Load(), + Drops: drops.Load(), + Refused: refused.Load(), + Concurrent: inflight.Load(), + } +} + +func bumpCounter(c *atomic.Uint64) func() { + c.Add(1) + return func() { c.Add(^uint64(0)) } +} + +// BeginQuery marks a query as in flight and returns its completion func. +func BeginQuery() func() { + inflight.Add(1) + queries.Add(1) + return func() { inflight.Add(-1) } +} + +// CountBlocked increments the blocked counter. +func CountBlocked() { blocked.Add(1) } + +// CountError increments the error counter. +func CountError() { errs.Add(1) } + +// CountDrop increments the drop counter. +func CountDrop() { drops.Add(1) } + +// CountRefused increments the refused counter. +func CountRefused() { refused.Add(1) } + +// Series is a fixed-window time series for the UI charts. +type Series struct { + // Buckets are the sample timestamps (epoch seconds), oldest first. + Buckets []int64 `json:"t"` + Values []int64 `json:"v"` + // ResolutionMS is the bucket width. + ResolutionMS int64 `json:"resolution_ms"` +} + +// Ring is a fixed-bucket counter ring: a circular array of counts indexed by +// bucket number. Lock-free on the write path, which matters because it is hit +// once per DNS query. +type Ring struct { + buckets []atomic.Int64 + res time.Duration + start atomic.Int64 // first bucket timestamp, epoch seconds + pos atomic.Uint32 + sealed atomic.Bool + count int +} + +// NewRing builds a ring of n buckets at the given resolution. +func NewRing(n int, res time.Duration) *Ring { + if n <= 0 { + n = 120 + } + if res <= 0 { + res = 5 * time.Second + } + r := &Ring{buckets: make([]atomic.Int64, n), res: res, count: n} + r.start.Store(time.Now().Unix()) + return r +} + +// Inc bumps the current bucket by 1, rotating when the window advances. +func (r *Ring) Inc() { r.Add(1) } + +// Add bumps the current bucket. +func (r *Ring) Add(delta int64) { + if r == nil { + return + } + now := time.Now().Unix() + bucket := now / int64(r.res.Seconds()) + start := r.start.Load() + // If more than count buckets elapsed, we skipped a full window: reset + // everything so a long idle period does not report phantom zeros followed + // by a sudden spike. + if bucket-start >= int64(r.count) { + if r.start.CompareAndSwap(start, bucket-int64(r.count)+1) { + for i := range r.buckets { + r.buckets[i].Store(0) + } + } + start = r.start.Load() + } + if bucket < start { + return + } + idx := int(bucket - start) + if idx >= r.count { + idx = r.count - 1 + } + // Store at the position implied by the bucket so readers can map index to + // time without extra bookkeeping. + r.buckets[idx%r.count].Add(delta) +} + +// AddAt bumps an explicit bucket (used by tests). +func (r *Ring) AddAt(bucket int64, delta int64) { + start := r.start.Load() + idx := int(bucket - start) + if idx < 0 || idx >= r.count { + return + } + r.buckets[idx%r.count].Add(delta) +} + +// Series snapshots the ring into aligned arrays. +func (r *Ring) Snapshot() ([]int64, []int64) { + if r == nil { + return nil, nil + } + start := r.start.Load() + now := time.Now().Unix() + step := int64(r.res.Seconds()) + ts := make([]int64, r.count) + vs := make([]int64, r.count) + for i := 0; i < r.count; i++ { + b := start + int64(i) + ts[i] = b * step + vs[i] = r.buckets[i%r.count].Load() + } + // Trim leading buckets that are in the future (ring not yet filled) so the + // chart starts at "now" rather than at zero time. + if now > ts[len(ts)-1] { + shift := int((now-ts[len(ts)-1])/step) + 1 + if shift >= len(ts) { + return []int64{now}, []int64{0} + } + ts = append(ts[:0], ts[shift:]...) + vs = append(vs[:0], vs[shift:]...) + } + return ts, vs +} + +// Series is the snapshot form. +func (r *Ring) Series() Series { + ts, vs := r.Snapshot() + return Series{Buckets: ts, Values: vs, ResolutionMS: r.res.Milliseconds()} +} + +// LCG is a tiny deterministic PRNG for jitter, so the test suite does not +// depend on the global rand. +type LCG struct{ s uint64 } + +func NewLCG(seed uint64) *LCG { return &LCG{s: seed | 1} } + +func (l *LCG) Next() uint64 { + l.s = l.s*6364136223846793005 + 1442695040888963407 + return l.s >> 11 +} + +func (l *LCG) Float() float64 { return float64(l.Next()) / float64(1<<53) } + +// SafeFloat converts an int count to a float for charting, guarding NaN. +func SafeFloat(n int64) float64 { + if n <= 0 { + return 0 + } + return float64(n) +} + +// Percent computes a safe percentage. +func Percent(part, total int64) float64 { + if total <= 0 { + return 0 + } + p := float64(part) / float64(total) * 100 + if math.IsNaN(p) || math.IsInf(p, 0) { + return 0 + } + return p +} diff --git a/internal/qlog/counts.go b/internal/qlog/counts.go new file mode 100644 index 0000000..425e149 --- /dev/null +++ b/internal/qlog/counts.go @@ -0,0 +1,148 @@ +package qlog + +import ( + "math/rand/v2" + "sort" + "sync" + "time" +) + +// randFloat is a 0..1 sample draw, isolated so tests can reason about +// sampling without seeding the global source. +func randFloat() float64 { return rand.Float64() } + +// domainCount is a rolling per-domain counter. +type domainCount struct { + name string + qtype uint16 + qtypeS string + total uint64 + blocked uint64 + last time.Time +} + +// domainCounts is a bounded, TTL-evicting map of domain counters. It replaces +// the hot half of "what is everyone asking for" without the cost of a sorted +// set on every query. +type domainCounts struct { + mu sync.Mutex + counts map[string]*domainCount + limit int + ttl time.Duration + now func() time.Time +} + +func newDomainCounts(limit int, ttl time.Duration) *domainCounts { + return &domainCounts{ + counts: make(map[string]*domainCount, 1024), + limit: limit, + ttl: ttl, + now: time.Now, + } +} + +func countKey(name string, qtype uint16) string { + return name + "|" + itoa(int(qtype)) +} + +func itoa(n int) string { + if n == 0 { + return "0" + } + var buf [8]byte + i := len(buf) + for n > 0 { + i-- + buf[i] = byte('0' + n%10) + n /= 10 + } + return string(buf[i:]) +} + +// observe records a query against its domain counter. +func (d *domainCounts) observe(e Entry) { + if e.Name == "" { + return + } + key := countKey(e.Name, e.QType) + now := d.now() + d.mu.Lock() + c, ok := d.counts[key] + if !ok { + if len(d.counts) >= d.limit { + d.evictLocked(now) + } + c = &domainCount{name: trimDot(e.Name), qtype: e.QType, qtypeS: e.QTypeStr} + d.counts[key] = c + } + c.total++ + if e.Blocked { + c.blocked++ + } + c.last = now + d.mu.Unlock() +} + +// evictLocked removes expired counters, and if that is not enough, the oldest +// quarter. Callers hold d.mu. +func (d *domainCounts) evictLocked(now time.Time) { + cutoff := now.Add(-d.ttl) + removed := 0 + for k, c := range d.counts { + if c.last.Before(cutoff) { + delete(d.counts, k) + removed++ + } + } + if removed == 0 && len(d.counts) > 0 { + // Nothing has expired (a very busy window): drop the oldest quarter. + type kv struct { + k string + t time.Time + } + all := make([]kv, 0, len(d.counts)) + for k, c := range d.counts { + all = append(all, kv{k, c.last}) + } + sort.Slice(all, func(i, j int) bool { return all[i].t.Before(all[j].t) }) + n := len(all) / 4 + if n < 1 { + n = 1 + } + for i := 0; i < n && i < len(all); i++ { + delete(d.counts, all[i].k) + } + } +} + +// top returns the n hottest domains. +func (d *domainCounts) top(n int, blockedOnly bool) []DomainCount { + if n <= 0 { + n = 25 + } + d.mu.Lock() + out := make([]DomainCount, 0, n) + for _, c := range d.counts { + if blockedOnly && c.blocked == 0 { + continue + } + dc := DomainCount{Name: c.name, Count: c.total, Blocked: c.blocked, QType: c.qtype, QTypeS: c.qtypeS} + if blockedOnly { + dc.Count = c.blocked + } + out = append(out, dc) + } + d.mu.Unlock() + sort.Slice(out, func(i, j int) bool { return out[i].Count > out[j].Count }) + if len(out) > n { + out = out[:n] + } + return out +} + +func trimDot(s string) string { + if n := len(s); n > 1 && s[n-1] == '.' { + return s[:n-1] + } + return s +} diff --git a/internal/qlog/qlog.go b/internal/qlog/qlog.go new file mode 100644 index 0000000..9db6b73 --- /dev/null +++ b/internal/qlog/qlog.go @@ -0,0 +1,712 @@ +// Package qlog records DNS queries for the admin console: a live in-memory +// ring for the SSE stream, a bbolt-backed ring for the query log, and rolling +// per-domain counters that back the "top blocked" and "top queried" panels. +// +// The write path is deliberately allocation-light: entries are value types, the +// live ring is a fixed array, and bbolt writes are batched on a background +// goroutine so a burst of queries never blocks a DNS response. +package qlog + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "sync" + "sync/atomic" + "time" + + "github.com/miekg/dns" + bolt "go.etcd.io/bbolt" +) + +// Action is the outcome classification shown in the log. +type Action string + +const ( + // ActionAllow is a normal resolution. + ActionAllow Action = "allow" + // ActionBlock is a blocklist hit. + ActionBlock Action = "block" + // ActionCached is a cache hit. + ActionCached Action = "cached" + // ActionError is a SERVFAIL or other failure. + ActionError Action = "error" + // ActionDrop is a query answered with silence. + ActionDrop Action = "drop" + // ActionRefused is an ACL refusal. + ActionRefused Action = "refused" +) + +// Entry is one logged query. +type Entry struct { + ID uint64 `json:"id"` + TS time.Time `json:"ts"` + Client string `json:"client"` + Group string `json:"client_group,omitempty"` + Name string `json:"name"` + QType uint16 `json:"qtype"` + QTypeStr string `json:"qtype_name"` + RCode int `json:"rcode"` + Action Action `json:"action"` + Response string `json:"response,omitempty"` + Duration int64 `json:"duration_ms"` + Upstream string `json:"upstream,omitempty"` + List string `json:"list,omitempty"` + Protocol string `json:"protocol,omitempty"` + // Blocked is a convenience mirror of Action == ActionBlock so the UI can + // filter without parsing the action string. + Blocked bool `json:"blocked"` +} + +// FromMsg fills the question-derived fields from a DNS message. +func (e *Entry) FromMsg(m *dns.Msg) { + if len(m.Question) > 0 { + q := m.Question[0] + e.Name = q.Name + e.QType = q.Qtype + e.QTypeStr = dns.Type(q.Qtype).String() + } + e.RCode = m.Rcode +} + +// RCodeName renders the RCODE as its mnemonic. +func (e Entry) RCodeName() string { + if s, ok := dns.RcodeToString[e.RCode]; ok { + return s + } + return fmt.Sprintf("RCODE%d", e.RCode) +} + +// liveEntry is a decoded copy kept in memory for the SSE stream. +type liveEntry struct { + entry Entry +} + +// Logger batches query logging to bbolt and maintains the live ring. +type Logger struct { + opts Options + + // seq assigns monotonic ids so the UI can detect drops. + seq atomic.Uint64 + + // live is a fixed-size ring of the most recent entries. + live []liveEntry + livePos atomic.Uint32 + liveMu sync.RWMutex + liveCond *sync.Cond + liveFull atomic.Bool + + // pending batches entries between bbolt transactions. + pendingMu sync.Mutex + pending []Entry + + // counts are rolling per-domain counters. + counts *domainCounts + + // logErrors counts persistence failures, which the API surfaces so a + // silently-failing query log never looks healthy. + logErrors atomic.Uint64 + + // subscribers is the set of live SSE consumers. + subMu sync.Mutex + subs map[int]chan Entry + subSeq int + + db *bolt.DB + stop chan struct{} + done chan struct{} + wg sync.WaitGroup +} + +// Options configures a Logger. +type Options struct { + // Path is the bbolt file; empty disables persistence. + Path string + // MaxEntries bounds the persisted log ring. + MaxEntries int + // LiveBuffer is the in-memory ring size for the SSE stream. + LiveBuffer int + // FlushInterval is the bbolt batch window. + FlushInterval time.Duration + // SampleRate is the fraction of non-blocked, non-error queries to keep. + SampleRate float64 + // LogBlocked, LogCached, LogErrors are forced categories. + LogBlocked bool + LogCached bool + LogErrors bool + // TopDomains is the size of the rolling counter set. + TopDomains int + // TopTTL is how long a counter survives without being touched. + TopTTL time.Duration + // Now is injectable for tests. + Now func() time.Time +} + +// DefaultOptions returns sane defaults. +func DefaultOptions() Options { + return Options{ + Path: "data/queries.db", + MaxEntries: 200000, + LiveBuffer: 2000, + FlushInterval: time.Second, + SampleRate: 1, + LogBlocked: true, + LogCached: true, + LogErrors: true, + TopDomains: 5000, + TopTTL: 5 * time.Minute, + } +} + +// New opens a Logger, creating the bbolt file when a path is given. +func New(opt Options) (*Logger, error) { + if opt.Now == nil { + opt.Now = time.Now + } + if opt.LiveBuffer <= 0 { + opt.LiveBuffer = 2000 + } + if opt.FlushInterval <= 0 { + opt.FlushInterval = time.Second + } + if opt.SampleRate <= 0 { + opt.SampleRate = 1 + } + if opt.SampleRate > 1 { + opt.SampleRate = 1 + } + if opt.TopDomains <= 0 { + opt.TopDomains = 5000 + } + if opt.TopTTL <= 0 { + opt.TopTTL = 5 * time.Minute + } + l := &Logger{ + opts: opt, + live: make([]liveEntry, opt.LiveBuffer), + counts: newDomainCounts(opt.TopDomains, opt.TopTTL), + subs: make(map[int]chan Entry), + stop: make(chan struct{}), + done: make(chan struct{}), + pending: make([]Entry, 0, 4096), + } + l.liveCond = sync.NewCond(&l.liveMu) + if opt.Path != "" { + if err := os.MkdirAll(filepath.Dir(opt.Path), 0o755); err != nil { + return nil, fmt.Errorf("qlog: create data dir: %w", err) + } + db, err := bolt.Open(opt.Path, 0o600, &bolt.Options{Timeout: 5 * time.Second, NoFreelistSync: true}) + if err != nil { + return nil, fmt.Errorf("qlog: open %s: %w", opt.Path, err) + } + if err := db.Update(func(tx *bolt.Tx) error { + _, err := tx.CreateBucketIfNotExists(bucketLog) + if err != nil { + return err + } + _, err = tx.CreateBucketIfNotExists(bucketMeta) + return err + }); err != nil { + _ = db.Close() + return nil, err + } + l.db = db + l.wg.Add(1) + go l.flushLoop() + } else { + close(l.done) + } + return l, nil +} + +var ( + bucketLog = []byte("log") + bucketMeta = []byte("meta") + keyNextID = []byte("next_id") +) + +// ShouldLog reports whether an entry with this action passes the sampling +// policy. Blocked, cached and error entries are always kept when their +// category flag is set; ordinary resolutions are sampled. +func (l *Logger) ShouldLog(a Action) bool { + switch a { + case ActionBlock: + return l.opts.LogBlocked + case ActionCached: + return l.opts.LogCached + case ActionError, ActionDrop: + return l.opts.LogErrors + default: + if l.opts.SampleRate >= 1 { + return true + } + return randFloat() < l.opts.SampleRate + } +} + +// Log records a query. It never blocks on bbolt: the entry goes to the live +// ring and a batch, and a background goroutine does the disk write. +func (l *Logger) Log(e Entry) { + if e.TS.IsZero() { + e.TS = l.opts.Now() + } + if e.QTypeStr == "" && e.QType != 0 { + e.QTypeStr = dns.Type(e.QType).String() + } + e.Blocked = e.Action == ActionBlock + e.ID = l.seq.Add(1) + l.counts.observe(e) + + // Live ring. + pos := l.livePos.Add(1) - 1 + l.live[pos%uint32(len(l.live))] = liveEntry{entry: e} + + // Fan out to SSE subscribers (non-blocking: a slow consumer drops entries + // rather than stalling the query path). + l.subMu.Lock() + for _, ch := range l.subs { + select { + case ch <- e: + default: + } + } + l.subMu.Unlock() + + if l.db == nil { + return + } + l.pendingMu.Lock() + l.pending = append(l.pending, e) + n := len(l.pending) + l.pendingMu.Unlock() + if n >= 2048 { + go l.Flush() + } +} + +// flushLoop writes pending batches on a timer. +func (l *Logger) flushLoop() { + defer l.wg.Done() + t := time.NewTicker(l.opts.FlushInterval) + defer t.Stop() + for { + select { + case <-l.stop: + l.Flush() + return + case <-t.C: + l.Flush() + } + } +} + +// Flush writes any pending entries to bbolt and trims the ring. +func (l *Logger) Flush() { + if l.db == nil { + return + } + l.pendingMu.Lock() + if len(l.pending) == 0 { + l.pendingMu.Unlock() + return + } + batch := l.pending + l.pending = l.pending[:0] + l.pendingMu.Unlock() + + err := l.db.Update(func(tx *bolt.Tx) error { + b := tx.Bucket(bucketLog) + if b == nil { + return nil + } + meta := tx.Bucket(bucketMeta) + nextID := uint64(1) + if meta != nil { + if v := meta.Get(keyNextID); len(v) == 8 { + nextID = beUint64(v) + } + } + for _, e := range batch { + data, err := json.Marshal(e) + if err != nil { + continue + } + if err := b.Put(be64b(nextID), data); err != nil { + return err + } + nextID++ + } + if meta != nil { + meta.Put(keyNextID, be64b(nextID)) + } + return l.trim(b, nextID) + }) + if err != nil { + // A logging failure must never take the resolver down; surface it via + // the error counter the API reads. + l.logErrors.Add(1) + } +} + +// trim enforces the entry cap by deleting the oldest ids. +func (l *Logger) trim(b *bolt.Bucket, nextID uint64) error { + if l.opts.MaxEntries <= 0 { + return nil + } + stats := b.Stats() + if stats.KeyN <= l.opts.MaxEntries { + return nil + } + excess := stats.KeyN - l.opts.MaxEntries + cur := b.Cursor() + for k, _ := cur.First(); k != nil && excess > 0; k, _ = cur.Next() { + if err := b.Delete(k); err != nil { + return err + } + excess-- + } + return nil +} + +// ErrorCount reports how many batch writes have failed. +func (l *Logger) ErrorCount() uint64 { return l.logErrors.Load() } + +// be64b encodes a uint64 big-endian for use as a bbolt key. +func be64b(v uint64) []byte { + return []byte{ + byte(v >> 56), byte(v >> 48), byte(v >> 40), byte(v >> 32), + byte(v >> 24), byte(v >> 16), byte(v >> 8), byte(v), + } +} + +// beUint64 decodes what be64b wrote. +func beUint64(b []byte) uint64 { + var v uint64 + for _, c := range b { + v = v<<8 | uint64(c) + } + return v +} + +// Query filters the persisted log. +type Query struct { + // Limit is the page size. + Limit int + // Offset skips the newest Offset entries. + Offset int + // Text matches name, client or list. + Text string + // Action filters by classification. + Action string + // Client filters by client address. + Client string + // RCode filters by numeric rcode (0 = no filter). + RCode int + // BlockedOnly keeps only blocklist hits. + BlockedOnly bool + // Since keeps only entries at or after this time. + Since time.Time +} + +// Page is a page of log entries plus the total match count. +type Page struct { + Items []Entry `json:"items"` + Total int `json:"total"` + Offset int `json:"offset"` + Limit int `json:"limit"` +} + +// Recent returns the newest entries from the in-memory ring, newest first. +// It powers the SSE initial burst so a client connecting mid-stream sees +// recent history immediately. +func (l *Logger) Recent(limit int) []Entry { + if limit <= 0 { + limit = 200 + } + if limit > len(l.live) { + limit = len(l.live) + } + out := make([]Entry, 0, limit) + pos := l.livePos.Load() + total := pos + if total > uint32(len(l.live)) { + total = uint32(len(l.live)) + } + for i := uint32(0); i < total; i++ { + idx := (pos - 1 - i) % uint32(len(l.live)) + out = append(out, l.live[idx].entry) + if len(out) >= limit { + break + } + } + return out +} + +// Search queries the persisted log. +func (l *Logger) Search(q Query) (Page, error) { + l.Flush() + page := Page{Offset: q.Offset, Limit: q.Limit} + if q.Limit <= 0 { + q.Limit = 200 + } + if q.Limit > 1000 { + q.Limit = 1000 + } + if l.db == nil { + // No persistence: serve from the live ring. + items := l.Recent(1000) + filtered := l.filter(items, q) + page.Total = len(filtered) + page.Items = paginate(filtered, q.Offset, q.Limit) + return page, nil + } + var ( + matched []Entry + total int + ) + err := l.db.View(func(tx *bolt.Tx) error { + b := tx.Bucket(bucketLog) + if b == nil { + return nil + } + // Walk newest-first. + c := b.Cursor() + for k, v := c.Last(); k != nil; k, v = c.Prev() { + var e Entry + if err := json.Unmarshal(v, &e); err != nil { + continue + } + if !matchEntry(e, q) { + continue + } + total++ + if total > q.Offset && len(matched) < q.Limit { + matched = append(matched, e) + } + if total >= q.Offset+q.Limit+1 && q.Offset+q.Limit > 0 { + // We have enough to fill the page and know the total is at + // least this high; keep scanning only if we still need an + // exact total. For the UI, a "has more" hint is enough. + break + } + } + return nil + }) + if err != nil { + return page, err + } + page.Items = matched + page.Total = total + return page, nil +} + +func (l *Logger) filter(items []Entry, q Query) []Entry { + out := make([]Entry, 0, len(items)) + for _, e := range items { + if matchEntry(e, q) { + out = append(out, e) + } + } + return out +} + +func matchEntry(e Entry, q Query) bool { + if q.BlockedOnly && !e.Blocked { + return false + } + if q.Action != "" && string(e.Action) != q.Action { + return false + } + if q.Client != "" && e.Client != q.Client { + return false + } + if q.RCode != 0 && e.RCode != q.RCode { + return false + } + if !q.Since.IsZero() && e.TS.Before(q.Since) { + return false + } + if q.Text != "" { + t := q.Text + if !containsFold(e.Name, t) && !containsFold(e.Client, t) && !containsFold(e.List, t) { + return false + } + } + return true +} + +func paginate(items []Entry, offset, limit int) []Entry { + if offset >= len(items) { + return []Entry{} + } + end := offset + limit + if end > len(items) { + end = len(items) + } + return items[offset:end] +} + +func containsFold(hay, needle string) bool { + if len(needle) == 0 { + return true + } + return indexFold(hay, needle) >= 0 +} + +func indexFold(hay, needle string) int { + n := len(needle) + if n == 0 { + return 0 + } + if n > len(hay) { + return -1 + } + for i := 0; i+n <= len(hay); i++ { + match := true + for j := 0; j < n; j++ { + if lower(hay[i+j]) != lower(needle[j]) { + match = false + break + } + } + if match { + return i + } + } + return -1 +} + +func lower(b byte) byte { + if b >= 'A' && b <= 'Z' { + return b + 32 + } + return b +} + +// Subscribe registers a live-stream consumer. The returned cancel func must +// be called. Entries are delivered best-effort: a full channel drops rather +// than blocking the DNS path. +func (l *Logger) Subscribe() (<-chan Entry, func()) { + l.subMu.Lock() + defer l.subMu.Unlock() + l.subSeq++ + id := l.subSeq + ch := make(chan Entry, 256) + l.subs[id] = ch + return ch, func() { + l.subMu.Lock() + if c, ok := l.subs[id]; ok { + delete(l.subs, id) + close(c) + } + l.subMu.Unlock() + } +} + +// SubscriberCount reports how many live streams are attached. +func (l *Logger) SubscriberCount() int { + l.subMu.Lock() + defer l.subMu.Unlock() + return len(l.subs) +} + +// Clear removes every persisted entry. +func (l *Logger) Clear() error { + if l.db == nil { + return nil + } + err := l.db.Update(func(tx *bolt.Tx) error { + if tx.Bucket(bucketLog) == nil { + return nil + } + return tx.DeleteBucket(bucketLog) + }) + if err != nil { + l.logErrors.Add(1) + } + return err +} + +// Count is the number of persisted entries. +func (l *Logger) Count() int { + if l.db == nil { + return int(l.seq.Load()) + } + n := 0 + _ = l.db.View(func(tx *bolt.Tx) error { + if b := tx.Bucket(bucketLog); b != nil { + n = b.Stats().KeyN + } + return nil + }) + return n +} + +// TopDomains returns the hottest domains, optionally only blocked ones. +type DomainCount struct { + Name string `json:"domain"` + Count uint64 `json:"count"` + Blocked uint64 `json:"blocked"` + QType uint16 `json:"qtype"` + QTypeS string `json:"qtype_name"` +} + +// TopDomains returns the top n domains by query count. +func (l *Logger) TopDomains(n int, blockedOnly bool) []DomainCount { + return l.counts.top(n, blockedOnly) +} + +// TopBlocked returns the top blocked domains. +func (l *Logger) TopBlocked(n int) []DomainCount { return l.counts.top(n, true) } + +// TopQueried returns the top queried domains. +func (l *Logger) TopQueried(n int) []DomainCount { return l.counts.top(n, false) } + +// Stats is a JSON-friendly summary. +type Stats struct { + Enabled bool `json:"enabled"` + Path string `json:"path"` + Entries int `json:"entries"` + MaxEntries int `json:"max_entries"` + LiveBuffer int `json:"live_buffer"` + Subscribers int `json:"subscribers"` + SampleRate float64 `json:"sample_rate"` + TotalLogged uint64 `json:"total_logged"` + Pending int `json:"pending"` + Errors uint64 `json:"errors"` +} + +// Stats snapshots the logger. +func (l *Logger) Stats() Stats { + l.pendingMu.Lock() + pending := len(l.pending) + l.pendingMu.Unlock() + return Stats{ + Enabled: l.db != nil, + Path: l.opts.Path, + Entries: l.Count(), + MaxEntries: l.opts.MaxEntries, + LiveBuffer: l.opts.LiveBuffer, + Subscribers: l.SubscriberCount(), + SampleRate: l.opts.SampleRate, + TotalLogged: l.seq.Load(), + Pending: pending, + Errors: l.logErrors.Load(), + } +} + +// Close flushes and releases resources. +func (l *Logger) Close() error { + select { + case <-l.stop: + default: + close(l.stop) + } + l.wg.Wait() + if l.db != nil { + l.Flush() + return l.db.Close() + } + return nil +} diff --git a/internal/resolver/pool.go b/internal/resolver/pool.go new file mode 100644 index 0000000..f458a34 --- /dev/null +++ b/internal/resolver/pool.go @@ -0,0 +1,598 @@ +// Package resolver forwards queries to upstream recursive servers with +// health tracking, per-upstream circuit breakers and parallel racing. +package resolver + +import ( + "context" + "crypto/tls" + "errors" + "fmt" + "math/rand/v2" + "net" + "sort" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/miekg/dns" + + "git.k8s-git-k6n.net/mats/fancy-dns/internal/config" +) + +// ErrNoUpstream is returned when every configured upstream is unavailable. +var ErrNoUpstream = errors.New("resolver: no healthy upstream available") + +// ErrCircuitOpen is returned by a single upstream whose breaker is open. +var ErrCircuitOpen = errors.New("resolver: upstream circuit breaker open") + +// Health is an upstream's current state. +type Health string + +const ( + // HealthUp means the last probes and queries succeeded. + HealthUp Health = "up" + // HealthDegraded means recent failures but still serving. + HealthDegraded Health = "degraded" + // HealthDown means failing or the breaker is open. + HealthDown Health = "down" + // HealthUnknown means not probed yet. + HealthUnknown Health = "unknown" +) + +// Upstream is one configured server plus its live health. +type Upstream struct { + cfg config.UpstreamServer + // addr is the address actually dialled: a bootstrap IP for TLS (SNI keeps + // the hostname) and the literal address otherwise. + addr string + // resolved holds the current bootstrap addresses when the configured + // address is a name. + resolved []string + + queries atomic.Uint64 + failures atomic.Uint64 + consecutive atomic.Uint32 + latencySum atomic.Uint64 // microseconds + latencyN atomic.Uint64 + p95 []float64 // recent latencies in ms, for the UI + p95mu sync.Mutex + p95ring []float64 + + breakerOpenUntil atomic.Int64 + health atomic.Pointer[Health] + lastErr atomic.Pointer[string] +} + +// Addr is the address the resolver dials. +func (u *Upstream) Addr() string { return u.addr } + +// Config returns the upstream's configuration entry. +func (u *Upstream) Config() config.UpstreamServer { return u.cfg } + +// Health returns the current health state. +func (u *Upstream) Health() Health { + if h := u.health.Load(); h != nil { + return *h + } + return HealthUnknown +} + +func (u *Upstream) setHealth(h Health) { u.health.Store(&h) } + +// SetError records the last error message for the UI. +func (u *Upstream) SetError(err error) { + if err == nil { + u.lastErr.Store(nil) + return + } + s := err.Error() + u.lastErr.Store(&s) +} + +// LastError returns the last error message, or "". +func (u *Upstream) LastError() string { + if p := u.lastErr.Load(); p != nil { + return *p + } + return "" +} + +// Success records a successful query. +func (u *Upstream) Success(d time.Duration) { + u.queries.Add(1) + u.consecutive.Store(0) + u.latencySum.Add(uint64(d.Microseconds())) + u.latencyN.Add(1) + u.recordLatency(d) + u.SetError(nil) + if u.Health() != HealthUp { + u.setHealth(HealthUp) + } +} + +// Failure records a failed query and trips the breaker once the threshold is +// crossed. +func (u *Upstream) Failure(err error, threshold int, cooldown time.Duration) { + u.queries.Add(1) + u.failures.Add(1) + n := u.consecutive.Add(1) + u.SetError(err) + if threshold > 0 && int(n) >= threshold { + u.breakerOpenUntil.Store(time.Now().Add(cooldown).UnixNano()) + u.setHealth(HealthDown) + return + } + if u.Health() != HealthDown { + u.setHealth(HealthDegraded) + } +} + +// BreakerOpen reports whether the upstream's breaker is open. +func (u *Upstream) BreakerOpen() bool { + until := u.breakerOpenUntil.Load() + return until > time.Now().UnixNano() +} + +func (u *Upstream) recordLatency(d time.Duration) { + ms := float64(d.Microseconds()) / 1000 + u.p95mu.Lock() + if len(u.p95ring) < 512 { + u.p95ring = append(u.p95ring, ms) + } else { + copy(u.p95ring, u.p95ring[1:]) + u.p95ring[511] = ms + } + u.p95mu.Unlock() +} + +// LatencyStats returns average and p95 latency in milliseconds. +func (u *Upstream) LatencyStats() (avg, p95 float64) { + n := u.latencyN.Load() + if n == 0 { + return 0, 0 + } + avg = float64(u.latencySum.Load()) / float64(n) / 1000 + u.p95mu.Lock() + samples := append([]float64(nil), u.p95ring...) + u.p95mu.Unlock() + if len(samples) == 0 { + return avg, 0 + } + sort.Float64s(samples) + idx := int(float64(len(samples)) * 0.95) + if idx >= len(samples) { + idx = len(samples) - 1 + } + return avg, samples[idx] +} + +// Stats is the JSON-friendly upstream state for the API. +type Stats struct { + Addr string `json:"addr"` + Proto string `json:"proto"` + ServerName string `json:"server_name"` + Weight int `json:"weight"` + Comment string `json:"comment,omitempty"` + Health Health `json:"health"` + LatencyMS float64 `json:"latency_ms"` + AvgMS float64 `json:"avg_ms"` + P95MS float64 `json:"p95_ms"` + FailRate float64 `json:"fail_rate"` + Queries uint64 `json:"queries"` + Failures uint64 `json:"failures"` + BreakerOpen bool `json:"breaker_open"` + LastError string `json:"last_error,omitempty"` +} + +// Stats snapshots one upstream. +func (u *Upstream) Stats() Stats { + q := u.queries.Load() + f := u.failures.Load() + var rate float64 + if q > 0 { + rate = float64(f) / float64(q) + } + avg, p95 := u.LatencyStats() + return Stats{ + Addr: u.addr, + Proto: u.cfg.Proto, + ServerName: u.cfg.ServerName, + Weight: u.cfg.Weight, + Comment: u.cfg.Comment, + Health: u.Health(), + LatencyMS: p95, + AvgMS: avg, + P95MS: p95, + FailRate: rate, + Queries: q, + Failures: f, + BreakerOpen: u.BreakerOpen(), + LastError: u.LastError(), + } +} + +// Pool is the set of upstreams plus the policy that selects among them. +type Pool struct { + cfg config.Upstream + mu sync.RWMutex + ups []*Upstream + byTag map[string][]*Upstream + // clients are reused per upstream: one UDP socket, one TCP dialer, one TLS + // session pool. Reusing them is what keeps the per-query cost low. + clients map[*Upstream]*dns.Client + // bootstrap resolves names to addresses. + bootstrap map[string][]string + + rng *rand.Rand + mu2 sync.Mutex +} + +// NewPool builds a pool from config. bootstrapIPs may be empty; then upstream +// hostnames must be literal IPs (or resolved by the OS). +func NewPool(cfg config.Upstream) *Pool { + p := &Pool{ + cfg: cfg, + byTag: make(map[string][]*Upstream), + clients: make(map[*Upstream]*dns.Client), + bootstrap: make(map[string][]string), + rng: rand.New(rand.NewPCG(uint64(time.Now().UnixNano()), 0x9e3779b9)), + } + for _, b := range cfg.Bootstraps { + p.bootstrap[b.Name] = append([]string(nil), b.Addresses...) + } + for _, s := range cfg.Servers { + up := &Upstream{cfg: s} + up.setHealth(HealthUnknown) + p.ups = append(p.ups, up) + } + p.resolveAll() + return p +} + +func (p *Pool) resolveAll() { + for _, up := range p.ups { + host, port, err := net.SplitHostPort(up.cfg.Addr) + if err != nil { + continue + } + if net.ParseIP(host) != nil { + up.addr = up.cfg.Addr + continue + } + if addrs := p.bootstrap[host]; len(addrs) > 0 { + up.resolved = addrs + up.addr = net.JoinHostPort(addrs[0], port) + continue + } + // Fall back to the system resolver. + ips, err := net.LookupIP(host) + if err != nil || len(ips) == 0 { + up.addr = up.cfg.Addr + continue + } + strs := make([]string, 0, len(ips)) + for _, ip := range ips { + strs = append(strs, ip.String()) + } + up.resolved = strs + up.addr = net.JoinHostPort(strs[0], port) + } +} + +// Config returns the pool's upstream config. +func (p *Pool) Config() config.Upstream { return p.cfg } + +// All returns every upstream. +func (p *Pool) All() []*Upstream { return p.ups } + +// Get returns an upstream by address, or nil. +func (p *Pool) Get(addr string) *Upstream { + for _, u := range p.ups { + if u.addr == addr || u.cfg.Addr == addr { + return u + } + } + return nil +} + +// Healthy returns upstreams whose breaker is closed, in configured order. +func (p *Pool) Healthy() []*Upstream { + out := make([]*Upstream, 0, len(p.ups)) + for _, u := range p.ups { + if !u.BreakerOpen() { + out = append(out, u) + } + } + return out +} + +// Stats snapshots every upstream. +func (p *Pool) Stats() []Stats { + out := make([]Stats, 0, len(p.ups)) + for _, u := range p.ups { + out = append(out, u.Stats()) + } + return out +} + +// clientFor returns the memoised dns.Client for an upstream. +func (p *Pool) clientFor(u *Upstream) *dns.Client { + p.mu.RLock() + c, ok := p.clients[u] + p.mu.RUnlock() + if ok { + return c + } + var nc *dns.Client + switch u.cfg.Proto { + case "tls": + tlsCfg := &tls.Config{ + ServerName: u.cfg.ServerName, + InsecureSkipVerify: u.cfg.InsecureSkipVerify, + MinVersion: tls.VersionTLS12, + NextProtos: []string{"dot"}, + } + nc = &dns.Client{ + Net: "tcp-tls", + TLSConfig: tlsCfg, + Dialer: &net.Dialer{Timeout: 3 * time.Second}, + Timeout: 5 * time.Second, + } + case "tcp": + nc = &dns.Client{Net: "tcp", Timeout: 5 * time.Second} + default: + nc = &dns.Client{Net: "udp", UDPSize: 1232, Timeout: 3 * time.Second} + } + p.mu.Lock() + p.clients[u] = nc + p.mu.Unlock() + return nc +} + +// selectFor returns the upstreams to try, honouring the policy. tags, if +// non-empty, restricts the pool to a group's own upstreams. +func (p *Pool) selectFor(policy string, maxAttempts int) []*Upstream { + healthy := p.Healthy() + if len(healthy) == 0 { + // Every breaker is open: try them all anyway rather than failing the + // query outright. A blip should not become an outage. + healthy = append(healthy, p.ups...) + } + if len(healthy) == 0 { + return nil + } + if maxAttempts <= 0 || maxAttempts > len(healthy) { + maxAttempts = len(healthy) + } + switch policy { + case "failover": + // Configured order, and rotate past the unhealthy ones. + return healthy[:maxAttempts] + case "random": + p.mu2.Lock() + p.rng.Shuffle(len(healthy), func(i, j int) { healthy[i], healthy[j] = healthy[j], healthy[i] }) + p.mu2.Unlock() + return healthy[:maxAttempts] + default: // parallel + return healthy + } +} + +// Exchange forwards q to the pool and returns the first acceptable answer. +// +// policy is the pool's configured policy; tags restricts the pool to a +// per-client upstream override. edns0Size is the client's advertised buffer, +// used to decide TCP fallback on truncation. +func (p *Pool) Exchange(ctx context.Context, q *dns.Msg, tags []string, timeout time.Duration) (*dns.Msg, string, error) { + candidates := p.ups + if len(tags) > 0 { + if tagged := p.byTag[strings.Join(tags, ",")]; len(tagged) > 0 { + candidates = tagged + } + } + if len(candidates) == 0 { + return nil, "", ErrNoUpstream + } + attempts := p.cfg.MaxAttempts + chosen := selectFrom(candidates, p.cfg.Policy, attempts) + if len(chosen) == 0 { + return nil, "", ErrNoUpstream + } + + if len(chosen) == 1 { + msg, up, err := p.exchangeOne(ctx, chosen[0], q, timeout) + return msg, up, err + } + + // Parallel: send to all at once, take the first answer that is not a + // transport failure. Cancellable so we do not leak requests to a slow + // upstream after another one has answered. + type res struct { + msg *dns.Msg + up string + err error + } + results := make(chan res, len(chosen)) + sub, cancel := context.WithCancel(ctx) + defer cancel() + for _, up := range chosen { + go func(up *Upstream) { + msg, addr, err := p.exchangeOne(sub, up, q, timeout) + results <- res{msg: msg, up: addr, err: err} + }(up) + } + var lastErr error + for i := 0; i < len(chosen); i++ { + select { + case r := <-results: + if r.err == nil && r.msg != nil && !isTransportFailure(r.msg.Rcode) { + return r.msg, r.up, nil + } + if r.err != nil { + lastErr = r.err + } else if r.msg != nil { + lastErr = fmt.Errorf("upstream %s returned %s", r.up, dns.RcodeToString[r.msg.Rcode]) + } + case <-ctx.Done(): + return nil, "", ctx.Err() + } + } + if lastErr == nil { + lastErr = ErrNoUpstream + } + return nil, "", lastErr +} + +func selectFrom(ups []*Upstream, policy string, maxAttempts int) []*Upstream { + // Filter out open breakers but keep everything if that empties the list. + open := make([]*Upstream, 0, len(ups)) + for _, u := range ups { + if !u.BreakerOpen() { + open = append(open, u) + } + } + if len(open) == 0 { + open = ups + } + if maxAttempts <= 0 || maxAttempts > len(open) { + maxAttempts = len(open) + } + switch policy { + case "failover": + return open[:maxAttempts] + case "random": + rand.Shuffle(len(open), func(i, j int) { open[i], open[j] = open[j], open[i] }) + return open[:maxAttempts] + default: + return open + } +} + +// exchangeOne sends q to a single upstream, retrying over TCP when the UDP +// answer comes back truncated (RFC 1035 §4.2.1). +func (p *Pool) exchangeOne(ctx context.Context, up *Upstream, q *dns.Msg, timeout time.Duration) (*dns.Msg, string, error) { + if timeout <= 0 { + timeout = 2 * time.Second + } + client := p.clientFor(up) + msg := q.Copy() + start := time.Now() + resp, rtt, err := client.ExchangeContext(ctx, msg, up.addr) + up.Success(rtt) + if err != nil { + return nil, up.addr, err + } + _ = start + if !resp.Truncated { + return resp, up.addr, nil + } + // Retry over TCP to get the full answer. Some upstreams are configured + // UDP-only in which case this simply fails and we use the TC answer. + tcpClient := &dns.Client{Net: "tcp", Timeout: timeout} + resp2, rtt2, err2 := tcpClient.ExchangeContext(ctx, q.Copy(), up.addr) + if err2 == nil && resp2 != nil && !resp2.Truncated { + up.Success(rtt2) + return resp2, up.addr, nil + } + up.Failure(fmt.Errorf("truncated answer, TCP retry failed: %w", err2), up.breakerThreshold(), p.cfg.BreakerCooldown.D()) + // Return the truncated answer; the client will retry over TCP itself. + return resp, up.addr, nil +} + +func isTransportFailure(rcode int) bool { + return rcode == dns.RcodeServerFailure +} + +// breakerThreshold is the effective failure threshold for an upstream. +func (u *Upstream) breakerThreshold() int { + if u.cfg.MaxFails > 0 { + return u.cfg.MaxFails + } + return 0 +} + +// HealthCheck probes every upstream with a cheap query, refreshing health +// state even when no client traffic is flowing. It returns the number of +// upstreams that answered. +func (p *Pool) HealthCheck(ctx context.Context, timeout time.Duration) int { + probe := new(dns.Msg) + probe.SetQuestion(".", dns.TypeNS) + probe.RecursionDesired = true + ok := 0 + for _, up := range p.ups { + if up.BreakerOpen() { + continue + } + c := p.clientFor(up) + _, rtt, err := c.ExchangeContext(ctx, probe, up.addr) + if err != nil { + up.Failure(err, p.breakerThresholdFor(up), p.cfg.BreakerCooldown.D()) + continue + } + up.Success(rtt) + ok++ + } + return ok +} + +func (p *Pool) breakerThresholdFor(u *Upstream) int { + if t := u.breakerThreshold(); t > 0 { + return t + } + return p.cfg.BreakerThreshold +} + +// Rebind applies a new upstream configuration in place, keeping the live +// health state of upstreams whose address is unchanged. +func (p *Pool) Rebind(cfg config.Upstream) { + p.mu.Lock() + defer p.mu.Unlock() + p.cfg = cfg + old := make(map[string]*Upstream, len(p.ups)) + for _, u := range p.ups { + old[u.cfg.Addr+"/"+u.cfg.Proto] = u + } + next := make([]*Upstream, 0, len(cfg.Servers)) + for _, s := range cfg.Servers { + if u, ok := old[s.Addr+"/"+s.Proto]; ok { + u.cfg = s + next = append(next, u) + delete(old, s.Addr+"/"+s.Proto) + continue + } + u := &Upstream{cfg: s} + u.setHealth(HealthUnknown) + next = append(next, u) + } + p.ups = next + // Drop clients for removed upstreams. + for u := range p.clients { + if old[u.cfg.Addr+"/"+u.cfg.Proto] != nil { + delete(p.clients, u) + } + } + p.resolveAllLocked() +} + +func (p *Pool) resolveAllLocked() { + for _, b := range p.cfg.Bootstraps { + p.bootstrap[b.Name] = append([]string(nil), b.Addresses...) + } + for _, up := range p.ups { + host, port, err := net.SplitHostPort(up.cfg.Addr) + if err != nil { + continue + } + if net.ParseIP(host) != nil { + up.addr = up.cfg.Addr + continue + } + if addrs := p.bootstrap[host]; len(addrs) > 0 { + up.resolved = addrs + up.addr = net.JoinHostPort(addrs[0], port) + continue + } + up.addr = up.cfg.Addr + } +} diff --git a/internal/server/server.go b/internal/server/server.go new file mode 100644 index 0000000..78a17c7 --- /dev/null +++ b/internal/server/server.go @@ -0,0 +1,848 @@ +// Package server runs the DNS listeners: plain DNS on UDP/TCP, DNS-over-TLS +// (RFC 7858) and DNS-over-HTTPS (RFC 8484). +// +// All four transports funnel into one handler, so a query behaves identically +// whichever way it arrived. The transports are deliberately thin: parse, hand +// to the engine, write. Anything heavier belongs behind the engine. +package server + +import ( + "context" + "crypto/tls" + "crypto/x509" + "encoding/base64" + "errors" + "fmt" + "io" + "log/slog" + "net" + "net/http" + "net/netip" + "os" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/miekg/dns" + "golang.org/x/net/http2" + "golang.org/x/net/http2/h2c" + + "git.k8s-git-k6n.net/mats/fancy-dns/internal/config" + "git.k8s-git-k6n.net/mats/fancy-dns/internal/engine" +) + +// Handler is the interface the transports use to answer a query. +type Handler interface { + Handle(ctx context.Context, req engine.Request) engine.Response + Inflight() int64 + Flush() +} + +// identityFunc resolves a client IP to its reverse-DNS names. The app installs +// it so the server does not depend on the engine's cache directly. +type identityFunc func(ip string) []string + +// tagFunc derives ACL tags from a client IP. +type tagFunc func(ip string) []string + +// Server owns every DNS listener. +type Server struct { + eng Handler + cfg *config.Store + log *slog.Logger + version string + + names atomic.Pointer[identityFunc] + tags atomic.Pointer[tagFunc] + + mu sync.Mutex + started bool + shutdown context.CancelFunc + wait sync.WaitGroup + listeners []listener + // counters is keyed by ".". + counters sync.Map + // active is the listener snapshot the API serves. + active atomic.Pointer[[]ListenerInfo] +} + +// listener couples a close function with the info the API reports for it. +type listener struct { + close func() error + info ListenerInfo +} + +// ListenerInfo describes one bound listener. +type ListenerInfo struct { + Transport string `json:"transport"` + Addr string `json:"addr"` + Enabled bool `json:"enabled"` + Running bool `json:"running"` + Err string `json:"err,omitempty"` +} + +// Options configures a Server. +type Options struct { + // Engine handles queries. + Engine Handler + // Config is the hot-reloadable config store; the server subscribes to it. + Config *config.Store + // Logger is the structured logger. + Logger *slog.Logger + // Version is reported in the DoH server header and the admin API. + Version string +} + +// New builds a Server. +func New(opt Options) *Server { + log := opt.Logger + if log == nil { + log = slog.Default() + } + return &Server{ + eng: opt.Engine, + cfg: opt.Config, + log: log.With("component", "dns"), + version: opt.Version, + } +} + +// SetIdentity installs the client reverse-name and tag resolvers. +func (s *Server) SetIdentity(names identityFunc, tags tagFunc) { + s.names.Store(&names) + s.tags.Store(&tags) +} + +// Start binds every enabled listener and begins serving. It returns once all +// listeners have been bound, so a bind failure surfaces synchronously. +func (s *Server) Start(ctx context.Context) error { + cfg := s.cfg.Get() + ctx, cancel := context.WithCancel(ctx) + + s.mu.Lock() + if s.started { + s.mu.Unlock() + cancel() + return errors.New("server: already started") + } + s.started = true + s.shutdown = cancel + s.mu.Unlock() + + var failures []error + for _, addr := range cfg.DNS.UDP { + if err := s.serveUDP(ctx, addr); err != nil { + failures = append(failures, err) + } + } + for _, addr := range cfg.DNS.TCP { + if err := s.serveTCP(ctx, addr); err != nil { + failures = append(failures, err) + } + } + if cfg.DNS.DoT.Enabled { + if err := s.serveDoT(ctx, cfg); err != nil { + failures = append(failures, err) + } + } + if cfg.DNS.DoH.Enabled { + if err := s.serveDoH(ctx, cfg); err != nil { + failures = append(failures, err) + } + } + s.publish() + if err := errors.Join(failures...); err != nil { + s.log.Warn("some listeners failed to start", "error", err) + } + if s.count() == 0 && len(failures) > 0 { + cancel() + return fmt.Errorf("server: no listener started: %w", errors.Join(failures...)) + } + return nil +} + +func (s *Server) count() int { + s.mu.Lock() + defer s.mu.Unlock() + return len(s.listeners) +} + +func (s *Server) add(l listener) { + s.mu.Lock() + s.listeners = append(s.listeners, l) + s.mu.Unlock() +} + +func (s *Server) publish() { + s.mu.Lock() + infos := make([]ListenerInfo, 0, len(s.listeners)) + for _, l := range s.listeners { + infos = append(infos, l.info) + } + s.mu.Unlock() + s.active.Store(&infos) +} + +// Listeners returns the current listener snapshot. +func (s *Server) Listeners() []ListenerInfo { + if p := s.active.Load(); p != nil { + return *p + } + return nil +} + +// Stop shuts every listener down and waits for their goroutines. +func (s *Server) Stop(ctx context.Context) error { + s.mu.Lock() + if !s.started { + s.mu.Unlock() + return nil + } + s.started = false + shutdown := s.shutdown + ls := s.listeners + s.listeners = nil + s.mu.Unlock() + + if shutdown != nil { + shutdown() + } + var errs []error + for _, l := range ls { + if err := l.close(); err != nil { + errs = append(errs, err) + } + } + done := make(chan struct{}) + go func() { + s.wait.Wait() + close(done) + }() + select { + case <-done: + case <-ctx.Done(): + errs = append(errs, ctx.Err()) + } + s.publish() + return errors.Join(errs...) +} + +// serveUDP binds a UDP listener. One short-lived goroutine per packet keeps +// lock hold times at zero; a large socket buffer absorbs bursts instead of +// dropping them. +func (s *Server) serveUDP(ctx context.Context, addr string) error { + pc, err := net.ListenPacket("udp", addr) + if err != nil { + return fmt.Errorf("bind udp %s: %w", addr, err) + } + if uc, ok := pc.(*net.UDPConn); ok { + _ = uc.SetReadBuffer(4 << 20) + _ = uc.SetWriteBuffer(4 << 20) + } + // The read deadline is what lets the loop notice cancellation promptly; + // without it a blocked ReadFrom would outlive shutdown. It has to be reset + // on every iteration: a deadline set once expires for good and turns the + // loop into a spin that never reads another packet. + const readTick = 500 * time.Millisecond + s.add(listener{close: pc.Close, info: ListenerInfo{ + Transport: "udp", Addr: pc.LocalAddr().String(), Enabled: true, Running: true, + }}) + s.log.Info("dns listener up", "transport", "udp", "addr", pc.LocalAddr().String()) + + s.wait.Add(1) + go func() { + defer s.wait.Done() + buf := make([]byte, dns.MaxMsgSize) + for { + if ctx.Err() != nil { + return + } + _ = pc.SetReadDeadline(time.Now().Add(readTick)) + n, from, err := pc.ReadFrom(buf) + if err != nil { + if ctx.Err() != nil { + return + } + if isTimeout(err) { + continue + } + // A closed listener during shutdown lands here. + if errors.Is(err, net.ErrClosed) { + return + } + s.log.Debug("udp read", "error", err) + continue + } + pkt := make([]byte, n) + copy(pkt, buf[:n]) + addr, _ := net.ResolveUDPAddr("udp", from.String()) + go s.servePacket(ctx, pc, pkt, from, addr) + } + }() + return nil +} + +func isTimeout(err error) bool { + var ne net.Error + return errors.As(err, &ne) && ne.Timeout() +} + +// servePacket answers one UDP query. The listener is passed in so the reply +// goes out on the very same socket the query arrived on: a fresh socket per +// answer would burn an ephemeral port and a connect handshake per query. +func (s *Server) servePacket(ctx context.Context, pc net.PacketConn, pkt []byte, from net.Addr, to *net.UDPAddr) { + m := new(dns.Msg) + if err := m.Unpack(pkt); err != nil { + // An unparsable message cannot be replied to: there is no ID and no + // question to echo. Dropping it is the only correct response. + s.bump("udp", "errors") + return + } + // A message with no question is still answerable (FORMERR), so it goes + // through the engine's validation rather than being dropped here. + // Cap the client's advertised buffer: nobody needs 64 KiB of DNS, and an + // unbounded value is a cheap amplification vector. + if o := m.IsEdns0(); o != nil && o.UDPSize() > 4096 { + o.SetUDPSize(4096) + } + req := s.request(ctx, m, from, "udp") + res := s.eng.Handle(ctx, req) + s.bump("udp", "queries") + s.classify("udp", res) + if res.Drop || res.Msg == nil { + s.bump("udp", "dropped") + return + } + if to == nil { + return + } + out := s.fitUDP(res.Msg, m, 512) + if out == nil { + return + } + if c, ok := pc.(interface{ SetWriteDeadline(time.Time) error }); ok { + _ = c.SetWriteDeadline(time.Now().Add(2 * time.Second)) + } + s.bump("udp", "sent") + _, _ = pc.WriteTo(out, to) +} + +// fitUDP packs a reply into a UDP datagram, setting TC and returning a +// question-only response when it does not fit (RFC 1035 §4.2.1, RFC 2181 §9). +func (s *Server) fitUDP(res *dns.Msg, q *dns.Msg, floor int) []byte { + limit := floor + if o := q.IsEdns0(); o != nil { + if n := int(o.UDPSize()); n >= 512 { + limit = n + } + } + if limit > 4096 { + limit = 4096 + } + out, err := res.Pack() + if err != nil { + return nil + } + if len(out) <= limit { + return out + } + tc := new(dns.Msg) + tc.SetReply(q) + tc.Rcode = res.Rcode + tc.Truncated = true + tc.AuthenticatedData = res.AuthenticatedData + if o := q.IsEdns0(); o != nil { + tc.SetEdns0(uint16(limit), o.Do()) + } + out, err = tc.Pack() + if err != nil { + return nil + } + s.bump("udp", "truncated") + return out +} + +// request builds an engine.Request, filling in the client's identity. +func (s *Server) request(ctx context.Context, m *dns.Msg, from net.Addr, transport string) engine.Request { + ip := addrToAddr(from) + key := ip.String() + req := engine.Request{ + Msg: m, + Remote: ip, + Transport: transport, + Start: time.Now(), + } + if f := s.names.Load(); f != nil { + req.ClientNames = (*f)(key) + } + if f := s.tags.Load(); f != nil { + req.ClientTags = (*f)(key) + } + return req +} + +// classify records per-transport outcome counters. +func (s *Server) classify(transport string, res engine.Response) { + switch res.Action { + case "block": + s.bump(transport, "blocked") + case "cached": + s.bump(transport, "cached") + case "error", "drop": + s.bump(transport, "errors") + } +} + +// serveTCP binds a TCP listener for plain DNS. +func (s *Server) serveTCP(ctx context.Context, addr string) error { + ln, err := net.Listen("tcp", addr) + if err != nil { + return fmt.Errorf("bind tcp %s: %w", addr, err) + } + return s.serveStream(ctx, ln, "tcp", nil, 0) +} + +// serveStream runs the accept loop shared by TCP and DoT. +func (s *Server) serveStream(ctx context.Context, ln net.Listener, transport string, tlsCfg *tls.Config, idleTimeout time.Duration) error { + if tlsCfg != nil { + ln = tls.NewListener(ln, tlsCfg) + } + s.add(listener{close: ln.Close, info: ListenerInfo{ + Transport: transport, Addr: ln.Addr().String(), Enabled: true, Running: true, + }}) + s.log.Info("dns listener up", "transport", transport, "addr", ln.Addr().String()) + s.wait.Add(1) + go func() { + defer s.wait.Done() + var wg sync.WaitGroup + defer wg.Wait() + for { + conn, err := ln.Accept() + if err != nil { + if ctx.Err() != nil { + return + } + if isTimeout(err) { + continue + } + return + } + wg.Add(1) + go func() { + defer wg.Done() + s.serveConn(ctx, conn, transport, idleTimeout) + }() + } + }() + return nil +} + +// serveConn handles one stream connection with RFC 1035 §4.2.2 length +// prefixes, so a client may pipeline several queries. +func (s *Server) serveConn(ctx context.Context, conn net.Conn, transport string, idleTimeout time.Duration) { + defer func() { _ = conn.Close() }() + if idleTimeout > 0 { + _ = conn.SetDeadline(time.Now().Add(idleTimeout)) + } + co := &dns.Conn{Conn: conn} + for { + if ctx.Err() != nil { + return + } + if idleTimeout > 0 { + _ = conn.SetReadDeadline(time.Now().Add(idleTimeout)) + } + m, err := co.ReadMsg() + if err != nil { + return + } + if len(m.Question) == 0 { + s.bump(transport, "errors") + return + } + req := s.request(ctx, m, conn.RemoteAddr(), transport) + req.TCP = true + res := s.eng.Handle(ctx, req) + s.bump(transport, "queries") + s.classify(transport, res) + if res.Drop || res.Msg == nil { + s.bump(transport, "dropped") + return + } + if idleTimeout > 0 { + _ = conn.SetWriteDeadline(time.Now().Add(idleTimeout)) + } + if err := co.WriteMsg(res.Msg); err != nil { + return + } + s.bump(transport, "sent") + } +} + +// serveDoT binds the DNS-over-TLS listener. +func (s *Server) serveDoT(ctx context.Context, cfg *config.Config) error { + tlsCfg, err := tlsConfig(cfg.DNS.DoT.CertFile, cfg.DNS.DoT.KeyFile, cfg.DNS.DoT.ClientCA, cfg.DNS.DoT.MinVersion) + if err != nil { + return fmt.Errorf("dot: %w", err) + } + if tlsCfg == nil { + return errors.New("dot: enabled but no certificate configured") + } + tlsCfg.NextProtos = []string{"dot"} + timeout := cfg.Server.Timeouts.TLS.D() + var errs []error + for _, addr := range cfg.DNS.DoT.Listen { + ln, err := net.Listen("tcp", addr) + if err != nil { + errs = append(errs, fmt.Errorf("bind dot %s: %w", addr, err)) + continue + } + if err := s.serveStream(ctx, ln, "dot", tlsCfg, timeout); err != nil { + errs = append(errs, err) + } + } + return errors.Join(errs...) +} + +// serveDoH binds the DNS-over-HTTPS listener. GET (with ?dns=) and POST +// (application/dns-message) are both supported per RFC 8484, and the handler +// speaks h2 with an h2c fallback so it also works on a plain TCP listener. +func (s *Server) serveDoH(ctx context.Context, cfg *config.Config) error { + base := normaliseBase(cfg.DNS.DoH.BasePath) + mux := http.NewServeMux() + h := s.doHHandler(base, cfg.DNS.DoH.AllowPost) + mux.Handle(base, h) + // RFC 8484 §4.1 reserves /.well-known/dns-query as an alias. + if base != "/dns-query" { + mux.Handle("/.well-known/dns-query", h) + } + mux.HandleFunc("/healthz", func(w http.ResponseWriter, _ *http.Request) { + w.Header().Set("Content-Type", "text/plain") + _, _ = w.Write([]byte("ok\n")) + }) + + h2s := &http2.Server{IdleTimeout: 90 * time.Second} + handler := h2c.NewHandler(mux, h2s) + + tlsCfg, tlsErr := tlsConfig(cfg.DNS.DoH.CertFile, cfg.DNS.DoH.KeyFile, "", cfg.DNS.DoH.MinVersion) + if tlsCfg != nil { + tlsCfg.NextProtos = []string{"h2", "http/1.1"} + } + + var errs []error + for _, addr := range cfg.DNS.DoH.Listen { + ln, err := net.Listen("tcp", addr) + if err != nil { + errs = append(errs, fmt.Errorf("bind doh %s: %w", addr, err)) + continue + } + actual := ln.Addr().String() + srv := &http.Server{ + Handler: handler, + ReadHeaderTimeout: 10 * time.Second, + IdleTimeout: 90 * time.Second, + // No WriteTimeout: a long-lived h2 stream should not be cut off, + // and ReadHeaderTimeout plus IdleTimeout already bound the damage. + } + closeFn := ln.Close + if tlsCfg != nil { + srv.TLSConfig = tlsCfg + ln = tls.NewListener(ln, tlsCfg) + closeFn = ln.Close + } + s.add(listener{close: closeFn, info: ListenerInfo{ + Transport: "doh", Addr: actual, Enabled: true, Running: true, + }}) + if tlsErr != nil { + s.log.Warn("doh: running without TLS", "error", tlsErr) + } + s.log.Info("dns listener up", "transport", "doh", "addr", actual, "path", base) + s.wait.Add(1) + go func() { + defer s.wait.Done() + if err := srv.Serve(ln); err != nil && !errors.Is(err, http.ErrServerClosed) { + s.log.Debug("doh server stopped", "error", err) + } + }() + s.wait.Add(1) + go func() { + defer s.wait.Done() + <-ctx.Done() + shutCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + _ = srv.Shutdown(shutCtx) + }() + } + return errors.Join(errs...) +} + +const contentTypeDNS = "application/dns-message" + +// maxGETResponse bounds a DoH GET response so no intermediary truncates it. +const maxGETResponse = 65535 + +// doHHandler builds the RFC 8484 handler. +func (s *Server) doHHandler(base string, allowPost bool) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet && r.Method != http.MethodPost { + w.Header().Set("Allow", "GET, POST") + http.Error(w, "method not allowed", http.StatusMethodNotAllowed) + return + } + var ( + payload []byte + err error + ) + switch r.Method { + case http.MethodGet: + // RFC 8484 §4.1 defines exactly one parameter, "dns", holding + // unpadded base64url. An unknown parameter is a 400 rather than a + // 404 so a client can tell its own mistake from a wrong path. + q := r.URL.Query() + if !q.Has("dns") { + writeDoHError(w, http.StatusBadRequest, "missing dns parameter") + return + } + if len(q) > 1 { + for k := range q { + if k != "dns" { + writeDoHError(w, http.StatusBadRequest, "unsupported parameter "+k) + return + } + } + } + payload, err = decodeBase64URL(q.Get("dns")) + if err != nil { + writeDoHError(w, http.StatusBadRequest, "malformed dns parameter") + return + } + case http.MethodPost: + if !allowPost { + w.Header().Set("Allow", "GET") + http.Error(w, "POST not allowed", http.StatusMethodNotAllowed) + return + } + if ct := r.Header.Get("Content-Type"); ct != contentTypeDNS { + writeDoHError(w, http.StatusUnsupportedMediaType, "content-type must be "+contentTypeDNS) + return + } + payload, err = readCapped(r, dns.MaxMsgSize) + if err != nil { + writeDoHError(w, http.StatusBadRequest, "cannot read body") + return + } + } + + m := new(dns.Msg) + if err := m.Unpack(payload); err != nil { + writeDoHError(w, http.StatusBadRequest, "malformed DNS message") + return + } + if len(m.Question) == 0 { + writeDoHError(w, http.StatusBadRequest, "no question") + return + } + req := s.request(r.Context(), m, httpRemoteAddr(r), "doh") + req.TCP = true + req.DoHPath = r.URL.Path + res := s.eng.Handle(r.Context(), req) + s.bump("doh", "queries") + s.classify("doh", res) + if res.Drop || res.Msg == nil { + // A dropped query still needs a body: unlike UDP, this is a + // well-formed HTTP exchange, so hanging up would read as a + // transport error rather than a policy decision. + res.Msg = new(dns.Msg) + res.Msg.SetRcode(m, dns.RcodeSuccess) + } + wire, err := res.Msg.Pack() + if err != nil { + http.Error(w, "pack failed", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", contentTypeDNS) + w.Header().Set("Cache-Control", "max-age=0") + if !cfgHideIdentity(s) { + w.Header().Set("Server", "fancy-dns/"+s.version) + } + w.WriteHeader(http.StatusOK) + _, _ = w.Write(wire) + }) +} + +func cfgHideIdentity(s *Server) bool { + if s.cfg == nil { + return false + } + return s.cfg.Get().DNS.HideIdentity +} + +func writeDoHError(w http.ResponseWriter, code int, msg string) { + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + w.Header().Set("X-Content-Type-Options", "nosniff") + http.Error(w, msg, code) +} + +// tlsConfig loads a certificate for the encrypted listeners. It returns +// (nil, nil) when no certificate is configured, which means "run plaintext". +func tlsConfig(certFile, keyFile, clientCA, minVersion string) (*tls.Config, error) { + if certFile == "" || keyFile == "" { + return nil, nil + } + cert, err := tls.LoadX509KeyPair(certFile, keyFile) + if err != nil { + return nil, fmt.Errorf("load certificate: %w", err) + } + cfg := &tls.Config{ + Certificates: []tls.Certificate{cert}, + MinVersion: parseTLSVersion(minVersion), + } + if clientCA != "" { + pem, err := os.ReadFile(clientCA) + if err != nil { + return nil, fmt.Errorf("read client CA: %w", err) + } + pool := x509.NewCertPool() + if !pool.AppendCertsFromPEM(pem) { + return nil, errors.New("client CA: no certificates found") + } + cfg.ClientCAs = pool + cfg.ClientAuth = tls.RequireAndVerifyClientCert + } + return cfg, nil +} + +func parseTLSVersion(s string) uint16 { + switch s { + case "1.3": + return tls.VersionTLS13 + case "1.0": + return tls.VersionTLS10 + default: + return tls.VersionTLS12 + } +} + +func normaliseBase(p string) string { + if p == "" { + return "/dns-query" + } + if !strings.HasPrefix(p, "/") { + p = "/" + p + } + for len(p) > 1 && p[len(p)-1] == '/' { + p = p[:len(p)-1] + } + return p +} + +func readCapped(r *http.Request, max int64) ([]byte, error) { + if r.ContentLength > max { + return nil, fmt.Errorf("body too large: %d", r.ContentLength) + } + // LimitReader plus one extra byte is how you detect "too large" without + // trusting Content-Length, which a client may lie about. + body := io.LimitReader(r.Body, max+1) + buf, err := io.ReadAll(body) + if err != nil { + return nil, err + } + if int64(len(buf)) > max { + return nil, errors.New("body too large") + } + return buf, nil +} + +func decodeBase64URL(s string) ([]byte, error) { + // RFC 8484 requires unpadded base64url, but every major client sends + // padding, so accept both rather than fail a legitimate request. + if b, err := base64.RawURLEncoding.DecodeString(s); err == nil { + return b, nil + } + return base64.URLEncoding.DecodeString(s) +} + +// httpRemoteAddr turns an http.Request's RemoteAddr into a net.Addr so the +// shared request builder can be used. Over plain HTTP this is the socket peer; +// behind a reverse proxy it is the proxy, which is why the caller must trust +// X-Forwarded-For before that matters (handled in the API layer). +func httpRemoteAddr(r *http.Request) net.Addr { + if r.RemoteAddr == "" { + return &net.TCPAddr{} + } + ap, err := netip.ParseAddrPort(r.RemoteAddr) + if err != nil { + return &net.TCPAddr{} + } + return net.UDPAddrFromAddrPort(ap) +} + +// addrToAddr extracts a netip.Addr from a net.Addr. +func addrToAddr(a net.Addr) netip.Addr { + switch v := a.(type) { + case *net.UDPAddr: + return v.AddrPort().Addr().Unmap() + case *net.TCPAddr: + return v.AddrPort().Addr().Unmap() + default: + ap, err := netip.ParseAddrPort(a.String()) + if err == nil { + return ap.Addr().Unmap() + } + if ip, err := netip.ParseAddr(a.String()); err == nil { + return ip.Unmap() + } + return netip.Addr{} + } +} + +// Stats aggregates the per-transport counters plus the engine's own view. +func (s *Server) Stats() HandlerStats { + var out HandlerStats + s.counters.Range(func(k, v any) bool { + key, _ := k.(string) + n := v.(*atomic.Uint64).Load() + dot := strings.IndexByte(key, '.') + if dot < 0 { + return true + } + switch key[dot+1:] { + case "queries": + out.Queries += n + case "blocked": + out.Blocked += n + case "cached": + out.Cached += n + case "errors": + out.Errors += n + case "dropped": + out.Dropped += n + } + return true + }) + if s.eng != nil { + out.Inflight = s.eng.Inflight() + } + return out +} + +func (s *Server) bump(transport, field string) { + if transport == "" { + transport = "udp" + } + key := transport + "." + field + v, _ := s.counters.LoadOrStore(key, new(atomic.Uint64)) + v.(*atomic.Uint64).Add(1) +} + +// flusher is implemented by the engine: it pushes buffered cache and log state +// to disk on demand (used by the admin API's "flush" action). +type flusher interface{ Flush() } + +// Flush pushes buffered state to disk. +func (s *Server) Flush() { + if f, ok := s.eng.(flusher); ok { + f.Flush() + } +} diff --git a/internal/server/stats.go b/internal/server/stats.go new file mode 100644 index 0000000..4d12894 --- /dev/null +++ b/internal/server/stats.go @@ -0,0 +1,56 @@ +package server + +import "sync/atomic" + +// HandlerStats aggregates the per-transport counters plus the engine's own +// view. It is the "what is this thing doing right now" summary the admin API +// and the health endpoint read. +type HandlerStats struct { + // Queries is every query the server accepted across all transports. + Queries uint64 `json:"queries"` + // Blocked is queries answered by a blocklist rule. + Blocked uint64 `json:"blocked"` + // Cached is queries answered from the cache. + Cached uint64 `json:"cached"` + // Errors is queries answered with SERVFAIL, dropped or malformed. + Errors uint64 `json:"errors"` + // Dropped is queries answered with silence. + Dropped uint64 `json:"dropped"` + // Inflight is the current in-flight count. + Inflight int64 `json:"inflight"` +} + +// ByTransport returns a per-transport breakdown for the UI's transport tab. +func (s *Server) ByTransport() map[string]TransportStats { + out := map[string]TransportStats{} + for _, t := range []string{"udp", "tcp", "dot", "doh"} { + ts := TransportStats{Transport: t} + ts.Queries = s.load(t, "queries") + ts.Blocked = s.load(t, "blocked") + ts.Cached = s.load(t, "cached") + ts.Errors = s.load(t, "errors") + ts.Truncated = s.load(t, "truncated") + ts.Sent = s.load(t, "sent") + out[t] = ts + } + return out +} + +func (s *Server) load(transport, field string) uint64 { + v, ok := s.counters.Load(transport + "." + field) + if !ok { + return 0 + } + return v.(*atomic.Uint64).Load() +} + +// TransportStats is a per-transport counter set. +type TransportStats struct { + Transport string `json:"transport"` + Queries uint64 `json:"queries"` + Blocked uint64 `json:"blocked"` + Cached uint64 `json:"cached"` + Errors uint64 `json:"errors"` + Truncated uint64 `json:"truncated"` + Sent uint64 `json:"sent"` +} diff --git a/internal/web/dist/.gitkeep b/internal/web/dist/.gitkeep new file mode 100644 index 0000000..1d40ad1 --- /dev/null +++ b/internal/web/dist/.gitkeep @@ -0,0 +1 @@ +Build artifacts land here: run `make web` (npm ci && npm run build) then rebuild the binary. diff --git a/internal/web/dist/index.html b/internal/web/dist/index.html new file mode 100644 index 0000000..b671cb9 --- /dev/null +++ b/internal/web/dist/index.html @@ -0,0 +1,3 @@ +fancy-dns +

fancy-dns

+

Web console assets are not built in this binary. Run make web and rebuild.

diff --git a/internal/web/web.go b/internal/web/web.go new file mode 100644 index 0000000..fde306c --- /dev/null +++ b/internal/web/web.go @@ -0,0 +1,99 @@ +// Package web serves the embedded admin console as a single-page app. +// +// The assets are compiled into the binary, so a deployment is one file plus a +// config; there is no node process in production and no CDN dependency. When +// the assets are absent (a `go build` without `npm run build`) the server says +// so plainly instead of returning a confusing 404. +package web + +import ( + "embed" + "fmt" + "io/fs" + "net/http" + "strconv" + "strings" +) + +//go:embed all:dist +var dist embed.FS + +// Available reports whether compiled assets are present in this binary. +func Available() bool { + _, err := dist.Open("dist/index.html") + return err == nil +} + +// Handler serves the console, falling back to index.html for client-side +// routes so a deep link like /logs works on a hard refresh. +func Handler(basePath string) (http.Handler, error) { + sub, err := fs.Sub(dist, "dist") + if err != nil { + return nil, fmt.Errorf("web: open assets: %w", err) + } + if _, err := fs.Stat(sub, "index.html"); err != nil { + return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.WriteHeader(http.StatusServiceUnavailable) + _, _ = w.Write([]byte(missingAssets)) + }), nil + } + files := http.FileServer(http.FS(sub)) + prefix := "/" + if basePath != "" && basePath != "/" { + prefix = "/" + strings.Trim(basePath, "/") + "/" + } + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Hashed asset filenames are immutable, so they can be cached hard. + if strings.HasPrefix(r.URL.Path, prefix+"assets/") { + w.Header().Set("Cache-Control", "public, max-age=31536000, immutable") + } else { + w.Header().Set("Cache-Control", "no-cache") + } + clean := strings.TrimPrefix(r.URL.Path, strings.TrimSuffix(prefix, "/")) + clean = strings.TrimPrefix(clean, "/") + if clean == "" { + clean = "index.html" + } + if _, err := fs.Stat(sub, clean); err != nil { + // Unknown path: hand it to the SPA router. + b, rerr := fs.ReadFile(sub, "index.html") + if rerr != nil { + http.NotFound(w, r) + return + } + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.Header().Set("Cache-Control", "no-cache") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(b) + return + } + files.ServeHTTP(w, r) + }), nil +} + +const missingAssets = ` +fancy-dns + +

fancy-dns

+

The admin API is running, but the web console was not built into this binary.

+

Build it with make web (or cd web && npm ci && npm run build), then rebuild the binary.

+

The JSON API is available under /api.

` + +// Version is the asset build stamp, exposed in the UI footer. +func Version() string { + b, err := dist.ReadFile("dist/.build-version") + if err != nil { + return "" + } + return strings.TrimSpace(string(b)) +} + +// CacheControlMaxAge is the immutable-asset max age in seconds. +const CacheControlMaxAge = 31536000 + +// maxAgeHeader builds the Cache-Control value for a hashed asset. +func maxAgeHeader(seconds int) string { + return "public, max-age=" + strconv.Itoa(seconds) + ", immutable" +} diff --git a/internal/zonefile/zonefile.go b/internal/zonefile/zonefile.go new file mode 100644 index 0000000..cc8d9e0 --- /dev/null +++ b/internal/zonefile/zonefile.go @@ -0,0 +1,532 @@ +// Package zonefile parses RFC 1035 master files ("zone files") with the +// $TTL/$ORIGIN directives, parenthesised continuations and RFC 1982/1996 +// serial arithmetic. +// +// fancy-dns uses master files for two things: locally defined authoritative +// data, and RPZ-style response-policy zones that double as a blocklist source. +// Sharing one parser keeps operator expectations ("it is just a zone file") +// true for both. +package zonefile + +import ( + "bufio" + "fmt" + "io" + "os" + "strconv" + "strings" + + "github.com/miekg/dns" +) + +// Record is one parsed resource record with its origin resolved. +type Record struct { + // Name is the fully-qualified, lowercased owner name. + Name string + TTL uint32 + RR dns.RR + // Line is the 1-based source line, for error reporting. + Line int + // File is the source path, for error reporting. + File string +} + +// Text renders the record back into zone-file syntax. +func (r Record) Text() string { return r.RR.String() } + +// Zone is the result of parsing a master file. +type Zone struct { + // Origin is the zone's apex as configured. + Origin string + // Records are in file order. + Records []Record + // File is the path parsed, or "" for reader input. + File string + // MinTTL is the smallest explicit TTL seen. + MinTTL uint32 + // SOA holds the zone's start-of-authority record, if present. + SOA *dns.SOA + // DefaultTTL is the $TTL directive value, else the SOA minimum. + DefaultTTL uint32 +} + +// Options tunes parsing. +type Options struct { + // Origin overrides $ORIGIN and is the default when a file has none. + Origin string + // File is used in error messages. + File string + // MaxIncludeDepth bounds $INCLUDE recursion; 0 disables $INCLUDE. + MaxIncludeDepth int + // BaseDir is where relative $INCLUDE paths resolve; empty means the + // directory of the primary file. + BaseDir string + // DefaultTTL is the TTL applied to records that carry none, when the + // file has neither $TTL nor an SOA. + DefaultTTL uint32 +} + +// Parse reads a master file from r. +func Parse(r io.Reader, opt Options) (*Zone, error) { + origin := ensureDot(opt.Origin) + if origin == "" { + origin = "." + } + if opt.BaseDir == "" && opt.File != "" { + opt.BaseDir = dirOf(opt.File) + } + z := &Zone{Origin: origin, File: opt.File, DefaultTTL: opt.DefaultTTL} + + var lastOwner string + lineno := 0 + lines := bufio.NewScanner(r) + lines.Buffer(make([]byte, 0, 64*1024), 8*1024*1024) + + for lines.Scan() { + startLine := lineno + 1 + lineno++ + stripped := strings.TrimSpace(stripComment(lines.Text())) + if stripped == "" { + continue + } + // Fold parenthesised continuations into one logical line. + logical, err := fold(lines, stripped, &lineno, opt) + if err != nil { + return nil, fmt.Errorf("%s:%d: %w", where(opt.File), startLine, err) + } + if strings.HasPrefix(logical, "$") { + if err := z.directive(logical, opt); err != nil { + return nil, fmt.Errorf("%s:%d: %w", where(opt.File), startLine, err) + } + lastOwner = z.Origin + continue + } + assembled, err := z.assemble(logical, lastOwner) + if err != nil { + return nil, fmt.Errorf("%s:%d: %w", where(opt.File), startLine, err) + } + rr, err := dns.NewRR(assembled) + if err != nil { + return nil, fmt.Errorf("%s:%d: %q: %w", where(opt.File), startLine, assembled, err) + } + rec := Record{ + Name: strings.ToLower(ensureDot(rr.Header().Name)), + TTL: rr.Header().Ttl, + RR: rr, + Line: startLine, + File: opt.File, + } + if rec.TTL == 0 { + rec.TTL = z.DefaultTTL + } + if rec.TTL > 0 && (z.MinTTL == 0 || rec.TTL < z.MinTTL) { + z.MinTTL = rec.TTL + } + if soa, ok := rr.(*dns.SOA); ok { + z.SOA = cloneSOA(soa) + if rec.TTL > 0 { + z.DefaultTTL = rec.TTL + } else if z.DefaultTTL == 0 { + z.DefaultTTL = soa.Minttl + } + } + z.Records = append(z.Records, rec) + lastOwner = rec.Name + } + if err := lines.Err(); err != nil { + return nil, fmt.Errorf("%s: read: %w", opt.File, err) + } + return z, nil +} + +// fold joins a line with any parenthesised continuation lines still pending on +// the scanner. open reports how many continuations are still outstanding after +// the returned line, so a caller can loop until it reaches zero. +func fold(lines *bufio.Scanner, first string, lineno *int, opt Options) (string, error) { + depth := strings.Count(first, "(") - strings.Count(first, ")") + var sb strings.Builder + sb.WriteString(deparen(first)) + for depth > 0 { + if !lines.Scan() { + return "", fmt.Errorf("unterminated parenthesis") + } + *lineno++ + next := strings.TrimSpace(stripComment(lines.Text())) + if next == "" { + continue + } + depth += strings.Count(next, "(") - strings.Count(next, ")") + sb.WriteString(" ") + sb.WriteString(deparen(next)) + } + return strings.TrimSpace(sb.String()), nil +} + +// deparen removes continuation markers, leaving a single-space token stream. +func deparen(s string) string { + s = strings.ReplaceAll(s, "(", " ") + s = strings.ReplaceAll(s, ")", " ") + return strings.TrimSpace(s) +} + +// assemble fills in the omitted owner name, TTL and class so that the result +// is a complete RR line that dns.NewRR will accept. +func (z *Zone) assemble(line, lastOwner string) (string, error) { + fields := splitFields(line) + if len(fields) == 0 { + return "", fmt.Errorf("empty record") + } + var head string + var rest []string + if isRRTYPE(fields[0]) { + // Owner omitted: it repeats the previous record's owner. + head = lastOwner + rest = fields + } else { + head = fields[0] + rest = fields[1:] + } + if head == "" { + return "", fmt.Errorf("record has no owner name and no previous owner to inherit") + } + head = relative(head, z.Origin) + + out := []string{head} + // Consume optional TTL and class in any order, then the type. + for len(rest) > 0 && !isRRTYPE(rest[0]) { + switch { + case isTTLToken(rest[0]): + out = append(out, rest[0]) + case isClassToken(rest[0]): + out = append(out, strings.ToUpper(rest[0])) + default: + return "", fmt.Errorf("unexpected token %q before the record type", rest[0]) + } + rest = rest[1:] + } + if len(rest) == 0 { + return "", fmt.Errorf("record %q has no type", head) + } + out = append(out, rest...) + return strings.Join(out, " "), nil +} + +// directive handles $TTL, $ORIGIN and $INCLUDE. +func (z *Zone) directive(line string, opt Options) error { + fields := strings.Fields(line) + switch strings.ToUpper(fields[0]) { + case "$TTL": + if len(fields) < 2 { + return fmt.Errorf("$TTL needs a value") + } + ttl, err := ParseTTL(fields[1]) + if err != nil { + return err + } + z.DefaultTTL = ttl + case "$ORIGIN": + if len(fields) < 2 { + return fmt.Errorf("$ORIGIN needs a name") + } + z.Origin = ensureDot(fields[1]) + case "$INCLUDE": + if len(fields) < 2 { + return fmt.Errorf("$INCLUDE needs a file name") + } + if opt.MaxIncludeDepth <= 0 { + return fmt.Errorf("$INCLUDE %q is disabled in this context", fields[1]) + } + return fmt.Errorf("$INCLUDE %q is not supported; use blocklist.local_zones or a list source instead", fields[1]) + } + return nil +} + +// rrTypes is the set of record types the assembler recognises as a type +// token; anything absent is treated as an owner name. +var rrTypes = map[string]bool{} + +func init() { + for _, t := range []uint16{ + dns.TypeA, dns.TypeAAAA, dns.TypeNS, dns.TypeCNAME, dns.TypeSOA, dns.TypePTR, + dns.TypeMX, dns.TypeTXT, dns.TypeSRV, dns.TypeCAA, dns.TypeDS, dns.TypeDNSKEY, + dns.TypeNSEC, dns.TypeNSEC3, dns.TypeNSEC3PARAM, dns.TypeRRSIG, dns.TypeNSEC, + dns.TypeNAPTR, dns.TypeTLSA, dns.TypeSSHFP, dns.TypeSVCB, dns.TypeHTTPS, + dns.TypeHINFO, dns.TypeLOC, dns.TypeSPF, dns.TypeAXFR, + dns.TypeIXFR, dns.TypeANY, dns.TypeURI, dns.TypeDHCID, dns.TypeSMIMEA, + } { + rrTypes[dns.TypeToString[t]] = true + } +} + +// cloneSOA copies an SOA because dns.SOA.Copy is unexported. +func cloneSOA(in *dns.SOA) *dns.SOA { + if in == nil { + return nil + } + out := *in // value copy is already deep: Ns/Mbox are plain strings + return &out +} + +func isRRTYPE(s string) bool { return rrTypes[strings.ToUpper(s)] } + +func isTTLToken(s string) bool { + if s == "" || s[0] < '0' || s[0] > '9' { + return false + } + if _, err := ParseTTL(s); err != nil { + return false + } + return !isClassToken(s) +} + +func isClassToken(s string) bool { + switch strings.ToUpper(s) { + case "IN", "CH", "HS": + return true + } + return false +} + +func where(file string) string { + if file == "" { + return "zone" + } + return file +} + +func dirOf(p string) string { + i := strings.LastIndexByte(p, '/') + if i < 0 { + return "." + } + return p[:i] +} + +func ensureDot(s string) string { + if s == "" { + return "" + } + if strings.HasSuffix(s, ".") { + return s + } + return s + "." +} + +// relative expands a possibly-relative name against origin. +func relative(name, origin string) string { + if name == "@" { + return ensureDot(origin) + } + // A name that already ends in a dot is absolute, so it never gets the + // origin appended. This is the common case in RPZ-style policy files, + // where owners are written fully qualified. + if strings.HasSuffix(name, ".") { + return name + } + if origin == "" || origin == "." { + return ensureDot(name) + } + return ensureDot(name) + origin +} + +func stripComment(s string) string { + inQuote := false + for i := 0; i < len(s); i++ { + switch s[i] { + case '\\': + i++ + case '"': + inQuote = !inQuote + case ';': + if !inQuote { + return s[:i] + } + } + } + return s +} + +// splitFields splits on whitespace while keeping quoted strings intact (TXT +// payloads are handed to dns.NewRR untouched). +func splitFields(s string) []string { + var out []string + var cur strings.Builder + inQuote := false + started := false + for i := 0; i < len(s); i++ { + c := s[i] + switch { + case c == '\\' && i+1 < len(s): + cur.WriteByte(c) + i++ + cur.WriteByte(s[i]) + started = true + case c == '"': + inQuote = !inQuote + cur.WriteByte(c) + started = true + case (c == ' ' || c == '\t') && !inQuote: + if started { + out = append(out, cur.String()) + cur.Reset() + started = false + } + default: + cur.WriteByte(c) + started = true + } + } + if started { + out = append(out, cur.String()) + } + return out +} + +// ParseTTL parses the RFC 1035 TTL grammar (unit suffixes s/m/h/d/w) and a +// bare number of seconds. +func ParseTTL(s string) (uint32, error) { + s = strings.TrimSpace(s) + if s == "" { + return 0, fmt.Errorf("empty TTL") + } + var total uint64 + i := 0 + for i < len(s) { + start := i + for i < len(s) && s[i] >= '0' && s[i] <= '9' { + i++ + } + if start == i { + return 0, fmt.Errorf("bad TTL %q", s) + } + n, err := strconv.ParseUint(s[start:i], 10, 64) + if err != nil { + return 0, fmt.Errorf("bad TTL %q", s) + } + unitStart := i + for i < len(s) && (s[i] < '0' || s[i] > '9') { + i++ + } + var mult uint64 + switch strings.ToLower(s[unitStart:i]) { + case "", "s", "sec", "secs", "second", "seconds": + mult = 1 + case "m", "min", "mins", "minute", "minutes": + mult = 60 + case "h", "hour", "hours": + mult = 3600 + case "d", "day", "days": + mult = 86400 + case "w", "week", "weeks": + mult = 604800 + default: + return 0, fmt.Errorf("bad TTL unit in %q", s) + } + total += n * mult + if total > 0xFFFFFFFF { + return 0, fmt.Errorf("TTL %q overflows", s) + } + } + return uint32(total), nil +} + +// FormatTTL renders a TTL in the compact unit form operators expect. +func FormatTTL(ttl uint32) string { + switch { + case ttl >= 604800 && ttl%604800 == 0: + return strconv.FormatUint(uint64(ttl/604800), 10) + "w" + case ttl >= 86400 && ttl%86400 == 0: + return strconv.FormatUint(uint64(ttl/86400), 10) + "d" + case ttl >= 3600 && ttl%3600 == 0: + return strconv.FormatUint(uint64(ttl/3600), 10) + "h" + case ttl >= 60 && ttl%60 == 0: + return strconv.FormatUint(uint64(ttl/60), 10) + "m" + default: + return strconv.FormatUint(uint64(ttl), 10) + } +} + +// SerialNext applies RFC 1982 serial arithmetic: "+N"/"-N" or a plain number. +func SerialNext(current uint32, spec string) (uint32, error) { + spec = strings.TrimSpace(spec) + switch { + case spec == "": + return 0, fmt.Errorf("empty serial") + case spec[0] == '+': + n, err := strconv.ParseUint(spec[1:], 10, 32) + if err != nil { + return 0, fmt.Errorf("bad serial %q", spec) + } + return addSerial(current, uint32(n)), nil + case spec[0] == '-': + n, err := strconv.ParseUint(spec[1:], 10, 32) + if err != nil { + return 0, fmt.Errorf("bad serial %q", spec) + } + return addSerial(current, -uint32(n)), nil + default: + n, err := strconv.ParseUint(spec, 10, 32) + if err != nil { + return 0, fmt.Errorf("bad serial %q", spec) + } + return uint32(n), nil + } +} + +func addSerial(a, b uint32) uint32 { + sum := (uint64(a) + uint64(b)) & 0xFFFFFFFF + // Both operands in the "high" half means the sum stays inside the epoch, + // so no wrap correction applies (RFC 1982 §3.2). + if a >= 0x80000000 && b >= 0x80000000 { + return uint32(sum) + } + if sum >= 0x100000000 { + return uint32(sum - 0x100000000) + } + return uint32(sum) +} + +// ParseFile reads and parses a master file from disk. +func ParseFile(path string, origin string) (*Zone, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + return Parse(f, Options{Origin: origin, File: path, BaseDir: dirOf(path)}) +} + +// ParseFiles parses every file in paths and merges the records into one zone. +// Origins default to the file's base name, which is what a directory of +// per-list policy zones usually wants. +func ParseFiles(paths []string, originFor func(string) string) (*Zone, error) { + z := &Zone{Origin: "."} + for _, p := range paths { + origin := originFor(p) + sub, err := ParseFile(p, origin) + if err != nil { + return nil, err + } + z.Records = append(z.Records, sub.Records...) + if sub.DefaultTTL > 0 { + z.DefaultTTL = sub.DefaultTTL + } + if sub.SOA != nil { + z.SOA = sub.SOA + } + } + return z, nil +} + +// OriginFromPath derives a zone origin from a file path: "rpz/ads.zone" and +// "ads.zone" both become "ads.zone.". +func OriginFromPath(p string) string { + base := p + if i := strings.LastIndexByte(base, '/'); i >= 0 { + base = base[i+1:] + } + if i := strings.IndexByte(base, '.'); i > 0 { + base = base[:i] + } + return ensureDot(base) +} diff --git a/web/.codesearch/codesearch.db b/web/.codesearch/codesearch.db new file mode 100644 index 0000000000000000000000000000000000000000..cf25c6666232164ca530384ced1baa0faeb68466 GIT binary patch literal 344064 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.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 z z!@41#OP3)#u)4=fWviL69OpRMsgi@Rs(Y;J3Mh}VaseJA8|9jkoTGcR9CdbH(>+}! z&8RFzLc*u-9;wEEq~K`HBEoBSkC4)u%W{Semwj?bN@I4_fB}UQ)+%AfqCCC3Z;@?_ z8Bwzyf?jo0nxQ5bJ688#b)IW;$ga^9?VeS`+h14Zw2X@Zl-X4SMJ@zhd3S#~AxRZ% zHoE)C){;WHyRVedh$FSB-Q7nv$wXtwLuqx@KoKnB$!T;~Wb)IjP+xR+lKZkbS1whNs?qB1D3!@JQp-49JILt@!3&^LMuq@S zcY7%#oCg^Ma)Yk=NGPXLD=1HWBrIaAvbx(y0b#IluzG7bOeGDqKv(6j3`>`){FN=C zpjlltNYr9;(CT)#kbWJ^s{|M6LJdAPzRx?>Ipb5lJA60##=a|kO<%%yj_*W#n=kwJ z@NMVY#AoB{{7+Em|HAvQ_W|!0yr1xX(ED!h(0c{qty%8{-c!6sAkI4L-PyYZya1;V zUwzK=GtVQQZ+X7#`2=+O@A6#fxzLmIoa;FW-{-5Iy*xWWsc+f;P)hxu*^j{4?@LJI zal8Fqdkn4q+whGZvCmRk{ds#gduw}*ty_P#UVv8ryVlpN&sra`Zm@>X=Lz?emcI<4}>4!_QocL*KoRDcR!0PeLr+R;Qpff6YdYe z53uXcx?AqNJK{bQGq{Jim)yI!w{rX4PW=y1>OTTEz%RlJ@K*f>y{})YH{b<$mVS(W zu)d`4rn~@MuGioN_)FL0_(K1R>u%@^-V1%f70~JzTrt-) z{GIlc_K0@B_CTi9^|W_rH7%`Opq;KAqaCa*X*+9MY15hpwf-NRzjQw8{3gEB z?{MCvzSA#umYs3T@;rlCo*yF1<7biO@jZcl;L<=fkP2K7I31dUgW(XkOJK`DAmBho z$EPvN^N{~*{(ImMc)fq%zue!{Q;Io)`&}pRHJyUadd@=wfd8alfsIAl3b>5>)~gisu9FlYMwI3MZzbcBccxR&;X01sekoD#(Kc=J`sUtA9XOrJlwB-F zzob+6GSKYp6}e~fy6dK+1_nht#D?HzAhVL=ivANG1mm%0y~s_#OnOXljyAruxD8f2 z4#rN28-WzMmMif<(#ieCd$N0pE0I7|yJWHmo_KPy7}ngEO%`Xgsh_c`k$kxTnj%xa zq>Xd%;6xwBL*Y$y(yg@ zg2_<44l4XAOMvJT3W`^`8%8N!0I3>S*kNv=#FVbD@fffdFzCvpKDONC^kOc?#a>HQ zMSQv&n^3Jm<8dkLQ7u=%xHhKAf=yNPB}jG8Qk=t7HJL7D3XL? zCP#ow=1F#^vTo2%=ZP)PH1PIg9XQ!)M)T72GKJ)DC$c5TibI)3ss#13wW#=osZuf$ zkJh6Z$Q$T5l>*h!piLAq6gqC=!HSJMvPYfGk|0-4v62OmlI+S&)ElM#(BwxDZ;2>P&QYLrlZR+LwsF51ykAV zOsv#sX^y*Cm27-Tb6n5zvUtHcXR;da&DNVHtHH+JmIdQk!~r0cN#Q9+kFyk{z}~lU z+YF|we#mV>qnz9l=`1GS91pT&v77V2BLEphQ-(70&9kR%;wKn2m~i|Kujf)aBZTj zie4o8dE7IO$0kw&;}z72bj+SKJ1{ILom*jAWpcXkIix?y)52u! z+MT=sqp5nn0+D!`d*EqE*F50JRantfQHItdI zL`o=oXYPt|ioUH$n5sDV&Xa7#H0R6eD9IM8Tv9!dY_?`#Q%8|svWag4Yb|-t&1@xE zi9tr-{KaI;7%U6D6NY#b^F_=O$}IHSyH%}{4U8_{52>pr*{C<7i|~Q4wo`qdY=kn6 z1a5-cR3*ig!_Df{F~_$3WD&9wYL=39%+1)8S>U_K!}~T_gA&}LqjRzrt}jP1!^(&%}2X4taC*kEwnI8R-#!@(!Gs`-L99!XyVm~$mm4tJL=#VOV@PL@I(4S=q<#H9Gg*B7)sNcDh^`SVvoqBg>DaCvXo;uc~i88nBo@giWk*2wS!%JbKHG=D_tbQSk(+a;bd=oll zy30LLDnOIz;hR}9p9s&U;m|pusplXJt$5aJc;)`IGnuQw93z;+yvk2m;Qwe{3GX+I z($gDuR83A}K27thGlP792F;CSjzIr3S3d{(F63~ldk$7Tl`a->ADhRh)0Zyh3z#m}NcdMD z#`?Q>6q)06ds#wZWig6?owmrbVOHY$^<)tuLN}|75Z>e+7}vu~T!(??T5gy{eePfd zlzV`S_f|R!z19aOo8X0Ob2av-v-6R~WG$Lb#>04s?asn*XpJR3Zwnpt?-e$@V^{TcgK`+9p|Uv4+-Ed2jYvX8Kr;8w7O9k4a{ z|A|+@_uy4->cCgU)MJ#J}haJ5R$!^Pm5$p>nDz7RBdnsOCXy^~hol?>EC^)I8h5e5Q&q zW~gjx5=xzG4OP%AH#>t5+M$@2IWP_Hw1-E?%vCiN6`PEqa;T|Qs!JFlhKI>t>apTV zT$>&qiujmAe4}A;97epwX%62ag}|K3=^3gi(O?OxC(Sm7DsmRXOy!V~vn9N%4prnV zlg1?CP&w3On-VS??k{t6p#a8-6d zumr1B=qxGvA@6Wm1sXD~r8Ht4)^JJoXe5@9Z*;gQ?FdI_m!R_;E}+uZDsI~0ynNK; z@)5jD?O+aROM_>FHI%tgM?Qo&h;KL}bCA{9mBxH%2EI;1H9=a&XR0;aOAZm049(_{ zGo*N6Swl5LT3kX%)H{?YniHf9OruV{$1_xMv|?js0pVVIxSLdK@?JRHRjQSTdD2i3 zDMY1Z4OJ8^lY%psIowH_ovFj zTPYgf$@Wl%(aMp;GBo=`H91;bl#Llflkm!LD>+O~Vmd=LIT|jOU`#XI0;k3Szv>7i zr^1KiP)HP(N&xN~%FCM7Oe1S; zvapQ5`Q>lTkc>t{6+K%_FN=@UP_Zax;E zE*fsZAjljFox%bA9D2l%w#MN(YYxSr#({M9PXADsa7J`vdS}m2SzMOGr5a|G%%O^; zA=HmWr|ch&OP4F3vmBy&=5R{Z7V!~h3>29niV2Q^GO4M=ATHCa!P}%s^`c;oZqqr zd8ue?bro}00|}rxO3?`37uJ}Atn^nAW2`aAs50@1GEjVqV6N1_H~T<2o8f9R2P$$V zDJIN;a48(H>U7$JxKy!P%Hj2t5b6z8lNr?09z^AjH0w795vgDT-(KcGh0e+d zf_nxb>4tnNlaT9t5R`4Qm{#%*E|BwGoL^cfl`%0nIA7XOOC|96GdNEjGu%KQS%Y)s z4{G|w9-Je8$iOB* z@(1V)jlt=%G=s0)fpRztmT*lCPL*rw-{Nm;px70`3f|nzfv_tacyn`FgOj9AnaCoj z7=sg~pgPDc1MxO<)RJ&&1dqaH4OG}H6p~omK!wf9LHK_Rj+H9aV}<#-j9g8}NU^hX z+R64n4Hmgd9q}6P;3(NFoGfHo@Fe#Pj+A~Z6-#N%LwN>A$ge7l$%Mc#I9yd{89s)_ zKupc75@rzxhsx3lp3;N2$ltRme12PlLu9$ss3E>OI9N)_rdG@1m^Dx%MXQ8>-$2FA z!a@`=2P$^f5+^wnFHlu zmP16!9xTfltkjlZjAIU#WX}d3V)j6d5D6vaw+0JRdOU-4D89kGTM6bj9@XB#-qLq(_+ZMv{=v2?P+QK0 zXBL{E7kCHTNOMZfR3eCvRqtSH`I&1pLoJx&`Uh{4+C_7TU=DdaFc~@6N=|D%n+fA# zYz(%Ph85-J+X73DD&}MC!RFE z1UCoD%&fkQSAoGg)qzcUKCP9~;ckfTQKX9nxiZy=QHa3C)H4XkVQ?cBFrn)k_~qmk zDw*ZE6yArdfwDAH9wO#Ih77B}siAu9R{? z^p|HKOgubFA$->kFa{3kN6h`ib(7#v?JXb~s^u-<7k&{4gUq%i`A&RN3 zP0hYIBs*|hfd(lS$qt+(r`2y^M@Ja^s6*|(GRMTY2TL2XuY8h2m^AVCg?j-<)Hfz2 z%|4wm@pv%%RXK1%qC0&>$15O*3to@<$|*T7)_DDr)FN9gXS8K+U$HOH!1?7O`lDY^ z*HCP=SP^p$CHv5*hpP1WkBWxGs# z4p&D%CAA4635eNO!$=hLB2Pad9hecRJub_>qUB9&CCt89WIBqVo0xsYzi6%CEuydZ z7fG2#F#2I^VMRc6>4)TMEmamV@#pOarRKFpK9MQP3AjKV8LxMC|9shuNqEfud9pr_ zMp%6{f;5|ORQ2}HL4zEHOcn1+nrZgWmaR&wcs1*bPo|?D#9-t$`)`%?G4a~zpDCqg zOJVrmc>BsPxxSQ$hRP-IY){7ta*7uPZ6#ns+gCh{D()YvuXq?uG0rji!o#o-88Q1O zOVObuo;m%KWToT_>#IQ|j-Y@41nHOAS#8DYtMMbcP?l0(MdNG9a( zA1K#ur4=oP@-f&>8hx=&whG{v^!HcKw?-wnxVpNG4~@PWO|q5w4644bl+#L=W8peF z&g@S(dw72J)reBYwPE(vh*Aa7(C9Bqxv(~{`s#}#E_nmY{-RVei&QdJUyUZw)e2_g z|5yM2vi+R>Yd9P}W`7?ZhhIgO!MmUrxCNO5uCs^sRrWjVmR+_pcGNx(%7GK@qmV;j zUwZ*r1a`K!u{Q%d!Ny#|->p{>F@DDS1?(Iiw!ZVf`v3pc|Nno~|C?JVjgGlFfqE~K zdM|SmuB6_}q~6P1$CYad)O(rKdzsXGnSTDwN1)!zq~6P<-pi!k%QU$O^EWl-p4Jk6C9dKnaY86W1# z+X%N3ZXtY#@Ik@{2saaMBD|mQKEjQJ_Y!U(Tu*op;oXGm2-gy>A-s!lHDOE`5r%{T zp-<=$x`Ym)O}L8iPQsOhD+repE+bq@cn9GU!o`HQ6W&I+h;SjHMQ9QlggT){s1hoK zGND8$5(FH;WWajgi{D76HX$WNH~FTJmEOPv4mp?M-z@B97#BWa5&*G!l8t>5Dp<6OgM;e zAmISQ{)GJq`x5pctP)lT%Y-GuB4L3rPnaXj5@rZ{6ZRtPN!Ww%X2R}--3Yr9b|LIc z*om+sVF$wYgzX6161E|1O?VSwE5eq9EeM+vHY03G*o3fwu%57vu$HifFii*$`~)At zOYjhEf<-V12Ek3x2`++0a1tDZDFsL%q*U7fB>aQ$cf#KYeH*e;~X_c!BVH!t;dZ2+tCJM|g(tTf)#b8qmHpO653^v7JQw%o6U{ee>#b8qmHpO653^v7JQw%o6U{ee>#b8qm zHpO653^v7JQw%o6U{ee>#h5hZ8*I^igs&66M))e>D}*l-zC^f}@I}HG2%jf>j__H+ zX9)KYK25lra2MfIgijJaLAaCfal*$4cMv{GxSjA31#ULQ&8E276gQiKEL`e#VpH5~ ziknSwvndGGsZH1vH=E*SQ`~Hdn@vH|aJ40y;$~CaYzo4C>Thfc=)~$5n*sr_`o*TW z*%UXM;$~Calcs!_Ti!;vm2eB;Lxc|!K0vsca1-JEg!d6{B)pe!1L1nYdkF6)Tt~Q; za1G&IgsTZ-!iX>=38YVO9}5FTtc{*@OHx6 z2p179B(w-kLW58z)Cg5Vg-|Ax2t`7HkSF8_Swe=8CZq^SLV^${#0XJBgb*f#2tmRH zg!2jK5zZx?LpYmo7U8XgGYMx9PA8nk{C~$x1zrg}9e4uz|F1*;e@Ea0folTq3|utP z|DS*ifJ<VZ|QT~1Wd;52U z{@?HWyYD66Z+$=YJ>>g_?{iQXydUcSD|`)K#&^E&6yM>#eZc|P$+x-B3l6~Vp)YvU z`=Iwr-j8{2LTb<}p)Sb5%k4De0NmF*0}rIn{UB>Ii?~R`uj~New2XK$^5#xQxYjBnEcB5c~jWdm7zyz2#b}}|M zOz8h#cK;GQfbY1!;{G&l@%Ov01`nVG_5WG!6WnhB4?yx5Z07cX2k?siTm8rSxAm{+ zpN9JX2Jir`&|7)|On}q$qmTno)c@;2y!(e@0zBdRzU#}-{@)5^!4S@LRaeS&KE6qX z2`~#)fge6}FTsQEN7{F^uW6rw``r7rYqTr0rk2yr(@p{pU>~LYUjs$KpOA~;XU^}b z?0YI3ZI|lH3H(@VEYqNv9fc!;Jyt=q zdOnA|)!wlRqP;&H@B^kKKP#__W1?reN-cmNmfI4c7 zC3a@z5TY0>VOnuU(p!!}mFEwiBiZKKU#!8)5DMKt|!rB_eMZlmo$7^J<0xG*Xo|eV@A_#WlfE*;>2qVri z_RDH`9%IobRW2@QxI`qIoTFTgBc+yv@5dfFR%|JT+}j2uGH67(g7c{YX!&L#o6apE zd8aitrQ})xQBlv>kglCg7SrN_F?P#eB6(F=WnZBbIrdm(1qudX@qikDe2>Z?AD}&! zs2Q#dxOk%|hZI#y%18yvz)!(?#j}V8 zlh`OQsz`jd952vDt77i#moPkkE{uoK+8Z*h2`Z5AcqoVu~a%87DQj+C_ zShkPyvKDFQo%TrLWsY1BffD@4sv2a&NJwXnGSZ;9II@pqv~Zvgot{w&n>b+8kB5rO z8cDbeCL@x|XryQt5MJU?aoIJDyr`a0O!}~~G*iyvbc~o_v=M>P$S5KQOE)94U}%lP z(j$d(5ghlC$}b9PfNvC3k7R_K=w3g%K$Sn9oBQ-`83WXRV zR-@CT&RHZAk@I;fYGVocWhC)22Y5M7V4JDJrZzQo}@AsmMGd zB~s4E>fkeJ-jNz5qD#Tl%8K;(5z^RtB8lhHNHHxEG0AW+QbR*4g=gkS4GlFUCH0Tq zB2UUtBAaZj&c>zR)cC+GEu({_GUX7+A|n+qi#C>n%SCxUjubhs1__ZlQUgSJseuks zj0+5!fzf_)Vg5(91!J_Y^ivdp>X8~Hnz8uGEW-AqRcU6DuGu3MD2w3T#2m>8;Xuq3 zr&Wds2a-GJ_DH-fKw5!XH(-uvZh;K+=12_?=_c49qdDn-PzK~ZbEHOxP$q?LnvroM z^@cQJw6~NAgB`70YttB1AZL0e2^RpgX|0@x@)Br~=13?O zjso7ytdZhaL?Up^utsWts28hXeveez(QLdF1OXs0^2zlR3ePQ-SC@03F4!ZXNh5P! zql{5)Bs6I&niuuHl1o`haEQ#25Ud?gb)zd3#UdJ$$Eh+ns#an_kc&oYd}yR%pb?H# z%IR{efU(~ixm1y9$$U7{s-oll!=yY=a?yOG8frkcVh+_PfoB^UD&G|r%*U)@ObQAi2PY`0 zQMs^NjYb+7g^XcDwkZg&Gb}w?DbztIu!bSo0W?#*fe(YS2?TM*P=*I9vVy-WK3+m{ zk66R=WZPO2Z?pDL8Ct|6`BVy&!%*fCTe4^V`m6n;EJ#Bpn==o7g(E~?>4>Y{3{ zuHd0LJW+Zt0==VWsPavx>-83V7VM!K8NdgEYnjCVecF7l?z@PZPuhikUC&C z+xJ)B3vmB?#P=<@|J~)g)pr9F0GIg6zSu_hzukOW`FuXj`)BWq-d}rvtUaW?S3B4H zE$X(}dT+1<2%cwC4c00q)}2!ZVFLhOgUC!wv8U_BWsj_?Uf@eT{u3;`(X(d}sm= zv-h$0vUfl%-)lRq*RAKRpIeVu4_aTb?uIVlM(b+pD(h`l*$P{4wN9`Owid13tgWrJ zmfQTR`J(v?^HF#W+-rWy{D66l`A)N8=FE_Jx_PX5kU3}WY;J0Ljei-h!VmCKI1PLO zZh#*&t}{Bug_sS9Vm9D-<1NODv8S z@)|h9eVqGX_dGoM4s-7czkxMwL;o8b2Y!w3clmNp>OX=`;4Avw`iJ%RV}9Ury{@P9 z3ot)$jDCo(W5t`2H3QX{Z4na(>nM8RtjgEI>Vg%mbX_m}nYvN^8Q@-#YUjDIXgB zIVI%DhsxDrb2Z$8l9mFzdJ);z@hPQYfw0B;B3A}Ma@tWI$Ig5Zd@Q}r z4T2!qD1lslb*3Dy;G@YKs0m>Ni|k)?A0PmP>g&HLQDC_7dJg zpbb&=SenRBwiI%4~?5#@8!RKHXr6%GZrZ;SgMU5qeDRR} z^^a{lq;LIwsxlCSg`y?z`cJcnXt|7RSl;!YUo!D{`;FlwQJ! zHCB{Z?muR6C;`t^l3>jDc$^C8Se~0%6yBk3WkoQoPhF}mGk7zFa>4luKIb(xk~>vy zY}YH34QDisvcnv{_ovuXbWC)=i`6RCLm-;2V^c~{D=%m9ig&H*##|``-Xy-}e$V2d z6x8=;Wgy+{a3wm_y(3pbi+MjwRd!+SZ6-fNgJImk&GF9fzKf+7R%V)UJg6VT3x?&$ z5rY^vPFBNI(sc@p zNCh>AhX+y04dY!bB&F%ka|?0O;j11vRn3}QQQ&}kzQax9n){!ugQDdd=Wyd#MsuAuS;RC)jpus8H+8?n#>9{~ z)AIzE@t`oL57@YDOm90`hTz6-@-#$i8N5C?zA*U<=;@w$-aZ>&kBnz|4P!2%0x_X? z{hL@#@EMtKDi>+Ne!`|$KNpE<+CHq?g!btECQFZC{>@7X_arm7YjRxqs5Q@Eu@Oz9 zKSVAJv7?pXzF~aE!M8_sHcr>oJiuhm*ZeKJD^yy59mwUAAE`WEx^7_ILzvY`ix7mS z6yjT@f0?C)H2os>MX*(bv55Cn9x+%*Y92aTB^xURM!#aCA{k=eTijry0~$@ z%X{a>WzEcq7)Q-xIM1G}#=NBYrOEP4U7PyF-vP!rJU*Hn1k1$)X(pt(d z!Qs&p;9sCxK9Uy$GL1W#vlWwR<_-Kav;}YG61ei;Vvj5|=0Ode+|LWus^&V5o8T&? z?h_`1+C8k@EV67nn9NGa>kPUlZ8Y*j*fh zv+#*Cd5uD=0(V#HYelzW1l19hbk6v)>W^%5ww{GM&KCTOIA`g%s8gP8#8VBZnc&bY z=OWt(|6lCAceE@;`7XR?x@WqpyJzN{v-cr$$l(xo4g|?LgXB0l?8$kCEEy%7iCd8j zA_#&=5>SvNB0)d|L_|PAM2RK@@q4PCIl%9(^{u<^_pNo;@80EKPft&GRlS|6>aF*A z-ZYi~cv3x>pM|ajN!~J0)qA@#oURe`P-QHny1dLko2i!KiE+(y0NV;DnTP#U24ZLK z%?5kNG*3zO2r}whPNWhs%|-1H6$kG9fORM;gs~OtsAygfcPp7X&&w$pGRUa3m!J&l%?#vu-&c?NBQ|83|etOykO%~(;fiMPeYY^9lE zEsoK-rhSh^$u$D=*}-u#>e|aB$OAvU`4b*iNTI{xI4XlMayQ>@&YjH>noz(iyw6~B zOmm&iW+1cJSGW@dX~E=slzQ~~2Kyn1#B7C7BLzjCDcmx7T+G1{xu!jQ6&sSn!j0?T z!FCZZ*w*Tkl*whGZ3J4NJlRWbiYgsI11_d|Bp4qvi2Z z4gIiwJIzW}i_ki;{=%9hyWm+Ck;=j?wew&bgeqf~!3l~)W$dIhhccB04 zSXH!)In7(D*U4bp-DE*>Dd3dB5z(?(EO;ZMkz~*wR!%E-M*gsdnekTrFaj^J?x^N{ zh$l;Tfid`wL?$Ogn*FAn{|{;PAKORduh*BJgtHnZUzJU+(fiD{wx12&up^f&G!u zei|NxwE}*nBJh^~6=bx3)PFB>+J6iBau@hd^;i7!{-gYRBd7h8e>49w_z*nsA-wH- z#rG6c1nxlwf$Myi`r5v8v?sMYd`(}@7eSW$1AIIB#t=skP+0_Cb)I$}0=K>E-09rp zTnROSuQ{hXRpf;`0kH&oINLkp&U(%&h$V2@f3x3&_uwh}e)~52dUy{y_G!rbCNl{f zWbY0=fvun?u!?OVlHeWdx9}Z20N=s&;03h638*UH!Iz;Yu)Q^oS>r0ockmBz0DdQ4 zfTqCx;&ySpxLo@f`2@}vCn2A}v0{I*vl!Rj(yl=~!D6AAe}_`xD^M!@iFuFqfO#YQ z2YvH=^Hj5F#?52Q1I^vdIde;MeRDO_f(PM4co2SN{M>lZxWl-?xXfr9r^ADAtZ}gN zA8ckUGZq_$_havS-Z$Vqcn|?eHzJ!r8yVwH^yaYiVC z9`*dtbBh+$j?nhdw%4}OHqeGO!~GBU+gR~`#{H1{Zud=C@o%}$h1P%G9dRG!-p?)l z@$R7^^}$?8ST#;ik7Z#zhHT$DdltCAjF;5I$K}DVt5>Zs8cj|^+vQ00fXaOCRO-n$ zHJw6TgH=rPYE@)jIkb$Y`J+BQnb-7jb#5NgY*kfezSf+95Wa^}H2E4<9z1*TglcmZ z<1W5`Tmm((R4va}%P9~>HHRO-d=;)}`+D_iLYsR!2cnMVDyw%;YIS>e8=N&aK0lt- za2sXM0Y9Qad6#^p8gEX_VChNQo;53dPS1k60QpK9qp3VgW9C|tu8<{oh9)Qu*5akq zG|A;<%3rt_ma8vvK3K$975RLzXLVIzE}L#FT57Uz=%WXgGL5v{?;m+ywRKR4f8^Q! zp%DMb(`?Dylrz#%-E%H7F;U6Q2BCh%3H$%uJ{&g|S|`Ln7t1%t21@Yy{iuP zV@U82i--0HWui>R$O$)P=<*2&FzK8
aUsLgipIA8!=VJD$U8Vj%jvzryPj%Y{=|ruZ?- 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 literal 0 HcmV?d00001 diff --git a/web/.gitignore b/web/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/web/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/web/.oxlintrc.json b/web/.oxlintrc.json new file mode 100644 index 0000000..6fa991d --- /dev/null +++ b/web/.oxlintrc.json @@ -0,0 +1,8 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["react", "typescript", "oxc"], + "rules": { + "react/rules-of-hooks": "error", + "react/only-export-components": ["warn", { "allowConstantExport": true }] + } +} diff --git a/web/README.md b/web/README.md new file mode 100644 index 0000000..d6af7e3 --- /dev/null +++ b/web/README.md @@ -0,0 +1,32 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some Oxlint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs) +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) + +## React Compiler + +The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). + +## Expanding the Oxlint configuration + +If you are developing a production application, we recommend enabling type-aware lint rules by installing `oxlint-tsgolint` and editing `.oxlintrc.json`: + +```json +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["react", "typescript", "oxc"], + "options": { + "typeAware": true + }, + "rules": { + "react/rules-of-hooks": "error", + "react/only-export-components": ["warn", { "allowConstantExport": true }] + } +} +``` + +See the [Oxlint rules documentation](https://oxc.rs/docs/guide/usage/linter/rules) for the full list of rules and categories. diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..5e3836a --- /dev/null +++ b/web/index.html @@ -0,0 +1,13 @@ + + + + + + + web + + +
+ + + diff --git a/web/package-lock.json b/web/package-lock.json new file mode 100644 index 0000000..2fbb040 --- /dev/null +++ b/web/package-lock.json @@ -0,0 +1,2488 @@ +{ + "name": "web", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "web", + "version": "0.0.0", + "dependencies": { + "clsx": "^2.1.1", + "lucide-react": "^1.48.0", + "react": "^19.2.8", + "react-dom": "^19.2.8", + "react-router-dom": "^7.18.4", + "recharts": "^3.10.1" + }, + "devDependencies": { + "@tailwindcss/vite": "^4.3.3", + "@types/node": "^24.13.3", + "@types/react": "^19.2.18", + "@types/react-dom": "^19.2.7", + "@vitejs/plugin-react": "^6.1.1", + "oxlint": "^1.81.0", + "tailwindcss": "^4.3.3", + "typescript": "~6.0.2", + "vite": "^8.3.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.151.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.151.0.tgz", + "integrity": "sha512-J1yXrIlNDZVzE3ada310xeAw7nH8yCAyLPuUIsjKatFPmfn5bS1oW+cM+QsGOtVWd5nhSpbwZWx/rue+r5Z+PA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/oxc-project" + } + }, + "node_modules/@oxlint/binding-android-arm-eabi": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.85.0.tgz", + "integrity": "sha512-q2KO/Zso9UT+OMn0NF9ywn4E4t0MI3yxiDhNyhsQ7DyQJrC4FhFE4TXOi4bktFnOWXTMds8qZSbpv2XwRaNOBg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-android-arm64": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.85.0.tgz", + "integrity": "sha512-SxLN3ALjoT9NNdvpjEevGeHvfzTAFrF0NBYB5tzK7/GtCKMze3j1e/m/X2ozqGj2U9hfGG/dg/OG8vpVK4PiDA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-darwin-arm64": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.85.0.tgz", + "integrity": "sha512-Y/Sup/J4f0f9UGsSd/xyCNTeWL+gepO63GBdEDAfue9nBsnk9zMmnIXx1O6b1V8C90vB5nucYNZ0pbMXAp8zJA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-darwin-x64": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.85.0.tgz", + "integrity": "sha512-ApOSNC04ynpDTwvBD+//0wyfODRSbEzvRoKpX8teffmc27z8AockwSNeMXGJXn5KP85eahDgR/2llICWLkzcnw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-freebsd-x64": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.85.0.tgz", + "integrity": "sha512-bNrVrCOA/kHky3Tu79IXWXe5bhIgLXfUuUEDHlAGOHUk96MkvDZ1ecaQF19rwstrnaqfP1o9nBTqzIr9+ZHkUg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-arm-gnueabihf": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.85.0.tgz", + "integrity": "sha512-NUrzOJ1s/EqsVvfn2L/1D8Wro2LPIZUbihL8kOJLh5fEdGEN3rdOGUYq3HwnUIL8sjpoP+4N6RaGrgmMJnaMPw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-arm-musleabihf": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.85.0.tgz", + "integrity": "sha512-UJXrAT3E/RWkEqXLIs2ehETja1qfgkPb+5gwLIIS+o/6cf+grHvoOXTa5997a/YNQfcJS0DRBTOfZt95cvOI1g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-arm64-gnu": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.85.0.tgz", + "integrity": "sha512-lK40QLjI0HxigO7CjDDshEtfYIeiYS0020v5BHFPqN4uuQBQxd2K9LNom2dW15o9F1937quSCRVp4ZsVhdbYdg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-arm64-musl": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.85.0.tgz", + "integrity": "sha512-c2zbdBwGKreHXwRx3gWBuFGJxLhxgsg6YlZ+3H+RgRusU/UEV9jNwJ3HGYK+nRo0LvBa7mt6Kj86xoVotUo8cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-ppc64-gnu": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.85.0.tgz", + "integrity": "sha512-tlt/Hy8lZ97/lCPmCgw/B3k/mwh+BzaIPbPkldZEly7TwLmx0xe2CQcaW2g/rR0dOgS9JNGCZsMEqLhUNMGvaw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-riscv64-gnu": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.85.0.tgz", + "integrity": "sha512-3tNR9Xey82X0zKuY1d8hJ6Rc9gwRDurmqGLnQZa5xqOXy8/YyiqFXjAtugkKLY82obOlpK1eSiDRlgcNPuxtIg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-riscv64-musl": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.85.0.tgz", + "integrity": "sha512-wbGRd5PqCcjkJFHhZuZ2OBSUQY9czlQsoA/cQQB9JK/L9mC5MQgGoKAh+xd8QjA5V+0D3j+Qd1lAWn1I8zlelA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-s390x-gnu": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.85.0.tgz", + "integrity": "sha512-3Sn0kSrE4DPZCWV/8o+n4x3aFZxI9ulMnkYlwCbJ8eUVkwRK2IerohE/A/z3SNbCwoPFOCJmGE5Avrq0rrvdvQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-x64-gnu": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.85.0.tgz", + "integrity": "sha512-JY2pxxYfB62bAGfejljVCqc44etItehPuAyaeSAdMuEMtwNA00ggMnS66lC1oIhos6oOXUkuU6mZ9bpFh3BqWg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-x64-musl": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.85.0.tgz", + "integrity": "sha512-5k74vZ6qJBjBHEOlBk9B/iv68Yu0F1Afw/vvT2ar6OGCqEeXLaSjXz2n/IPCbhLG22UoKoYEJTzpYraRdcp6PA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-openharmony-arm64": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.85.0.tgz", + "integrity": "sha512-GbAl5qt5TCkPLXTaIISZJnugrcBhra6rodcXc9jYt620UtdsTt71NlNmJmm0frxzFpd54x/G+MkitEJA8I/BoA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-win32-arm64-msvc": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.85.0.tgz", + "integrity": "sha512-kjmws5MK0et2swk4ND85D7NVQyDHw162i6whtZDLUA/lo6FQyBZDcmMRCMcVZcNrAhIaftVb00x9ChGDOjjNJA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-win32-ia32-msvc": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.85.0.tgz", + "integrity": "sha512-eSsIJx9n4yxvOqYTZyPEMyEXRmE60XH7xGAU7i0Qbsn1lf6Za3CWJ9aRd82oSFKXaxhp+sA6/yMJVRIpLpna6A==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-win32-x64-msvc": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.85.0.tgz", + "integrity": "sha512-pBebIPUpKKhWrhSMWhy8TdAZBewiXnfxmaAGxhzxM1068GagqFaTwgKlU6e+UyJ2sPR+VoHouhXuGJkQjsrDvA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@reduxjs/toolkit": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.12.0.tgz", + "integrity": "sha512-KiT+RzZbp6mQET+Mg+h2c97+9j1sNflUxQkIHI7Yuzf6Peu+OYpmkn6nbHWmLLWj+1ZODUJFwGZ7gx3L9R9EOw==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^11.0.0", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.11.tgz", + "integrity": "sha512-A5kXfGKvKWWZE0TtPrfsvT+q4Y5d1QG8gGUzpYjGydM+fARM9MuX90PrXYXe0XbsDVgyxxNzHo6giCj90bsFNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.11.tgz", + "integrity": "sha512-z6cTycz+iJ4PVkuL4HHW4DfTfoeU/2nqYYuSOrTmH7yHK5Y0LCOnA03V4ZNxavyVaU1oOqUgIg2klN/s+USGOA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.11.tgz", + "integrity": "sha512-jShvqNtP6vDC6/A5JOAzbVV+DkgHqhl/ScVCJEbt+TUY6QYz7YnXcrg3sLtFBniro0f/Ld50ZwCWA6f7KYD1nQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.11.tgz", + "integrity": "sha512-f2i2xiNWq1Z1l2++q2fuhZRdLAT3aqxD6vRNm1RAxpUoBcdqNB3C0s1Bt+K+PbEx2F5F4gQp6hqKkphCY/xF9w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.11.tgz", + "integrity": "sha512-4Ir5FSOKIAMr4r0kExpt1s3bMgzJU3rA45AYOHtQpls0oNeqcYBKrWMlckrYH4KCfGLfkfn1tN1dmZPMVsdXow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.11.tgz", + "integrity": "sha512-/gnRDM+39BROzAN/k1OZjDPnDMcZxB/0EUxKjONO5yVkNEvlsoMDrxGNKgZi/ttFriS2gwlDNzB65pvNbFOXIQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.11.tgz", + "integrity": "sha512-PFaK8HwvAHbaKbBcDNQihjMKYvFnA5hiENx/l5tphTDz1E0WFp32l0A7aq7lyUwGsRw/xSrNIy/gIK4thrSCrw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.11.tgz", + "integrity": "sha512-AskzJUIKRLPxkruR1wLKewGbOw+EYfU/9lOrBFj4AFrEA8hPpKFnODWNu2WLaNs0QNkEb9QIJufmVZZIL/bJlg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.11.tgz", + "integrity": "sha512-qlUGAheh2yh8afH7QBgx0PrRHN85hKnNd78x8MeMhXivuevgd8vgf6/CstOzmNKY/lLTHvNTrPy98cLnAugzJw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.11.tgz", + "integrity": "sha512-secpEad+0vCbSfn8upFySkDskv+bGPk3THSDS9Y89yc4rb4kzqHp8Dmyd9BkQW4SnhNXBZCl/6CrO//hZahNJQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.11.tgz", + "integrity": "sha512-mOVBT3dPpkWm8XBWPmU4bf+U6dYDLeMo/9ojUmis4N0L5uu10qra5vOyngZ7/PSdoE4G9KvRt4bloRxNjLas7A==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.11.tgz", + "integrity": "sha512-Is78i9A8Ui4SqcxUwFJ9uMmjDn58IbVTjFWYdQestFEgeuEmHMLGNriXnVJKkwG2YiZjw8cP0zCTyDMdDGtOOg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.11.tgz", + "integrity": "sha512-dUCXneZ87INUMyQ0D+C0HrEBNUPNXHaPmU5GTjyKTJEiussw9Kaj5Ln8UztPe4epV/ffvgNBEadksdYhmW6xJA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.11.tgz", + "integrity": "sha512-jByxb6qfd+bH1xUd0qnfFnb17i9sWBPY2tOavJ0l3tdr3OTu+Kvtm8cd/JV5nFt657b1VqGltxg9olOEfofXWw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.11.tgz", + "integrity": "sha512-/PzKqzAJ03i19oy2ItPvyvaVjOjBCNnfaJs8yvUdGBKmiESgnrJSQ2awd81QzFbbnAmu7YO9ZnJrDCb9VSJPRA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, + "node_modules/@tailwindcss/node": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz", + "integrity": "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.24.1", + "jiti": "^2.7.0", + "lightningcss": "1.32.0", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.3.3" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.3.tgz", + "integrity": "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-x64": "4.3.3", + "@tailwindcss/oxide-freebsd-x64": "4.3.3", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-x64-musl": "4.3.3", + "@tailwindcss/oxide-wasm32-wasi": "4.3.3", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.3.tgz", + "integrity": "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.3.tgz", + "integrity": "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.3.tgz", + "integrity": "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.3.tgz", + "integrity": "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.3.tgz", + "integrity": "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.3.tgz", + "integrity": "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.3.tgz", + "integrity": "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.3.tgz", + "integrity": "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.3.tgz", + "integrity": "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.3.tgz", + "integrity": "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.11.1", + "@emnapi/runtime": "^1.11.1", + "@emnapi/wasi-threads": "^1.2.2", + "@napi-rs/wasm-runtime": "^1.1.4", + "@tybys/wasm-util": "^0.10.2", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz", + "integrity": "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.3.tgz", + "integrity": "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.3.tgz", + "integrity": "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.3.3", + "@tailwindcss/oxide": "4.3.3", + "tailwindcss": "4.3.3" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7 || ^8" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-kVd74ta9eof3eJOvbNd1vGKS/XERRyQbT26Og63hIsvDO84cjD5gEOhsXf26w3FSoNlPVz84DOFcKv/oou+fMw==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.19.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.19.0.tgz", + "integrity": "sha512-zY+5tKxXdhGh1PYI0ac+7juvEu4OI6vWtVVoj5i2m42jxAY1U+zHGt6QCyOFwykdP62sM3MJ9stoYYUw5aCWew==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": ">=7.24.0 <7.24.7" + } + }, + "node_modules/@types/react": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.3.0.tgz", + "integrity": "sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.3.0" + } + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, + "node_modules/@vitejs/plugin-react": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.1.1.tgz", + "integrity": "sha512-yxLaQV9gkhS8ezJqCM6+ndU7mDY6gqAg75NQ+0IjwEI8IYOmQCgkRwHKVSfWXW076DsqMo0Dk+0FK1U+M5RgFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "^1.0.1" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "oxc-transform-react": "^0.145.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "oxc-transform-react": { + "optional": true + } + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.25.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.25.1.tgz", + "integrity": "sha512-nGXts5znJzmWPu+mIE9izCOzdg63oJca2mDzGWWTth7sr4aCToKcoyFVBQwN75Ij5Pf6p510EwkTqViTRzDV+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-toolkit": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.52.0.tgz", + "integrity": "sha512-XTNEJQh1tY1ZJVcf6ayP/2n4ZPyaHlW2FWs7xvw5ddPuhUVjLD3olQVQS7kf58JbAB48iL0uL/jerTrjtV3lDA==", + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks", + "tests/types", + "tests/browser-compat" + ] + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/immer": { + "version": "11.1.18", + "resolved": "https://registry.npmjs.org/immer/-/immer-11.1.18.tgz", + "integrity": "sha512-EQyQtLiYW029lyoczMl/Hh4Xu7cDecSc58JRYpHyL4tIAu3eqd1yJzQX04d2BZHDkzFFvm6qJEJWOtfDSWAXbQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lucide-react": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.48.0.tgz", + "integrity": "sha512-R0CIKY/fXiC6y9xRBADgsK+VW2p/pcTJOMhLZf1T+uG+vJUvyUR02nGOgmIIC7MPkiNK4Ox8QDnbqF8rJYWPZQ==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/nanoid": { + "version": "3.3.19", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz", + "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/oxlint": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.85.0.tgz", + "integrity": "sha512-bc26s97nuvPj1ViyPsqmKecVkUWFMEdtayO8MaQ6oiLfs1pj94cQlZZhrh4BPNlr9HQosjhIlwgZKsfcwmcNgg==", + "dev": true, + "license": "MIT", + "bin": { + "oxlint": "bin/oxlint" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/oxc-project" + }, + "optionalDependencies": { + "@oxlint/binding-android-arm-eabi": "1.85.0", + "@oxlint/binding-android-arm64": "1.85.0", + "@oxlint/binding-darwin-arm64": "1.85.0", + "@oxlint/binding-darwin-x64": "1.85.0", + "@oxlint/binding-freebsd-x64": "1.85.0", + "@oxlint/binding-linux-arm-gnueabihf": "1.85.0", + "@oxlint/binding-linux-arm-musleabihf": "1.85.0", + "@oxlint/binding-linux-arm64-gnu": "1.85.0", + "@oxlint/binding-linux-arm64-musl": "1.85.0", + "@oxlint/binding-linux-ppc64-gnu": "1.85.0", + "@oxlint/binding-linux-riscv64-gnu": "1.85.0", + "@oxlint/binding-linux-riscv64-musl": "1.85.0", + "@oxlint/binding-linux-s390x-gnu": "1.85.0", + "@oxlint/binding-linux-x64-gnu": "1.85.0", + "@oxlint/binding-linux-x64-musl": "1.85.0", + "@oxlint/binding-openharmony-arm64": "1.85.0", + "@oxlint/binding-win32-arm64-msvc": "1.85.0", + "@oxlint/binding-win32-ia32-msvc": "1.85.0", + "@oxlint/binding-win32-x64-msvc": "1.85.0" + }, + "peerDependencies": { + "oxlint-tsgolint": ">=7.0.2001", + "vite-plus": "*" + }, + "peerDependenciesMeta": { + "oxlint-tsgolint": { + "optional": true + }, + "vite-plus": { + "optional": true + } + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", + "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.18", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.3.0.tgz", + "integrity": "sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.28.0" + }, + "peerDependencies": { + "react": "^19.3.0" + } + }, + "node_modules/react-is": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.3.0.tgz", + "integrity": "sha512-UpMYezM4v5/18F28aC66AEsjXIgE02kyEMH6yLdgLXu/UTfa1Ntwck/nNLrbqJsEXW7gPb0coNO9FQse9WTovA==", + "license": "MIT", + "peer": true + }, + "node_modules/react-redux": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.3.0.tgz", + "integrity": "sha512-KQopgqFo/p/fgmAs5qz6p5RWaNAzq40WAu7fJIXnQpYxFPbJYtsJPWvGeF2rOBaY/kEuV77AVsX8TsQzKm+A/g==", + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-router": { + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.18.4.tgz", + "integrity": "sha512-PUPQcMhMGRAslLcvtlPz/kmzBEWPhLdgLFrL7pLNepBL6dX0lWj4WD2cUYVgYCuT3jxvghYFg81cDTj44DhetQ==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.18.4.tgz", + "integrity": "sha512-yrfmJHIpDG7taCpqKjT1G5B6q3O2K+RN8/fgNf0lTjCwiPbQ0ei6vXX9ZjQR+7ld8Tr7Z5xmyMnZ8YJrphWQUw==", + "license": "MIT", + "dependencies": { + "react-router": "7.18.4" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/recharts": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.10.1.tgz", + "integrity": "sha512-QXFrvt6IVcw7eeZCoyXTwkIJAX3Dv1nyVhMicXJ47GsGDDpcN8z6o644DibE9XjpBTThtsomLKnTV6lc+cVFUA==", + "license": "MIT", + "workspaces": [ + "www" + ], + "dependencies": { + "@reduxjs/toolkit": "^1.9.0 || 2.x.x", + "clsx": "^2.1.1", + "decimal.js-light": "^2.5.1", + "es-toolkit": "^1.39.3", + "eventemitter3": "^5.0.1", + "immer": "^11.1.8", + "react-redux": "8.x.x || 9.x.x", + "reselect": "5.2.0", + "tiny-invariant": "^1.3.3", + "use-sync-external-store": "^1.2.2", + "victory-vendor": "^37.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, + "node_modules/reselect": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.2.0.tgz", + "integrity": "sha512-AgZ3UOZm3YndfrJ4OYjgrT7bmCm/1iqkjvEfH/oYjzh6PD2qw4QuT3jjnXIrpdt4MTpMXclMT3lXbmRY+XRakw==", + "license": "MIT" + }, + "node_modules/rolldown": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.11.tgz", + "integrity": "sha512-qpSwIyz0jHQq5qXBTNxFmE6664rJ7O+4TvPFOiOaBSrz8IOHc1koKKSqTM2H6u1UG1+TveuC6vaDHKXFOvb1Kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.151.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm-eabi": "1.2.11", + "@rolldown/binding-android-arm64": "1.2.11", + "@rolldown/binding-darwin-arm64": "1.2.11", + "@rolldown/binding-darwin-x64": "1.2.11", + "@rolldown/binding-freebsd-x64": "1.2.11", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.11", + "@rolldown/binding-linux-arm64-gnu": "1.2.11", + "@rolldown/binding-linux-arm64-musl": "1.2.11", + "@rolldown/binding-linux-ppc64-gnu": "1.2.11", + "@rolldown/binding-linux-s390x-gnu": "1.2.11", + "@rolldown/binding-linux-x64-gnu": "1.2.11", + "@rolldown/binding-linux-x64-musl": "1.2.11", + "@rolldown/binding-openharmony-arm64": "1.2.11", + "@rolldown/binding-win32-arm64-msvc": "1.2.11", + "@rolldown/binding-win32-x64-msvc": "1.2.11" + } + }, + "node_modules/scheduler": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.28.0.tgz", + "integrity": "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==", + "license": "MIT" + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tailwindcss": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz", + "integrity": "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", + "dev": true, + "license": "MIT" + }, + "node_modules/use-sync-external-store": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.7.0.tgz", + "integrity": "sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/victory-vendor": { + "version": "37.3.6", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz", + "integrity": "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==", + "license": "MIT AND ISC", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, + "node_modules/vite": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.1.tgz", + "integrity": "sha512-/bvH9E9tmCXRGp2uXY3WbOldqpTwFkbha/8ANaEQ6VkxhH60KyqLwgZq6lG2y+4uT55x9+9eUHMpQ7uGnOCKjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.33.0", + "picomatch": "^4.0.7", + "postcss": "^8.5.28", + "rolldown": "~1.2.9", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.7.1", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + } + } +} diff --git a/web/package.json b/web/package.json new file mode 100644 index 0000000..7e802ab --- /dev/null +++ b/web/package.json @@ -0,0 +1,31 @@ +{ + "name": "web", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "oxlint", + "preview": "vite preview" + }, + "dependencies": { + "clsx": "^2.1.1", + "lucide-react": "^1.48.0", + "react": "^19.2.8", + "react-dom": "^19.2.8", + "react-router-dom": "^7.18.4", + "recharts": "^3.10.1" + }, + "devDependencies": { + "@tailwindcss/vite": "^4.3.3", + "@types/node": "^24.13.3", + "@types/react": "^19.2.18", + "@types/react-dom": "^19.2.7", + "@vitejs/plugin-react": "^6.1.1", + "oxlint": "^1.81.0", + "tailwindcss": "^4.3.3", + "typescript": "~6.0.2", + "vite": "^8.3.0" + } +} diff --git a/web/public/favicon.svg b/web/public/favicon.svg new file mode 100644 index 0000000..6893eb1 --- /dev/null +++ b/web/public/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/public/icons.svg b/web/public/icons.svg new file mode 100644 index 0000000..e952219 --- /dev/null +++ b/web/public/icons.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/src/App.css b/web/src/App.css new file mode 100644 index 0000000..f90339d --- /dev/null +++ b/web/src/App.css @@ -0,0 +1,184 @@ +.counter { + font-size: 16px; + padding: 5px 10px; + border-radius: 5px; + color: var(--accent); + background: var(--accent-bg); + border: 2px solid transparent; + transition: border-color 0.3s; + margin-bottom: 24px; + + &:hover { + border-color: var(--accent-border); + } + &:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; + } +} + +.hero { + position: relative; + + .base, + .framework, + .vite { + inset-inline: 0; + margin: 0 auto; + } + + .base { + width: 170px; + position: relative; + z-index: 0; + } + + .framework, + .vite { + position: absolute; + } + + .framework { + z-index: 1; + top: 34px; + height: 28px; + transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg) + scale(1.4); + } + + .vite { + z-index: 0; + top: 107px; + height: 26px; + width: auto; + transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg) + scale(0.8); + } +} + +#center { + display: flex; + flex-direction: column; + gap: 25px; + place-content: center; + place-items: center; + flex-grow: 1; + + @media (max-width: 1024px) { + padding: 32px 20px 24px; + gap: 18px; + } +} + +#next-steps { + display: flex; + border-top: 1px solid var(--border); + text-align: left; + + & > div { + flex: 1 1 0; + padding: 32px; + @media (max-width: 1024px) { + padding: 24px 20px; + } + } + + .icon { + margin-bottom: 16px; + width: 22px; + height: 22px; + } + + @media (max-width: 1024px) { + flex-direction: column; + text-align: center; + } +} + +#docs { + border-right: 1px solid var(--border); + + @media (max-width: 1024px) { + border-right: none; + border-bottom: 1px solid var(--border); + } +} + +#next-steps ul { + list-style: none; + padding: 0; + display: flex; + gap: 8px; + margin: 32px 0 0; + + .logo { + height: 18px; + } + + a { + color: var(--text-h); + font-size: 16px; + border-radius: 6px; + background: var(--social-bg); + display: flex; + padding: 6px 12px; + align-items: center; + gap: 8px; + text-decoration: none; + transition: box-shadow 0.3s; + + &:hover { + box-shadow: var(--shadow); + } + .button-icon { + height: 18px; + width: 18px; + } + } + + @media (max-width: 1024px) { + margin-top: 20px; + flex-wrap: wrap; + justify-content: center; + + li { + flex: 1 1 calc(50% - 8px); + } + + a { + width: 100%; + justify-content: center; + box-sizing: border-box; + } + } +} + +#spacer { + height: 88px; + border-top: 1px solid var(--border); + @media (max-width: 1024px) { + height: 48px; + } +} + +.ticks { + position: relative; + width: 100%; + + &::before, + &::after { + content: ''; + position: absolute; + top: -4.5px; + border: 5px solid transparent; + } + + &::before { + left: 0; + border-left-color: var(--border); + } + &::after { + right: 0; + border-right-color: var(--border); + } +} diff --git a/web/src/App.tsx b/web/src/App.tsx new file mode 100644 index 0000000..9ca8e8d --- /dev/null +++ b/web/src/App.tsx @@ -0,0 +1,122 @@ +import { useState } from 'react' +import heroImg from './assets/hero.png' +import reactLogo from './assets/react.svg' +import viteLogo from './assets/vite.svg' +import './App.css' + +function App() { + const [count, setCount] = useState(0) + + return ( + <> +
+
+ + React logo + Vite logo +
+
+

Get started

+

+ Edit src/App.tsx and save to test HMR +

+
+ +
+ +
+ +
+ +
+
+ + ) +} + +export default App diff --git a/web/src/assets/hero.png b/web/src/assets/hero.png new file mode 100644 index 0000000000000000000000000000000000000000..02251f4b956c55af2d76fd0788124d7eee2b45eb GIT binary patch literal 13057 zcmV+cGycqpP)V|)f$;Qooc7=_G zlYe)HToTQIc!$)^+J1M1y0*T%w!p~7%ux`!eRhO?c80XDxKQ*R^lUUMnA>6NT^?feoZ8xxvP32D&s-9ow zqjcM}eesrC)NeDmsf)*P7wJ|K!&xP%Zy4iI8lF)Tv2!reW)tCzg_1=PmOwd1SQfxa z8;58t!=z~Ba7CYlNWVG>he8aRPY|+-JmozNhn!#9i#77Aa_Edt$ijyCWL#=~I>~2X zZNrQ8I0=D+NWD4pq=7~(i zhfThMNw|G>g^y9pGzxX7ZSApl@tIxFcs{p#MX{Ax&XZT+cR#U+OWc@S)pkIuI}dzu zH?^Q=<(y&Vq-oxSLfc0Zmq81bjZWf}RnssBaD6}2g-XJHLcN_|*IOu>m|x$nbm(?E zyNy!Zp=RroS;?Vg*kmoJYBi!n5{_^@rA!)=t#a^;N$8GL!*DsQb}`yvEuX!G@||An znOfUZAevPrkV_qjl|<~3QRZzG&h@C9Y5z zqpNH4xqbF_InIPh)kX}Vn^5kyed|mOuq+2>M;v~KO37a#yrEn3XDqtOl=rc6_KZ!; zreo)DFVB4|>1Zd(bvMI%8uM;3!)YMYu&cG?(PE!B~y@3yKBMt|R zAf=I16tFwPsl)!jDqvYkLHaAQ+f@W1m6F5aZvwhm4JL z{_l)@b;)mDSzle2gyFP5-r1x-5X{G}ot%VyWP@vEW80!Q=f%RTfpg>B*TA^pyWYUQ z<=xPtz}WcZ!;rFl4m1D&FFHv?K~#9!?A%+fn=lXt;9!Fc#kQ;zk~gZFsH z8e5iu@c_pzX&qb8&Dum*oXwB+fm6l6gFfC|o*wgEiy6tw~&co z9Vd_4)P%wP-KwQW7|lN-znGK#?N+j24U=$982myIBM+vsiKsc*@4-rwJxuAaHKna6 zT3wi!C~a4ZKH03qU}_1bKyx0&$CaK7_%Z+Kl$)fF5^op zZApQF2TvDav!s|krTjw-8US6ep z%!VmX4luub+fseQz_D9ATJQ?iQQwD}TZz{-yo#l12a%+7bT@E(X-hyaVS-5vuXc#^ zx^w;L21;NphGVoj*{s3f4dme0y2LC=G1-7THd`#z?;tuC{^9k(dM{Rf2GOxg7Jzho z7nSZHl7?M9kdalX`)YgoKEfiae5+;$(OGeN1eqxrv!ZCVKyH>xiyNqfe8xzY8*7)H zQls8KMp)F4D>ED;idMOU^^WhVF@q>ZSmeB0y~qC~|DB648hr%Sh|*T(4q|w2l?m2+ zvBVw3@7+Mz?^Yc#+se6KM;a<=(W-I>k)$-qL2V*t}VaW`;?P4)WqI%maIDq8!oUcSYAD`}wWjkSyAVsnF65#2zQ zZ>(K*TlS(E#4y$4Zq+e^_&}d)q20hCe3!LfLYP%nQpLJ~gM6a1hJlz3)aS<9C9me| zAcmJ#>tOwBy{HoP0Sm1&_(E+S@6 zgBIFUoei8zJmdpiq8q5=OY7t@`)JWxn_&GvKVr=Zdb_pEL_j|=?f;WK^U9Q0efd#K z9q7SfJTl4pmA$jsZ5oK8@O9#!I3Cv-kL)<8SalSsp#dcpvJ}Nz#G6FC0%9|7Fi#8; zGDJXtj!&GljT3*HE@0EE>G8Se&d)*nkqe}-?`3vPl&UqK?xG z!3XJ4M-x`EuQjhBbu?ik-)rmIt=DF_N?TVMP)8Gjn)TZ2V%H|zENbeix}kOxd@0}Q z>)HuH6Ean!uS#~4g2Ne2WsMGel|h%j9*W_quQheG^JqmKhc*RYzp0wKlGjBq2VzY_ zgOv8WC1+%W=W)k)Yp_`8kfE=uiiwOZTXi8Uj9YGr$f@yJcJ;#&-Nq~sJ7anE(@;QN z=~br%7%7`isKStX|7!1?L(apl^QvPKlrHV4S+6tNVQ*R1iGdC~WMNE1$a+=rpQmcB z>wxiLIBvOnm;u*;9Y!kJdy(T4lk|8>JAm(&wEsFIF1$_*{>2ZNd$V6DS=SfrGxAv0 zzKe377JI`&o9Ljr+VnS*EwehA{f&{cKZF(6*MG5!p5MvrFA3ll{fmRG*L@6^cb;o^ z3Wm8c?Sc6$`>~VEWw(c$Y?nRO;2Q$=ulpqPtM^=1IZx;@xK0PgO7rKQ^WHVLwtgUT z%|JF{^f(VH)wLKQ%dYiu2RmchBdxL0-M?wxxul_z*{h6ZZ`>-k(vizs((vW8Lt6Z6 zY;Dt?@JWyN`O`f;&d1Mb?e%9oyRK1ql?EE5XB2(W)|D1~Rx35$H6@6)$F?)7V|zEO zI}fu0-0}8W5=6sg$fPnZ~7=tTudl?Ecb@pxbo)vni%gP-?hL|%*?62C;x6?@E`VRnJv z?fTb;k4x;TS7Cu-z%J}uy}e-pwpLQ17Q@4DC+FCdAmNKklG$`I_pyw7E{fYmw~{Fj zi?6KcVy=Wrel)EB_DWO|0CKmI|13!gBV?X`Ozp7x>?6jr`>Qz=^4ea35!$*f}) zS$i+x_k+@P2q1RFUH^ZTTk7=n?cjfR>hTq3l3SY~#w+I8SSutXGyhw;Ws~=zMQ%Vc z>$On~47Ut?P*_!TOQ&PFmLAyJieB2X4_Fd_!WxI-AY`q1Lc-oK?+qcOTzlQ?@~x@OT}*9jTVNfl@3rGvZpWI=eKg>T zZb@6YWz)J=IhP7CF|c?G62vMEG%#U}?#86$0jR4sG~i(jRd#jmn`7b(O#?N;3a;1t zhXLssmUwGhp79luw#(*V8WL0|8+E z6=YZ_O@er~$LrD_PYGc(kJgB=;yw#+Z3X6LDUZ(NcwN=B-hjdiHm!JFar%m{(5bEW z@@_VEtG$5;`EJZ|OkJ@l&G9n((w@uNFwmU%bG|s#TbcJJos!{e+bjCjrCq_}LcN!UFgKtgg7siV*7# z!}1whTRRi*-avJPu->C}Z8EiuK$#886+H_#_!btv+rsiBbv2jAJvJ+O0{#}y(%L3H zfjU-kq_-L@2XrL*ae{{qYJkD{@dw%*bkh2P&YS-0!Xt!PRz7KHV0+~j(t9W8lAVWR zt@B*DgURgEz4>WuN>o?_iKcw$?k{||Pg7{Q2o4|VmJ)mg?{VQJA<}zEr^YAAS zgGm5RT4T3p)U;yz-tfBO^kw8?IoG!IVmc+Z3m#}AOQ?5MRa>)OcU!$N^_+yK6ayn? zK>~WK0!#ysuj^oNLakm)Zvu+J)OSubX^kv!c*xgdIvs;kln!rgG4*uZ;w0mQQO4XD zO9P{GNdv!=cQ(CAL{S(%KtuV^zC&Q{%g)PoXnp^gn^>c*`E>$hLYg2HjnbVGtWLa{7zHdG1jT@B{|Dm16 z7K2(jsfG+m*Zxof)iXxu+!H5Mo-0$pkyV3VV4B@Qms46M zuBxGRV@HxU7Wwx-6CB zaU*HO<_qn$5GH>&@?nRy1{z zkik!sLfWQ)r#75)vVwCBU*r_)Q6mp?!j85{#Xqse)ApRdE$V0%I0*~e(_{)5H)`Mk z#rExC>yjhZxuL@|+#v4#<Axw$+VpV zuT;!2Vww$je$DpAW`$FX_Ab|Ip%$;&T$-lW8jS~B$>G}rd>eQG+$h9lQx4Mx0w={m zx9?T6VU`>sR}XClkAhHEShOUe8awiq zmizhL+}5UKs3}6~It7vBTig9dfQ2Q8coo+Miiaw7n~>4ybv2Ptt0^^=VqX(t*Yya9 zr`FxxFX8(v*H=+uJ#JJWIB2A(==HDYx~^zZ2nu?2`}|Wsa*f3h3ixc+U|FDtAG$Y! z*lc_7se5Oso-Cgqe0){{!8H4g$3<8!R<6JOurD;((({c$1(pwb>(#TT!sge@4>r2@ zVL7>U`0`nsWAYErezk4(Z!gMI2?UTo{J3Ajo(u4)KYIRd>BRcG4BoS3G0EXyEp@tw z%P7__?A^a>Q&AKL@ayDO9D*Qkc!NHnO9l}kpp_6hXbMppYL(X1L?njdFT|-h2<_$; zAtDZ!1Rf%|yb!qbWKd}%0b`LzBeyNy43|QO(&h2mxQLUL)|0%agVOW)6TV!&Ip^Ls z`PG2cygM8)IecQx=Fc+nqYRo4hS^^-nM_&-y8?EJXUczP=DIw(GkTJdpEdh<_STs{ z|A)4n1GKdE=Wu!!nYoZHcUQ4S&R;oDOKX2lrkdF(mK>hz<$Pp>igjOcvoRIjlN=W8 zu8Gx5(roqn8$>gEE5vy{GiGeW8Tq{vnf3hS-V=$tZkQuftUVuU8o6k&dn=Yg3)6MOIH>nlK^-2+C6BZITr~1@So?NvG#TwL)|~=1YXGMTLpS<)ziK_CSOabe z=cB#5)yz|@0i9dSo?*CX)}UP=s6)B+F@~Em(u@Q(I9J9i_V{LmMu8BfXYMh~*oPP+ z!3~xTv|(>|=n6ZOtT~C@V!z!w%18*8T2t6}U2S##rC)mekBql&VsBX;$~ByGE$oA9 z`0Wzq8p?R{4)$l*on;!cLa}Dh^Xe?owiQZt9nH1fxxh$pN9K%CtOw?u3>85L7rr!d zXs)l{TZ{xXP&U8exz?9cv~dNNibOmt*K4I$?RxqIBZ0(?Mg-9FS{*9Bc49Qc1`=sIF-rye`aNT1G@4NwXcnyc@+bw_mTsR>5< zF<2;X0QesG_pw|TonqVBhRtfqI>ty(SIu&VOXd0CrLlfp+;WH7HYjhqnu^oAY!9cB z=B6#R?Rfz9BP`dJ=@v_?70s3HxQPk+{6Y+lM85f2NF^00*^OcM0~?JOZfR9ZPYF+# zYSs}(_BUYV8{n@2a1hD^SV41bwmi2uztR;PeBgF1F-`9>`zoNss-@3LaF2sjl~>OaaVmp7PNp+UT`6@}gR%uzqHDVeEZ14{Yt?n%JeQm+t(1_u zSc}oj^{b;+rlS|ME%+LjzSI&xu0Bblxo$MJ-J$kJ?Qu_XUXh}*@*-x@ny|}wVM%Lg z3tNB`yvr*}N?ClGL;H2cglcvErIccU3(eP7>@~4nOIcI~-`P8tSQnx=jI&{9)!1}l z;gQ%_h>ZlPSV@o@Azq1R$C6ja5!^ZGh;YRhhxs58qJWo9@Bceac&yy(pET1hnn`~7@}2L0&dfPKYs$ih7m2}R!25!(hxqA(!UIw; zK4+~Jowy3=RNC6nE=ncU{LH5?*9@W24lacJlvCZXB$CYtE@>c+~H zkV=(5I&gb{xn2!~f&fs2NQgAL6`p|kyt6kpWk}iVlqIp(H;ig`{_U9yxs1jzu^ETM z7~)Rg8C-NueqTYP&U8l{DY=Y47cR zOR@U%$KQV{mkRF|4)z9Y^t3K`@p>duY&QLUFeh6VoV`a`$U@)(z!-N*5Cj<11$EZW&hJLX83TO{lJYP74rlDZQPkm@t<=U^I)x@|UnHHkdQlh?!ltZwl92rE;;^ zZuIappj4dhld1}kttYYV-j|KF1Kus zWBnzttD^00%LFK(wrwNragFub6xiV8QE2rm<`&fcR4SLFcdtLxVuN!Aal-g6dE4%k zARZ}|xeo;K{0yf7@9aua%2j5o)CPcIOc6uLHFJOcgtB5owlcNAwyAHc0QB0Dts?c@ zUemG~j_E&W7R%+x-IO4FJl8e&*2Blmp1S#RA|)geVrxvP)NHdYuxi~g&Etn?QdNK8ZDKZ?QFLU?zh30G|t9G>a_X4zk}Ygw<^$7K!GIn(Io$>(d4ODJQ2XSd%jpK zm7>ptl$a3GyB}5-%p4>Q*p#VL^B{yQMuFCM^#l#+N!Ne z5_PrJWB=@Iy+t)H`g1lX`{bm($KE5I?0c(JEYm#t{F}j!xtsbob0{xu@0TB_*>G7w0ICn zr#VoBktqHZ~XxhiKD*lcG|b;H*|Ny3P^8ceV`sfBRfrhwZ!T+MFZ!F1Bt{q$8d9i6o?~ zODj^POr}&ivSa^R^YFIq7o0giLBKCycH_aU`F6)O6JX%nPTwh~Q`eq6*0iE#Srj2^ z*_hN3%*b83zfafy60@Cp3{J({RlSaEn&E?mrxRNC9GQ7#+f=s! z0KBf-9Ny_v2VbE%aB|Di)5kNJ^t&C`4D(>t7zYUWUFtbxt+Oq=!@O7BU)}>d*R72o zFF)3jQD_lLe4is&xzyJYC1-c{8TX$RU>&>P$%)ufpez0XSAukmh!xcekg`s$c<>-q zI#zn^JU0zzF}V60)o$_gY}PQH>b2M9&8fRZa#OauglPb zeQ@pMm&=!vNgos4CluQjLMV!pfkmxK+35bi^k&=k>9h02?l+u+m0agG;(h2|Jslc-llvtEwn~*w3bx7qnvZACG<8}AGeaDVvcHbKd2>3G^ zSFPULUn-?Pmo^-_`mLZr??uNH`2=I&yajlrF{DtUxMy#Nu}z=3y7qbUA;5`)hibMR zhXL@@uKyV0-2&A@t@!xyrBnMJl&^o@Gx$&5_q6?D=ji5grd-~=?dlg;ur(_V0wjh! zA=JV^C1m+DDkOsgr<%O9ZQFg!0}pD(#PSz4Dr_EyS5$`)VIAv);4n-SFP~YtC7sH= z7&*MfpH;gd*FHbkmD#)hVxb6xjc9~`t?_{=JS+@ip_cTicXxG<=7m9& zPX+Z8IC*GSAXuGCrZDHgR$r%jyk-fctis2Kx4HvZ|B~8uC@o)m^>Hy-O!&TKA?$&n zkP2Xc54w~!=z2?^NafyL*L0V9cbYrugHBBUj`xVyZmGFR&kvk#>1J*Z~i zNTz}?IAdJ$gkqd2!Gw(%LzE!O5s4C7q4%T~e_P{+z=DNDKrG**p=U`d5yg^vp`;Zn zsU=8gd0a9s4s0FPJePWR9eH5=+O^Kks&kC-iblNqTh2&Pw*^(4384f+D8N|fewZu_ zg2ejQ)ov;ztz;NQl7yj;A`(!H!XQu_$sqY9h_IrH*}_%1{L&_YLDvO?%R5Z-t+ClW z_qERbL?HKUZ!nt+!E9S`uoh^5A|DaIHe*_gf1`E_Vq+}{&T@t$EGhMnRjJ4z2w_W8 zp+qjs7as22^&S3wY1?+}^j-I=RcCE>#|39)g(lU7v_8;?=qK(9D8-*pPdiy)P3lIblG`+?%ea| zYoD3dopYt!tKgFicfNmNi(EWE=E4hC6(r|PYtanqJlmt57YOVrr2^tfrG(eG9C##X zu&1t@%L$RIvpj!wUA z8i>Pqot#_+Cnp6L2XPcZy1ar|9MnY+7eNvK1E)@Tr#2KsXq1*>)uUCozT7L##ok?o zhA6ofP4E|b*9tAfG?uf$#}>TIR&1A!yslP8}i7w-EzW(x#9VEvx18k%Tn=-$VV zkOtUr0b2!w3t>h?#8AZl^Az*(6KCGlD;4j~yx};`#2gN1_gv=%7KVzecIRakN{f*4 zeaI>yH;-o4OGhvGTU)(quWI)-q?V*(sVesSMv|wMUQ3hLEt=lBB$KZ9TyHr>)f7o%) zPYeU<3P)*P10*7vE)nA5#{c=6-E-_>r_u4e3i!I2+UksELwDqwMeBZ9FSP$;^Ajro z_@M#_Ss$?ejoB@!wN|kbGKs(0zLo%0QpQXW#t;oC$B0MZYZ&Ej?8~fNhcCVvPo3vo zFn0WWZaPliF^8_}yzb`*f@yg0uWv6HgNI)xa=pO%Ck(C<=-60l#uD3(wXP~c7!NoX z0&^6=N`zcc90F#qt@=Rn@r!3(*1v(Tl{B!m?Mc7yIA+nEHpY{YWr$=)F7rhR1P}(v zt{YhY#;jsW6G>#xhP*B`OCk|Pf+NN;ju1rxa*HAgoGq*rvqw&xe~;t1JA31$s?GBb z*g7&@cbKo4n<`>)!UlIAgR6q&))B0KYU8r66GbFj?8Guw4E%&}Qi_lT003LtoIZei zwD~=XZmeo+yZ2Pq3KYCF-R&11^p= z@H%s+=G`}wrbJ{()Mh71#2SP3Zy3m>l1n?0N-N1Q;z6?oSxr-G(H5m4EO>~&;}VKi zfY}3w+9z>vp#d)hVuu`)vG_aaH%3b=WKMnSu&c31;<3O;bz2iD=w+o4#oBb36 z5ZCF*Gu?zjZIR0S>_%pHY2$k8D^n7Sz_K8tCDeXM+dO<#LSg%h6`~dnVG1N@T7v&e z%wEd1!k{^zfz_1BTW{!$!B%g)J^2b87!9Y>>100X1SgT7s0z$o>^lAA=Gp_cC1(h=*5Tmf8z&LGJJ>$|K^~s`z9*OWz5MFUr?>Bi?_PGBB)#psD5?>n+q{o_ zz7~ez&;t#h8l$jwGPCC&xq2YetXYQT+0F3j(`xmNGf8dj#an|p#I*pvI*kwW4iuB> z+q3_7xB8y;pLzHG-S%+UHQA zvqp;$kmGJY>lLsN4C~&TcvAS1SErTcwcw0r@wngk zShAUA1M9b#g}^pL-zH7Q#z^&j#r9F8BTVfkR&qF<=e35goTu7c|GN)0mokj4m0%~0 zXJ8j4Hc_l;HJ&uU*Iw`8d_EscJ``s0tk9mkKo^&#TYXm-EoAzTQObxa@^u~g2t#T) zJz|rE!I_?i4dCJC=B8(_pZ{YR>|V?0iCcnU;E@$239^x?SYCfNaMHN;CtHIS_zHN9 zTkQc1v@O35okiFtq5_u+5FkY55ap@pi)O?}x0D1c*qB0KpYR}>Ul+B0Vmr}Z@+%mJ|As}sis_=ROPbov@*2thpE&?!V#Qgu$snYvCZ zrkhmkMU+fSf-s8(L37fPr&M*jRs{{THb!aXQu|P9l_-vJhHvLzMGH zE?1U0H_+PmNABp9`|KzkGfrrZ%XvdGo6*<{d5m9~L7 z_^`M;X6xDo=m6LY6RfvJEvsTK1!u8d2HPx|$S}p;sRy!I zWL55Yxu~_B`OP@~(q6&W3#)~I&+MGL%GWR$#udC151^wsswhqlii;rP9jJpiI7o&Z zAb})=HY7?4HA|re3ns`%$)FuvKCFWjhb~?IE)F6dF2K5}poj-NK6Gf;hw$t3=1txY zoxQxZWrQU6K!%|~!m?~Bnw-6Rr!F3BZ{u5!LqnZTDON}Coj9^@&le)V!NYrVwS~B% zEL+>Sr@}qGwGvu|HrOo|gSt__ezN^&%~{*)a=rf7y1HujUcr`zZB<4#l@T#eN)si} z)lZA<{=tKx8E%c9>A(##6}_p+~EZpKsl5a4pj`E*;_-6`ysiv zffA!7=MT1vCz}-m4~tjVey1b2KSR4OEtLd-(_DdUqYZ74LaDkhH?KFh?%WAOP2WbX zp@zT+Dx|5_f%JQiAGvVw!oh+g3e50u!aPfMxdC=E)XB{F5IcEZhePIM- zph6Y`$Oy?JBL<8Ex(SqEhLeQ@XcrdA>a?rx+_~HLA;l14)WmmpH}_w?Pg#HBZs0eS zwypwAW?M-x+3AU-(GGWSJ=ngxUEcEZ5OsX(Qlt!MQ zn^(`S{GHkAv(8@D`EAfSYig%Cxv?z!{=w^F#y)5_d7FuKZH7qlR-#5B0bt806%D0I zT7VdVP_?q*%Rq8UR;JkD4i^RXowt+E%#V2U>TfDqzZSDZ+dR!a#T3I>-z_$q9@k|m zy5~A*m~&JWP@E7a=pc}4kVHTc4h&R;Li7d@f`|hKMLkbb^uhOakNr3&FLjlm~i5NBM< zFaYI{;cpiHCNRdE0dg*>qIm(_t?#$h=(SCw?h3rJV2*ER8{O4^3#=dO)KwklZkoqU zS8i5c%YL*y*4;FY#D=XmkQnYj%LH)?02~gSJH`Qp1XY64g>%c_K$xseI&|e)7vRoL zAqRba$G@%fSGA7X7hQk%_3NVOYVS+$leU_!&6*5uN)8#5ZBz_6ASCA;azYS-Rt@ki zg2NWz(=;t}SC(~Ibl63$5C8FPmhXqb^)5#jaJ~I{Ex3xZ!+2h8$}}h_g@Be>HZ;72 z6#y#>AY3^skuVKF#0WxFBQ()5d5_nWb?c6c>EeMM|Mh+*&wEpPyxHCq{R-Gdr-`hN zF=1sxl&mBoK+#qRLl9#CEN|Fg8>nbmsTg3a1;#M9enQ$RgWk}kp#-5wh=EF&1tl%mJln2V^8o%Qv(*=zEuO7y z=m*8?xpUn-*@h5Cl_3BK3joiGkyaScK+>|MWdMRWm@RT!Q1piAlv5hL@B6>3&GI8) zP!xBc6}ZNIpJLL%2a8Y!+(<=f%WX>_uWVxlga9!D*oYt$l0cxRDMvqfU;Kq_mLK5k z)dvqYcgLa_Lz?3HyeF)@$%$&6lI?r4I>6W#M*<)vq{?&Oqrx``d`mhpVPr> z#q078F6gw_X<=?KR>8%^t%@wbITvNMu!hKiTSkCTJkw>1!e*Y{%31#_yMf=LW7{RJ zYoC^w$6%3cBtVG5)x#{Hg6IVTh9XEcM{gQwXk!R^y95^f-hZ`d{aVa+xW1EO4wDV4 zB?JgD7*?qkvc|$nIykTvNl2x0j3Q!MXoLL^)~}d7jcYf(H8D~c+?$pKL(px>Z3`eb z04RzS6_AgFT6Pn#iZAg$Sl_j8#;6ShF%&(Fag#E2asU@@LaN;=b=Wf7sgPKhfzhBM zC@eFL8^MrnA*9&Khe*Ab@CC9*uyJGXyi(;y2>lQLJZt;ShtJi?3Yf_t`F+$hY!+Q2Ndsx=U+bjTiAy7djLji>7k%k`$9&--f<*BNA3Hy&ZrHH|4 zG5H&9cB?O#zI1_OOf0Ce%mDfQxdtp3vU%(iY6yji3iISS61XLv#z|!zI_sZqza@B+ zyu9st5-h+`H7QUKx9}3w@oU@EO}&cEzG?fu!!bLO->%zkcg;i9^j`S~=WKMnDi1f= P00000NkvXXu0mjft=yBf literal 0 HcmV?d00001 diff --git a/web/src/assets/react.svg b/web/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/web/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/src/assets/vite.svg b/web/src/assets/vite.svg new file mode 100644 index 0000000..5101b67 --- /dev/null +++ b/web/src/assets/vite.svg @@ -0,0 +1 @@ +Vite diff --git a/web/src/components/layout/AppShell.tsx b/web/src/components/layout/AppShell.tsx new file mode 100644 index 0000000..5d504e6 --- /dev/null +++ b/web/src/components/layout/AppShell.tsx @@ -0,0 +1,264 @@ +import { useCallback, useEffect, useState } from 'react' +import type { ReactNode } from 'react' +import { NavLink, useLocation, useNavigate } from 'react-router-dom' +import type { LucideIcon } from 'lucide-react' +import { + Database, + Globe, + LayoutDashboard, + ListChecks, + LogOut, + Menu, + Network, + PanelLeftClose, + ScrollText, + Settings, + Users, + X, +} from 'lucide-react' +import { cn } from '../../lib/cn.ts' +import { logout } from '../../lib/api.ts' +import type { Health } from '../../lib/types.ts' +import { HealthPill } from './HealthPill.tsx' +import { ThemeToggle } from './ThemeToggle.tsx' +import { Tooltip } from '../ui/Tooltip.tsx' + +interface NavItem { + to: string + label: string + icon: LucideIcon + end?: boolean +} + +const NAV: NavItem[] = [ + { to: '/', label: 'Dashboard', icon: LayoutDashboard, end: true }, + { to: '/blocklists', label: 'Blocklists', icon: ListChecks }, + { to: '/domains', label: 'Domains', icon: Globe }, + { to: '/clients', label: 'Clients', icon: Users }, + { to: '/upstreams', label: 'Upstreams', icon: Network }, + { to: '/logs', label: 'Logs', icon: ScrollText }, + { to: '/cache', label: 'Cache', icon: Database }, + { to: '/settings', label: 'Settings', icon: Settings }, +] + +const MOBILE_QUERY = '(max-width: 1023px)' + +export function AppShell({ + children, + health, + nodeId, +}: { + children: ReactNode + health?: Health + nodeId?: string +}) { + const [collapsed, setCollapsed] = useState(false) + const [sheetOpen, setSheetOpen] = useState(false) + const [isMobile, setIsMobile] = useState(false) + const [signingOut, setSigningOut] = useState(false) + const location = useLocation() + const navigate = useNavigate() + + useEffect(() => { + const query = window.matchMedia(MOBILE_QUERY) + const sync = (): void => { + setIsMobile(query.matches) + if (!query.matches) setSheetOpen(false) + } + sync() + query.addEventListener('change', sync) + return () => query.removeEventListener('change', sync) + }, []) + + // Any navigation closes the mobile sheet. + useEffect(() => { + setSheetOpen(false) + }, [location.pathname]) + + useEffect(() => { + if (!sheetOpen) return + const onKey = (event: KeyboardEvent): void => { + if (event.key === 'Escape') setSheetOpen(false) + } + document.addEventListener('keydown', onKey) + const previous = document.body.style.overflow + document.body.style.overflow = 'hidden' + return () => { + document.removeEventListener('keydown', onKey) + document.body.style.overflow = previous + } + }, [sheetOpen]) + + const onSignOut = useCallback(() => { + setSigningOut(true) + logout() + .catch(() => { + /* the token is cleared either way */ + }) + .finally(() => { + setSigningOut(false) + navigate('/auth/login', { replace: true }) + }) + }, [navigate]) + + const rail = !isMobile && collapsed + + return ( +
+ {/* Desktop rail toggle lives in the top bar; on mobile the bar carries + the hamburger that opens the sheet instead. */} +
+ {isMobile ? ( + + ) : ( + + )} + +
+ + + fancy-dns +
+ +
+ {nodeId !== undefined && nodeId !== '' && ( + + {nodeId} + + )} + {health !== undefined && } + + +
+
+ + {/* Desktop sidebar. */} + + + {/* Mobile sheet. */} + {sheetOpen && ( +
+ +
+ + +
+ )} + +
+
+ {children} +
+
+ + ) +} + +/** Re-exported so pages can label collapsed rail items without importing ui. */ +export { Tooltip } diff --git a/web/src/components/layout/HealthPill.tsx b/web/src/components/layout/HealthPill.tsx new file mode 100644 index 0000000..5d85689 --- /dev/null +++ b/web/src/components/layout/HealthPill.tsx @@ -0,0 +1,32 @@ +import type { Health } from '../../lib/types.ts' +import { cn } from '../../lib/cn.ts' + +const STYLES: Record = { + ok: { dot: 'bg-ok', text: 'text-ok', ring: 'border-ok/30 bg-ok-soft' }, + degraded: { dot: 'bg-warn', text: 'text-warn', ring: 'border-warn/30 bg-warn-soft' }, + down: { dot: 'bg-danger', text: 'text-danger', ring: 'border-danger/30 bg-danger-soft' }, +} + +const DEFAULT_LABEL: Record = { + ok: 'Healthy', + degraded: 'Degraded', + down: 'Down', +} + +export function HealthPill({ health, label, className }: { health: Health; label?: string; className?: string }) { + const style = STYLES[health] ?? STYLES.degraded + return ( + + + {label ?? DEFAULT_LABEL[health] ?? health} + + ) +} diff --git a/web/src/components/layout/LoadingBlock.tsx b/web/src/components/layout/LoadingBlock.tsx new file mode 100644 index 0000000..c2e29e1 --- /dev/null +++ b/web/src/components/layout/LoadingBlock.tsx @@ -0,0 +1,18 @@ +import { Skeleton } from '../ui/Skeleton.tsx' +import { cn } from '../../lib/cn.ts' + +export function LoadingBlock({ rows = 5, className }: { rows?: number; className?: string }) { + const count = Math.max(1, Math.min(rows, 50)) + return ( +
+ Loading… + {Array.from({ length: count }, (_, index) => ( +
+ + + +
+ ))} +
+ ) +} diff --git a/web/src/components/layout/PageError.tsx b/web/src/components/layout/PageError.tsx new file mode 100644 index 0000000..c087cd8 --- /dev/null +++ b/web/src/components/layout/PageError.tsx @@ -0,0 +1,36 @@ +import { AlertTriangle, RefreshCw } from 'lucide-react' +import { Button } from '../ui/Button.tsx' +import { cn } from '../../lib/cn.ts' + +export function PageError({ + error, + onRetry, + className, +}: { + error: string + onRetry?: () => void + className?: string +}) { + return ( +
+
+
+ {onRetry && ( + + )} +
+ ) +} diff --git a/web/src/components/layout/PageHeader.tsx b/web/src/components/layout/PageHeader.tsx new file mode 100644 index 0000000..3a59aa2 --- /dev/null +++ b/web/src/components/layout/PageHeader.tsx @@ -0,0 +1,28 @@ +import type { ReactNode } from 'react' +import { cn } from '../../lib/cn.ts' + +export function PageHeader({ + title, + description, + actions, + className, +}: { + title: ReactNode + description?: ReactNode + actions?: ReactNode + className?: string +}) { + return ( +
+
+

{title}

+ {description !== undefined && ( +

{description}

+ )} +
+ {actions !== undefined && ( +
{actions}
+ )} +
+ ) +} diff --git a/web/src/components/layout/ThemeToggle.tsx b/web/src/components/layout/ThemeToggle.tsx new file mode 100644 index 0000000..3753269 --- /dev/null +++ b/web/src/components/layout/ThemeToggle.tsx @@ -0,0 +1,75 @@ +import { useEffect, useState } from 'react' +import { Moon, Sun } from 'lucide-react' +import { cn } from '../../lib/cn.ts' + +export type Theme = 'dark' | 'light' + +const STORAGE_KEY = 'fancydns.theme' + +function readStoredTheme(): Theme { + try { + const value = localStorage.getItem(STORAGE_KEY) + if (value === 'light' || value === 'dark') return value + } catch { + /* storage disabled: fall through to the default */ + } + return 'dark' +} + +/** + * Runs at module evaluation, i.e. while the bundle is still being parsed and + * before the first paint, so the console never flashes the wrong theme. + */ +const INITIAL_THEME: Theme = (() => { + if (typeof document === 'undefined') return 'dark' + const theme = readStoredTheme() + document.documentElement.dataset.theme = theme + return theme +})() + +export function ThemeToggle({ className }: { className?: string }) { + const [theme, setTheme] = useState(INITIAL_THEME) + + // A second tab changing the theme should not desync this one. + useEffect(() => { + const onStorage = (event: StorageEvent): void => { + if (event.key !== STORAGE_KEY) return + const next = readStoredTheme() + document.documentElement.dataset.theme = next + setTheme(next) + } + window.addEventListener('storage', onStorage) + return () => window.removeEventListener('storage', onStorage) + }, []) + + const apply = (next: Theme): void => { + document.documentElement.dataset.theme = next + try { + localStorage.setItem(STORAGE_KEY, next) + } catch { + /* not fatal: the choice just does not survive a reload */ + } + setTheme(next) + } + + const next: Theme = theme === 'dark' ? 'light' : 'dark' + + return ( + + ) +} diff --git a/web/src/components/layout/index.ts b/web/src/components/layout/index.ts new file mode 100644 index 0000000..01ec264 --- /dev/null +++ b/web/src/components/layout/index.ts @@ -0,0 +1,8 @@ +/** The shell and the page-level helpers. */ +export { AppShell } from './AppShell.tsx' +export { PageHeader } from './PageHeader.tsx' +export { ThemeToggle } from './ThemeToggle.tsx' +export { HealthPill } from './HealthPill.tsx' +export { PageError } from './PageError.tsx' +export { LoadingBlock } from './LoadingBlock.tsx' +export type { Theme } from './ThemeToggle.tsx' diff --git a/web/src/components/ui/Badge.tsx b/web/src/components/ui/Badge.tsx new file mode 100644 index 0000000..d5f3a81 --- /dev/null +++ b/web/src/components/ui/Badge.tsx @@ -0,0 +1,35 @@ +import type { ReactNode } from 'react' +import { cn } from '../../lib/cn.ts' + +export type BadgeTone = 'default' | 'ok' | 'warn' | 'danger' | 'info' | 'muted' + +export const BADGE_TONES: Record = { + default: 'border-line bg-surface-3 text-fg', + ok: 'border-transparent bg-ok-soft text-ok', + warn: 'border-transparent bg-warn-soft text-warn', + danger: 'border-transparent bg-danger-soft text-danger', + info: 'border-transparent bg-info-soft text-info', + muted: 'border-transparent bg-surface-3 text-fg-subtle', +} + +export function Badge({ + tone = 'default', + children, + className, +}: { + tone?: BadgeTone + children: ReactNode + className?: string +}) { + return ( + + {children} + + ) +} diff --git a/web/src/components/ui/Button.tsx b/web/src/components/ui/Button.tsx new file mode 100644 index 0000000..cc967dd --- /dev/null +++ b/web/src/components/ui/Button.tsx @@ -0,0 +1,72 @@ +import type { ButtonHTMLAttributes, ReactNode } from 'react' +import type { LucideIcon } from 'lucide-react' +import { cn } from '../../lib/cn.ts' +import { Spinner } from './Spinner.tsx' + +export type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'outline' +export type ButtonSize = 'sm' | 'md' | 'lg' | 'icon' + +export const BUTTON_VARIANTS: Record = { + primary: 'bg-accent-strong text-accent-fg hover:brightness-110 active:brightness-95', + secondary: 'bg-surface-3 text-fg hover:bg-line-strong border border-line', + ghost: 'text-fg-muted hover:bg-surface-3 hover:text-fg', + danger: 'bg-danger text-white hover:brightness-110 active:brightness-95', + outline: 'border border-line-strong text-fg hover:bg-surface-3', +} + +export const BUTTON_SIZES: Record = { + sm: 'h-8 gap-1.5 px-2.5 text-xs', + md: 'h-9 gap-2 px-3 text-sm', + lg: 'h-11 gap-2 px-5 text-sm', + icon: 'size-9 justify-center', +} + +export interface ButtonProps extends ButtonHTMLAttributes { + variant?: ButtonVariant + size?: ButtonSize + loading?: boolean + icon?: LucideIcon + iconRight?: LucideIcon + children?: ReactNode +} + +export function Button({ + variant = 'secondary', + size = 'md', + loading = false, + icon: Icon, + iconRight: IconRight, + className, + children, + disabled, + type = 'button', + ...props +}: ButtonProps) { + return ( + + ) +} diff --git a/web/src/components/ui/Card.tsx b/web/src/components/ui/Card.tsx new file mode 100644 index 0000000..60cbfac --- /dev/null +++ b/web/src/components/ui/Card.tsx @@ -0,0 +1,111 @@ +import type { ReactNode } from 'react' +import { cn } from '../../lib/cn.ts' + +export function Card({ + title, + subtitle, + actions, + children, + className, + padded = true, +}: { + title?: ReactNode + subtitle?: ReactNode + actions?: ReactNode + children?: ReactNode + className?: string + padded?: boolean +}) { + const hasHeader = title !== undefined || subtitle !== undefined || actions !== undefined + return ( +
+ {hasHeader && ( + + {title !== undefined && {title}} + {title === undefined && subtitle !== undefined && ( +

{subtitle}

+ )} +
+ )} + {children} +
+ ) +} + +export function CardHeader({ + title, + subtitle, + actions, + children, + className, +}: { + title?: ReactNode + subtitle?: ReactNode + actions?: ReactNode + children?: ReactNode + className?: string +}) { + return ( +
+
+ {title !== undefined && {title}} + {children} +
+ {actions !== undefined &&
{actions}
} +
+ ) +} + +export function CardTitle({ + children, + subtitle, + className, +}: { + children?: ReactNode + subtitle?: ReactNode + className?: string +}) { + return ( +
+

{children}

+ {subtitle !== undefined &&

{subtitle}

} +
+ ) +} + +export function CardBody({ + children, + className, + padded = true, +}: { + children?: ReactNode + className?: string + padded?: boolean +}) { + return ( +
{children}
+ ) +} + +export function CardFooter({ children, className }: { children?: ReactNode; className?: string }) { + return ( +
+ {children} +
+ ) +} diff --git a/web/src/components/ui/ConfirmDialog.tsx b/web/src/components/ui/ConfirmDialog.tsx new file mode 100644 index 0000000..49dac30 --- /dev/null +++ b/web/src/components/ui/ConfirmDialog.tsx @@ -0,0 +1,48 @@ +import type { ReactNode } from 'react' +import { Button } from './Button.tsx' +import { Dialog } from './Dialog.tsx' + +export function ConfirmDialog({ + open, + onClose, + onConfirm, + title, + message, + confirmLabel = 'Confirm', + destructive = false, + pending = false, +}: { + open: boolean + onClose: () => void + onConfirm: () => void | Promise + title: ReactNode + message: ReactNode + confirmLabel?: string + destructive?: boolean + pending?: boolean +}) { + return ( + + + + + } + > +

{message}

+
+ ) +} diff --git a/web/src/components/ui/CopyButton.tsx b/web/src/components/ui/CopyButton.tsx new file mode 100644 index 0000000..70f6cc4 --- /dev/null +++ b/web/src/components/ui/CopyButton.tsx @@ -0,0 +1,51 @@ +import { useEffect, useRef, useState } from 'react' +import { Check, Copy } from 'lucide-react' +import { cn } from '../../lib/cn.ts' +import { IconButton } from './IconButton.tsx' + +/** Copies a value (a rule, an address, a key) to the clipboard. */ +export function CopyButton({ + value, + label = 'Copy', + className, +}: { + value: string + label?: string + className?: string +}) { + const [copied, setCopied] = useState(false) + const timer = useRef | undefined>(undefined) + + useEffect(() => { + return () => { + if (timer.current !== undefined) clearTimeout(timer.current) + } + }, []) + + const copy = (): void => { + const clipboard = navigator?.clipboard + if (!clipboard) return + void clipboard.writeText(value).then( + () => { + setCopied(true) + if (timer.current !== undefined) clearTimeout(timer.current) + timer.current = setTimeout(() => setCopied(false), 1500) + }, + () => { + // A denied clipboard permission is not worth a toast; the button just + // does not flip. + }, + ) + } + + return ( + + ) +} diff --git a/web/src/components/ui/Dialog.tsx b/web/src/components/ui/Dialog.tsx new file mode 100644 index 0000000..ba024eb --- /dev/null +++ b/web/src/components/ui/Dialog.tsx @@ -0,0 +1,103 @@ +import { useEffect, useId, useRef } from 'react' +import type { MouseEvent, ReactNode } from 'react' +import { X } from 'lucide-react' +import { cn } from '../../lib/cn.ts' +import { IconButton } from './IconButton.tsx' + +const SIZES = { + sm: 'max-w-sm', + md: 'max-w-lg', + lg: 'max-w-2xl', + xl: 'max-w-4xl', +} as const + +/** + * Native ``: focus trapping, inert background and Escape handling come + * from the platform instead of a focus-trap library. + */ +export function Dialog({ + open, + onClose, + title, + description, + children, + footer, + size = 'md', +}: { + open: boolean + onClose: () => void + title: ReactNode + description?: ReactNode + children?: ReactNode + footer?: ReactNode + size?: 'sm' | 'md' | 'lg' | 'xl' +}) { + const ref = useRef(null) + const titleId = useId() + const descId = useId() + + useEffect(() => { + const el = ref.current + if (!el) return + if (open && !el.open) { + if (typeof el.showModal === 'function') el.showModal() + else el.setAttribute('open', '') + } else if (!open && el.open) { + el.close() + } + }, [open]) + + // The element can be removed while open (route change): close it so the + // top layer does not keep a detached node. + useEffect(() => { + const el = ref.current + return () => { + if (el?.open) el.close() + } + }, []) + + const onBackdropClick = (event: MouseEvent): void => { + // Only a click on the dialog element itself is a backdrop click; clicks + // inside the panel bubble up with a different target. + if (event.target === ref.current) onClose() + } + + return ( + { + event.preventDefault() + onClose() + }} + onClose={onClose} + onClick={onBackdropClick} + className={cn( + 'm-auto w-[calc(100vw-2rem)] rounded-xl border border-line bg-surface p-0 text-fg shadow-panel backdrop:bg-black/60', + 'open:animate-slide-up', + SIZES[size], + )} + > +
+
+

+ {title} +

+ {description !== undefined && ( +

+ {description} +

+ )} +
+ +
+
{children}
+ {footer !== undefined && ( +
+ {footer} +
+ )} +
+ ) +} diff --git a/web/src/components/ui/EmptyState.tsx b/web/src/components/ui/EmptyState.tsx new file mode 100644 index 0000000..09d0ab0 --- /dev/null +++ b/web/src/components/ui/EmptyState.tsx @@ -0,0 +1,38 @@ +import type { ReactNode } from 'react' +import type { LucideIcon } from 'lucide-react' +import { Inbox } from 'lucide-react' +import { cn } from '../../lib/cn.ts' + +export function EmptyState({ + icon: Icon = Inbox, + title, + description, + action, + className, +}: { + icon?: LucideIcon + title: ReactNode + description?: ReactNode + action?: ReactNode + className?: string +}) { + return ( +
+ + +
+

{title}

+ {description !== undefined && ( +

{description}

+ )} +
+ {action !== undefined &&
{action}
} +
+ ) +} diff --git a/web/src/components/ui/IconButton.tsx b/web/src/components/ui/IconButton.tsx new file mode 100644 index 0000000..5ea70b1 --- /dev/null +++ b/web/src/components/ui/IconButton.tsx @@ -0,0 +1,45 @@ +import type { ButtonHTMLAttributes } from 'react' +import type { LucideIcon } from 'lucide-react' +import { cn } from '../../lib/cn.ts' +import { BUTTON_SIZES, BUTTON_VARIANTS } from './Button.tsx' +import type { ButtonSize, ButtonVariant } from './Button.tsx' +import { Tooltip } from './Tooltip.tsx' + +export interface IconButtonProps extends Omit, 'aria-label'> { + icon: LucideIcon + label: string + variant?: ButtonVariant + size?: ButtonSize + tooltipSide?: 'top' | 'bottom' | 'left' | 'right' +} + +export function IconButton({ + icon: Icon, + label, + variant = 'ghost', + size = 'icon', + tooltipSide = 'top', + className, + type = 'button', + ...props +}: IconButtonProps) { + return ( + + + + ) +} diff --git a/web/src/components/ui/Input.tsx b/web/src/components/ui/Input.tsx new file mode 100644 index 0000000..5bac87f --- /dev/null +++ b/web/src/components/ui/Input.tsx @@ -0,0 +1,88 @@ +import { useId } from 'react' +import type { InputHTMLAttributes, ReactNode } from 'react' +import type { LucideIcon } from 'lucide-react' +import { cn } from '../../lib/cn.ts' + +export const FIELD_BASE = + 'w-full rounded-lg border bg-surface-2 text-fg placeholder:text-fg-subtle transition-colors focus:outline-none focus-visible:border-accent disabled:opacity-60' + +export function FieldFrame({ + id, + label, + hint, + error, + children, +}: { + id: string + label?: ReactNode + hint?: ReactNode + error?: ReactNode + children: ReactNode +}) { + return ( +
+ {label !== undefined && ( + + )} + {children} + {error !== undefined && error !== null && error !== '' ? ( + + ) : hint !== undefined ? ( +

+ {hint} +

+ ) : null} +
+ ) +} + +export interface InputProps extends InputHTMLAttributes { + label?: ReactNode + hint?: ReactNode + error?: ReactNode + icon?: LucideIcon + className?: string +} + +export function Input({ label, hint, error, icon: Icon, className, id, ...props }: InputProps) { + const autoId = useId() + const inputId = id ?? autoId + const describedBy = error ? `${inputId}-error` : hint !== undefined ? `${inputId}-hint` : undefined + + const input = ( +
+ {Icon && ( +
+ ) + + if (label === undefined && hint === undefined && error === undefined) return input + return ( + + {input} + + ) +} diff --git a/web/src/components/ui/Kbd.tsx b/web/src/components/ui/Kbd.tsx new file mode 100644 index 0000000..86407bb --- /dev/null +++ b/web/src/components/ui/Kbd.tsx @@ -0,0 +1,15 @@ +import type { ReactNode } from 'react' +import { cn } from '../../lib/cn.ts' + +export function Kbd({ children, className }: { children: ReactNode; className?: string }) { + return ( + + {children} + + ) +} diff --git a/web/src/components/ui/Pagination.tsx b/web/src/components/ui/Pagination.tsx new file mode 100644 index 0000000..d7dfc1e --- /dev/null +++ b/web/src/components/ui/Pagination.tsx @@ -0,0 +1,61 @@ +import { ChevronLeft, ChevronRight } from 'lucide-react' +import { cn } from '../../lib/cn.ts' +import { Button } from './Button.tsx' + +export function Pagination({ + page, + perPage, + total, + onPage, + className, +}: { + page: number + perPage: number + total: number + onPage: (page: number) => void + className?: string +}) { + const size = perPage > 0 ? perPage : 1 + const pages = Math.max(1, Math.ceil(total / size)) + const current = Math.min(Math.max(1, page), pages) + const first = (current - 1) * size + 1 + const last = Math.min(total, current * size) + + return ( +
+

+ {total === 0 ? 'no rows' : `${first}–${last} of ${total.toLocaleString('en-US')}`} +

+
+ + + {current} / {pages} + + +
+
+ ) +} diff --git a/web/src/components/ui/Progress.tsx b/web/src/components/ui/Progress.tsx new file mode 100644 index 0000000..7a3a961 --- /dev/null +++ b/web/src/components/ui/Progress.tsx @@ -0,0 +1,51 @@ +import { cn } from '../../lib/cn.ts' + +export type ProgressTone = 'default' | 'ok' | 'warn' | 'danger' | 'info' + +const TONES: Record = { + default: 'bg-accent', + ok: 'bg-ok', + warn: 'bg-warn', + danger: 'bg-danger', + info: 'bg-info', +} + +export function Progress({ + value, + max = 100, + tone = 'default', + className, + showLabel = false, +}: { + value: number + max?: number + tone?: ProgressTone + className?: string + showLabel?: boolean +}) { + const safeMax = Number.isFinite(max) && max > 0 ? max : 100 + const safeValue = Number.isFinite(value) ? value : 0 + const pct = Math.max(0, Math.min(100, (safeValue / safeMax) * 100)) + + return ( +
+
+
+
+ {showLabel && ( + + {pct.toFixed(0)}% + + )} +
+ ) +} diff --git a/web/src/components/ui/SectionTitle.tsx b/web/src/components/ui/SectionTitle.tsx new file mode 100644 index 0000000..d3053d4 --- /dev/null +++ b/web/src/components/ui/SectionTitle.tsx @@ -0,0 +1,28 @@ +import type { ReactNode } from 'react' +import { cn } from '../../lib/cn.ts' + +export function SectionTitle({ + title, + description, + actions, + className, +}: { + title: ReactNode + description?: ReactNode + actions?: ReactNode + className?: string +}) { + return ( +
+
+

{title}

+ {description !== undefined && ( +

{description}

+ )} +
+ {actions !== undefined && ( +
{actions}
+ )} +
+ ) +} diff --git a/web/src/components/ui/Select.tsx b/web/src/components/ui/Select.tsx new file mode 100644 index 0000000..6c3a0df --- /dev/null +++ b/web/src/components/ui/Select.tsx @@ -0,0 +1,71 @@ +import { useId } from 'react' +import type { ReactNode, SelectHTMLAttributes } from 'react' +import { ChevronDown } from 'lucide-react' +import { cn } from '../../lib/cn.ts' +import { FIELD_BASE, FieldFrame } from './Input.tsx' + +export interface SelectOption { + value: string + label: string + disabled?: boolean +} + +export interface SelectProps extends SelectHTMLAttributes { + label?: ReactNode + hint?: ReactNode + error?: ReactNode + options: SelectOption[] + className?: string + selectClassName?: string +} + +export function Select({ + label, + hint, + error, + options, + className, + selectClassName, + id, + ...props +}: SelectProps) { + const autoId = useId() + const selectId = id ?? autoId + const describedBy = error ? `${selectId}-error` : hint !== undefined ? `${selectId}-hint` : undefined + + const select = ( +
+ +
+ ) + + if (label === undefined && hint === undefined && error === undefined) return select + return ( + + {select} + + ) +} diff --git a/web/src/components/ui/Skeleton.tsx b/web/src/components/ui/Skeleton.tsx new file mode 100644 index 0000000..49f4e9f --- /dev/null +++ b/web/src/components/ui/Skeleton.tsx @@ -0,0 +1,15 @@ +import { cn } from '../../lib/cn.ts' + +/** A shimmer placeholder used while a panel's data is in flight. */ +export function Skeleton({ className }: { className?: string }) { + return ( +
+ +
+ +

Connect with us

+

Join the Vite community

+ +
+

OIyp3KGW%*73vi|d_+pRK}k*(yAnt->?eDmB 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 rUuVUrmx-s@C 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°N|mgGk~=cgv^d_{Eaiwd*L7i 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