60 lines
1.2 KiB
Go
60 lines
1.2 KiB
Go
package proxy
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net"
|
|
)
|
|
|
|
// RunTCPProxy starts a basic TCP reverse proxy listening on the given port
|
|
// and forwarding all traffic to the target backend.
|
|
func RunTCPProxy(port int, targetBackend string) error {
|
|
addr := fmt.Sprintf(":%d", port)
|
|
listener, err := net.Listen("tcp", addr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer listener.Close()
|
|
|
|
log.Printf("Starting TCP proxy on %s, forwarding to %s\n", addr, targetBackend)
|
|
|
|
for {
|
|
clientConn, err := listener.Accept()
|
|
if err != nil {
|
|
log.Printf("TCP Accept error: %v", err)
|
|
continue
|
|
}
|
|
|
|
go handleTCPConnection(clientConn, targetBackend)
|
|
}
|
|
}
|
|
|
|
func handleTCPConnection(clientConn net.Conn, targetBackend string) {
|
|
defer clientConn.Close()
|
|
|
|
backendConn, err := net.Dial("tcp", targetBackend)
|
|
if err != nil {
|
|
log.Printf("TCP Dial error to %s: %v", targetBackend, err)
|
|
return
|
|
}
|
|
defer backendConn.Close()
|
|
|
|
errChan := make(chan error, 2)
|
|
|
|
// Copy data from client to backend
|
|
go func() {
|
|
_, err := io.Copy(backendConn, clientConn)
|
|
errChan <- err
|
|
}()
|
|
|
|
// Copy data from backend to client
|
|
go func() {
|
|
_, err := io.Copy(clientConn, backendConn)
|
|
errChan <- err
|
|
}()
|
|
|
|
// Wait for one of the streams to finish (either EOF or error)
|
|
<-errChan
|
|
}
|