Skip to content
Snippets Groups Projects
Commit ab9f257a authored by Konrad Zemek's avatar Konrad Zemek
Browse files

Add --listeners option.

parent db725607
No related branches found
No related tags found
No related merge requests found
...@@ -50,6 +50,8 @@ Usage of ./go-mmproxy: ...@@ -50,6 +50,8 @@ Usage of ./go-mmproxy:
Path to a file that contains allowed subnets of the proxy servers Path to a file that contains allowed subnets of the proxy servers
-l string -l string
Adress the proxy listens on (default "0.0.0.0:8443") Adress the proxy listens on (default "0.0.0.0:8443")
-listeners int
Number of listener sockets that will be opened for the listen address (default 1)
-mark int -mark int
The mark that will be set on outbound packets The mark that will be set on outbound packets
-v int -v int
...@@ -57,6 +59,7 @@ Usage of ./go-mmproxy: ...@@ -57,6 +59,7 @@ Usage of ./go-mmproxy:
1 - log errors occuring in individual connections 1 - log errors occuring in individual connections
2 - log all state changes of individual connections 2 - log all state changes of individual connections
``` ```
Example invocation: Example invocation:
......
...@@ -7,6 +7,7 @@ package main ...@@ -7,6 +7,7 @@ package main
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"context"
"encoding/binary" "encoding/binary"
"flag" "flag"
"fmt" "fmt"
...@@ -26,6 +27,7 @@ var targetAddr6 string ...@@ -26,6 +27,7 @@ var targetAddr6 string
var allowedSubnetsPath string var allowedSubnetsPath string
var mark int var mark int
var verbose int var verbose int
var listeners int
var allowedSubnets []*net.IPNet var allowedSubnets []*net.IPNet
var logger *zap.Logger var logger *zap.Logger
...@@ -40,6 +42,7 @@ func init() { ...@@ -40,6 +42,7 @@ func init() {
flag.IntVar(&verbose, "v", 0, `0 - no logging of individual connections flag.IntVar(&verbose, "v", 0, `0 - no logging of individual connections
1 - log errors occuring in individual connections 1 - log errors occuring in individual connections
2 - log all state changes of individual connections`) 2 - log all state changes of individual connections`)
flag.IntVar(&listeners, "listeners", 1, "Number of listener sockets that will be opened for the listen address")
} }
func readRemoteAddrPROXYv2(conn net.Conn, ctrlBuf []byte) (net.Addr, net.Addr, []byte, error) { func readRemoteAddrPROXYv2(conn net.Conn, ctrlBuf []byte) (net.Addr, net.Addr, []byte, error) {
...@@ -233,9 +236,9 @@ func checkOriginAllowed(conn net.Conn) bool { ...@@ -233,9 +236,9 @@ func checkOriginAllowed(conn net.Conn) bool {
return false return false
} }
func handleConnection(conn net.Conn) { func handleConnection(conn net.Conn, listenLog *zap.Logger) {
defer conn.Close() defer conn.Close()
connLog := logger.With(zap.String("remoteAddr", conn.RemoteAddr().String()), connLog := listenLog.With(zap.String("remoteAddr", conn.RemoteAddr().String()),
zap.String("localAddr", conn.LocalAddr().String())) zap.String("localAddr", conn.LocalAddr().String()))
if !checkOriginAllowed(conn) { if !checkOriginAllowed(conn) {
...@@ -309,6 +312,43 @@ func handleConnection(conn net.Conn) { ...@@ -309,6 +312,43 @@ func handleConnection(conn net.Conn) {
} }
} }
func listen(listenerNum int, errors chan<- error) {
listenLog := logger.With(zap.Int("listenerNum", listenerNum))
listenConfig := net.ListenConfig{}
if listeners > 1 {
listenConfig.Control = func(network, address string, c syscall.RawConn) error {
return c.Control(func(fd uintptr) {
soReusePort := 15
if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, soReusePort, 1); err != nil {
listenLog.Warn("failed to set SO_REUSEPORT - only one listener setup will succeed")
}
})
}
}
ctx := context.Background()
ln, err := listenConfig.Listen(ctx, "tcp", listenAddr)
if err != nil {
listenLog.Error("failed to bind listener", zap.String("listenAddr", listenAddr), zap.Error(err))
errors <- err
return
}
listenLog.Info("listening", zap.String("listenAddr", listenAddr))
for {
conn, err := ln.Accept()
if err != nil {
listenLog.Error("failed to accept new connection", zap.Error(err))
errors <- err
return
}
go handleConnection(conn, listenLog)
}
}
func loadAllowedSubnets() error { func loadAllowedSubnets() error {
file, err := os.Open(allowedSubnetsPath) file, err := os.Open(allowedSubnetsPath)
if err != nil { if err != nil {
...@@ -345,29 +385,26 @@ func initLogger() error { ...@@ -345,29 +385,26 @@ func initLogger() error {
func main() { func main() {
flag.Parse() flag.Parse()
if err := initLogger(); err != nil { if err := initLogger(); err != nil {
log.Fatalf("Failed to initialize logging: %s", err.Error()) log.Fatalf("Failed to initialize logging: %s", err.Error())
} }
defer logger.Sync() defer logger.Sync()
if listeners <= 0 {
logger.Fatal("--listeners has to be >= 1")
}
if allowedSubnetsPath != "" { if allowedSubnetsPath != "" {
if err := loadAllowedSubnets(); err != nil { if err := loadAllowedSubnets(); err != nil {
logger.Fatal("failed to load allowed subnets file", zap.String("path", allowedSubnetsPath), zap.Error(err)) logger.Fatal("failed to load allowed subnets file", zap.String("path", allowedSubnetsPath), zap.Error(err))
} }
} }
ln, err := net.Listen("tcp", listenAddr) listenErrors := make(chan error, listeners)
if err != nil { for i := 0; i < listeners; i++ {
logger.Fatal("failed to bind listener", zap.String("listenAddr", listenAddr), zap.Error(err)) go listen(i, listenErrors)
} }
for i := 0; i < listeners; i++ {
for { <-listenErrors
conn, err := ln.Accept()
if err != nil {
logger.Fatal("failed to accept new connection", zap.Error(err))
}
go handleConnection(conn)
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment