Avoid TIME_WAIT leaking connections
This commit is contained in:
@@ -91,7 +91,8 @@ func (f *localCachedFactory) GetForInstance(instance *types.Instance) (DockerApi
|
|||||||
Timeout: 1 * time.Second,
|
Timeout: 1 * time.Second,
|
||||||
KeepAlive: 30 * time.Second,
|
KeepAlive: 30 * time.Second,
|
||||||
}).DialContext,
|
}).DialContext,
|
||||||
Proxy: http.ProxyURL(proxyUrl),
|
MaxIdleConnsPerHost: 5,
|
||||||
|
Proxy: http.ProxyURL(proxyUrl),
|
||||||
}
|
}
|
||||||
if tlsConfig != nil {
|
if tlsConfig != nil {
|
||||||
transport.TLSClientConfig = tlsConfig
|
transport.TLSClientConfig = tlsConfig
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
|
|
||||||
@@ -34,11 +35,12 @@ type proxyRouter struct {
|
|||||||
keyPath string
|
keyPath string
|
||||||
director Director
|
director Director
|
||||||
closed bool
|
closed bool
|
||||||
httpListener net.Listener
|
httpListener *net.TCPListener
|
||||||
udpDnsServer *dns.Server
|
udpDnsServer *dns.Server
|
||||||
tcpDnsServer *dns.Server
|
tcpDnsServer *dns.Server
|
||||||
sshListener net.Listener
|
sshListener net.Listener
|
||||||
sshConfig *ssh.ServerConfig
|
sshConfig *ssh.ServerConfig
|
||||||
|
dialer *net.Dialer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *proxyRouter) Listen(httpAddr, dnsAddr, sshAddr string) {
|
func (r *proxyRouter) Listen(httpAddr, dnsAddr, sshAddr string) {
|
||||||
@@ -52,8 +54,11 @@ func (r *proxyRouter) ListenAndWait(httpAddr, dnsAddr, sshAddr string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *proxyRouter) listen(wg *sync.WaitGroup, httpAddr, dnsAddr, sshAddr string) {
|
func (r *proxyRouter) listen(wg *sync.WaitGroup, httpAddr, dnsAddr, sshAddr string) {
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr("tcp", httpAddr)
|
||||||
l, err := net.Listen("tcp", httpAddr)
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
l, err := net.ListenTCP("tcp", tcpAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -61,10 +66,12 @@ func (r *proxyRouter) listen(wg *sync.WaitGroup, httpAddr, dnsAddr, sshAddr stri
|
|||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
for !r.closed {
|
for !r.closed {
|
||||||
conn, err := r.httpListener.Accept()
|
conn, err := r.httpListener.AcceptTCP()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
conn.SetKeepAlive(true)
|
||||||
|
conn.SetKeepAlivePeriod(3 * time.Minute)
|
||||||
go r.handleConnection(conn)
|
go r.handleConnection(conn)
|
||||||
}
|
}
|
||||||
wg.Done()
|
wg.Done()
|
||||||
@@ -333,7 +340,7 @@ func (r *proxyRouter) handleConnection(c net.Conn) {
|
|||||||
log.Printf("Error directing request: %v\n", err)
|
log.Printf("Error directing request: %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
d, err := net.Dial("tcp", dstHost.String())
|
d, err := r.dialer.Dial("tcp", dstHost.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error dialing backend %s: %v\n", dstHost.String(), err)
|
log.Printf("Error dialing backend %s: %v\n", dstHost.String(), err)
|
||||||
return
|
return
|
||||||
@@ -358,7 +365,7 @@ func (r *proxyRouter) handleConnection(c net.Conn) {
|
|||||||
log.Printf("Error directing request: %v\n", err)
|
log.Printf("Error directing request: %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
d, err := net.Dial("tcp", dstHost.String())
|
d, err := r.dialer.Dial("tcp", dstHost.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error dialing backend %s: %v\n", dstHost.String(), err)
|
log.Printf("Error dialing backend %s: %v\n", dstHost.String(), err)
|
||||||
return
|
return
|
||||||
@@ -423,10 +430,11 @@ func proxySsh(reqs1, reqs2 <-chan *ssh.Request, channel1, channel2 ssh.Channel)
|
|||||||
|
|
||||||
func proxyConn(src, dst net.Conn) {
|
func proxyConn(src, dst net.Conn) {
|
||||||
errc := make(chan error, 2)
|
errc := make(chan error, 2)
|
||||||
cp := func(dst io.Writer, src io.Reader) {
|
cp := func(dst net.Conn, src net.Conn) {
|
||||||
_, err := io.Copy(dst, src)
|
_, err := io.Copy(dst, src)
|
||||||
errc <- err
|
errc <- err
|
||||||
}
|
}
|
||||||
|
|
||||||
go cp(src, dst)
|
go cp(src, dst)
|
||||||
go cp(dst, src)
|
go cp(dst, src)
|
||||||
<-errc
|
<-errc
|
||||||
@@ -450,5 +458,13 @@ func NewRouter(director Director, keyPath string) *proxyRouter {
|
|||||||
|
|
||||||
sshConfig.AddHostKey(private)
|
sshConfig.AddHostKey(private)
|
||||||
|
|
||||||
return &proxyRouter{director: director, sshConfig: sshConfig}
|
return &proxyRouter{
|
||||||
|
director: director,
|
||||||
|
sshConfig: sshConfig,
|
||||||
|
dialer: &net.Dialer{
|
||||||
|
Timeout: 30 * time.Second,
|
||||||
|
KeepAlive: 30 * time.Second,
|
||||||
|
DualStack: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user