summaryrefslogtreecommitdiff
path: root/pkg/server/socket/sys.go
diff options
context:
space:
mode:
authorMikhail Osipov <mike.osipov@gmail.com>2020-05-26 03:22:32 +0300
committerMikhail Osipov <mike.osipov@gmail.com>2020-05-26 03:22:32 +0300
commite43c60b56401be7515d7fbfdfe3e4e56d1886a23 (patch)
tree58711f3bbbe2b34e91836087c274773564e29029 /pkg/server/socket/sys.go
parent97802849e3a21952e6c5896622d52153b2d96ee7 (diff)
add tproxy listen option
Diffstat (limited to 'pkg/server/socket/sys.go')
-rw-r--r--pkg/server/socket/sys.go44
1 files changed, 41 insertions, 3 deletions
diff --git a/pkg/server/socket/sys.go b/pkg/server/socket/sys.go
index d09df12..70b59a6 100644
--- a/pkg/server/socket/sys.go
+++ b/pkg/server/socket/sys.go
@@ -47,16 +47,18 @@ func ioctl(fd int, req int, ptr unsafe.Pointer) error {
return nil
}
-func getRawConn(conn net.Conn) (syscall.RawConn, error) {
+func getRawConn(conn interface{}) (syscall.RawConn, error) {
switch c := conn.(type) {
case *net.TCPConn:
return c.SyscallConn()
+ case *net.TCPListener:
+ return c.SyscallConn()
default:
return nil, errors.New("unknown connection type")
}
}
-func withConnControl(conn net.Conn, f func(fd int) error) (err error) {
+func withConnControl(conn interface{}, f func(fd int) error) (err error) {
var c syscall.RawConn
var ferr error
@@ -75,12 +77,16 @@ func withConnControl(conn net.Conn, f func(fd int) error) (err error) {
return
}
+func getSocketDomain(fd int) (int, error) {
+ return unix.GetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_DOMAIN)
+}
+
func getSocketOriginalDst(fd int, sa *unix.RawSockaddrAny) error {
const SO_ORIGINAL_DST = 80
p, n := unsafe.Pointer(sa), int(unsafe.Sizeof(*sa))
- family, err := unix.GetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_DOMAIN)
+ family, err := getSocketDomain(fd)
if err != nil {
return err
}
@@ -129,3 +135,35 @@ func getConnOriginalAddr(conn net.Conn, addr *string) error {
return nil
}
+
+func setSocketTransparent(fd int) error {
+ family, err := getSocketDomain(fd)
+ if err != nil {
+ return err
+ }
+
+ var level, opt int
+
+ switch family {
+ case unix.AF_INET6:
+ level, opt = unix.SOL_IPV6, unix.IPV6_TRANSPARENT
+ case unix.AF_INET:
+ level, opt = unix.SOL_IP, unix.IP_TRANSPARENT
+ default:
+ return errors.New("unknown address family")
+ }
+
+ return unix.SetsockoptInt(fd, level, opt, 1)
+}
+
+func setConnTransparent(conn interface{}) error {
+ f := func(fd int) error {
+ return setSocketTransparent(fd)
+ }
+
+ if err := withConnControl(conn, f); err != nil {
+ return fmt.Errorf("set-transparent: %w", err)
+ }
+
+ return nil
+}