Skip to content

Commit

Permalink
Support TPROXY TCP on Linux
Browse files Browse the repository at this point in the history
  • Loading branch information
riobard committed Apr 14, 2018
1 parent 14d0f44 commit c067360
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 7 deletions.
6 changes: 6 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func main() {
Socks string
RedirTCP string
RedirTCP6 string
TproxyTCP string
}

listCiphers := flag.Bool("cipher", false, "List supported ciphers")
Expand All @@ -45,6 +46,7 @@ func main() {
flag.StringVar(&flags.Socks, "socks", "", "(client-only) SOCKS listen address")
flag.StringVar(&flags.RedirTCP, "redir", "", "(client-only) redirect TCP from this address")
flag.StringVar(&flags.RedirTCP6, "redir6", "", "(client-only) redirect TCP IPv6 from this address")
flag.StringVar(&flags.TproxyTCP, "tproxytcp", "", "(client-only) TPROXY TCP listen address")
flag.DurationVar(&config.UDPTimeout, "udptimeout", 120*time.Second, "UDP tunnel timeout")
flag.Parse()

Expand Down Expand Up @@ -96,6 +98,10 @@ func main() {
if flags.RedirTCP6 != "" {
go redir6Local(flags.RedirTCP6, d)
}

if flags.TproxyTCP != "" {
go tproxyTCP(flags.TproxyTCP, d)
}
}

if len(flags.Server) > 0 { // server mode
Expand Down
40 changes: 40 additions & 0 deletions tcp_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,43 @@ func ipv6_getorigdst(fd uintptr) (socks.Addr, error) {
addr[1+net.IPv6len], addr[1+net.IPv6len+1] = port[0], port[1]
return addr, nil
}

func tproxyTCP(addr string, d Dialer) error {
l, err := net.Listen("tcp", addr)
if err != nil {
return err
}
rc, err := l.(*net.TCPListener).SyscallConn()
if err != nil {
return err
}
rc.Control(func(fd uintptr) { err = syscall.SetsockoptInt(int(fd), syscall.SOL_IP, syscall.IP_TRANSPARENT, 1) })
if err != nil {
return err
}
logf("TPROXY on tcp://%v", addr)
for {
c, err := l.Accept()
if err != nil {
return err
}
go func() {
defer c.Close()
tcpKeepAlive(c)
rc, err := d.Dial("tcp", c.LocalAddr().String())
if err != nil {
logf("failed to connect: %v", err)
return
}
defer rc.Close()
tcpKeepAlive(rc)
logf("TPROXY TCP %s <--[%s]--> %s", c.RemoteAddr(), rc.RemoteAddr(), c.LocalAddr())
if err = relay(rc, c); err != nil {
if err, ok := err.(net.Error); ok && err.Timeout() {
return // ignore i/o timeout
}
logf("relay error: %v", err)
}
}()
}
}
10 changes: 3 additions & 7 deletions tcp_other.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

package main

func redirLocal(addr string, d Dialer) {
logf("TCP redirect not supported")
}

func redir6Local(addr string, d Dialer) {
logf("TCP6 redirect not supported")
}
func redirLocal(addr string, d Dialer) { panic("TCP redirect not supported") }
func redir6Local(addr string, d Dialer) { panic("TCP6 redirect not supported") }
func tproxyTCP(addr string, d Dialer) { panic("TPROXY TCP not supported") }

0 comments on commit c067360

Please sign in to comment.