From 3f5b6b55b08e19d9ed2ae5936117f2f0887caaa4 Mon Sep 17 00:00:00 2001
From: Paul Saab <ps@mu.org>
Date: Thu, 25 Sep 2014 10:58:07 -0700
Subject: [PATCH] Limit number of concurrent connections

Go's net/http library has no limits in place for number of concurrent
requests currently being processed.  This can result in an enormous
number of goroutines being created and the read/write buffer pools
growing unbounded resulting in OOM situations.
---
 config/config.go | 1 +
 http/http.go     | 4 ++++
 2 files changed, 5 insertions(+)

diff --git a/config/config.go b/config/config.go
index b636efc..c46cb04 100644
--- a/config/config.go
+++ b/config/config.go
@@ -82,6 +82,7 @@ type Config struct {
 	RequestTimeout   Duration `json:"request_timeout"`
 	HttpReadTimeout  Duration `json:"http_read_timeout"`
 	HttpWriteTimeout Duration `json:"http_write_timeout"`
+	HttpListenLimit  int      `json:"http_listen_limit"`
 	NumWantFallback  int      `json:"default_num_want"`
 
 	ClientWhitelistEnabled bool     `json:"client_whitelist_enabled"`
diff --git a/http/http.go b/http/http.go
index c0f177a..8d71be3 100644
--- a/http/http.go
+++ b/http/http.go
@@ -117,10 +117,14 @@ func Serve(cfg *config.Config, tkr *tracker.Tracker) {
 	}
 
 	glog.V(0).Info("Starting on ", cfg.Addr)
+	if cfg.HttpListenLimit != 0 {
+		glog.V(0).Info("Limiting connections to ", cfg.HttpListenLimit)
+	}
 
 	grace := &graceful.Server{
 		Timeout:   cfg.RequestTimeout.Duration,
 		ConnState: srv.connState,
+		ListenLimit: cfg.HttpListenLimit,
 		Server: &http.Server{
 			Addr:         cfg.Addr,
 			Handler:      newRouter(srv),