Skip to content

Commit

Permalink
Avoid TIME_WAIT leaking connections
Browse files Browse the repository at this point in the history
  • Loading branch information
xetorthio committed Aug 21, 2017
1 parent e00dfb6 commit 2549d64
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 9 deletions.
3 changes: 2 additions & 1 deletion docker/local_cached_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ func (f *localCachedFactory) GetForInstance(instance *types.Instance) (DockerApi
Timeout: 1 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
Proxy: http.ProxyURL(proxyUrl),
MaxIdleConnsPerHost: 5,
Proxy: http.ProxyURL(proxyUrl),
}
if tlsConfig != nil {
transport.TLSClientConfig = tlsConfig
Expand Down
32 changes: 24 additions & 8 deletions router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"net/http"
"strings"
"sync"
"time"

"golang.org/x/crypto/ssh"

Expand All @@ -34,11 +35,12 @@ type proxyRouter struct {
keyPath string
director Director
closed bool
httpListener net.Listener
httpListener *net.TCPListener
udpDnsServer *dns.Server
tcpDnsServer *dns.Server
sshListener net.Listener
sshConfig *ssh.ServerConfig
dialer *net.Dialer
}

func (r *proxyRouter) Listen(httpAddr, dnsAddr, sshAddr string) {
Expand All @@ -52,19 +54,24 @@ func (r *proxyRouter) ListenAndWait(httpAddr, dnsAddr, sshAddr string) {
}

func (r *proxyRouter) listen(wg *sync.WaitGroup, httpAddr, dnsAddr, sshAddr string) {

l, err := net.Listen("tcp", httpAddr)
tcpAddr, err := net.ResolveTCPAddr("tcp", httpAddr)
if err != nil {
log.Fatal(err)
}
l, err := net.ListenTCP("tcp", tcpAddr)
if err != nil {
log.Fatal(err)
}
r.httpListener = l
wg.Add(1)
go func() {
for !r.closed {
conn, err := r.httpListener.Accept()
conn, err := r.httpListener.AcceptTCP()
if err != nil {
continue
}
conn.SetKeepAlive(true)
conn.SetKeepAlivePeriod(3 * time.Minute)
go r.handleConnection(conn)
}
wg.Done()
Expand Down Expand Up @@ -333,7 +340,7 @@ func (r *proxyRouter) handleConnection(c net.Conn) {
log.Printf("Error directing request: %v\n", err)
return
}
d, err := net.Dial("tcp", dstHost.String())
d, err := r.dialer.Dial("tcp", dstHost.String())
if err != nil {
log.Printf("Error dialing backend %s: %v\n", dstHost.String(), err)
return
Expand All @@ -358,7 +365,7 @@ func (r *proxyRouter) handleConnection(c net.Conn) {
log.Printf("Error directing request: %v\n", err)
return
}
d, err := net.Dial("tcp", dstHost.String())
d, err := r.dialer.Dial("tcp", dstHost.String())
if err != nil {
log.Printf("Error dialing backend %s: %v\n", dstHost.String(), err)
return
Expand Down Expand Up @@ -423,10 +430,11 @@ func proxySsh(reqs1, reqs2 <-chan *ssh.Request, channel1, channel2 ssh.Channel)

func proxyConn(src, dst net.Conn) {
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)
errc <- err
}

go cp(src, dst)
go cp(dst, src)
<-errc
Expand All @@ -450,5 +458,13 @@ func NewRouter(director Director, keyPath string) *proxyRouter {

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

0 comments on commit 2549d64

Please sign in to comment.