From 2f6dc9ee5b42f624395b156e24929d1a5b56568f Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 8 Jun 2021 15:41:24 +0200 Subject: [PATCH] dnsdist: More documentation on 'TCP only', outgoing DoT --- .../docs/advanced/internal-design.rst | 16 ++++++- .../docs/advanced/tls-sessions-management.rst | 18 ++++++-- pdns/dnsdistdist/docs/advanced/tuning.rst | 10 ++++- .../docs/guides/dns-over-https.rst | 10 +++-- pdns/dnsdistdist/docs/guides/dns-over-tls.rst | 11 ++++- pdns/dnsdistdist/docs/guides/downstreams.rst | 6 +++ pdns/dnsdistdist/docs/imgs/DNSDistDoH17.png | Bin 0 -> 33122 bytes pdns/dnsdistdist/docs/imgs/DNSDistUDPDoT.png | Bin 0 -> 18235 bytes pdns/dnsdistdist/docs/reference/config.rst | 30 +++++++++++++ pdns/dnsdistdist/docs/running.rst | 41 ++++++++++-------- 10 files changed, 113 insertions(+), 29 deletions(-) create mode 100644 pdns/dnsdistdist/docs/imgs/DNSDistDoH17.png create mode 100644 pdns/dnsdistdist/docs/imgs/DNSDistUDPDoT.png diff --git a/pdns/dnsdistdist/docs/advanced/internal-design.rst b/pdns/dnsdistdist/docs/advanced/internal-design.rst index 6641020f4a..505be769c8 100644 --- a/pdns/dnsdistdist/docs/advanced/internal-design.rst +++ b/pdns/dnsdistdist/docs/advanced/internal-design.rst @@ -17,7 +17,13 @@ That design means that there is a maximum of 65535 in-flight UDP queries per bac Note that the source address and port used to contact a given backend is set at startup, for performance reasons, and then only changes on reconnect. There might be more than one socket, and thus several ports, if the ``sockets`` parameter was set to a higher value than 1 on the :func:`newServer` directive. -Note that, since 1.7.0, UDP queries can be passed to the backend over TCP if the backend is TCP-only, or configured for DNS over TLS. +Note that, since 1.7, UDP queries can be passed to the backend over TCP if the backend is TCP-only, or configured for DNS over TLS. This is done by passing the incoming query to a TCP worker over a pipe, as was already done for incoming TCP queries. + +.. figure:: ../imgs/DNSDistUDPDoT.png + :align: center + :alt: DNSDist UDP design for TCP-only, DoT backends + +In that case the response will be sent back, directly by the TCP worker, over UDP, instead of being passed back to the UDP responder thread. TCP / DoT design ---------------- @@ -33,8 +39,14 @@ DoH design .. figure:: ../imgs/DNSDistDoH.png :align: center - :alt: DNSDist DoH design + :alt: DNSDist DoH design before 1.7 For DoH, two threads are created for each :func:`addDOHLocal` directive, one handling the TLS and HTTP layers, then passing the queries to the second one over a pipe. The second thread does DNS processing, applying rules and forwarding the query to the backend if needed, over UDP. Note that even if the query does not need to be passed to a backend (cache-hit, self-generated answer), the response will be passed back to the first thread via a pipe, since only that thread deals with the client. If the response comes from a backend, it will be picked up by the regular UDP listener for that backend, the corresponding *IDState* object located, and the response sent to the first thread over a pipe. + +Since 1.7, if the UDP response coming from the backend has been truncated (TC bit is set), dnsdist will retry over TCP by passing the query to a TCP worker over a pipe, as was already done for incoming TCP queries. The response will then be passed back to the DoH worker thread over the same pipe that for UDP queries. That also happens if the backend is marked TCP-only, or configured for DNS over TLS, in which case the query is obviously not sent over UDP first but immediately sent to a TCP worker thread. + +.. figure:: ../imgs/DNSDistDoH17.png + :align: center + :alt: DNSDist DoH design since 1.7 diff --git a/pdns/dnsdistdist/docs/advanced/tls-sessions-management.rst b/pdns/dnsdistdist/docs/advanced/tls-sessions-management.rst index 199a7f1372..357587dd59 100644 --- a/pdns/dnsdistdist/docs/advanced/tls-sessions-management.rst +++ b/pdns/dnsdistdist/docs/advanced/tls-sessions-management.rst @@ -6,7 +6,7 @@ TLS sessions One of the most costly TLS operation is the negotiation of a new session, since both the client and the server need to generate and agree on cryptographic materials. In order to reduce that cost, TLS implements what is called session resumption, where a client opening a new connection to a server can reuse the cryptographic materials negotiated for a previous TLS session. -The following figures show that, with the same number of established connections and queries per second, the ratio of new TLS sessions and resumed sessions has a huge impact on CPU usage: +The following figures show that, with the same number of established incoming connections and queries per second, the ratio of new TLS sessions and resumed sessions has a huge impact on CPU usage: .. figure:: ../imgs/tls_resumptions.png :align: center @@ -23,10 +23,10 @@ The server uses Session Ticket Encryption Key (STEK) to sign and encrypt the inf Knowing the STEK is all the information needed to be able to decrypt a live TLS session, but also a recorded one, so it is very important to keep that key well-protected. It should never be exchanged in clear-text, and ideally should not be written to persistent storage but be kept in a tmpfs with no swap configured. It should also be regularly rotated to preserve TLS' forward secrecy properties. -Keys management in dnsdist --------------------------- +Keys management for incoming connections in dnsdist +--------------------------------------------------- -dnsdist supports both server's side (sessions) and client's side (tickets) resumption. +dnsdist supports both server's side (sessions) and client's side (tickets) resumption for incoming connections (client to dnsdist). Since server-side sessions cannot be shared between several instances, and pretty much all clients support tickets anyway, we do recommend disabling the sessions by passing ``numberOfStoredSessions=0`` to the :func:`addDOHLocal` (for DNS over HTTPS) and :func:`addTLSLocal` (for DNS over TLS) functions. @@ -65,3 +65,13 @@ For GnuTLS: - a 16 bytes binary key identifier - a 32 bytes AES 256 key - a 16 bytes HMAC SHA-1 key + +Sessions management for outgoing connections +-------------------------------------------- + +Since 1.7, dnsdist supports securing the connection toward backends using DNS over TLS. For these connections, it keeps a cache of TLS tickets to be able to resume a TLS session quickly. By default that cache contains up to 20 TLS tickets per-backend, is cleaned up every every 60s, and TLS tickets expire if they have not been used after 600 seconds. +These values can be set at configuration time via: + + * :func:`setOutgoingTLSSessionsCacheMaxTicketsPerBackend` + * :func:`setOutgoingTLSSessionsCacheCleanupDelay` + * :func:`setOutgoingTLSSessionsCacheMaxTicketValidity` diff --git a/pdns/dnsdistdist/docs/advanced/tuning.rst b/pdns/dnsdistdist/docs/advanced/tuning.rst index 14b0506c1c..9afa06c7d0 100644 --- a/pdns/dnsdistdist/docs/advanced/tuning.rst +++ b/pdns/dnsdistdist/docs/advanced/tuning.rst @@ -56,12 +56,18 @@ In the same way, if the number of ``Drops`` in :func:`showServers` increase fast Using a single connected UDP socket to contact a backend, and thus a single (source address, source port, destination address, destination port) tuple, might not play well with some load-balancing mechanisms present in front of the backend. Linux's ``reuseport``, for example, does not balance the incoming datagrams to several threads in that case. That can be worked around by using the ``sockets`` option of the :func:`newServer` directive to open several sockets instead of one. You may want to set that number to a value somewhat higher than the number of worker threads configured in the backend. dnsdist will then select a socket using round-robin to forward a query to the backend, and use event multiplexing on the receiving side. -.. figure:: ../imgs/DNSDistDoH.png +Note that, since 1.7, dnsdist supports marking a backend as "TCP only", as well as enabling DNS over TLS communication between dnsdist and that backend. That leads to a different model where UDP queries are instead passed to a TCP worker: + +.. figure:: ../imgs/DNSDistUDPDoT.png :align: center - :alt: DNSDist DoH design + :alt: DNSDist UDP design for TCP-only, DoT backends For DNS over HTTPS, every :func:`addDOHLocal` directive adds a new thread dealing with incoming connections, so it might be useful to add more than one directive, as indicated above. +.. figure:: ../imgs/DNSDistDoH17.png + :align: center + :alt: DNSDist DoH design + When dealing with a large traffic load, it might happen that the internal pipe used to pass queries between the threads handling the incoming connections and the one getting a response from the backend become full too quickly, degrading performance and causing timeouts. This can be prevented by increasing the size of the internal pipe buffer, via the `internalPipeBufferSize` option of :func:`addDOHLocal`. Setting a value of `1048576` is known to yield good results on Linux. TCP and DNS over TLS diff --git a/pdns/dnsdistdist/docs/guides/dns-over-https.rst b/pdns/dnsdistdist/docs/guides/dns-over-https.rst index 662ffc86b8..b4035ab055 100644 --- a/pdns/dnsdistdist/docs/guides/dns-over-https.rst +++ b/pdns/dnsdistdist/docs/guides/dns-over-https.rst @@ -54,14 +54,18 @@ To let dnsdist listen for DoH queries over HTTP on localhost at port 8053 add on Internal design --------------- -The internal design used for DoH handling uses two threads per :func:`addDOHLocal` directive. The first thread will handle the HTTP/2 communication with the client and pass the received DNS queries to a second thread which will apply the rules and pass the query to a backend, over **UDP** (except if the backend is TCP-only, or uses DNS over TLS). The response will be received by the regular UDP response handler for that backend and passed back to the first thread. That allows the first thread to be low-latency dealing with TLS and HTTP/2 only and never blocking. +The internal design used for DoH handling uses two threads per :func:`addDOHLocal` directive. The first thread will handle the HTTP/2 communication with the client and pass the received DNS queries to a second thread which will apply the rules and pass the query to a backend, over **UDP** (except if the backend is TCP-only, or uses DNS over TLS, see the second schema below). The response will be received by the regular UDP response handler for that backend and passed back to the first thread. That allows the first thread to be low-latency dealing with TLS and HTTP/2 only and never blocking. .. figure:: ../imgs/DNSDistDoH.png :align: center - :alt: DNSDist DoH design + :alt: DNSDist DoH design before 1.7 The fact that the queries are forwarded over UDP means that a large UDP payload size should be configured between dnsdist and the backend to avoid most truncation issues, and dnsdist will advise a 4096-byte UDP Payload Buffer size. UDP datagrams can still be larger than the MTU as long as fragmented datagrams are not dropped on the path between dnsdist and the backend. -Since 1.7.0, truncated answers received over UDP for a DoH query will lead to a retry over TCP. +Since 1.7.0, truncated answers received over UDP for a DoH query will lead to a retry over TCP, passing the query to a TCP worker, as illustrated below. + +.. figure:: ../imgs/DNSDistDoH17.png + :align: center + :alt: DNSDist DoH design since 1.7 Investigating issues -------------------- diff --git a/pdns/dnsdistdist/docs/guides/dns-over-tls.rst b/pdns/dnsdistdist/docs/guides/dns-over-tls.rst index da716bb517..3c964e22a3 100644 --- a/pdns/dnsdistdist/docs/guides/dns-over-tls.rst +++ b/pdns/dnsdistdist/docs/guides/dns-over-tls.rst @@ -1,7 +1,10 @@ DNS-over-TLS ============ -Since version 1.3.0, :program:`dnsdist` supports experimental DNS-over-TLS support. +Incoming +-------- + +Since version 1.3.0, :program:`dnsdist` supports DNS-over-TLS for incoming queries. To see if the installation supports this, run ``dnsdist --version``. If the output shows ``dns-over-tls`` with one or more SSL libraries in brackets, DNS-over-TLS is supported. @@ -21,6 +24,12 @@ A particular attention should be taken to the permissions of the certificate and More information about sessions management can also be found in :doc:`../advanced/tls-sessions-management`. +Outgoing +-------- + +Support for securing the exchanges between dnsdist and the backend will be implemented in 1.7.0, and will lead to all queries, regardless of whether they were initially received by dnsdist over UDP, TCP, DoT or DoH, being forwarded over a secure DNS over TLS channel. +That support can be enabled via the ``tls`` parameter of the :func:`newServer` command. Additional parameters control the validation of the certificate presented by the backend (``caStore``, ``validateCertificates``), the actual TLS ciphers used (``ciphers``, ``ciphersTLS13``) and the SNI value sent (``subjectName``). + Investigating issues -------------------- diff --git a/pdns/dnsdistdist/docs/guides/downstreams.rst b/pdns/dnsdistdist/docs/guides/downstreams.rst index 26c1761cc6..59acbcfa7f 100644 --- a/pdns/dnsdistdist/docs/guides/downstreams.rst +++ b/pdns/dnsdistdist/docs/guides/downstreams.rst @@ -74,3 +74,9 @@ The supported values for source are: - an IPv4 or IPv6 address followed by '@' then an interface name Please note that specifying the interface name is only supported on system having `IP_PKTINFO`. + +Securing the channel +-------------------- + +Support for securing the exchanges between dnsdist and the backend will be implemented in 1.7.0, and will lead to all queries, regardless of whether they were initially received by dnsdist over UDP, TCP, DoT or DoH, being forwarded over a secure DNS over TLS channel. +That support can be enabled via the ``tls`` parameter of the :func:`newServer` command. Additional parameters control the validation of the certificate presented by the backend (``caStore``, ``validateCertificates``), the actual TLS ciphers used (``ciphers``, ``ciphersTLS13``) and the SNI value sent (``subjectName``). diff --git a/pdns/dnsdistdist/docs/imgs/DNSDistDoH17.png b/pdns/dnsdistdist/docs/imgs/DNSDistDoH17.png new file mode 100644 index 0000000000000000000000000000000000000000..1345f29448e2c69dc5a4be17a43248e1e8abb492 GIT binary patch literal 33122 zc-oA-cOaJS`#-LwWZrf{+(xp6Y$~@1DSPiNdqgrS*(;fqQMbt6dxj7y-DYHDWs_{e z@3?y2@2Ah__x=9y{j2A>T+Zt}kMlTQq`zIo}xwJWN)iYr&|EHY}UUee4}3sM+TzkhUCG|e7S^voyr z=Y7M(LCb*-iP>qN^&ivI^ys$t$B(A`e@7p!$)p^#)0%HG(waxiGftLt(wbx5TgD5t zxs$u-T1E(<|6CFet;)OHMvMA$DFtJobXeIFS3>+fP4w z^hl?{N36o(TTt)Y+fyr}wO+fwGUgKPpZ=ZB#_;CiVDa5S-jB&*6ao0ek6*q#PbX}5 zl9ZJ6-Cd5;Wu<*!|PH0Q-RGds&7E=~v6n#yc@O&lB|c@1m6 zmv&3H?5@wswfEltXaBNDEQO_{7;e41qWSHefwwmeufaQs)jIVVb9_?9yoyHAq79Hg7t78nXdpmRK(aw7twz%T|W?B!f zV@dwJB34 zr)bB~nrrN_$GkSXru`4s(`<&zF1@(o5cc%xQ_i=ZGo4he3H_anGWK8j$xy@Pci*lX z2Vd5Dp08htRe!58H&!ok#bNkKS(y+n=83|sTdgo*T)w_Y-R6M)*9wQ1a|+G>6a$tn zuK&Xa1yOPF$aR4H`V&0ku>bJDfkyL9Oi!TM}>Fb4gou~Ej%++0q+=TfE9IFe=`KYlDS zX*&Mq&6|)Y)|3B4H0PQw@tHI4uyWy)iQTDExf)uL5fM-0<4@sLxy_QmqE3I;>~I*X z6PtFe?pdSNy!D@FC2D3GySloP(b9$-JAuz6Bt%(VU5#a#FI!r&&(kSB4)bdN_*^h1 zG4Z1KGp)btR87BOI{P^#tc!qvK+&??V{stt8&u$1j@;JPR-`P)yrzgD{Z8WJV_&_x zI52sBN$hRez0=>EYAjert5TH36QYc7-T z2{KBCp{QCNGP)L~+M{EVlFr~ER@Lox~Q^J-pi|Mj)U&n zKhV5Gq!p3f4;i(~<ZH2fEzv*qmVx%2Y!oEQ2o;ZzqgC@!kJYiqmV zq9Y-D^qB%9_95%hx_<$I&b!@ zpipVA*eA`=3Sa*l5+3;|`lb*R3#R>x*hbEs`Bpb#dQq~|q>LKo=udyiFqfK(D_5Lh zBkhn^&vLN3WH7N|q{_v-s-|XgDq7}-nVDH&wC$Hy$LJXt1UwcrplmgEM=&Q@SXkT_ z`Un75vo;qmN%%Tsce!O`W?tuv&k=~U`Wq0IUKy}zWH6(-S`owR^pZ}W&8c?k??6*_%5^Oaq8sh64u=}IcZl??DxAdy_p`a$3 z0!}AM`_^=tH>#b|*V^A+Ep*=pxCJZ=hC*!l_D$bK-^)uBrXKX<$w>=qYja3d#a^ym ze^=MbWA|qnmcACtx_s-5=Mpe`e} zem}n-)2nohbZXeWF<+sTuQvhw64nJ%@Y-LljAz_m8WP02>gZU|bJyL?O}%pmDmE)4 z5A*|-Y%ob{OEBr8B+sq?k;)q0-r@iieOKxsDri2w+w(Pbb&^7MeG2n6VFO(tE#7r> z+??^%xa513oJ{{DFz~f?cWT%o?D!w$W7n58LfXViP5_EYQ>E5-f6HdH#-m#H!A;g@ zu5v@e!!w}E_ z4>ad%UWzzz#@~50iQX&pKOpq;^W$7iR~*{6wzlS4E?t*d13xwr`N zimX1-`E20iy|$Llm6VkHY^5=N1#5_Ji0VmHS}lF??AdV{8JY6d-cS)V!yp0I2t~-aBYslJTu)vUCP>^ezMMz0Wsc!wV1Se^2hV9>};TbWo zceb>gfcnuec)OB*tnXC(C3O%%bECB)Ant?@M`VMDa64```W-kti_7QQq8M_&Vuy=N zWrZ9^Xn~r^8DbFNJGiys^)bo$@^d1H`ApdO#WbJCg$;X(cXECy4h&9Cn!zf~$Lj9S zjZ~L@*VwaN|M7`d(258~oOTt<%g?9sKZ%I)dhbp0!xpZ8A*tUjSG%z7!D_wsgabUR z`Sb;!S2LJ+uG$7G$f&+P4VUVytTQlJKx`}p-~%ETY50uryfmFf?7!lHP|(rQdDq)Z zfkL4)rK32-NbCTs@QG+&xmV}dE{!)DyU=Ulz&J$AbS28N$4-FM-6%xr&eHv)QjrE9PoZ{x&8dK`VDK-w{f&?aOOf=Gcz7s8T%x z1EPx;FTxgcjmm&N9UB{?6?JAxmAsEFPyRRAa;>8-$dH^qeOl7*ca`4uc&Rlh@Xf0U zjegmTioCYg)~3->!}-%D6@hc&5s|;5_;5zZTKS zd>$C67!JG<+gVTuDRmu6geq}#bd*b~Pi=7^pKBDft_ziv6V%q)Cz0`Y{ryyY#tnJ> zLYSM1iq`=rVa-gj9SB@_5%-san?yvybVn?m;_li1#6O0VtWC(_-NR!b_-*qUYrQuY z^klSB;EAC1e*XOV?zx~fUfpoxF97i7QtNK;LxFq^JI8^NPT&D|U0N=!vF&A-!)b0- zg{6AJL!TQvZ2pR9SIA{+PgDH-6Htg4pNSeufq{W`X;*raK|zR0NN|PaD6`ADyO*`4I<1b? z^9u{Ng2q@7V)z$@&OHTD^zOrlGaxDYzq%RJd7+%@)`HqHyZcr*2aVf-cd6ur+1YP! z$$RbqJAWxKlrVs_)QZ0N@8TbQt?}Rzcb|I*Borw#SmUwy1*RS;Lz*kW$Hxbb_WJzd z5uzvVcKa_5@VGAzQ#CX+fH^O~ng5Lh9&r1_>S|&C>!#9GTd-BNsjdyqQQNTmHKq^<~N_LNw5@teHE!wKZ@h=|a* zR@1jfG01MOj0(Wor+@qii?Y1q>gvjG^^q1_&Ey;|U6D}jca4LHEl8r0q+h9MEwOixcAYalTc^gr~0N?;Kctr{8V zOG=`JTW+~y%3o_+ZW5q)sP_e$XwA(+8Kci}&8|(gJ3BkSgMYw|$6mah$|NpM7ZVec zbj5)#A|e9Oh#^rKi30_O;cb!UTe`ao4Q@t8L|`;DC{v|brbTAkKjF8TV z{3-K@P!?}VE9DMwMH7>gkKepu#i{mTi;Bp!3k)6^@V0|xe<)zy_DVjQQK!yJ;Ig2g zTzjwW{QNwETizRUkBZIPC*P*|mBiC{%-`TCWZ_TEb(jwA2h+>A9b zHGKs69ruk-lRcIh77LlBprS&}plzNtc|j+V6{~@MkvkfFwvCoT9#jx5-uL?Lv6dXo zT=3^r-Pw7aun$poj z&dZm{Nf{-{7<8u;HgR}bC{;<+=0N8~h!g=UL~7H(-kuv|An*`I9`^#Y)kv);>1=nJ zcH978<8N}H^q|N{Vg$1xljo*&6Z__O*Jr<0yIll5{-w-TeP?IK1RQ02Lf`sq_Y~-0 zfEj8AL$0g^S?y|+Dl2N44XqyOugBk(#Dr}(*NR>qsRlvH_@T3toIx%Gi$(uF++PJ@ z6a;dZvb6l}pxN|?n4*%BW__pnKwzh2Ff_0SqMj@CkaHohUu#{JER&Ay0pg5WnPaRTl)%*@cd22~FsH8V;o z?yp-RM_hAXUY~$C2$(jXd=eCN9X99UMR|Ao_>$7nwe@Zp79k-@P+Sk6KR<`yE~F8e zvEQy`#;NjYehnI4gD)=y@7Nyi|NREfj3MWsl124T>Tf`d>0`1CRuL<)U-^o92N2is+-)fSaO z2+u7KmnTVh@(!2To&ZnjKHqZ+1Q`afPbF1S*H#QE4rOH`(7}_FlRF9oS)21(-%z+y z=;4B~f0Jq-2b)KlMnfIF}EKk$Y@aM0Nao7iRoT}(fax8SM$!=RIy3ZapYWL zCZYG)!5womGcpE-NKlV-zol!0KS3naWL&gqU`IT0Wz?t9EvrpfOxv4={3afCM$o zJca0^_|G1@zbrv%O+l4;txX2b>1NR=NLj{*WC@~1S+Te5UND+R*v7+%=Zcn=?7h6a zOd!3m>9lq5e;}HX3aq-fOb5$*yCZx607coDqiubTXGrR`#U4N_Qb*t$gZ8&qS;WM2 zXZ=rRb}9H;mSgZxGbkKJ_;#W|n~)-82~nIfdjRD7pJVy#L0307(Ca}!TEExYFCb?% z&LAxe>b{m|C#4h9#lrJN4M}Mxi3;e=w&{;cE(K1hy zl0wSLgb@Dm%f=7xGu8?XQ4X;oMaiL5xrmk11lsykkV$-5=+8xjSZGvJk`c?NxPEdY z45d6KS9pg$LLieG5XH)*uD%{cNy#dXZ|)r}q_3rP5~WIqx_@_~n$|o|3lrV`@hW&G z#KHqHQZfVz1Y8}yl#9Wrp~V$2Z$m!lDs^|zn)kCq8sUG33TB~6e^F$yxwtge#!`}^YrXmcwSWIF8#jJ@LrjsN@{h5Q_9Erf(Y z+yp!ltX-=x#xK5~Tt9RUjVh;Mcp_jW3cIEp3{#=L^+KpA^1KK}-ZXEF<$xQu%`jw+ z9pyld+(wJsCJ!E`skc`h*8g=}!N1Ec6c63Wf(=C`z42$#4_&6(Ou^b>&H39DnGg72 z5Oz#ia0oUeEB-4-gn%y_Z2j?!jEtsFpNK*4Qb3Mq;h(#q%QGQ|alw@7Arn7DCVovN zO_~@CGWZvqDy=ycQwwJ<+v5<9$Pj5Vm{6t+GNFf-T?wY(*O13)Ftu?1lWLehspd@G zmc&Q~Bk`R7uZF@m&pT^T1v_#T?R^~+j_mBbD6(hI0Q_5;nvTIgG{}sIEq358G+L1f zdktBfdn_!@w&{OL9Y|x$=3CeiF_h{_M6H}}(xo*QzX7QvWDkA_v>Y`$e%T^7Yt|IZMB|yoB;cA%1NCWL_Ck34L$eWpraL5`C{+wmdOaD%POOUP7y{urhb5(Nt;n=H{Y{3qKek~0f^sLC4%B0w!OV>!@vY*)^j zD;pvYd!bcm6uCY2;5KA#QUY0Gf6Y%cRurwr1JlV{LGGaYi)_l_AzeA*e~`_W3Atel zNwq-O^{T3>@86pOkSCSFlXAl2LP$`!OK3ZGQ9{^8WE^rxq2Pdk6O1x`+~V+fJcy0s ziO{)AAjgxDbilSxc`pNV?CdQTb{SqECx2|(5@ahwX0B`vmhYDCAAzj^q1M@iP%jFD z?b6ZL=Q0!lU%_oyqj3k_mQ(=y`eGV`L1EmJLhMgkn?`6}+wd}QYHe+8YHmK>*4DPO zSlCE*;Q}cXQ19E@;ZbdnRPQY{&)*=&xuIWhA**slX42K(ewz6Fl_&A>R6jna5Q>P1 zyvfK2jcTRsMZxVawNN-GOrO3pNt@0oSly9cF^l`?dB2l5E#zRzsOjR z_LeO03=0eUQe-NdfwgmVBoP!8RA41nPU64jj%iCGfi+_tn6Sp7S-Ak({hr7JtVe4+ z!1yB~0ukf7rBMN92y_TtzT9~iW~~ZZ`vUR?;=_jz9Nq8Vv-bA& z3H5*cxOCgvdX_^;sjKV9k00$JHdEuh>nzwqOkYq4-C6IHARyDc#IuBi$Qd*SgE0Y^ zJ3~y|3XYNA@3$B73evnS;##g&{!d7O790)*J~A^i6FFfAw|9nufN2=XU2L=XWjj!}lAUX&91saVma`<+I+qi-L z(W6H{*VY~-CelD^PyG0SZ*6V;b!e!mr-vL81UV>SF~wIz^{kN^|e0)UK&F1X*v z#|Jr(o#{$6|5o83>bobjGFBg+$Y&hp*MT2em1n2uu-DZ^&7=3m#UJOu5Nh)*GV;@v z2M_j*xp{bE&kNc7>=_yo^KE`Ya2u-ONc+y6J1gKR*G4_ZnZbgCAC~p;kxZ4m|2Qs= z(!#=mNk--Z-qWxw^8M&ei!LhSUmC5YkvZ6)a2%~c&KeNerJ$^g0l5x#{pVyWVV&37 zaTriRNl6wg4WpFz6Xa!3gYS9dx3*SB!(ot*X)+fY8X92as}MHao0}9>H8ohL@rIqj z#>2qEhP|^m9PY!XPgGJbldd8<4YVP@+YeLeOfkU z%FWrC|M&0TaP8q0hv8R%6wYpLEdW6RcL%ta#_Az1BV>}+8y8%3HBYbb;VUX)R$o4U zo?ls7THBwcnoa}x(+RTB?+|o23Wa(EY|6~#2+;=*6N=3Fr3hamkmz$Dem_%d>+Rg< z&xgFxbSjvE$Fpe-s1k0Eeh~CzjEqs>rIElP|^FhN2>LaKc0 z)_Qxyx!4Lw1+!{{sK<|wGZR+S{90c}fq@aeJ3twIPLTamUtig~rltu`ZSBEZm_Eae zi2f5;n%8$oFG#b0s87+o95Fylv3fKXShJt@+0! zfv1WYP)tn~4&Q#x;aG5MIt<8(6KK=9k!ry=YL_x^y$ph9UhQtPMjE6B1_tJOG6<#j zmjwTKYRMFN1FhVE{qRTUZ6L@FvFx{g4VT|dtN`E9jL@jjJv$dLQ9fHk)~B2rcCB8- z#Hgm`=Pw(f>6pBO7CCU?N{a7__8xTCGrai=@_z7SEQajdDkn-ro0 z{z(R~yi4D3^F4(AJLp3~Lc+TJm0Fz|_e(^!K1L-L1T~(kBuYw3$V)<>feJ-n#7<{_ z0q4h4oCH8mma6Jy?sJb6a-e@+SJbo3}LT!_}p)q1V|R>h`2hYC4Y0DB4) zqbTNoD0%$&ai(}h0q5^mec)+X7pDY4&Ex6o>m%><6OH{)3`#(Y{XJEUwBG&#!omkt zw!N98V?OJj%7C^g`v=v<0XoeN_BQ1pH*b{|7vDFrv)kjtb=^1}V#H0i3F$MH;yHE= zK&RMe*A?+ZSQY{r8k%6pdgPTQvVr%OhuOr{>MJ}JwU8DH0G@W((1qnoo?!foU8Zih zFAfkp)o)V6{aN*aN5##_n{;sc&5(3f+5GyC&qnpTU*gV}4YwGA21upXJ!J3Zm zv$(h?;PhnCG4IC5FGxyr)q?p4C_qm8PZ3fxv9ZayvodELCTOnkandUK3zSz@jt_x_ zkq6f5nr#`*N=QkG1Y7i@^6ubDOh7;j3Hmas92Wa| zH?*{cjXzA?XF;iI9{~e$?C_J3-_rXC-TpX)-R1DENDShcjiz{#2aVK&CM-+Swy7!_fl#1!eCko9XUOHvbC-4ZXz&a;hbgeDXg_; z3b#QOSz-MaU4_#)uXtF~P>lx{z|GGg>$K1)?BKnnugB!&t|P8m>SgF}PR>kF4r z&Ss2*@GfNJ9<<^H2DW~EEjAb2(TG@x2d=`U%UcUM3~!L5hQf`$(6M@J4R$^{aoWVz zHWVN*B+BgP6{j(xyLa!>i@PhhQ`SEN7cT9)_q~NwW?FqFN7v7E)6>d&= z7(x6u6`QwX z?d|Q6#uS`tUl36)gb1Z@_n`H|2OAC0Y=@JD-`{&5{uZNWVCZEd?@);3bzVkEDdqM- zVji9Z3Xr7gx$&xgk$zYCQ5X0y&`pW5*(XHupUMFi59REEbJZeKJ&Re){-{6LRe) z89pE#zScjeoTK%)fqw@gF~=CWK_f5U{z^6dh7`rYq|SW^po;!T(}_45@O59N{NJ5#3kSIC3f*0t+ccvY1BaKrH|8d$+9JCs z53o8jHzMic#q7Tp9op%BHw#G(oSB}PK~B?oI<#Hvhz^-g}LN(feI*uV8Omn^nY%0T%}fsr@($YwMPeAC+MiN}wD+ zba&G*$W8(Gbnh=NgaYJD{+wum(az4>BBRMH3>!-(r=;A!wupj-bEEAt+BOaKG2P;9 zz}r4yx23i==GBGn4#0qsVUdx6!NI|Ew0Zb?751SZs&E2!5gVmQIS7_7^ASURr#AZR zs=51Voj7&sR8dip*9{DDU*pQ%xH;Xo{9Zpz4C=g8VQTWO)$}bv#1ss&EMei{6AKGx z8PhhEu3bC!Lc}R*((FJSUuxbMnP0G7KcZ9pC0(Z#4i0Sd8TY&W57kX9EjLSlv>l5i zllq2NCqBN7^pCci*j;uSlMImLKipq!bm9+|%W;Br7kc_*Vp8J)8uoHC4=gch(!QzT zB%kaGt-Dj7W2W<))~=3Xx-TQWLJq@aD29M+-EeB2pWmDsL!(|_`L_ws#DgDrk6zO2 zj(db1%K;}O;)X%_emK+#;{_q@Mx=QU9W!m~XK?2{u9S#D-2EMLJOh)uH`7V=d+Ndw z8H21tUS8hLt0Qk-VPPt@Yz<^2sXrqbm+ys_mv2r21^lx8Ky+0>K_MnSzTb)`66L|> zZiIBU9y@mIx*-3jwe9V88e<=3@f#_DK|yA_zhq<_p=_3rgq&BcLyq@(HexuhS6G6odHI64;0ad@EP z6`Q6?O%-n5d=wc;tfsCmC!b9|e-k#tOf+YKFIGO1uJv0t@dt=;njA){T*9I+tmwY` z(pLeZ3(^K(*9Di6Ghrhq!_j{l^ti?G)mbiFxbWo3laMG?ww`EUp4N97!^Q@NhW?Yj zTSQ&`x!Mzxldhp52IbQ3eGx_X0jY&Rv8f<~J?)x7fM<+R#uF?`-R<&6)!v(&K_m=e z0Cr(fSn~O6$kez&o?WUW@;9`Rq{z6{dSY|FEEy`5cB%U z1XfP2oj=J%vv;-h1wif@;N+O(WbWx*;cM?^gRgBShS{u3*WZcBe|6*RQa@{177Mh;-`m)=??a{<;~2n?43EC zPWT=fjd6zU5fKqc@4P{k^EHRwL2A`SS>2hva1G9SYAPx=aqV)+2U|qT-zwWdjfNtk z1yE?`V0&D^X{^rGpXY8^0r!UmQMVsNfS^+7UubNQ<-ocaChj)IcHz9Xog7QyC^&9* zc6OcGdk%q>+w;Artv@Gc|E%b|tje}p9Cm0NyAP2;OG`5z{hpOUq;Tu9QUZ6=(c$XR zfR{Jb{8+t2h5gXukr4w6OUnu5vc_1W`1;k+P8I!>?oALBNONCEM1;mSq5ju7+u2~x z`UIpCKX(1E{w=rs%-1SGThh6qg4Um3f$0Eu+_Nz6maDI&H2vd;+1|#yqW(_k89t*r zyq|X3@e?h=JP!nHiHEz!*BC#u>-*+otrdV zT)FL@DrbC*8KS5c5C4w;w_C-Qyi_!9Hobr zh{uOqMqaPFW-HtFXB?{COSQDJ0#4xI&Go(j9>yF9&)L&6I56;(q?8o+dsWBbn3$Nb z?Fmq#czyZ38rBD783z6W0szg-kOaKVa zkdkWGtUhB?Lb{p^YwyKN5WhuoTR}x72!rl;t!=znn0b`Y_e{j41Rp=~MbFnor{S{f z9_=(X%U4B3WLsNX@he+JuCABu9UM^S&VlTx62FzpZl|tw?3L&0*v{^3+A)sA zen`^E`t32baiucLr#+7dj~uq4ZFF^vFnYEM;=RGi+k>8 zF1W;x8dGUTvv`+x=L7_t$W(rg3)mE9Qk z)k;Z8LC#qu{SOUdtBvETljSk`9@&j?pOz*k)#fj>S&p|eGBQ^AA2oE^%6R?60|aOj z8TUzd*EbZumKRi7#@p-0cUbJqBpPdsX@AqGzb#yBDa^}D0^ByU6`0@g zOTApOz_>9Astq9*7*?&i|I3##Yhl$AOU-}UQte(kYL=9gnAqFrm8IE3ezKAi^z`;} zapwY&I6FIMxr;m`r`z#iQX4CIajP(F;fMvz@=u1TsE{-_H-9O$zTN7PGuBQXikbJ- z!V;4h{zx?XBIcKOfS72GYJSqe<94I%+s0eOLJ0 z84ts3Uuo~&+ym*5kjHb48N#s(P13n+7Y;M#C*j|-goLIJ4urm6vWTB6<5wFL{Aw81=-<~+-_K(d zcSqjsYt|Hi*9gmhed*FA4?V_rxrNt(K;5dUt2HIG4cXVdAhMTG~J9-Q@i$()92RPK;JzD^c@TJ>`ld;wV( zIV+K7)QOeRTAP8q=RLlQJ+?Weej#cFjfhPTD){}PfU~2c19_tqM11}yco0w|la=Fs zEgzo?u7SYkT6t?Xf%J7<@ZCVAN<9e5%i~7AwVH!qmopO9?QO0=OuKxkGQt%PUKEI+ zJh%kUoJ6S}LrD$3!&9fAyT7cZr3LzmcYDGZTOfZT>+@#0@5pmO>z^yNt2vh5Y=bCN z!@-t5uq|3b;{16L$0u*!TBoEU?*J~|PR027Nk`F(sil*vdK+hhklNYZ&GxA0$(^>r ztEsRo2WGE{#=nEDs-lH@QCz(G@`^*zgKb9$nkg9YawA5}lh}*5krpf*4(IIRlKn69 z#L*L9egEJW)Q;ED!S=-W?|2}IB4`D!uRVDBtYl$nDZ=X0i`TlPR!QO>cGa@lw%K`^ zy}6NGM}^q)NU8cc#o6mRfGnF7*Ib<{D&o)Z)e>%qp(J_$1ANlFR>(rVUr-ie8WL!nsip`ydt!nt4JG<^R#bb0sj zBhkU$rh48RO(|+TnA0giLBV>_!gUZ|y4*1eB(c8|`b#ir6N)T_^*MqqA3>466mjD9 zl+rBvc-PI>kWu9B0QZxipaE}h%cEltmDyV!9y`GlugDy)DB$(;yJBN%zT=O8)1=Kq zL+9?@yLX0|ShIR1uHN9zormWHtq=+D`Sa(mjsA_p1K+~HP9Fn<-CNC*`yXYBG*o+d zM|J+_hBUi|NfL8o$NSUA;OhFgzP^64rR+-A)R)(?b6<;Dpw7kJ=kCl;G!w1)YEi&6 z+mZy#-B+Y^Y07u;vab7UiYzGlUpg3L`rltqK&A5;H@wf$%tiWv6j;eORz}aSt*zl1 z9bD7jYhaVdf+{(6r&2||e~(#B?qDVWsE&5y9MeLswC|n;1@1WK(5$Qo!E=#u|D$@n z+tjaBkfz7N#zRi=plhHqNVN)$^4;{ca$V=XFlQ7RKc7IpEKcAvF4*+d62AFv_VhN* z2~Ac1Vj%&63AaVMSM0Z5)G=X?Y5ck?KFVq_24#~V(Q`u30AxSX-c9seIVe}VFf2;l z;oP}%MP+4_3<0(e|7YJjT0Bbc%+Bxchi0!hm-u+}%68^~{;{P3!Zkj-mw}$|t*xFK z1!5$iRmhS3D*0=3Q%+eqqG;B77&*+3VUfSi9y>qnqLq8uWfJpq$6klmxFO=TY%pB5 zJrKkK43dyOcb4Sc-dw8L(DnsiOZYkuGs5bLGff9t*n~n9+)%2Gn}4p8fPrXcjO7IqtT& z{CqM^x}?0kf9QIPUFL>>zf#3kqVx|idF2eiX!wlY%N(we%3T7(>|IHC)mANABmeE5#c<+3o#PqX7M9jMy{Fz>w2Tkg z4`3?ozW~O!DZ?2e8%G-h*S9h6EKQT1b@(;I{F7Y2sFD!&1-jW--uQtC2RxNl6V zO-xGW!RB3Y3=jF<{rh(loIuixlc!EKjgK2=Q-T`|jncFZz$b17YR0sil>c0=9LL^H zlUCf%k@ntDaOaL!Xzb+NrjgQmdD!!=xfz{a^wjg{%fkcKxTDucSUwH1p0cy#w38y_DjfQRDhO<&r( z3f-NYF8(+rk9j^rdIknJOe3C_FDT?{j8H}2UQ3M#4aJ40OFTV{*F>-IdB0UT zXoXdL=B%+TWaxfyMd=cnGL z`KfW9`qQY7rg0(gkqv17p7#kZ4(+xs|_XWS5YuS{vzn(j6Ee!>% zO|^$dHEGaF+~dBtJe*OMakMm4iZ$0fKX0qcHhG98?He*?1z>(DA4UJ1ZBMTFR}j&; zXQtNHG%7RO>-^d4FAAiv*5-jK$)b;70W4Bdh7h+vu%rPY&P!hf>UmC;$NbYH|EE!l zQtOdw`VD4an?lc<%u>9$?+@hO+F~2ODrNMPOG`^%!Wz@>7m~tKo@3Cux=oKOa=V6k z9?t3Nz6R}#G+h=I6@8fxxHsrISZEv^A0MyA%po@J?c!2A=S7#8oE-7=DH&MTu&8Fm z=iq9tU%%c-)gMQBut&>wz?+L1F?N5(z8@YL6Qf#`p3aiiqg*sSZ2>zzE95xhb?p?P zp5EXo8RpNMLAWTwcopLKyF};sJ++H z8DtZZlZmvowc%0%SI(Z-JMW&O5=B^{wM}kg6&X&)+N_F*J*{A(9oMC zs7S8TR}aWyN^7Xg5<*k+IjN|r(U&iio3}+Yy?b;*uHDpsalBCmf~#GS)oF2=lB&OP zVjlMGYo*f#klQX0Wt_`G#y?++Xw73N*<^k__|vgpemzK4E3~Td%-iL|NepJx!NI|w z`0Uw9<6&DIY;)<-(vo9>?uYu&IYYFo#`fa@G_JHlkxgGmJ5T2kWY)y{Pzo$dzrK7l zBl4AT+~?yOzseg6(ufs$!K*v3jEHS44aMGeer-ue&CTIyZw$l(zK&TyK-IlYkEP`j z67MIde&ZM9s<+kEdn14R_;CvPhDK(*l7I}{vAva*mW`EF#p}nXMq@XobaHY+Qd|4) zZ7ygce|kd7d*dB&_vW7D`rePBQfq`2>+0&9e@%C|8W$VYduzI5QhxqFeIT%1Yx&gl zPi5+55FW_=+NL0`EH97T+}irwfiwUZ6DfkY2mc+@3;sg_Bb4{?`WE_Nzu(^y)4f1f z?SCX~W@c7oKXe&+I}O$n%W|#`WS2sQ8n$Z6_|9MQ|mWYn2scDR`|KacBIKd7wKu{`p zqBS}0GUw5tLUiM7?Q1fr+PmDs!c?=LQv#IP0}2cIz%{R}`XA}La|f)0H@eOl-#j>2 z+3c&{og&e$U#W>S#ZJ45{rL3qH1b-_pz4l0YXJY>ZxxzlQvZCWj~#w$n$S-^Vk~qu zaX(zJUVQ4RlbhRmJ=iht>U+z2V~?t-L8}<{6`8h}5fX-vYWOj4A3l&4p(uVTjJ!mQ z2aftaTz(g#(KOK#jC`_Jw>5nCYlCm?oQ<~=fFROf`XPn|kpyQOjq3dl#Q%K6pYs_q zmH?Zcj<|o@-pr;CAI=#2tOd^Lc-t-ym)nd~A(od@QbX_W=MOQaiO7c9rSlzR5TNRB z6<%51DzB)Jo|u@3*%-1;qq4HH3QG+Z=K%x5%*-4J8vW+Lz(9LQ7O7^PQ@cK1p zzYs3`l?q}m=H_gWa<5%&Xn~}gn4b@&;?iPbVUcy0tX~^6_BS0Wu|#}(5b1@e6Q@Zu zyc9UA4Wg{OQ$wS2wUO?knNBK5MC4OvWT%l2Dq6#70@|(n!Ce-EoZgtjod7b|6pwcr z^35b(k41Lg~GuMv3EH|K281E`p$uYEnC>?Qt-+f zE8L6=$g6XY#et^LQ7I+PcxiU5rpDTjUq|C(DZz4@6{dLpl$PUiCoyqsmE1*qx7?aW z1Zjlc6OFuM>tdt%qA{Yz?Q-c>M&J8D#cyS<9dVXAeG2c1uN@Php+2R$wRw2>?)g>f zYo=r8e(V|!8YB`~kF9@vzV`g3;HsE>&1l}tehC5do@KU3U|=AmWsL7K9W8ChZRy>U zg$;Y0^z`&aKD(}eKGS*L3}Vt`_ty;M=)?MY-*~s9H^%uvPo6NbvuCQVl#{c8DA+3Z zFfn05zW>NjqCq|`8%YysYHB*h*ZA8tLn$Lc<{>8s$C=R3P^^-p^BX-=&9HSPDmphm z+v}L+(5#CG+P{e$9F|*Nym(O!8sf&l;laLA{8|p9M@(ueiNF6*5BL~sTU*;1o4a=} zuw&0@9E6Wdb==mI;?gd7_3B~teVa2G85tpwk#ZQ!lO?Gd z-~D?L3=-5xE81Y;1>~(-oVH<3_{D>BQBhI+0s@c1!wK&#eN|oFzl=s7cX4sybPE(x z`&6X(e)rVFg_%SvjjcpQW6qbgUsgLD9=(1&ag&%h@;9)EC68fEnJ5~4edDe=Uvo=K zu|>x-ED3|Sg{_Uv^f_AEWG3vc#wOv&YRA3#eG7?8eRU*aWCyOoNsk{NAKJhR#h~}U ze5-c5I5INwC0Cmd$?M7Yp-7t3^&5OFD-$|-@+5Lz$}b`!pC;|gZ`yovX}CPMlZh#1 z|KdSSnrw~_B^4DQ!0Vm|eS?EE$ag)D9vwquo!5g0=>nUxNaxAj!2*6Eq4!YX#ilJm z)(w0V)>YCHILAI!C4NXlsvK+uJ9P(NnR@h{&jybBeIe0+qw)j_e`K>D&|gNTrR zLJ~$v9S1Vx??>6#a6lpqX3ZX63IJV$bdkS){hG=s-Qin>X=mJ}qRPtPf&yLxL&Mh* z2Sfe+RN~^|aIHP=l6sNv{+8W%Vo&d#6sZSV*@ag(u^}yX_mhn^_#5X`hYBX8HFg92 zUxrXG&dt%=0~q?O|M(Q{U~m5msv+!({nv-%e*475#l^1vsu{*F8N^&qHZ(NoR5_cz zE-&{;t*P-w`Zt~C;I~<^a<>;&wOjJHV`mR~VwYbnOdsln#l^-3ynl~D{xX)3P}z0o z_!W;75hq6EP#m)5s-YnRA_x}xbCHj^lSN&Q6A%zIFGNR2w}Ti$t|3iMP*nKH3+5;W z3FKRZ*9GXj)4bhTsacw=O;si{y>2t(r}CP z7U}8f&GltdQ1clP$t`q;Q}bL0K7XB`9|`4&G-d)i#~1i*ZP3qu`Eo~rmE54wFQq#U zk0iJM`=4A1`Tr{W5^yTF=x4UTbZta$}%o^k3bf zu~oY3()FVvBLlX}%U3#ESzXX0f}}Qp0+p$OKJ`zIb_+PayS0Lmk#VPIA1|=;b1f~V zzcSqu5)yu=6m8$mvw8DoEp6?6&d$=vw-09P;TdA0f=l(x6M?*tHlX_g9OSd4sIr~KPSUcPM;isdv^B1QB5365HN{R{zSxVH99}IgEiD}y8VaJ*rTC>y87wU=F+>wnv_Lp9p$k?H z&(|>r>ctBUH#fQPhzNZ9*q8_YJxo19B+L;MQ;V+jodAR)0H_gP`2NEOYbU1&@G}qU z>R2&Qv7}@>CK_Wr<8JTb+LHtocjfi#mtMShQA&lgX!^+(B=rxKIQ(FU)Ou2nqp1NE?K><6Rn7A5VXP7eE`ua5wR-rq6Iuw3?ZHL1W zCnqN?=QTUg{`iul4zg0!QUA>!N-z!_OoIHBQn{zP2swo^8W9dWSmH_f>%i5ymh6fq zghZWTAufMiVyK6Q$NH(MDLHFiA$(`}2QzPrRax6Fv;T-(i~AOM=~ z?%QN6%9n-_jXrhc(Oj`25Ty=ShjneF5LUnf#L`$|ufI}MnHRo>b*FN3H?L%82a#o$ zmzUq+@{Sin6t7(29~&QUOjlp`MFsE~*fC|RXzRuQH8?Bk| z4Zg9Sdj)(u1k6ctDDBG{wSY)iYdpK>A93{I>~Fin33`snYro1B?G0v5J9NiYaK~}X z(_{hYaP{idJ^K2bFdxT1l*_+qYD&w_X5r!CF*P+!wYcX67O$w^4de|I;=q^`1HrBU*;%z|jl8(y zUScV6OnLUSN-J&7oy+^OUWJ#RQT7%tA+_8TmBgNaybHx8C2kYnEe@BtF9VXWoR#$) zQ9O4ju7C7B$X^In@^4klbq=0L zD?WHYOTVYBaLtKVAEs4$t1=kd{fg&)==U`iWOrwW6DMpk4b08MpFKMO_)KEM2Il#h zQBFW%s{{o%wed))I8K^bdxG!8Jir}0cH9utSSt=Vqo%Ho_DWJO(~?o=Ef;_z;59Q~ z2vA=^?$)UI+}M^qYE7yKy~fPF&!1QE@limpl&jQoqpin#C+rLiR)J&3;PAV5ciza# zBFyZS36I>F*PLzNCBP|8SeJg3@HRf>J!{zU6>b5BKIX;>@zs&kJnEBZ>XEEs9X}<5 zR<@>yxm}OWjrm!Djk4sgOqT8*`r;<5CiJ-P>0J%|=9<2ESidpM#k+X%EJ)+b^k5Z+ zr8m({@XLtb!F5PWuLO^W2b#E^si|uPg@m47OM|7v15PS+Ie>f#0)f?}@QAvf-|o5D z2}_(T35j6N^G7|&bF<#xnzsOMX2QxGnA-QLdRgoALGg=0R6NDpZvW!Rk8thv+#wXo zI&djiH4$4)j@aTufY?7z*fEK7&_@hZt31}Gt5JKnxZ+*~T8}Hc1y~>0)HrLJiQ5QL z*u+^MyFFU1a5O;v&re+}hw>9ab40q#x@hLH`E+ez! zvu60L_-D?IWj@MzOM)^pCBb45-cNMKsHFog$HE^XbQ@aq^x329pyS&pbzkXorr+=T z5fbTjnw{IT7(lY(j7X-Hzy>}BOb-y^C&tGq*RBbdx_%&p_FbiQ2Bex&YiPT#OQcH^ z5}nMCY~vcZ5U3P+lScjin2<>;nvw>=zbfy8c+;Bxuu7L^}@Jzkfwm@o3f$fx|2|c~`JsBjVPi zzBjoCF}@o-$z-2e-jT&=xP6~JwfKVYCU~>yhlP%)R@2^qp8)d{3R3g7{!HYrma3u| z#f7t)5i%iiu-E~Y)?D8*j~18BjKK3-+F9+ByyoWAx~RfT|MnY`+Y$b zpB=6r%A2gdSx50qFg@A_t|op9mo0bWGHl-$y3k%ZPkVNxUKSI>E4)XA{Vei^I~HcV zZ?r|z)+G6w1P*bQ>q87FyaI-prJJ~i`15mw?3Yr#tcts0oA^H$nG4hsJyNIzVK~Hj zoH+5pB7*$s?}sr0Ba~C@%5-_c$l_}qU0kw@U2YqDtc$#PeqFg3o!1bg&h=wOm|=!S znq^f0H9DH#i0Pp7drn?9H`Dy6d&JmH<;!bLYq+rsPl^b9yu3?&eSHsH+p&UEOqJK1 z?V$9pwqdeyE-4K}foeggGdR(PAu!Q{gPi;K@2BL3hCQC$b8}T_Q{Vgb>ATV+tRkPr z;0*9?&eP5Ztzl+nZYi;k=`p%$wfH*!ckYC?4VE~l4VDY9`@4vh0Z`M`-QL@d_>Ys8 zGBbzEgs!MweC^25uuW0amH73`YN(2v98KfO&kT!WjC`bs5;qdJdTaOEh2|vj^qAcK zidbn&M!Ezg}VwYnj^R)dZ zyW+7FDaK5f^VS-30GaUIn9eP(ydD

d{p=Tg4PoE?AHZ-9!b9b5M^L|GUV##>&o) z89XF9ZaX`>t=qTP*r)iP@9%fU&w`8JDle}Nj@xa#kJM@twj9%v5)y>KW z{6%`$-Y&)_AmjJRt!}!%q#^cexa*B;*5e{vwp@lLD44tpf*C8Hx8y<9{9FWNhM!Asp^Yx^pnVaV0Z&HP?oURXQju`Tu#%eB{WVt@Dbq2d+qG9`tL^w$bJSqP*8L| zB}EMARwFQ1Q!_KBKq@Eww&A(!e@kHjsPHhxTv0DIbCO&VUxW4MN^Qt~cG?bUOr zhuSvF=|{9F{Yd$@^I0&4XzacF(VotP^0G9)A3| zMoCHO$i#I*5xZ#62aeI z05p)7C%sZ=+fv}lG_OPcv*T}1dUz1`?qxJGGJ08TtHVJLw^_y2#bcP-vro__To*Mt z3QUUsRB!gnrlv<&KQ{hVM>2<3KtKQho19yR4Gj$`4h*l9=op)}%S(D8LS(SFH%#8C z`ANW$`+iFNTg*cMDUE&qaL8*O<2&$Rg`XS|5rLFxx6c^nkl`+Wra2627<8~{N{LZE zl*DjmsDm+JcH9K%{nxKwF?dmG=193c$+00>1rM(b_**8ve_)f9mF?;46Nl*$^BZDR zIPp>XkgAjv8yKCTiHXppBvAmTSiq1W=*}HQaI6@rxKd>2Dp6&RpwLjw+iiVVKLz}q z?ZmzEa(7eG%E!6=PJtU26nN2d*_bY?tEPm8vK$GRw8fN#^m>P_`YiXbL=lKXoZetl zh9;+3P)2qZqwynPPr!-dW-A<<2v`MFTKWM0NKhU42D=y6!$fy^J$Uy{m_nh%)vCIE zCPuN;Hc95q%}o#f?4uU~-hgr1bUZlA_kDD9v?gQ)&oMQzohKRKGZdou!+P1O$P@P` znPK8_|0z8q18b=|x0ULa&VZ0yOiW}83=G7Q%z#VJmX#@eZ?B30^g`OXOI=To17JP< z0~tg4DfANmpPxcS$d7!IsKsGDk+|k{`xn++K2O^MfIkxp$KMzUwp!7ZDwF+@#Mh5l zqwG|-xT2x}0F{>@b&B0l~uC)s{6o{Tie;4uaB2y+O*5c`A2{2)$R6rlrBsaa&!y_HOR=x zSsu*7xsc5UD5M5vmEq*TJ9$B2VKf;Ud-gCOR83D8$BKqP@<3kpQk3Wzg9S{s)X7FR|L;r+v1h`Ycs(Yq?41i`%v$B|~NabCL zjeYR)B?h&`)k@3A)Ut^A8FY8Y#>OrMu4!s+Ug!F%um!k>K5nJtAG&j%LRn__?5g4B zmD7`x51&3=!NI`+-r!=A!Z)zU7&YBLFz^YeV{3_h#_7S2V5}+G*&E;8IT2Ip(pL8) zoCzEX>yG0VMs98{Ad9Y(08elD zS>Im4^+6(iDJrh80OFRDrn3#F+x=M%9z5tb@^oXmjc^T=2s3s}GA<7iQ=%H7zN zvp__6)$(Mri-qr?uWi1I0G(3f_#DfqtlNLys^?`IH7bhFBD(GqKu4{cHI5=&nOqm| zbn;KIG3xQJauCel*lFDqOx33LT)-~S z7FHfWwWYQ;>qp-~m5Slo)jLmpjqGt3mRuN}L|!tG7IF7g7Rzl8crFgFFJhPP4{2~} zjNpOa-#e}Ep%lf6({{9`&s3Zsp02jE`2kjQ6Vr2lWPN*1WcQg>V919?Mz}$!9s+p0 zaJNW!AJLomM*roMkWJo_#Wl+hObMJ*dehW&6RdV)<|Y;F!51+y3y+~HSJIVHA84w9 za`&m|-B#AcP`iq;S2{a=#&UYxWBIWQBkc6Yh<&bqxvN(zNatI8vx_O_F9UAedi>?u z!+0{Pq`kmbCPSKBiLtswE_YJ_n@E*k!V?#RacO|AaK{Bqr+R$G4x|Z=KZ~ZebMf&s z-e5k$X%ktw>R0nZw9LxN%BCfDQ9VYyufX|RA3L@b3^Kz!g#dzHO0W8bP^6DhxZu@ijVbFS8iF`^~l$dYvIf~ z#0PauNfPP4#Mq(g6y8X=4Htern#{ghVUMmZJ3PZ@5pM9Rl3rm#a(fv;A+>Leu{4qW zPvfl5pN~GfCeH={AFB)z<0V2oz7qyXB$2ThYxywh_c!g2m)b;zNiJ%3_?C6+7!j-@ z6TpgAT~A1Wt2XFer=B~v1nkqsobT42k1juU&YxebfVHR%aW%cKvxn=X3Lkv&vMWkd>rqffVZJJ!D4wxmr~p_h@Nb8H)5 z@S&j1XX>JaxVM7e9UC9N3GkvZ)A(C8g$*laeSMJ>ai=|Cb!lm-!NG(3f!1twYL-5b zq|65r_2|l$LnpyME@fenP*C8+lc6)*w2r%~dct38I{&v+HXkAXJaFv9$K5s^sn z!C1N;ld$nf1>^{c0`fJ)QqC<~7jg&hoIotH?1WI4=503m=mH-U{*iG`uJ&)_+pM9a zu3LVS?t(%>)`K4__kDZv*CoYwrK7AVc@k0Xuu@z|M>C>n4EUVUVhY>$@$A9ha#w!`X=Y`(8w+lF8W2NtD ztVqGd#g$%v@Qks)X_7WklIUR&AjSvM82w8ct8#KSVRE~ko}QMrw&Mj)5w!r3*IBy3 z$;oRz`i<)1c}w8@?CIbdTVe2DGl^)%(YIbEU|@tAD;zh!WB z4EQ5Hm$uSJfSnJ^cB&JJR?T^4Teoeiewns^7_ed|c#ZLGrRiXYxt1(hf{C=ZjyEm= zXj%)jkrN=0BnD2 zFOzub(m6aqHa9m%1A6r6(JuyRBX`}qSV53jMMXuW&5D;gI5?#1aG$HIb_CnbKcfVz zx9^wt>;wR{bmPX2c=7;39v6^u`EoE|ADbr^)(s60?{#%82qMI3dU+{e^+!M)Ht_ic z$9d^J@EoErSu=d@f>oqkBXQzbT(vbx9>gEZC0*X2d&xh4aA1Jl#l^+BwOIY6XI*cE z?ERputPSLX!<)-vnLU5>n;my@!p(nK_cBtgpp!9i!VX_@`{(p@&4ULFz)DRkeQtw? zr0_|RQ*{#+svEr9Rsq6Ih1dAH{%yTbh`5G!*v*tA`t<2jOhw1yL4Z6PyLJ$e%I|a& zXJ!`;dGp4&v8$q}rNtDi1avU1diFn0qgA9NBnasxDNB~eY7BgNdKt^cnppb7|8|2* zJ-uS4pd;8Arbb47Nu_n*W+UjQ^*76#N0(8Tm)Je`DR|8D@0Mi+;hD`snbgr41nb<{bZEa$Fbzf>~D#O6L+xtQ4gA2OjOpctrc#-SU zrAvLbyZ`fvJBAq=oBJIunm*?cRSw~j(Ae>$1q^}wH3b(|0fBfQ(fEI_T-`SyNfZoT z+}6T|DPjS@*nLDtfvDm!HW=n_o`-{K2sV*_HTeeHHgy)!Dqx|1-k8_^4r&9&gcg4@ z;O8fn9Zt8Mj|jA*qr-<#p*8|LK|KHpOo|a zdGdXQcS-duNFyaT*MTw(G>8dQe5}9qU^L&A-|{3xC)?R=fEgghKNJosEmfEU64u%v zBqU^DViKB_mDR5bW+x{%*BXRUT>A^IjQ(d4K(h;Rn)PZ#uTGhPz6Y7U9wYAJx48Offt>8$dIo++Kq(tsy#{=eq`@=p%9gH5Ho>Cu996wHtjpYTW z4TumZG&$cKi)VfR{v9h{IGc&@qm%P-UlgW!<(l1sV0lLTg!vXuh}#+~|MZWzD<_)s zgx;09M1a;d`}j6zea())edkX6hqq;?>|4)j+&R%+Fg$!)vLWD>&0~(cckg1wUW~2< zQKT*hXK?)0jTOi+%bJWt7p4A2kTr>*s=5ZSBj5K^US73e?lBzp)hnZ48IF%0J(7=qUl$L#Hy7(fyl zGj#+2Yp>h5F}r%(tCW<`-P4V^2eV%Spa2)t*%fbDu&OjFGIFcy`@5`x$HVq4DqHNP zJdMSD*tmkhO7BrS=v86u&1ey&b5W}m$*al1!NGFgBgZ0zwrlVoR&ag4+{wwwqvs`K zeY`9S1Ma1PXWIvs9cz7Kb!di;?rs(UnJq0X7&EZl?%4%O<^N_U_r|+nI=$P0l5nq-c{SuM0FM(}e`ktJkj8RrAEL(HS}h2W9WPW+2%%B&)n^YNCKv z-MV#)pwf+jHa-oN#-#ad)tR9hMnlbE|wQ`fe-tIhqCU`Pe$6Cogr+bW>zc;8Q}Z*GIz7MQ%z{(yr6hA3n^MJ&uTq%9qO%UcI_LnuFv2wxe1NsM$7K z4(RB)?Cgy}#YK+J&XHff9OLEZPY;}*Yq{^g3p^IHudnZyFJIPf+{jW`F~W-B;K0$q z(yWt{;{x1|ECQ>t5BzLuI(WqM8(!^$U@294NQX(E)TvS_TIZWw#L6%`HGY}mN)W)B z{9$)K`mlj#qYZmH9pA8FLvfIi>MefwF7OS$`{xUzXr+4r9MIoqHK~-soP>pi{T!;{ zT)2Z_Q(L0Lv17*ToXNKf=q82L@863s6#0xh;^r|}j=QG^lbw_8TpR=50gtiu^|XI> z^=yV_%x7@=@kv&J;0IcYtoP?P>kxl_O*}CKRVxF+li{US=SHco+sVi z_i1ahV)^sFKJ!oXslM7gJx51^`K{xOo}Qk#)daNp<(oH{YK0XIma*|$wUxSP9XR0k z)s+1o3uPF9iBWsInsp%BrtvP-suyq zvtofWa^M(49Um7KB#+PznfUl9<3&T4E^z}!5ri(%y(+Tr?Dv-CCTIFG<-Wg8($Ueu z0KwkgUilX(v5)f|UT5(IG{1cL01Rtmp=A}}j=C=G9rN>R^81e*Ig-CdNB?VHsbdo> zf>KJ?iKRuB!81kC&(7>A>v^~D2FIGkh82+zP*|87h+@APb(=Y3C&Np&nGL{ z=_;T89tj*5gC1W5#y(+kGsXKPjM9sI0RDRPx1dP!UHR6S!4fb(J7FI^kyq5$-!DDw z4Qq<`*7bK^zb?}1S2;Z~Xan{`aJyZkb76c+idb!onCzjs2WOcu!wmER0J_w@z$O}L zXl#sVYAOgQ`PhU`jiYDhTjLmG&u>eDFr-BMVk)?9Eq(pM#Yr_YGkf{+Wlqs7%xPL? zCIx&ap~i9VUPklVj--Jd4C+H;$s}D}UF2|JyvNJ!Z!7rrI8M!D)FWA$VnnL9tn}dn zRbXI%X5cdG1LEW3S+;D+SI)mv0Zwl%fk4}*1%~Qxu!>f;wvzV-&A#Qk`V&I{T=QY+ zl20|EQZsrwI`mg!Lg&w)_YB}LdZj`?d-g1qO3is~)AdI-mjyxF1q$-~xw@O1oY&w- zb}1<-@Cg!Y*D|R1jOCn^607LrCQC?2po2JOXD2Qz%jrKgw)fbv^;cvqIY4e>V`DqO zlDvHV8ZhE!%wJAdX9H56_G>p>z|s%(FWu>F0Wh7*{_=tSEjJx;B27&6y_@pcHnmB0 z_w-QZY-->9oN;8OGYnPD&vGUzxa=d7`L}J~j<;%>o%B}D#@JCWTZN|K-7N=+dpkPw58c7+ zVpDVT>c&RHQpGn74V)PoQTxF4Si88e1FLUM&O}m%_ilk)Qke2+tn{WROA8f!x}(LO z*0aj`mV{#3a55j6hld9b=x%`q;^{DeXlI$M9eDs#Fz5pVu{P)@AMSla3g;!WuUwg$ zmS(v5hIZ2rXNE4)cpw4TRFbl1H5S>}b^1Hj6TmY5@5@fXOLK(9*kVP?=D;wL@5%JG z;(a%S>+Bt`_0<5Z^IW=o`Qr8Kk$`JeC$5tikcLoms;9Ml+V$0D*Z&g4uEF_Fp<;N4 z=`mYd#!ZRacll3wysrur1Kq&;T7mT&c6YCpR9U^p%4#j(-GkYW>)3wjaYqsD0Ep1S zsitj_G9hqT1`Q9!!NYjwKhAKsG*sIH*5F{)fxY!twxkslaI9Xv`i!^tIz`2agc!VL zQHt_xq+X|?WC}V#-q}DK%kk?i3s(VSnZ%x&HLf}UB7gj2g*T-vjZ;iDU!KZs4*7>9+2(1uy1L#y`RQEGHdB@G$jHBkKGk3h7w|Dwmf+3Y|B$b^ zo5BO_RbmAN1@OA@C#|hQFfo^(oA?iPob9~2+s5llcEH3gH{;b|8Ns9Q>MRH_hWS^gs zewHctNh@b(X*L>n*wTd)4jTXBib6L{^F@^0mtw^z3ua$NGzpkP9zs&r_}w?M6L=AY zfSF-USoQ89JWqTO#K`xR23-x4p=w+9KoGzwU- z(lOw*qN0MZloUohS5dLMF|$edcMn@m>FDZG?%YuXEd#1um$1WuyP~pEYFQKBSex0j z;!jJqzx4G(fwSf1=f{0cO{&E-A(ysNN=%G?W-2XGz+>&7zFN=EP0Qk~$hdd^{VOH_OS<%2626TA2QOc)V&j+2;Wd`z4tu3v|EGg= zld`h13tH>(4rTD#VZ)t|B@`7+Jj|jnRjW2?btrD+gShkUb3A#n=#}WWrRbk8GIR0q zErZE?6d{1Ok$|xCSQuptJ>8h{;MFT`op_o2TZ-~KcJLY+8m8;yDgKch_OD>lm#numY^=*O}UbgfT=}T*yPM$<;2ii%RrKn;`q$u=q3Vz+rqW-_uhff z<%or%UfdxeAssMM+*U&?dpwG<1n^h7RDBjJHoV*5Dt+B%qM^M#$`}VC877kz7 zd{YqoJtuNy+FDu{{9Qx^1((ap%HsVQ7Wcd!eSMx7_nn|K4v1(OcvH}GrXvB9UE1;5 zTLKwKFbmu~JnHf9JAUs^)P5N0*T4TA^tqKYnRROa_f%5^G6@5k) zH?k3ZiTyWs#6>HLO5Jn#u!y#fj(WU|z@KTaUQE$ognwbpi>GQBn?wGU2vH66z76j}X=!WQZ(f{{+f6 zG(P?)T|MIEO&d+zoCULi*LQ&?N3T&aciG9#%DV6P@lETwR}@%Qy|CA2z|mdi{tzQ% z)AZ!YlRXCxL^@v!@(6I6Z2NzP!QXUvym>XxqJ6^ftkTtIHrdVVa1HWs(IBb(q`wtMwiyA zWWVyxff>gn_}flzg=a-Rl#BnC>w~N@Vt8?`IB@8VY~J$A9ztIqzI`hI!~u8IuO}tp z4Z#>b5X{WJ4_K&`wKXFknx5X?y%rXtnC0=m4I`gVNE_=doCppMcKiNbX}zT6@R~Qm z{}PX+&!3O(J~PBHJUsjpOgEQ^NF-hxK2Z@~5mzX+Z5ucI0+72VW*F<{@cvN)VG0P# zjjSwj85s^RBg;8C<3)AF)~u1)MZ2$BljGrY&SM5Rdq`*~#v6lpXzA*beg;3_75ZaM zS)WY`F)%PpVk|($mBhq|$jFs=lL_EU01wQV<$+fVRa4kN+4g`Nk$%R^!qN#?r?@g5 zoT#<6HT>cMg-zh(+>AFeK}2Z)BQF2|!^`dQjuBcE$L}u++OUTG7TicV${)vHdv)KR z1+qD??)R>9q+Hg8Kcf~rsI{oIIe9`OQ78O5SGV(y)(YB0%Kd-;=cd3|pn_s_r%cG^ RGMEI0ztr`J1^cYd{SR?>>yH2c literal 0 Hc-jL100001 diff --git a/pdns/dnsdistdist/docs/imgs/DNSDistUDPDoT.png b/pdns/dnsdistdist/docs/imgs/DNSDistUDPDoT.png new file mode 100644 index 0000000000000000000000000000000000000000..8b5e99c3d27b1e919849bad5491a98983ac014f0 GIT binary patch literal 18235 zc-qyxcR1Hy{6DN@B;rkE6C&BkUdh|aD%lxPNMvMYmMuk+kr5%YjAU;@c9Olf?7heR zeAVZp&-Zs<*YCc5*Zs$R-L5NF-d^Xt&Uv2a^YMH<&UqdIH=6bAJ%&75Qq3u5VbIZ4P5n^f(2*%=%LLc(*Tu%*1W)>lu4KQ+ z-Y_$b{jif{$mG;!@@B@y!aDV4X|~aeflTdGnE!KD5@J@>H{sW=>E6Fhf8p7>cd5Gv zK1BzW<6{%%tm$!{U>siC>7lLWx6My%+Qhb=6Ww}LNo7^~cH^bL|4h(R|K?C`d}34x zw%V2{`lnnqw;UQxd2=uhb&K(I4Lu5FcFo>H2K|x=-wTaSI?;JRf#Q4p|H}p&H&sl)hi;!7(vvtXV1t5EUASZ=5akdJe*uyYHDk-^7He_uiVGA zc=Tv=Z0w|!mDTp%UgEv_AaV(J(UX{%JT_x!Z*T9rwa-bNjt;hRtcJy7#9YV8WMsY@ zbKT<|DiYF)iulANBq1>|FPb8_7{$bBdV6~>UAlyUaqiqXdJz$-U%!48y6#+g9U5x0 zIj{Zo>(>!zRlB<}hjj9m*VJfnplGJ+6V+nz9H-rU4=PbMxGs>Z-2YL3{^-{LlIIc> z>5Amo0seBB>3g{*9K5_F2JSl-r`qCzCB3k#>guq|oHwcyqyw`p2ZhlxG7LgO+VYPY z8X9^^9J#tO^#ZfAx!31=Nf6_RI&mZI21^{r;r%xrGKv|JGchm_q%O8a#cppqdHeY# zs>F#~J37{{|LVwj*m-%zPWT)dSvqHy1{M~U|I3%P>FOEWZo77cMMdwehRd}|op^|e ziPa*y=W+jCwk~$py@i5EK6A2|*w~ftQiO&(tCNDR+u5_9uiDIfzrcPcAOB!)%P%nS z%saPD?fL!!6?^R#&trEWW4mzS1lZZ9q(np}h&mux;t-a4;HF;qEn`ztSWX&p9-~vD zVqz#_V$V4DU3q(LGKGH)#2dIaT}Zc`vcABm={br?ZF6^AIJg=_Ba&Q=ePvD(7)1Ij(@+Leyol~0i*f4LL_gCtl^bzys*-k5q?#?8p zH{HB(yi~^J`>P5sXhbyZDeQ0%?{1Sg(zT~(JYJpT7a19BDwiKkW$Kk+J32ac8ed{O zo&+%ph0@9~@|nFNhp7U%CC^ZcYGF?4A^$1Csk&%(7OXYjY_7qCT6U}Ab*qM&IH&AE;-7u2#n&2}qFuV#6 zPcDALd^{iRQ0Gyf^UHBZ`?9$k0p+|hlWjSxI3NHtCFpZ_aJJxY8Y#D=LL-89Kx4YS$Pd`_CaxLlz2^JaKvC+ zLqpZdcs&mQ7o>!7K$O(ainnf|0Fze+Y}*VczJ(ABIY?<&Z{0mQJecV(;4(5YifWm} z^7+@Y=Bir*wuH)Y;-7vAoA2VYN$3wgww-FOdO^YaP?s4nxwW+wy6Cl?j5}JXr)$qO zRq5&NeXp6NzdaRgb(x)o!B^*bU|`POs*~G0J5`;Xq!%t+xWvkumc0)PJu*IyDIp=@ zy3wiWyYO>5PsDN2J0&G0`NH}{L+H%UG!i>unoRw&^j>GBx5xe%mDctIv#hMloZ8{h z$KMmxEExFJkyS z^j#R6rqO&)j+~N`w6n9Yr>AGO&3GMN6Bl5#fYs2~u1|N`ArWGiZI*2f)qt;lG$U73 zQ1D7gVM$0#v{@VwYUwg>Jodki=KY;DLt|qs78aK6-Q5I0w3&_+LYWuj&*J0hUDsL! zAO&Sl^?&-s`*GjNzG-r5D#5rZoHRV7zaD=GaM@|5!D0zWGNIcZuy0FaPJyt6`89Z#JSS zk6raDpVRW)p8kGK^4&N6q5R2;Z;jrFc{vW+pI=>DV-pRJiwlP2uIBWyxNR4*-tyX7 zhW*>VpLwo3)4{+4LKtPMTUrPJRP21pOvAcw51P(QO=*m;PA&zQH{(*0~2Agp`zKpcAWJ(8xF;%k6 zF|M>QF*A=r#MSFL4q}Ojh)9uJ440P~Qrv51cHitZU0JRnWaQyN?d_bKAydJ2MKOtT7Kc&vC5Jb!XKrgjWoI?|%5fg5O3>?VS7WFP8sd4~P2lohd4O zI&o^f5(hp-wd}k+AOFg_y5#E5T&2q=4-b|+%!?1^=PjBec`(Jr#UHdMV3n4Y{SJ9; zZEauUq^LFg*0;PVb!+%tvOAM(!|8X1&l|Wt(=T(b8XBS%bJ;}O*?lq8<0{`~pr)ZA z=-%RBWv%)rV+slj8}(!x`YM!l=EeG!YA7s~uAOC8iux)BNQ5Rxg7|)Or@+#1p)YUd z`+Ll~7ZkTguiOV>=n2RJbkb(BF$^zjZ!C~&c_LJW-@fSQDVbo}m!xbO%aH(^3D~ND zI&wSjM_@##^PIYXE&z}7^YcWcr0SDJFs;JE!mHA0Kflf|ETAYT8hXF}^WKbzSzk{o zHbFu1`e3^5)GJr8Ac<8m28(*8re1ny3UQVC3}T%x{n4duWmr-gNlD45kAaFc+biQa z584@ORy=##IgN{VRo&uic_ zUZ3BOaOxEgtlYHL8*&;aU^gfqNbQeLM$ys+O~-i*5n+4mOrGz&$Vc%fmM$$cTMicc zKuns6pVOsVTwIhXVW;GKxxQ}aOIo%R%`sV#e z@qBMC4sct`)rHp%zJzo^06iMGUM&HCo{jpl_OS8&$S%US#rNiUfd(+TLM9~_wtL`n z4~t8$IH~v}^Tj`@BhgXovY+Ris*VmGz~(tp(lkyVN_q(iy2HamUwR}S!FM~2`Go!q zocvSb6(8tZ&~AoE*ls4i82{nZiv3Bho}7Dr7jWxpYx$abNB^Xc@1%)9P_OQbi&JLBTxe>Kl4(=c?}2Ck#77f$?7lcd|1IXFIXpDP7Hq14s?Cf{l} zi1l`IDyP@Om7lj&3;}jYef=j^jsIY!wQTII-kaHBVPW!wSlzPv`n1=jq6x>mXgD{l69ol@zrX*rz0HN_$)r=aUx$bL0=I&6oN$9^;&crK z0wGlP4uauV&*>T*K_ITQ%hFW=E!G@RzoQ9k?7R;*qHUss&VJ! z+f#px`?IHgez2sQ0oG%#F^tVWIJiDu(u;_UEV($w#CWvY2kiEd=wxC-0ukh%H*d~C zQ~Wp2D#~ zHJf37Oo8##{gM+1rhlSK~W=Wt+Cqt}hMKg|eu~=IQuQ8CBQbzT$EA z?AdMzVauMLo{0j$qe37}=kI)ZaLeM}y-+JtQ^%UBs?n&##POs3gM)iWQ$Zo21ysmJ zLAStdv~QrC0IEo#eUB**U#g0V-{R(A!P_sOUI4lct30umH#TZPw5frb(0?*X3bcfg zo&96uP-S7EAhn2tqJ01}h?;1&Dau8Sm2@f z_R6I5g9i_WK+vuHN{M4&X2uQ(2#`}&uA6L%2zmD|2+#+VC=EXPWPXtSFw7h7TENqC z9GCPz>Xne4A!EM;jHrXa+X%`FpDH)ACLl0I_LzQ7}!}`UxJ=gryv{NuotEQDG+wm!i^LJ zKR-WNhQ_DMvGChuFE6RlLC0aY_s|eVRWVB#K5P8Nf1V_S3HA2QFQHBYp4_mgD7;u@ zKftT`p)x9PF`vXl#$@H#=itWaoNY-lf;J}+L4#=NX5Kb6Ax`egm+=sT2L}E|+s7@w z-1s^t!A}H!^!M+LhjZMS0{JUu`|HOCX+J_bjX{Sf1o+6f^mUz<%C=1Uz@J^5ofnBh zQ0WrZ>G2kq1hvtdH(C}FcjxYJa_Sb|CGUCxx#GctOT~^$K|luXL0)XxyiAdnmZp_! zLg2hH>*KOiR?zriqEUq?02aPB@Vt72g@d=@cU>Mjt-?cyrKR4!zNxe1-1KWew>k6H z4HLl+fzc$czxShU{F0Yf_G@Bd-3s+9rT9WrPOGZTrNVnOO&N!H+TK5Yr~;c|xNxD0 z2yfVJOHVP9`vfg5EwZ%(&}zA&+4Ak%w@R2N5ji<77Z(?@9|Sreo#zxY6B9iv>*)_4 zKBOxMD8RZY!@7yl2?`1}Z?3Ku|DJyN!DfGL_@S3UsCjp$;b5_SEiikPWIw-pX&fBC ziVVwWlO&5v+c9c1c$qI}vtCNGa&p%BoHNhpnGMrNs>-p#J`jTQFhMe5Vc|?N6jvvK$+M5>39K}iONIRD z6_?4_E?&gKA*4kE>iBT4w~8#?1?fN2o68at6GL?F-2K8$OH0el+0W)-p`l)M9{Zph zQMh<`p5R-~oAUu?9m$Aee&WFhk7b@3sq!lI^!J6;Q{$ogS*^PI%quv!EgT|1*BKPa z8K>3WzR8J+yF06sSRmUg>>vcJ$WS7k1P@LCephhVLk^SK(EK_!SZISOFE0-$j(8{V zu?zHWK>D2)^16wrsb7e@?N$O;J8|NKR`%T!2**Vf4-is|)u<-lvaR`Eug(n3af74X z^Tqaa*f=;i>kIwotE#FXe^r7Xn&W%4x3@#rUdkyoAkPIm`fy>?Ke_3yKJA^tG&P+T z(8;&Z1_Uo==%h;!(#bVZ3dzf}&&kM`yV3c`ESXZ|oGw+TL7>S+P;92HF+BK;5i|x` zhnrP6boA`(_z-h-V2$>2Hy3|gU&Hceii2+Jsqm0+nD2RpP>93*9c0S_021k2OI!QB z+ukNZDBiH%&bA)CZZT9^)FtL&Tz>-C$OXU<)3$ec+xM8%L6(PBxmuexGtdc&h)B#$ zOxWF98LKU&eT`jRUA?NOtD6aIzwPE=zR9(~_al9&hr(Cy2v`nOLP#Q;ZBqW}91j3~ z2*7J)AfioLqI^IJ-vc&`C^KIIDqn|%zN)r1LSTs24i3IAUlJ^qZRtbOtL*KifDb_r zNtHM(aJz0>*UTZ*L_62y!quzi0OhJT7y9S$-NO7l?im?b!`pO=?E+jdqQS#2*Sp4Z z+-|`sfA{X4>^tY#wD|-EUpEdw$h+0vr+cAaKk2Ws_EORG9DbhWiMtusFmBwqVZG4D z$Hc-izC2pv9}pmEVPTQya+c~bNr;HEo4w0njCC1)qYd zM4piirmaPq9PU5aKipfAlb4q?F=2LEF8Kv{l)2vZ`?}hM7X}qobm_Nma*J!~BXe05 zocVcqEvN%NyJ(>Kcl~V;D;M`R`1h2DD*>+{UVC<3DVz{2Tn92|*I7d&e0FQ#qw)Rw zmEGL}O+!P6rxW=Lb(F-AfKgJG`MQ~BQO(`M6iKM))xP#DH+L-;;?g74J#jrnK9u=j zbawWkYHq;Q_=gBWMMu5xUoh{5*qng|!M9eQWo22-fMm%^cehpRgpA-V$d(0;tD}BE#auM+o0S*dOfA{CpHSs*$bdhiCrZCw6V_tw# zOv{X;jL*&{YHe-Rl=gVSfBTmEB|)?e$IB1JX8*n*ug>+ZFJ%}ZV08HrFxWu#^C|>e z4J>izii?X6ACwM1bLK7hJ$H?N=dQ#<7n$Wd<&`7lcedrG-c`OKpwgE9-vk*CX@7o= z`Mrkn$NhhGy*o7)pfIFhU^H;hYBL zF%cm-7^9=3wV9cjOXNERqgW^*u5cb?ty|>(S?ko(Q-`H_~t&^!k~#6 z-^=mEPUY&)H-x$i3kzq|&&&4Z=H#%VLJSG^`>le0KlPOd#3c+F+yB#dCJ0<#i)^h($z$u0OGM$=i6gThH$^2Q>iwJkH*lqJT zyq#X0y<6v!7zg<2KJ&l6l64Z3b*mr>uoIL)qRZA|R91ga)Z;sOX|D-&_4JNhcGu02 zH^vCrW&_6)jtIR`mA!v3HfF@Gm5t%wFD)mB3qXCDy#!R@_V#uqWDWzj4fQbl z09=#i$oHcnyg`sft2;aS)X|_UBWCsitrabG?Ez;JkwbC?O^WQ|XE4{sY7z7AW}&x2E$U?sa=*JTB?cul_;q zY<^5>CY8haGnW449)%1HDbncf_fmdy>HXO+)Pyawm7@6tJq}&-n#j(duYoUX33_@A z;C^|TdtW9a+wi(^#86{SYjTetTF{s|$aSN2o^cTH9K}T(y^4H>XSLD!- zlO7IRE1<;%KDg3P9%|Uy+U7Vc=-^Xc{kE)i|2`A2NMB@cS4gxOcqbMXR$gWazzZ@u zhovFC(ISxsdy()>F*IuF6RVVn4y=LG}`nvx$YUehyad-qac$SJXP@}YSQkUe@v z#>87$pBBqm*&G#zu5L*ETMJN0gnA;oezeB6cYT;BWDCty`Avd;Oh7da-BBJ~B?YA6i5nsMsJ$35T$U?zz9dP|; z2?-1_5+1Z`Q!O=+X)U!f^Xs(p9+D!5t-58-q{zPh9jh`Q_k-Qexjc-Ku`$m?*e;23IMlR;;1;1=6EK{&f!FSm}u~?MoK`m?lQ&_@;3Dd{`yPFm=Ef4LlgR|bY) z{&mgz>Qqaae^PAK#RQ4aQ|JlLH~n*(%CBZ*Uks&B2~A<1QP&f<&dJRk&%@!k3E-fB zzVH2}g)Du>9`#nQp0I%lwR2-VH+Y!z;D|o@I6?jptr@{b?WnK2V057GOVKp7k%nlR zI|U($Hkz=n!0M<5)P;Jt3?;(UbqXxqW*nplQ3o~*FDDsxN1U#q-AO`78GbCB?J`wX z6S!zLgB(7Wl!)Y8^qw4P<1RFAA}cH^8ZB8WzpYJcrWmC{PR+@XlR(#A#L5u&T<#8s zMzibPCl8x&s#HW*(D}0`?msIbLm#If?nCI7*vw_r3p;w8To14=O+L_3RYW%TKyR#9duo zL@1DHQs}#Y%l`hjogYH#zOGi^J(DJknxMF6^=7B?@z1w}u)<_qck(~V*}u1&M(}BV zc6K-J@yo%Q9tkprD~jtRDmTy)D-$8iJtntr4#wO+g@BaFVQ*hwI%mL(YwRreoZ-bR zp5z2;&n8nf#j|sBo7xbH#y0p2LI^0!M1=W_t`Ht;afRMo?+CKC(>LU!3 z<4(S}f4p&1xK`2Q53{eo;eIXsy{gj4s(x4upqHrywn+J!koF8d{zT3R6N{0`X9DQ^ zk{{|cK3I&&m(H-fE4@4=u!8g$@@9c%LSM4!;?#L;zW{dzxsVwa&-rsNnLQso-KlKm zyF>?)tj_&#XSy~$Fxhu+CNUTfRIB^z=k+He8wuq_P})qp0W1=M?qdN3jh?ge_PNj} zjmWn$&v1oiMtq0Y=_HbeDrVArcg494UN+!p0O#(NmKGJQjG368uBolPn4t?UmgjdWBD$lcXf+lvoBYA~5-V%fTV7Kj zA_0(I>DV+rUIRYFtQ_NCS$XXRmB3jV5r?a~nT`LiYmvULSKr+Upg;d1fW`BHH`sCD zmN>AWvozdyuLaEtNZQYJXBh;AhIYJuOdzI(K9pGSz`zCp#9{D6DJ}?963!|V*;|XxsjTfIQLyvBO{|%k&*s@OvrvN zFsE;=tum65CotmU<1u=Bd*xJA>XH5An3xy2rftY3Gt#On%ODs!K?-Dmg-OHct-JLc z-y_o$bH1wYx*~1SpHIM|9CLHO;ij<>rJ;3kMFwrB%tLp)vzX0ZZy5oV(TU zTvr=P0Su0e(+c;x2e_!F85nGlAV`2UwNqCMoMpD`0vWwB8DU^_xW7Yw^#Kv6*Y6pc zTq%jG0|BUSZeK zt`D(E41qr(ZPtf)SW$04aImbCli=?9FHA>AN5wdCnhcFkp2{h_JL7wJcz8rqRDpmw zhVXl9TU)8&a1qOGx<(s{otV6#@7In4)qG5-3~~Q zPdXu48S@c5I?HQEHRq1fX4`!qz656ZO0KEFs$zdz;LNc59tV&^EK^fc(e>|ATIH@n zXX(U07PBi+3)|rWvP&Hu9)J&en#Q@2?QJgH*3-zPuOsww40xh^svU3b+371L;>!Sq zr`I+%CNG+uQ&3Rw3JzAu%*)%Ten{DOpiI^G0{{HM*U&pg1IUyIj4m=U-CZ0gLdwLx zg)pwH)YFas-b=rd{%4ODlTqfy)07mJ>({R@cc@6DaW)wRtW@7ERExnSHc48D#GJw; zX;<5cf9Wr3Y;GRC)v0N)A}WRFx-%J33rJVQaHU99itrrD;}c~cewdPI12Me)kTUa* zeeRu@tsxh}GM6nGm{kstiL2cil)5Dj1P~Ci748St!){xn2V29Mdar9yk80v;l}@!2 ztvxeRiY44fCsm}ROlQ4+|2{_kr?jUSg0%RyPARck6(Z`~Rf6%uJVj{*pS2=YAe)&MYXBFzOZS1m<2p zm2-1P$69lt&G_RT#;i{R1G+D0MEJX#n&!Uvi|V9>VAigh5KwhsCd4^CRtM*P7rqPg zK2YbrGdenIZEan-yD_I8VH6H33P(glgk7&#&7RdnVU`X%dJiI*hmQO$>y+0}0$s3s zOK8$I{YL0PW#kc0tvCzryi0|7RZxPKN%8wg8rUvs(Ha-Bte& z6>hUUqpcbIdARAwpRrD3dbG#2JNpCh1wq~%&?$4~Bcy-ijj;6X%#y{+_6`n1 z%<5E6zAdyB< zzL}X>dJ_+osvG%7QPlm!5O)JuLf)y@ggVa;sja=x6NaD+vM^7cR6Wn7uY3Pj%Jah8 z+S=Nz9Ip;S1{Z2Yv&G)Hu)mgFW*t zGKKx!XD-RZ!dh?4s&^Wk59NP6A$Rt)Kn`?d*c{1|-o$M--4@4n#w!Nbh%%CJw&C@v zBu+csSMp1{2?ks1>-&kI83npC_4+MTqLCs=KJ%`45aj}cgM&wG3|R^rB`!_k1)EC! z7HSQc3@5p`xL%O+ob1nkR0CRC&EutF-T$^y@J)EQ(dK;b^6IK*SeUvt`2?D%quTW* zfkG>eMgrZ#IW7;fqZlu*8cUG$r8so1%Tpkh6gUpNb15h&dOjN~fTDD>>g(^HMz&kX zLZ*|ZWELIwY;zy}=t_vfz(Ax`N}M|-Qt-p9^6rII`HswrfWjxP@@*s+ers%0)w_`! z9uo2lBpz~1oUU-|;m+#hgZ_LD^eJHN^%+^^c<~KcN{Soxu1}{T2tP_6Nj$4cpzEi7 zytnx|I=X)gl06pmB~VjceS>}S`r^vUidLbup$%Bgs;{qas-(Dhkt8G{X%`!s*iyLe z*FhwBI%1L1S`7#F#s{^3U!7Wq${oOD0u<#D*LHn3R9 zpwaY~FXI7}r1xiP2nh*o17M>7PFUhxSCc<|dX!UAvS-Dx`s`=Sa+4*dbW+wb9z*iS zx_p3BVPvZUgd!;avs$H2Ikkknj|K`+9mz_!^{~|$1qI2Y`5&q3`QCB^5`&A6kA{3R zIx*pGGhR13RvXC2$%XGV<-HS6F@w?;!86#+iCv$ za}Ebm4~qy&56VS`52?R>>73iM8Lh@bYK--Y?Ih#G-H@_qtv>1gU}~Xi`Uhk0+;`1> zpRZFy-B4DpgB*Jr^x+qaUScU<{HkDyL#?cCyqb6+Bk>2xJC%CqlM`)kd5r4`-&81( zglK}#SFEnA2>qI!jk>__pfg>45z=**awPYK=?@Y5mvwVZ2#_WJgZnzsKdWv9X;=OG_)X`$bGlLSnNzA&;CXi8#zxM)8?1|4`r}MY=Ps_CEa! zkgJ;I4*t#-lrBJxv{)lLwFCIF}9$EZ|li;aTt_S zFZAVk`N!*(IQRz8zr2X=6%KCo_Th!yKz7G-2dv_anFX4INBC+(jb~j6O7%=-Q7eUd z5^p7577GFTwkOKgK!^cJ*?H{P=66T|)=oNzouw?3xFQy1uV|cUP!U8x#UF1_ z;g0Oqka6i-e0H&+_1IrA@#rJA{aX#3+C?a_f76)Zo6ni^SBHbR@%dSrahNs}=*+iB zLn{2`SWrcp>k$urUEKAhr1wy6=M*teiQj)afHR<<*}c#`=;9*gQBV zdMS{0#NT5@9A&`YmpA*ZqMN^la#idT0})r(!ybGV!YDho)+V8;hmCRI=r&MjL(1$) zzPIXA%`MlAgVa+wXiUEFEeY`r=;0>x)jn=c4VR!QoPi9rFH`ge?F= zOq31w1=){mrUNslbcXOhL!>B$o_VN_Di-y-jC&COqZ z38v-zD^NyEdRQOAYMj_ka=B*5S6y$Hqqm1Bhs!FT@bEn{P2gVaoJ zwGThiP2b!4-yDTF>?9;GAV#AXswvQiMgBC`l+2P^g_IR+w zV&T;4?Np*!4@vIXO9r zP(6Kp2@vJXBLDS_j-NYg(>Zp(Q~|acxL24M8EcmJ5es#ss0ciW?R1kt%Ef0pGpP3a znwu2`MMS6;w-)-(-@0|n-qO781qH_X`_;IkeHNX(hgb#%2Hw8D38|^6`h1$3-4%zO z+|7p#EOGQ#ubw;F@;LHy+uJ;W!NACf)b(~3=@pf2Sp!rqudjdP_m`2Cr3&Ah&uzoN zsI9FJ`zOH*bCxwMNB=J|T`3wg;7316g`>eqPtGZ62s-FrEAM`__#} zl4H+$k!&#*;OF=Issg|k5pWMuU$eQy;~)*i7WL-hU?7nA z8taqO5eDuQz|l;~^4S=Wf}LdqxTvr@e*9Rj#3WQJ6s~U!W8-m{*GfuGW)KrY3SxT- zZSKX+eUyh~gap`L;o$)etxj>-(asKSVPO$F$HVgXazFqQdC+JEyvfVp&YKWi+JmAT~1!2+Af#Do?PGSgyQWzZw1X?mPP-I*7FmoQLtaLD~ z7zPHyBwJhS0CbI$kxqdi?+LJYHtib>-8f*I!D3h?KzLODvoG)OwGIM4Xw_W1kAb{m?+FK|9tn`RaO~plOE=r%Q zEko>g@9JEWSlf8-N1JYQ=bzelL;e-u_|J3h)iYeYh{ejv>NKBIPwCc7k1;<`M8e=H z=CY~wWFGubKvbjK!Msm@r(R-bf@Hw9O$@1l2k#DS6W?Rc)GvDuv}){A!O(T!&XoJK zjc;0*gPuRHR*^XP8Q&en_V@bC&of-5Pm#+14SoHGLf!f|Zr}lOVp~~R_4M?_1KY+W zAduGA*N@F|Td6&t;a#}e6cKA`4fKe#l~;>DqZ{BF*kPoEhkID>*Stpsp8-GL`uZshK!Ce|uMaws38-mkko#dZNin{qepmkQ zCGn~Tt}9sYTvz2gjpHG6Y;SZMs7Dyy`ls?;O~~Z?>*MQNT}hvFb4SOEhyo zTtvKlxiP^6zgy<-ouKp7)Gx;CgEKh2uG&p}Ly4|_V??Ub?d}_{sF2>rNdVxxJ^b6(XXd@IZH>rKK;xORXP`O_>sB%f;7P;zB|KMSX5-#_D(Fl$t)be z5lcly#dUkskJR(7t}ZpFLHWmG(a`_gSS)@#i8nSr&hy|qy|<4~8fS{OcA@nJFb11< zWoqiBul4ne7cWZNKVg>oJ9>wWS@jt^;r(&Cqo2G_7 z=g*%b*;Fc}136%;NsM=**0N+U*pi^fA4OmlY^=WrvCc0kSW>*37FO zbOtFZwyM0xHcs0 z^NVF$Lzg37vq?xY2@6x6=h9cx``n8<9u&iy@Nfnm9@Od6r+sfCT-*p$G`M2rs|!-u z04aeL4`pOzu=6c?Ju54(fw(Xn`x?;m#q9RW3)~kjoRF87hvcEISFHW_4sHT+kq&f# z|I3#?$|=03;*bi}0G4-8GcwrV1>)X*evI4)Yf~5)*t1A2z=aEv_C-<1Er*NCJYN}YRj&OAgI$D~8%%bdQ+LGXnWNm_>&IcQUweWQV&LS=yiV>s9qWi3cOya_ z6g4g$-W6RJ@J3Dh-n_5VESh9R=wLxfi<(!|5W&Xi_GzT^^Ctmqbe) z`>S>-m4GEu84b}3u;CvR#D6LYNEUWh*(Rl@msfj=3SCcsKO;Ro29RlFr~z5!yLdo! zl=N+Tv$ue_XM>CF&lwzDFR&a$E_{M^Vh|K02g%n1lYBYK1?vG_fB$7C=(tF2szdec z7?@gan3ym_=DJ5N!zogpy}tlF|C*K-IkFp9<%N?7WR?hJH}m}juSxSYYwO=v)RCfD z&@@O5Em9Bt^($Jp*zR;%TH3e9#_Ru{OM&*1Q&Or$c32`K{Xgitp zU;n9z_;#9G8X9DP=~w4^8nc#0s=S;=p5e^8wgB+)^^1oT{Xv*(i6RX5e5>Z?EvO;O zwsr&Jn&-PQ*#2P$&#>*q&AT&wDk>yknfyQ*3=$0?zKh&GYJ9`Gys{z*tdNM56bl16 zM+WkU1Dpjw=z^$dY3s(p{#u)_m=|B!VY@7ykAFNc@k{LNrQ<r zaZZB1Jk zJq$l4sEi3Re`. + +In addition to TCP fallback for DoH, 1.7.0 introduced two new notions: + + * TCP-only backends, for which queries will always forwarded over a TCP connection (see the `tcpOnly` parameter of :func:`newServer`) + * and DNS over TLS backends, for which queries are forwarded over a DNS over TLS connection (see the `tls` parameter of :func:`newServer`) + +To sum it up: + ++--------------+--------------------+---------------------------+----------------------+ +| Incoming | Outgoing (regular) | Outgoing (TCP-only, 1.7+) | Outgoing (TLS, 1.7+) | ++==============+====================+===========================+======================+ +| UDP | UDP | TCP | TLS | ++--------------+--------------------+---------------------------+----------------------+ +| TCP | TCP | TCP | TLS | ++--------------+--------------------+---------------------------+----------------------+ +| DNSCrypt UDP | UDP | TCP | TLS | ++--------------+--------------------+---------------------------+----------------------+ +| DNSCrypt TCP | TCP | TCP | TLS | ++--------------+--------------------+---------------------------+----------------------+ +| DoT | TCP | TCP | TLS | ++--------------+--------------------+---------------------------+----------------------+ +| DoH | **UDP** | TCP | TLS | ++--------------+--------------------+---------------------------+----------------------+ -- 2.47.3