// Package sockets provides helper functions to create and configure Unix or TCP sockets.
package sockets

import (
	"errors"
	"net"
	"net/http"
	"time"
)

const defaultTimeout = 10 * time.Second

// ErrProtocolNotAvailable is returned when a given transport protocol is not provided by the operating system.
var ErrProtocolNotAvailable = errors.New("protocol not available")

// ConfigureTransport configures the specified Transport according to the
// specified proto and addr.
// If the proto is unix (using a unix socket to communicate) or npipe the
// compression is disabled.
func ConfigureTransport(tr *http.Transport, proto, addr string) error {
	switch proto {
	case "unix":
		return configureUnixTransport(tr, proto, addr)
	case "npipe":
		return configureNpipeTransport(tr, proto, addr)
	default:
		tr.Proxy = http.ProxyFromEnvironment
		dialer, err := DialerFromEnvironment(&net.Dialer{
			Timeout: defaultTimeout,
		})
		if err != nil {
			return err
		}
		tr.DialContext = dialer.DialContext
	}
	return nil
}

// Package sockets provides helper functions to create and configure Unix or TCP sockets.
package sockets

import (
	"errors"
	"net"
	"net/http"
	"time"
)

// Why 32? See https://github.com/docker/docker/pull/8035.
const defaultTimeout = 32 * time.Second

// ErrProtocolNotAvailable is returned when a given transport protocol is not provided by the operating system.
var ErrProtocolNotAvailable = errors.New("protocol not available")

// ConfigureTransport configures the specified Transport according to the
// specified proto and addr.
// If the proto is unix (using a unix socket to communicate) or npipe the
// compression is disabled.
func ConfigureTransport(tr *http.Transport, proto, addr string) error {
	switch proto {
	case "unix":
		return configureUnixTransport(tr, proto, addr)
	case "npipe":
		return configureNpipeTransport(tr, proto, addr)
	default:
		tr.Proxy = http.ProxyFromEnvironment
		dialer, err := DialerFromEnvironment(&net.Dialer{
			Timeout: defaultTimeout,
		})
		if err != nil {
			return err
		}
		tr.DialContext = dialer.DialContext
	}
	return nil
}

--- 
+++ 
@@ -8,8 +8,7 @@
 	"time"
 )
 
-// Why 32? See https://github.com/docker/docker/pull/8035.
-const defaultTimeout = 32 * time.Second
+const defaultTimeout = 10 * time.Second
 
 // ErrProtocolNotAvailable is returned when a given transport protocol is not provided by the operating system.
 var ErrProtocolNotAvailable = errors.New("protocol not available")
Reduce default connection time to 10s (from 32s)

This helps to address https://github.com/docker/cli/issues/1739, where an
invalid `DOCKER_HOST` setting could result in a 64s delay (that's twice the
delay here because the client was trying to hit the `/_ping` endpoint twice,
which was addressed in https://github.com/moby/moby/pull/39206)

I made a previous attempt to fix this purely on the Docker cli side
(https://github.com/docker/cli/pull/1872) however that had the side effect of
adding the timeout across the board and not just for the dial phase, which
caused a regression for `docker logs -f` (https://github.com/docker/cli/issues/1892)
and so was reverted (https://github.com/docker/cli/pull/1893).

The new value of 10s is just based on a gut feeling, no initial connection
should be taking that long in the real world unless something about the network
link is pretty broken (e.g. bad dns perhaps), in which case affected users are
surely pretty used to retrying things, better to fail faster in the normal case.

Also drop the comment since the linked issue just shows that the original
number, just like the new number, was arrived at fairly arbitrarily based on
gut feelings (rather than anything empirical) so the reference is not really
terribly useful.

Signed-off-by: Ian Campbell <a8db091655a7f47ecb9c39a2d278e9662e440dc0@docker.com>
