Skip to content

Instantly share code, notes, and snippets.

@methane
Created September 19, 2014 03:17
Show Gist options
  • Save methane/07d48a112eacbf93008c to your computer and use it in GitHub Desktop.
Save methane/07d48a112eacbf93008c to your computer and use it in GitHub Desktop.
package main
import (
"io"
"log"
"net"
"sync"
"time"
)
type CloseWriter interface {
io.WriteCloser
CloseWrite() error
}
func must(err error) {
if err != nil {
log.Fatal(err)
}
}
func proxy(conn *net.TCPConn) {
defer conn.Close()
fwdAddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:6000")
if err != nil {
log.Println(err)
return
}
fwd, err := net.DialTCP("tcp", nil, fwdAddr)
if err != nil {
log.Println(err)
return
}
defer fwd.Close()
wg := sync.WaitGroup{}
wg.Add(2)
transfer := func(d CloseWriter, s io.Reader) {
if _, err := io.Copy(d, s); err != nil {
log.Println(err)
}
if err := d.CloseWrite(); err != nil {
log.Println(err)
}
wg.Done()
}
go transfer(fwd, conn)
go transfer(conn, fwd)
wg.Wait()
}
func main() {
addr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:5000")
must(err)
l, err := net.ListenTCP("tcp", addr)
must(err)
for {
con, err := l.AcceptTCP()
if err != nil {
nerr, ok := err.(net.Error)
if ok && nerr.Temporary() {
time.Sleep(time.Millisecond * 10)
continue
}
l.Close()
log.Fatal(nerr)
}
proxy(con)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment