<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
{mso-style-priority:34;
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.5in;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
span.EmailStyle20
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
/* List Definitions */
@list l0
{mso-list-id:603612119;
mso-list-template-ids:-483368878;}
@list l0:level1
{mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level2
{mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level3
{mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level4
{mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level5
{mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level6
{mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level7
{mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level8
{mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level9
{mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1
{mso-list-id:1433083647;
mso-list-template-ids:-1259578880;}
@list l1:level1
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l1:level2
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l1:level3
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l1:level4
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l1:level5
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l1:level6
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l1:level7
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l1:level8
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l1:level9
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l2
{mso-list-id:2121795226;
mso-list-template-ids:-6651688;}
@list l2:level1
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l2:level2
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l2:level3
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l2:level4
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l2:level5
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l2:level6
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l2:level7
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l2:level8
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l2:level9
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
ol
{margin-bottom:0in;}
ul
{margin-bottom:0in;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="#0563C1" vlink="#954F72" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal">Hi Brad,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Thanks for reply. A few comments.<br>
<br>
> Infact, happyeyeballs itself doesn't always do parallel connection attempts, its an implementation-defined delay before also attempting the next address in the list.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">In case of Happy Eyeballs, a delay between IPv4 and IPv6 connections is constant and typically relatively short – 200-300ms.<br>
But non-functional IPv6 name servers in the server list may create dynamic delays in connection establishment which can be very large.<br>
<br>
<o:p></o:p></p>
<p class="MsoNormal">By default, c-ares uses 5s timeout per name server, so it may take 5s and more (if several IPv6 name servers are in the list) to get to the connection Happy Eyeballs thus taking much more than expected 200-300ms.<o:p></o:p></p>
<p class="MsoNormal"><br>
> It would be much easier to stay closer to happy eyeballs and just sort the dns server list using prior result success/fail (even upfront sorting using some algorithm to interleave ipv6/ipv4 in a pattern would help,
<o:p></o:p></p>
<p class="MsoNormal">> maybe with using logic such as from RFC6724 sec 2.1 like we do in ares_getaddrinfo for returned addresses, but instead of the nameservers themselves).
<br>
<br>
Yes, of course, it is possible that c-ares client can implement some kind of name server sorting/filtering logic outside of c-ares and just pass a list of “good” name servers to c-ares, but in this case it has to be more involved into the name resolution business
than it would be desired.<br>
<br>
A cross-platform client will have to implement a multi-platform logic to get a list of name servers like c-ares, thus potentially duplicating the code doing the same thing, and then also implement a mechanism of checking and filtering out bad servers to create
a list of good servers to feed it to c-ares or some c-ares client application.<br>
<br>
In my opinion, this is too much complexity to ask from a resolver client, which only desires to get host name resolutions from the resolver relying on the resolver to do it using the best and the fastest way.<br>
<br>
Using parallel DNS requests for IPv4 and IPv6 stacks in c-ares will help to avoid complicated workarounds in all clients trying to resolve dual-stack issues,<o:p></o:p></p>
<p class="MsoNormal">and option to use parallel requests for all servers in the list will help to address a general problem of bad name servers going before good ones.<br>
<br>
I think these issues are quite common, so I thought that it would be a good c-ares extension to provide an option to deal more easily with bad name servers for its clients using parallel approach.<br>
<br>
Thanks,<br>
Dmitry Karpov<br>
<br>
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b>From:</b> Brad House <brad@brad-house.com> <br>
<b>Sent:</b> Tuesday, January 18, 2022 2:56 PM<br>
<b>To:</b> c-ares discussions <c-ares@lists.haxx.se><br>
<b>Cc:</b> Dmitry Karpov <dkarpov@roku.com><br>
<b>Subject:</b> Re: Feature request for parallel queries for name servers from different protocol families (IPv4 vs IPv6)<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-bottom:12.0pt">We would certainly take patches to accomplish something like this. I'm not sure how easy it would be to work the internals of c-ares to understand parallel nameservers for the same query, it would probably
be a substantial change though. <br>
<br>
Also, I'm also not sure how "friendly" it is to actually perform the requests in parallel at all times.
<br>
<br>
Infact, happyeyeballs itself doesn't always do parallel connection attempts, its an implementation-defined delay before also attempting the next address in the list. It also has you maintain a feedback loop in order to sort known bad addresses to be least prefered.
It would be much easier to stay closer to happy eyeballs and just sort the dns server list using prior result success/fail (even upfront sorting using some algorithm to interleave ipv6/ipv4 in a pattern would help, maybe with using logic such as from RFC6724
sec 2.1 like we do in ares_getaddrinfo for returned addresses, but instead of the nameservers themselves).
<br>
<br>
Obviously, if you're using something that isn't maintaining state, the feedback loop won't help, but maybe the pre-sorting suggestion would. Assuming you're using libcurl, and not a stateless command line curl, I think it would ultimately accomplish your goal.<br>
<br>
-Brad<o:p></o:p></p>
<div>
<p class="MsoNormal">On 1/18/22 4:23 PM, Dmitry Karpov via c-ares wrote:<o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">Hello,<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">Using libcurl with c-ares for dual-stack scenarios, I observed that c-ares doesn’t distinguish between IPv4 and IPv6 nameservers in the name server list (i.e. listed in resolv.conf on Linux systems) and iterates through them sequentially.<br>
Such approach creates problems for dual-stack systems, when one stack is either not fully functional or have not responding/reachable name servers put on top of the list.
<br>
<br>
In such scenarios, problems with one stack (i.e. IPv6) may create name resolution delays and timeouts for the other fully functional stack (i.e. IPv4) if name servers from the not functioning stack go before the good stack like:<br>
<br>
<br>
<o:p></o:p></p>
<p class="MsoNormal">[IPv6 - BAD]<o:p></o:p></p>
<p class="MsoNormal">2001:4860:4860::8888<o:p></o:p></p>
<p class="MsoNormal">2001:4860:4860::8844<br>
[IPv4 - GOOD]<o:p></o:p></p>
<p class="MsoNormal">8.8.8.8<o:p></o:p></p>
<p class="MsoNormal">8.8.4.4<br>
<br>
In this scenario, it will take two resolution timeouts for bad IPv6 name servers before good IPv4 name servers are reached, and this negatively impacts Happy Eyeball implementations in client applications (i.e. libcurl) which have to wait for too long before
they can start dual-stack connections.<br>
<br>
So here is the feature request which should help dual-stack client applications to work more efficiently when name servers from not functioning stack are listed before name servers from a good stack:<o:p></o:p></p>
<ol style="margin-top:0in" start="1" type="1">
<li class="MsoListParagraph" style="margin-left:0in;mso-list:l0 level1 lfo3">Split the flat name server list for both stacks into two lists for each stack.<o:p></o:p></li><li class="MsoListParagraph" style="margin-left:0in;mso-list:l0 level1 lfo3">Execute parallel DNS queries for each stack list, iterating each stack list sequentially as it is currently done for the whole dual-stack list.<o:p></o:p></li><li class="MsoListParagraph" style="margin-left:0in;mso-list:l0 level1 lfo3">Return the result whichever comes first.<o:p></o:p></li></ol>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">This feature request can be also considered in a broader scope:<o:p></o:p></p>
<ol style="margin-top:0in" start="4" type="1">
<li class="MsoListParagraph" style="margin-left:0in;mso-list:l0 level1 lfo3">Run parallel queries for each name server in the dual-stack list regardless of whether it is IPv4 or IPv6 address.<o:p></o:p></li><li class="MsoListParagraph" style="margin-left:0in;mso-list:l0 level1 lfo3">Return the result whichever comes first.<o:p></o:p></li></ol>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">Such broader scope will also allow to skip over bad name servers and get host resolution results much more quickly even for the same stack (i.e. when name server list for a single stack contains some not responding name servers at the top).<br>
But in this case, it should be probably controlled by some new c-ares option, so the current sequential approach may be enforced if needed.<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">Thanks,<br>
Dmitry Karpov<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"><br>
<br>
<o:p></o:p></p>
</blockquote>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</body>
</html>