Skip to content

Commit

Permalink
Use syscall.RawConn interface to control raw fd
Browse files Browse the repository at this point in the history
Requires Go 1.9.
  • Loading branch information
riobard committed Aug 26, 2017
1 parent de996c8 commit 251be58
Showing 1 changed file with 11 additions and 14 deletions.
25 changes: 11 additions & 14 deletions tcp_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,26 +32,23 @@ func getOrigDst(conn net.Conn, ipv6 bool) (socks.Addr, error) {
if !ok {
return nil, errors.New("only work with TCP connection")
}
f, err := c.File()

rc, err := c.SyscallConn()
if err != nil {
return nil, err
}
defer f.Close()

fd := f.Fd()
var addr socks.Addr

// The File() call above puts both the original socket fd and the file fd in blocking mode.
// Set the file fd back to non-blocking mode and the original socket fd will become non-blocking as well.
// Otherwise blocking I/O will waste OS threads.
if err := syscall.SetNonblock(int(fd), true); err != nil {
return nil, err
}

if ipv6 {
return ipv6_getorigdst(fd)
}
rc.Control(func(fd uintptr) {
if ipv6 {
addr, err = ipv6_getorigdst(fd)
} else {
addr, err = getorigdst(fd)
}
})

return getorigdst(fd)
return addr, err
}

// Call getorigdst() from linux/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
Expand Down

0 comments on commit 251be58

Please sign in to comment.