Avoid TIME_WAIT leaking connections

This commit is contained in:
Jonathan Leibiusky @xetorthio
2017-08-21 15:12:53 -03:00
parent e00dfb638b
commit 2549d64b8b
2 changed files with 26 additions and 9 deletions

View File

@@ -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

View File

@@ -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,
},
}
} }