Subject: [v6ops] Open-Source Happy Eyeballs Implementation in Erlang

From: Simon Perreault <[email-masked]>
Date: Tue, 01 Mar 2011 07:38:23 -0500

Hi,

I made an implementation of Happy Eyeballs in Erlang. This programming
language makes it very easy to express asynchronous algorithms. Total
lines of code are less than 100. So I think it is perfect for
early-stage experimentation and tweaking algorithms. Maybe it could even
be considered the "reference" implementation, or included in an appendix
since it is so short.

Full announcement:
http://www.viagenie.ca/news/index.html#happy_eyeballs_erlang

Code:
http://www.viagenie.ca/ipv6/he-0.1.tar.gz

See the README file for instructions.

Doing this, I found two bugs with the spec:

Bug #1: An application-wide P value is a broken idea. Today, most
servers are IPv4-only. This means that as we establish connections and
IPv4 "wins", P will decrease to the minimum value. This will cause IPv6
to not win when attempting a connection to a dual-stack server.

In the future, when the situation is reversed and IPv6 is prevalent, P
will tend to increase to the maximum value, and IPv4 will almost never
be used. Some would consider this a good thing, but it effectively makes
happy eyeballs useless.

I thought that we could simply not update P when connecting to a
single-stack server. But it turns out that we don't know if a server is
single- or dual-stack when we just go with the first attempt without
even having started resolving for the other address family.

So I suggest removing the application-wide P value. Relying only on
per-destination P values along with a reasonable default (e.g. favour
IPv6 by 100m) works just fine.

Bug #2: When resolution fails for an address family, we should start
resolving for the other address family right away. E.g. if we favour
IPv6 by 100ms and we receive an empty answer section within 20ms,
there's no point waiting another 80ms before resolving for IPv4.

Simon
-- 
DTN made easy, lean, and smart --> http://postellation.viagenie.ca
NAT64/DNS64 open-source        --> http://ecdysis.viagenie.ca
STUN/TURN server               --> http://numb.viagenie.ca

---

From: Scott W Brim <[email-masked]>
Date: Tue, 1 Mar 2011 08:27:31 -0500

In an environment with v4 and dual-stack, it is difficult to move
aggressively to v6 ... but consider what an average user would do in that
situation, without happy eyeballs: just use v4 for everything.  Also, when
v6 wins, the algorithm aggressively moves back toward zero (and then slowly
out to favor v6).  Finally, most users connect to a cacheable number of
sites, so the destination-specific P value will dominate the app-specific
one.  So I see the draft as written as a conservative approach.  You could,
perhaps, add configuration to "seed" P values for specific destinations, or
even prefixes, to favor v6 (but allowing the algorithm to adjust P over
time).

> there's no point waiting another 80ms before resolving for IPv4.

Good.

Scott

---

From: Simon Perreault <[email-masked]>
Date: Tue, 01 Mar 2011 08:38:48 -0500

On 2011-03-01 08:27, Scott W Brim wrote:
> aggressively to v6 ... but consider what an average user would do in
> that situation, without happy eyeballs: just use v4 for everything.

I'm not following you. In a dual-stack environment, most current apps
prefer IPv6. If IPv6 times out, they try IPv4.

> Also, when v6 wins, the algorithm aggressively moves back toward zero
> (and then slowly out to favor v6).

The point is that once P reaches "favour IPv4 by 4 seconds", IPv6 will
*never* win unless when connecting to an IPv6-only server. That's not
helping the transition to IPv6.

> Finally, most users connect to a
> cacheable number of sites, so the destination-specific P value will
> dominate the app-specific one.

That's true. But the app-specific one will inherit from the global one,
and then it will continue the same behaviour: IPv4 will always win.

Initially my implementation had a global P. I quickly saw that it does
not work. IPv4 always wins. So practice agrees with theory.

Simon

---

From: Erik Kline <[email-masked]>
Date: Tue, 1 Mar 2011 22:44:44 +0900

> helping the transition to IPv6.

So in a world where only a small percentage of the destinations even
have AAAAs the application P value will be so heavily IPv4-dominant
that the poor one off destinations that are dualstacked will never see
IPv6 traffic?  If I understand you correctly I agree, this would make
IPv6 deployment nearly pointless.

---

From: Andrew Yourtchenko <[email-masked]>
Date: Tue, 1 Mar 2011 14:34:23 +0100 (CET)

Hi Simon,

thanks! This looks very cool! ('erl -make' dumps with "init terminating in 
do_boot" on two of my machines with ubuntu, so it looks like I've some 
environment problem - I'll try on a different box later tonight and try to hack 
on it a bit. Barring that, some comments below inline in just english)

> IPv6 by 100m) works just fine.

What about this: if we did not even start the resolution for the other AF, and 
the first connection already finished - should kick off that the name 
resolution alone - and see if it succeeds before updating P ? (this would 
resolve the single-stack/dual-stack question - and then would avoid updating 
the P for single-stack hosts *or* broken DNS ?)

> there's no point waiting another 80ms before resolving for IPv4.

Agreed. And then if we were to go with the above logic and keep global P - we 
would not need to touch it *and* would fall back pretty quick too ?

cheers,
andrew

> _______________________________________________
> v6ops mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/v6ops
>

---

From: Simon Perreault <[email-masked]>
Date: Tue, 01 Mar 2011 08:45:42 -0500

> IPv6 deployment nearly pointless.

Yes, you got it exactly right.

Thanks,
Simon

---

From: Simon Perreault <[email-masked]>
Date: Tue, 01 Mar 2011 08:53:56 -0500

On 2011-03-01 08:34, Andrew Yourtchenko wrote:
> thanks! This looks very cool! ('erl -make' dumps with "init terminating
> in do_boot" on two of my machines with ubuntu, so it looks like I've
> some environment problem - I'll try on a different box later tonight and
> try to hack on it a bit.

Yeah, I did not test on Ubuntu, but it definitely looks like something
is odd with your environment.

> What about this: if we did not even start the resolution for the other
> AF, and the first connection already finished - should kick off that the
> name resolution alone - and see if it succeeds before updating P ? (this
> would resolve the single-stack/dual-stack question - and then would
> avoid updating the P for single-stack hosts *or* broken DNS ?)

Good idea. That's exactly the kind of experiment I want to make quickly
feasible with an Erlang implementation! :)

Simon

---

From: Simon Perreault <[email-masked]>
Date: Tue, 01 Mar 2011 08:59:16 -0500

On 2011-03-01 08:34, Andrew Yourtchenko wrote:
> ('erl -make' dumps with "init terminating in do_boot" on two of my
> machines with ubuntu, so it looks like I've some environment problem

Try this:

sudo apt-get install erlang-tools

Simon

---

From: Andrew Yourtchenko <[email-masked]>
Date: Tue, 1 Mar 2011 15:44:04 +0100 (CET)

> sudo apt-get install erlang-tools

That works, thanks a lot!

Strange that it complained about max/2 not being there, so I had to 
roll in my own:

--- a/he.erl
+++ b/he.erl
@@ -29,6 +29,13 @@
  -module(he).
  -export([new/0, new/1, connect/3]).

+% For some odd reason it complained about not having max/2. Here's my own.
+max(X, Y) ->
+  if
+    X > Y -> X;
+    true -> Y
+  end.
+
  % Constructs a Happy Eyeballs "instance" which holds state across connections.
  % This state consists of per-destination P values. The default P value is 10,
  % meaning that IPv6 is favoured by 100ms.

Now it seems the erlang that the apt-get installs has the IPv6 support disabled ;-)

$ erl -noinput -s he_test

=ERROR REPORT==== 1-Mar-2011::15:25:03 ===
Error in process <0.35.0> with exit value: 
{{badmatch,{error,eafnosupport}},[{he,'-connect_loop/5-fun-1-',3}]}

I wonder if the shot I found in 
http://forum.trapexit.org/viewtopic.php?p=43831&sid=e0e7e2a21acf53f391b43429de0df828 
is somewhere close - and together with the missing max/2 it may point that 
R13B03 is too old for IPv6 tricks ?

cheers,
andrew

---

From: Simon Perreault <[email-masked]>
Date: Tue, 01 Mar 2011 10:05:51 -0500

On 2011-03-01 09:44, Andrew Yourtchenko wrote:
> is somewhere close - and together with the missing max/2 it may point
> that R13B03 is too old for IPv6 tricks ?

Yuck!

I tested on Fedora 14, which comes with R14B. Maybe the syntax is
different. The release notes do contain some IPv6-related changes. *sigh*

Simon

---

From: Javier Ubillos <[email-masked]>
Date: Tue, 01 Mar 2011 18:50:09 +0100

> feasible with an Erlang implementation! :) 

We chose to do resolutions simultaneously. If we only get one reply, we
don't do happy-eye balls and hence don't consider P.

Is there a particular reason to why resolutions should be done
separately (other than that "the spec says so") ?

// Javier

---

From: "Dan Wing" <[email-masked]>
Date: Tue, 1 Mar 2011 10:28:34 -0800

> -----Original Message-----
> From: [email-masked] [mailto:[email-masked]] On Behalf
> Of Javier Ubillos
> Sent: Tuesday, March 01, 2011 9:50 AM
> To: IPv6 Ops WG
> Subject: Re: [v6ops] Open-Source Happy Eyeballs Implementation in
> Erlang
> 
> > > AF, and the first connection already finished - should kick off
> that
> > the

Primarily a concern about local RFC4074 broken resolvers.

-d

---

From: "Dan Wing" <[email-masked]>
Date: Tue, 1 Mar 2011 10:29:31 -0800

> Of Erik Kline
> Sent: Tuesday, March 01, 2011 5:45 AM
> To: Simon Perreault
> Cc: Andrew Yourtchenko; IPv6 Ops WG; Scott W Brim

So, "P" should be prevented from trending towards IPv4 more than 
<some_number> milliseconds.

-d