|
@@ -72,6 +72,15 @@ func tlsDialWithDialer(dialer *net.Dialer, network, addr string, config *tls.Con
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
+ // When we set up a TCP connection for hijack, there could be long periods
|
|
|
+ // of inactivity (a long running command with no output) that in certain
|
|
|
+ // network setups may cause ECONNTIMEOUT, leaving the client in an unknown
|
|
|
+ // state. Setting TCP KeepAlive on the socket connection will prohibit
|
|
|
+ // ECONNTIMEOUT unless the socket connection truly is broken
|
|
|
+ if tcpConn, ok := rawConn.(*net.TCPConn); ok {
|
|
|
+ tcpConn.SetKeepAlive(true)
|
|
|
+ tcpConn.SetKeepAlivePeriod(30 * time.Second)
|
|
|
+ }
|
|
|
|
|
|
colonPos := strings.LastIndex(addr, ":")
|
|
|
if colonPos == -1 {
|
|
@@ -140,6 +149,15 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in io.Rea
|
|
|
req.Host = cli.addr
|
|
|
|
|
|
dial, err := cli.dial()
|
|
|
+ // When we set up a TCP connection for hijack, there could be long periods
|
|
|
+ // of inactivity (a long running command with no output) that in certain
|
|
|
+ // network setups may cause ECONNTIMEOUT, leaving the client in an unknown
|
|
|
+ // state. Setting TCP KeepAlive on the socket connection will prohibit
|
|
|
+ // ECONNTIMEOUT unless the socket connection truly is broken
|
|
|
+ if tcpConn, ok := dial.(*net.TCPConn); ok {
|
|
|
+ tcpConn.SetKeepAlive(true)
|
|
|
+ tcpConn.SetKeepAlivePeriod(30 * time.Second)
|
|
|
+ }
|
|
|
if err != nil {
|
|
|
if strings.Contains(err.Error(), "connection refused") {
|
|
|
return fmt.Errorf("Cannot connect to the Docker daemon. Is 'docker -d' running on this host?")
|