Skip to content

Instantly share code, notes, and snippets.

@rhs
Created April 26, 2018 12:37
Show Gist options
  • Save rhs/7ed17d49dff7196c3539d2d1b01f6049 to your computer and use it in GitHub Desktop.
Save rhs/7ed17d49dff7196c3539d2d1b01f6049 to your computer and use it in GitHub Desktop.
package main
import (
"flag"
"log"
"io"
"net"
"golang.org/x/net/proxy"
)
var host = flag.String("host", "httpbin.org:80", "intercepting host")
func main() {
flag.Parse()
ln, err := net.Listen("tcp", ":1234")
if err != nil {
log.Println(err)
return
}
log.Println("Listening...")
for {
conn, err := ln.Accept();
if err != nil {
log.Println(err)
} else {
switch conn.(type) {
case *net.TCPConn:
go handleConnection(conn.(*net.TCPConn))
default:
log.Println("Don't know how to handle conn:", conn)
}
}
}
}
func handleConnection(conn *net.TCPConn) {
log.Printf("CONNECTING: %s to %v\n", conn.RemoteAddr(), host)
dialer, err := proxy.SOCKS5("tcp", "localhost:1080", nil, proxy.Direct)
if err != nil {
log.Println(err)
conn.Close()
return
}
_proxy, err := dialer.Dial("tcp", *host)
if err != nil {
log.Println(err)
conn.Close()
return
}
proxy := _proxy.(*net.TCPConn)
go pipe(conn, proxy)
go pipe(proxy, conn)
}
func pipe(from, to *net.TCPConn) {
defer func() {
log.Println("CLOSED WRITE:", to.RemoteAddr())
to.CloseWrite()
}()
defer func() {
log.Println("CLOSED READ:", from.RemoteAddr())
from.CloseRead()
}()
const size = 64*1024
var buf [size]byte
for {
n, err := from.Read(buf[0:size])
if err != nil {
if err != io.EOF {
log.Println(err)
}
break
} else {
_, err := to.Write(buf[0:n])
if err != nil {
log.Println(err)
break
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment