MCPcopy Index your code
hub / github.com/cppla/moto / DialFast

Function DialFast

controller/direct.go:19–86  ·  view source on GitHub ↗

DialFast 实现简化版的 Happy Eyeballs,并记录拨号延迟。

(addr string)

Source from the content-addressed store, hash-verified

17
18// DialFast 实现简化版的 Happy Eyeballs,并记录拨号延迟。
19func DialFast(addr string) (net.Conn, error) {
20 start := time.Now()
21 host, port, err := net.SplitHostPort(addr)
22 if err != nil {
23 c, e := (&net.Dialer{Timeout: 3 * time.Second}).Dial("tcp", addr)
24 if e != nil {
25 return nil, e
26 }
27 return &dialConn{Conn: c, latency: time.Since(start)}, nil
28 }
29 if ip, perr := netip.ParseAddr(host); perr == nil {
30 target := net.JoinHostPort(ip.String(), port)
31 c, e := (&net.Dialer{Timeout: 3 * time.Second}).Dial("tcp", target)
32 if e != nil {
33 return nil, e
34 }
35 return &dialConn{Conn: c, latency: time.Since(start)}, nil
36 }
37 ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
38 defer cancel()
39 addrs, rerr := net.DefaultResolver.LookupIP(ctx, "ip", host)
40 if rerr != nil || len(addrs) == 0 {
41 c, e := (&net.Dialer{Timeout: 3 * time.Second}).Dial("tcp", addr)
42 if e != nil {
43 return nil, e
44 }
45 return &dialConn{Conn: c, latency: time.Since(start)}, nil
46 }
47 type result struct {
48 c net.Conn
49 err error
50 }
51 resCh := make(chan result, 1)
52 for i, ip := range addrs {
53 go func(delay int, ip net.IP) {
54 if delay > 0 {
55 select {
56 case <-time.After(time.Duration(delay) * 50 * time.Millisecond):
57 case <-ctx.Done():
58 return
59 }
60 }
61 d := &net.Dialer{Timeout: 2 * time.Second}
62 c, e := d.DialContext(ctx, "tcp", net.JoinHostPort(ip.String(), port))
63 if e == nil {
64 select {
65 case resCh <- result{c: c}:
66 cancel()
67 default:
68 _ = c.Close()
69 }
70 }
71 }(i, ip)
72 }
73 select {
74 case r := <-resCh:
75 if r.err != nil {
76 return nil, r.err

Callers 2

dialOneMethod · 0.85
outboundDialFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected