<pre class="notranslate">Forking this from <a href="https://golang.org/issue/3610" rel="nofollow">issue #3610</a>.

My experiments show that net.Dial has two modes of operation when connecting to a
dual-stack hostname:

1. By default, it prefers IPv4 :(
2. When using a net.Dialer{DualStack: true}, IPv4 and IPv6 SYNs are sent simultaneously,
and the resulting address family is unpredictable.

The latter violates a "MUST" in the Happy Eyeballs RFC:
<a href="http://tools.ietf.org/html/rfc6555#section-4.1" rel="nofollow">http://tools.ietf.org/html/rfc6555#section-4.1</a>

This is harmful for two reasons:
- It increases server load in the common case, by always sending two SYNs.
- Dual-stack clients cannot reliably use IPv6 to route around NATs.  The primary
incentive for a network operator to deploy IPv6 is to reduce NAT load (and therefore
save money), but this sort of client behavior invalidates that incentive.</pre>
<pre class="notranslate">The following program fails with gc but succeeds with 'ssadump -run', because gc is
computing the initialization order incorrectly.

---------------

package main

// The package-level var initialization dependency graph contains the           
// following edges:                                                             
//      order     -&gt; makeOrder                                                  
//      makeOrder -&gt; b                                                          
//      makeOrder -&gt; a                                                          
// Since a and b are incomparable in this partial order, we initialize          
// them in lexical order, a before b.  The total order of                       
// initialization is thus: [a, b, order].                                       
//                                                                              
// ssadump -run succeeds but go run fails.                                      
//                                                                              
// Interestingly, reversing the order of {b, a} in makeOrder (and {1,           
// 0} in the assertion) causes it to succeed with both tools, meaning           
// that gc uses the lexical order of the references within makeOrder,           
// not the lexical order of the declarations of a and b, to resolve             
// incomparability.                                                             

var counter int

func next() int {
        c := counter
        counter++
        return c
}

func makeOrder() [2]int {
        return [2]int{b, a}
}

var order = makeOrder()

func main() {
        if order != [2]int{1, 0} {
                panic(order) // gc panics (got {0, 1})                          
        }
}

var a, b = next(), next() // 0, 1                                               

---------------


(Again I feel a vague sense of deja vu, but couldn't find a duplicate report.)</pre>