61 lines
1.5 KiB
Go
61 lines
1.5 KiB
Go
// Example usage:
|
|
// Terminal 1: python -m http.server 8000
|
|
// Terminal 2: go run tcpproxy.go 9000 localhost:8000
|
|
// Terminal 3: curl localhost:9000
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"os"
|
|
)
|
|
|
|
func main() {
|
|
if len(os.Args) != 3 {
|
|
fmt.Println("Usage: go run tcpproxy.go <listen_port> <target_host:port>")
|
|
os.Exit(1)
|
|
}
|
|
|
|
listenPort := os.Args[1] // port to listen on
|
|
targetAddr := os.Args[2] // target server address
|
|
|
|
// create TCP listener on specified port
|
|
listener, err := net.Listen("tcp", ":"+listenPort)
|
|
if err != nil {
|
|
fmt.Printf("Failed to listen on port %s: %v\n", listenPort, err)
|
|
os.Exit(1)
|
|
}
|
|
defer listener.Close()
|
|
|
|
fmt.Printf("TCP proxy listening on port %s, forwarding to %s\n", listenPort, targetAddr)
|
|
|
|
// accept incoming connections
|
|
for {
|
|
clientConn, err := listener.Accept()
|
|
if err != nil {
|
|
fmt.Printf("Failed to accept connection: %v\n", err)
|
|
continue
|
|
}
|
|
|
|
// handle each client connection concurrently
|
|
go handleConnection(clientConn, targetAddr)
|
|
}
|
|
}
|
|
|
|
func handleConnection(clientConn net.Conn, targetAddr string) {
|
|
defer clientConn.Close() // ensure client connection is closed
|
|
|
|
// connect to target server
|
|
serverConn, err := net.Dial("tcp", targetAddr)
|
|
if err != nil {
|
|
fmt.Printf("Failed to connect to target %s: %v\n", targetAddr, err)
|
|
return
|
|
}
|
|
defer serverConn.Close() // ensure server connection is closed
|
|
|
|
// start bidirectional data copying
|
|
go io.Copy(serverConn, clientConn) // client -> server
|
|
io.Copy(clientConn, serverConn) // server -> client (blocks until done)
|
|
}
|