diff --git a/README.md b/README.md index e5bb80f..bd1ac34 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,8 @@ Usage of ./go-mmproxy: Path to a file that contains allowed subnets of the proxy servers -close-after int Number of seconds after which UDP socket will be cleaned up (default 60) + -dynamic-destination + Traffic will be forwarded to the destination specified in the PROXY protocol header -l string Address the proxy listens on (default "0.0.0.0:8443") -listeners int diff --git a/main.go b/main.go index 395f464..00cf71f 100644 --- a/main.go +++ b/main.go @@ -29,6 +29,7 @@ type options struct { Logger *zap.Logger udpCloseAfter int UDPCloseAfter time.Duration + DynamicDestination bool } var Opts options @@ -47,6 +48,7 @@ func init() { flag.IntVar(&Opts.Listeners, "listeners", 1, "Number of listener sockets that will be opened for the listen address (Linux 3.9+)") flag.IntVar(&Opts.udpCloseAfter, "close-after", 60, "Number of seconds after which UDP socket will be cleaned up") + flag.BoolVar(&Opts.DynamicDestination, "dynamic-destination", false, "Traffic will be forwarded to the destination specified in the PROXY protocol header") } func listen(listenerNum int, errors chan<- error) { diff --git a/tcp.go b/tcp.go index a206256..d2aef89 100644 --- a/tcp.go +++ b/tcp.go @@ -44,19 +44,24 @@ func tcpHandleConnection(conn net.Conn, logger *zap.Logger) { return } - saddr, _, restBytes, err := PROXYReadRemoteAddr(buffer[:n], TCP) + saddr, daddr, restBytes, err := PROXYReadRemoteAddr(buffer[:n], TCP) if err != nil { logger.Debug("failed to parse PROXY header", zap.Error(err), zap.Bool("dropConnection", true)) return } targetAddr := Opts.TargetAddr6 - if saddr == nil { - if AddrVersion(conn.RemoteAddr()) == 4 { + + if !Opts.DynamicDestination { + if saddr == nil { + if AddrVersion(conn.RemoteAddr()) == 4 { + targetAddr = Opts.TargetAddr4 + } + } else if AddrVersion(saddr) == 4 { targetAddr = Opts.TargetAddr4 } - } else if AddrVersion(saddr) == 4 { - targetAddr = Opts.TargetAddr4 + } else { + targetAddr = daddr.String() } clientAddr := "UNKNOWN" diff --git a/udp.go b/udp.go index 923bc64..b2457b3 100644 --- a/udp.go +++ b/udp.go @@ -81,7 +81,7 @@ func udpCopyFromUpstream(downstream net.PacketConn, conn *udpConnection) { } } -func udpGetSocketFromMap(downstream net.PacketConn, downstreamAddr, saddr net.Addr, logger *zap.Logger, +func udpGetSocketFromMap(downstream net.PacketConn, downstreamAddr, saddr net.Addr, daddr net.Addr, logger *zap.Logger, connMap map[string]*udpConnection, socketClosures chan<- string) (*udpConnection, error) { connKey := "" if saddr != nil { @@ -93,8 +93,13 @@ func udpGetSocketFromMap(downstream net.PacketConn, downstreamAddr, saddr net.Ad } targetAddr := Opts.TargetAddr6 - if AddrVersion(downstreamAddr) == 4 { - targetAddr = Opts.TargetAddr4 + + if !Opts.DynamicDestination { + if AddrVersion(downstreamAddr) == 4 { + targetAddr = Opts.TargetAddr4 + } + } else { + targetAddr = daddr.String() } logger = logger.With(zap.String("downstreamAddr", downstreamAddr.String()), zap.String("targetAddr", targetAddr)) @@ -158,7 +163,7 @@ func UDPListen(listenConfig *net.ListenConfig, logger *zap.Logger, errors chan<- continue } - saddr, _, restBytes, err := PROXYReadRemoteAddr(buffer[:n], UDP) + saddr, daddr, restBytes, err := PROXYReadRemoteAddr(buffer[:n], UDP) if err != nil { logger.Debug("failed to parse PROXY header", zap.Error(err), zap.String("remoteAddr", remoteAddr.String())) continue @@ -177,7 +182,7 @@ func UDPListen(listenConfig *net.ListenConfig, logger *zap.Logger, errors chan<- } } - conn, err := udpGetSocketFromMap(ln, remoteAddr, saddr, logger, connectionMap, socketClosures) + conn, err := udpGetSocketFromMap(ln, remoteAddr, saddr, daddr, logger, connectionMap, socketClosures) if err != nil { continue }