Skip to content

Instantly share code, notes, and snippets.

@lafolle
Last active December 6, 2018 08:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lafolle/49b1889d2bba6188ebf7781a0fb5a5fc to your computer and use it in GitHub Desktop.
Save lafolle/49b1889d2bba6188ebf7781a0fb5a5fc to your computer and use it in GitHub Desktop.
Basic TCP proxy
package main
import (
"flag"
"fmt"
"io"
"log"
"net"
)
var (
from = flag.String("from", "", "read from here: of the form ip:port")
to = flag.String("to", "", "write to: of the form ip:port")
)
func proxy(from net.Conn, to net.Conn) {
go func() {
toConn := &toStdout{to}
n, err := io.Copy(toConn, from)
if err != nil {
fmt.Println("reading err:", err, n)
} else {
log.Println("read done.")
}
}()
go func() {
fromConn := &toStdout{from}
n, err := io.Copy(fromConn, to)
if err != nil {
fmt.Println("writing err:", err, n)
} else {
log.Println("write done.")
}
}()
}
type toStdout struct {
conn net.Conn
}
func (t *toStdout) Write(data []byte) (n int, err error) {
fmt.Println(string(data))
return t.conn.Write(data)
}
func main() {
flag.Parse()
if *from == "" {
println("missing from.")
}
if *to == "" {
println("missing to.")
}
fmt.Printf("proxying from %s to %s\n", *from, *to)
l, err := net.Listen("tcp", *from)
if err != nil {
fmt.Println("failed to listen on from:", err)
return
}
for {
fromConn, err := l.Accept()
if err != nil {
fmt.Println("failed to accept connection:", err)
return
}
toConn, err := net.Dial("tcp", *to)
if err != nil {
fmt.Println("failed dial tcp connection:", err)
fromConn.Close()
continue
}
go proxy(fromConn, toConn)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment