Skip to content
Permalink
Browse files

SO_REUSEPORT support

  • Loading branch information...
DarthSim committed Jun 27, 2019
1 parent 435e5d4 commit c76696caf78bb24eabd71b782a50858b0233ca96
Showing with 62 additions and 9 deletions.
  1. +3 −0 config.go
  2. +1 −0 docs/configuration.md
  3. +1 −1 go.mod
  4. +15 −0 listen_no_reuseport.go
  5. +33 −0 listen_reuseport.go
  6. +8 −6 prometheus.go
  7. +1 −2 server.go
@@ -136,6 +136,7 @@ type config struct {
Concurrency int
MaxClients int
TTL int
SoReuseport bool

MaxSrcDimension int
MaxSrcResolution int
@@ -258,6 +259,8 @@ func configure() {

intEnvConfig(&conf.TTL, "IMGPROXY_TTL")

boolEnvConfig(&conf.SoReuseport, "IMGPROXY_SO_REUSEPORT")

intEnvConfig(&conf.MaxSrcDimension, "IMGPROXY_MAX_SRC_DIMENSION")
megaIntEnvConfig(&conf.MaxSrcResolution, "IMGPROXY_MAX_SRC_RESOLUTION")
intEnvConfig(&conf.MaxSrcFileSize, "IMGPROXY_MAX_SRC_FILE_SIZE")
@@ -34,6 +34,7 @@ $ echo $(xxd -g 2 -l 64 -p /dev/random | tr -d '\n')
* `IMGPROXY_CONCURRENCY`: the maximum number of image requests to be processed simultaneously. Default: number of CPU cores times two;
* `IMGPROXY_MAX_CLIENTS`: the maximum number of simultaneous active connections. Default: `IMGPROXY_CONCURRENCY * 10`;
* `IMGPROXY_TTL`: duration (in seconds) sent in `Expires` and `Cache-Control: max-age` HTTP headers. Default: `3600` (1 hour);
* `IMGPROXY_SO_REUSEPORT`: when `true`, enables `SO_REUSEPORT` socket option (currently on linux and darwin only);
* `IMGPROXY_USER_AGENT`: User-Agent header that will be sent with source image request. Default: `imgproxy/%current_version`;
* `IMGPROXY_USE_ETAG`: when `true`, enables using [ETag](https://en.wikipedia.org/wiki/HTTP_ETag) HTTP header for HTTP cache control. Default: false;

2 go.mod
@@ -35,7 +35,7 @@ require (
golang.org/x/net v0.0.0-20190110200230-915654e7eabc
golang.org/x/oauth2 v0.0.0-20190110195249-fd3eaa146cbb // indirect
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4
golang.org/x/sys v0.0.0-20190109145017-48ac38b7c8cb // indirect
golang.org/x/sys v0.0.0-20190109145017-48ac38b7c8cb
google.golang.org/api v0.1.0
google.golang.org/genproto v0.0.0-20190110221437-6909d8a4a91b // indirect
)
@@ -0,0 +1,15 @@
// +build !linux,!darwin !go1.11

package main

import (
"net"
)

func listenReuseport(network, address string) (net.Listener, error) {
if conf.SoReuseport {
logWarning("SO_REUSEPORT support is not implemented for your OS or Go version")
}

return net.Listen(network, address)
}
@@ -0,0 +1,33 @@
// +build linux darwin
// +build go1.11

package main

import (
"context"
"net"
"syscall"

"golang.org/x/sys/unix"
)

func listenReuseport(network, address string) (net.Listener, error) {
if !conf.SoReuseport {
return net.Listen(network, address)
}

lc := net.ListenConfig{
Control: func(_, _ string, c syscall.RawConn) error {
var cerr error
err := c.Control(func(fd uintptr) {
cerr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1)
})
if err != nil {
return err
}
return cerr
},
}

return lc.Listen(context.Background(), network, address)
}
@@ -100,14 +100,16 @@ func initPrometheus() {

prometheusEnabled = true

s := http.Server{
Addr: conf.PrometheusBind,
Handler: promhttp.Handler(),
}
s := http.Server{Handler: promhttp.Handler()}

go func() {
logNotice("Starting Prometheus server at %s\n", s.Addr)
if err := s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
l, err := listenReuseport("tcp", conf.PrometheusBind)
if err != nil {
logFatal(err.Error())
}

logNotice("Starting Prometheus server at %s\n", conf.PrometheusBind)
if err := s.Serve(l); err != nil && err != http.ErrServerClosed {
logFatal(err.Error())
}
}()
@@ -4,7 +4,6 @@ import (
"context"
"crypto/subtle"
"fmt"
"net"
"net/http"
"time"

@@ -30,7 +29,7 @@ func buildRouter() *router {
}

func startServer() *http.Server {
l, err := net.Listen("tcp", conf.Bind)
l, err := listenReuseport("tcp", conf.Bind)
if err != nil {
logFatal(err.Error())
}

0 comments on commit c76696c

Please sign in to comment.
You can’t perform that action at this time.