diff options
Diffstat (limited to 'libgo/go/net/dial.go')
-rw-r--r-- | libgo/go/net/dial.go | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/libgo/go/net/dial.go b/libgo/go/net/dial.go index 6304818bf1..e6f0436cdd 100644 --- a/libgo/go/net/dial.go +++ b/libgo/go/net/dial.go @@ -44,6 +44,12 @@ type Dialer struct { // destination is a host name that has multiple address family // DNS records. DualStack bool + + // KeepAlive specifies the keep-alive period for an active + // network connection. + // If zero, keep-alives are not enabled. Network protocols + // that do not support keep-alives ignore this field. + KeepAlive time.Duration } // Return either now+Timeout or Deadline, whichever comes first. @@ -112,9 +118,8 @@ func resolveAddr(op, net, addr string, deadline time.Time) (netaddr, error) { // "unixpacket". // // For TCP and UDP networks, addresses have the form host:port. -// If host is a literal IPv6 address or host name, it must be enclosed -// in square brackets as in "[::1]:80", "[ipv6-host]:http" or -// "[ipv6-host%zone]:80". +// If host is a literal IPv6 address it must be enclosed +// in square brackets as in "[::1]:80" or "[ipv6-host%zone]:80". // The functions JoinHostPort and SplitHostPort manipulate addresses // in this form. // @@ -162,9 +167,19 @@ func (d *Dialer) Dial(network, address string) (Conn, error) { return dialMulti(network, address, d.LocalAddr, ras, deadline) } } - return dial(network, ra.toAddr(), dialer, d.deadline()) + c, err := dial(network, ra.toAddr(), dialer, d.deadline()) + if d.KeepAlive > 0 && err == nil { + if tc, ok := c.(*TCPConn); ok { + tc.SetKeepAlive(true) + tc.SetKeepAlivePeriod(d.KeepAlive) + testHookSetKeepAlive() + } + } + return c, err } +var testHookSetKeepAlive = func() {} // changed by dial_test.go + // dialMulti attempts to establish connections to each destination of // the list of addresses. It will return the first established // connection and close the other connections. Otherwise it returns @@ -172,7 +187,6 @@ func (d *Dialer) Dial(network, address string) (Conn, error) { func dialMulti(net, addr string, la Addr, ras addrList, deadline time.Time) (Conn, error) { type racer struct { Conn - Addr error } // Sig controls the flow of dial results on lane. It passes a @@ -184,7 +198,7 @@ func dialMulti(net, addr string, la Addr, ras addrList, deadline time.Time) (Con go func(ra Addr) { c, err := dialSingle(net, addr, la, ra, deadline) if _, ok := <-sig; ok { - lane <- racer{c, ra, err} + lane <- racer{c, err} } else if err == nil { // We have to return the resources // that belong to the other @@ -195,22 +209,18 @@ func dialMulti(net, addr string, la Addr, ras addrList, deadline time.Time) (Con }(ra.toAddr()) } defer close(sig) - var failAddr Addr lastErr := errTimeout nracers := len(ras) for nracers > 0 { sig <- true - select { - case racer := <-lane: - if racer.error == nil { - return racer.Conn, nil - } - failAddr = racer.Addr - lastErr = racer.error - nracers-- + racer := <-lane + if racer.error == nil { + return racer.Conn, nil } + lastErr = racer.error + nracers-- } - return nil, &OpError{Op: "dial", Net: net, Addr: failAddr, Err: lastErr} + return nil, lastErr } // dialSingle attempts to establish and returns a single connection to |