99 lines
2.4 KiB
Go
99 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"git.eve.moe/jackyyf/transparent-proxy/server"
|
|
"io"
|
|
"net"
|
|
)
|
|
|
|
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)
|
|
}
|
|
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 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)
|
|
}
|
|
}
|
|
|
|
func pipeThenClose(reader io.Reader, writer io.WriteCloser) {
|
|
defer writer.Close()
|
|
buff := make([]byte, 4096)
|
|
for {
|
|
n, err := reader.Read(buff)
|
|
if n > 0 {
|
|
_, err := writer.Write(buff[:n])
|
|
if err != nil {
|
|
fmt.Printf("Write Error: %#v\n", err.Error())
|
|
return
|
|
}
|
|
}
|
|
if err == io.EOF {
|
|
// fmt.Println("Reader reached EOF, closing.")
|
|
return
|
|
}
|
|
if err != nil {
|
|
// Enable this line ONLY FOR DEBUG PURPOSE.
|
|
// fmt.Printf("Read Error: %#v\n", err.Error())
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
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())
|
|
}
|
|
|
|
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())
|
|
}
|