diff --git a/go.mod b/go.mod index 8fdd46a..f63a5f3 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/dop251/goja v0.0.0-20241024094426-79f3a7efcdbd github.com/hashicorp/go-multierror v1.1.1 github.com/jellydator/ttlcache/v3 v3.3.0 + github.com/libp2p/go-reuseport v0.4.0 github.com/tg123/go-htpasswd v1.2.3 github.com/zeebo/xxh3 v1.0.2 golang.org/x/crypto v0.31.0 diff --git a/go.sum b/go.sum index ade32ce..336c098 100644 --- a/go.sum +++ b/go.sum @@ -24,6 +24,8 @@ github.com/jellydator/ttlcache/v3 v3.3.0 h1:BdoC9cE81qXfrxeb9eoJi9dWrdhSuwXMAnHT github.com/jellydator/ttlcache/v3 v3.3.0/go.mod h1:bj2/e0l4jRnQdrnSTaGTsh4GSXvMjQcy41i7th0GVGw= github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= +github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= +github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= diff --git a/main.go b/main.go index ee75e57..fa7934f 100644 --- a/main.go +++ b/main.go @@ -23,6 +23,7 @@ import ( "time" "github.com/coreos/go-systemd/v22/activation" + "github.com/libp2p/go-reuseport" "golang.org/x/crypto/acme" "golang.org/x/crypto/acme/autocert" "golang.org/x/crypto/bcrypt" @@ -176,6 +177,7 @@ type proxyArg struct { type CLIArgs struct { bind_address string + bind_reuseport bool auth string verbosity int cert, key, cafile string @@ -229,6 +231,7 @@ func parse_args() CLIArgs { }, } flag.StringVar(&args.bind_address, "bind-address", ":8080", "HTTP proxy listen address. Set empty value to use systemd socket activation.") + flag.BoolVar(&args.bind_reuseport, "bind-reuseport", false, "allow multiple server instances on the same port") flag.StringVar(&args.auth, "auth", "none://", "auth parameters") flag.IntVar(&args.verbosity, "verbosity", 20, "logging verbosity "+ "(10 - debug, 20 - info, 30 - warning, 40 - error, 50 - critical)") @@ -470,7 +473,15 @@ func run() int { } listener = listeners[0] } else { - newListener, err := net.Listen("tcp", args.bind_address) + listenerFactory := net.Listen + if args.bind_reuseport { + if reuseport.Available() { + listenerFactory = reuseport.Listen + } else { + mainLogger.Warning("reuseport was requested but not available!") + } + } + newListener, err := listenerFactory("tcp", args.bind_address) if err != nil { mainLogger.Critical("listen failed: %v", err) return 3