diff --git a/main.go b/main.go index e3876ae..2fe29aa 100644 --- a/main.go +++ b/main.go @@ -1,14 +1,24 @@ package main import ( - "go.megvii-inc.com/transparent-proxy/server" + "flag" "fmt" - "net" + "git.eve.moe/jackyyf/transparent-proxy/server" "io" + "net" ) -func main() { - proxy_listener, err := server.NewIPv4TransparentListener(":9091") +var port = flag.Int("port", 1080, "Listen port of the server") + +func main() { + flag.Parse() + go IPv4Handler() + go IPv6Handler() + select {} +} + +func IPv4Handler() { + proxy_listener, err := server.NewIPv4TransparentListener(fmt.Sprintf("0.0.0.0:%d", *port)) if err != nil { panic(err) } @@ -18,8 +28,24 @@ func main() { fmt.Println("Accept Error: ", err.Error()) continue } - fmt.Printf("Accepted connection: %s => %s\n", conn.TCPConn().RemoteAddr().String(), conn.RealAddr().String()) - go handle(conn) + // fmt.Printf("Accepted connection: %s => %s\n", conn.TCPConn().RemoteAddr().String(), conn.RealAddr().String()) + go handle4(conn) + } +} + +func IPv6Handler() { + proxy_listener, err := server.NewIPv6TransparentListener(fmt.Sprintf("[::]:%d", *port)) + if err != nil { + panic(err) + } + for { + conn, err := proxy_listener.Accept() + if err != nil { + fmt.Println("Accept Error: ", err.Error()) + continue + } + // fmt.Printf("Accepted connection: %s => %s\n", conn.TCPConn().RemoteAddr().String(), conn.RealAddr().String()) + go handle6(conn) } } @@ -36,7 +62,7 @@ func pipeThenClose(reader io.Reader, writer io.WriteCloser) { } } if err == io.EOF { - fmt.Println("Reader reached EOF, closing.") + // fmt.Println("Reader reached EOF, closing.") return } if err != nil { @@ -47,13 +73,26 @@ func pipeThenClose(reader io.Reader, writer io.WriteCloser) { } } -func handle(conn server.TransparentConnection) { +func handle4(conn server.TransparentConnection) { rconn, err := net.DialTCP("tcp4", nil, conn.RealAddr()) if err != nil { fmt.Println("Connect to ", conn.RealAddr().String(), " error: ", err.Error()) conn.TCPConn().Close() return } + // fmt.Printf("ESTABLISHED %s <=> %s\n", conn.TCPConn().RemoteAddr().String(), conn.RealAddr().String()) go pipeThenClose(conn.TCPConn(), rconn) go pipeThenClose(rconn, conn.TCPConn()) -} \ No newline at end of file +} + +func handle6(conn server.TransparentConnection) { + rconn, err := net.DialTCP("tcp6", conn.TCPConn().RemoteAddr().(*net.TCPAddr), conn.RealAddr()) + if err != nil { + fmt.Println("Connect to ", conn.RealAddr().String(), " error: ", err.Error()) + conn.TCPConn().Close() + return + } + // fmt.Printf("ESTABLISHED %s <=> %s\n", conn.TCPConn().RemoteAddr().String(), conn.RealAddr().String()) + go pipeThenClose(conn.TCPConn(), rconn) + go pipeThenClose(rconn, conn.TCPConn()) +} diff --git a/server/hack_linux.go b/server/hack_linux.go index 2b93b8a..7383fb9 100644 --- a/server/hack_linux.go +++ b/server/hack_linux.go @@ -9,9 +9,9 @@ package server // WARZONE BEGINS HERE! MIND YOUR HEAD! import ( - "reflect" - "net" "golang.org/x/sys/unix" + "net" + "reflect" ) const ( @@ -19,13 +19,14 @@ const ( ) func GetFDFromTCPConn(conn *net.TCPConn) int { - // Actual fd is stored at: (*(*TCPConn).conn.fd).sysfd + // Actual fd is stored at: (*(*TCPConn).conn.fd).pfd.Sysfd v := reflect.ValueOf(*conn) c := v.FieldByName("conn") fdp := c.FieldByName("fd") fd := reflect.Indirect(fdp) - sysfd := fd.FieldByName("sysfd") - return int(sysfd.Int()) + pfd := fd.FieldByName("pfd") + Sysfd := pfd.FieldByName("Sysfd") + return int(Sysfd.Int()) } func GetAddr4FromFD(fd int) *net.TCPAddr { @@ -41,9 +42,9 @@ func GetAddr4FromFD(fd int) *net.TCPAddr { Flowinfo 4byte ipv4 address Addr 16byte ignore for ipv4 Scope_id 4byte ignore for ipv4 - */ + */ addr.Flowinfo = be32toh(addr.Flowinfo) - a, b, c, d := byte(addr.Flowinfo >> 24), byte((addr.Flowinfo >> 16) & 255), byte((addr.Flowinfo >> 8) & 255), byte(addr.Flowinfo & 255) + a, b, c, d := byte(addr.Flowinfo>>24), byte((addr.Flowinfo>>16)&255), byte((addr.Flowinfo>>8)&255), byte(addr.Flowinfo&255) ip := net.IPv4(a, b, c, d) return &net.TCPAddr{IP: ip, Port: int(be16toh(addr.Port)), Zone: ""} } @@ -61,9 +62,9 @@ func GetAddr6FromFD(fd int) *net.TCPAddr { Flowinfo 4byte ipv6 flowinfo ignore Addr 16byte ipv6 addr Scope_id 4byte ipv6 scope id ignore - */ + */ v6addr := make(net.IP, 16) // Make GC happy? copy(v6addr, addr.Addr[:]) return &net.TCPAddr{IP: v6addr, Port: int(be16toh(addr.Port)), Zone: ""} -} \ No newline at end of file +}