fix: build failure on linux 386

This commit is contained in:
Toby 2022-06-07 12:44:38 -07:00
parent d1e7d4c7cb
commit 8a64099a96
3 changed files with 76 additions and 26 deletions

View File

@ -0,0 +1,38 @@
//go:build !386
// +build !386
package redirect
import (
"syscall"
"unsafe"
)
const (
SO_ORIGINAL_DST = 80
IP6T_SO_ORIGINAL_DST = 80
)
type sockAddr struct {
family uint16
port [2]byte // big endian regardless of host byte order
data [24]byte // check sockaddr_in or sockaddr_in6 for more information
}
func getOrigDst(fd uintptr) (*sockAddr, error) {
var addr sockAddr
addrSize := uint32(unsafe.Sizeof(addr))
// try IPv6 first
_, _, err := syscall.Syscall6(syscall.SYS_GETSOCKOPT, fd, syscall.SOL_IPV6, IP6T_SO_ORIGINAL_DST,
uintptr(unsafe.Pointer(&addr)), uintptr(unsafe.Pointer(&addrSize)), 0)
if err != 0 {
// try IPv4
_, _, err = syscall.Syscall6(syscall.SYS_GETSOCKOPT, fd, syscall.SOL_IP, SO_ORIGINAL_DST,
uintptr(unsafe.Pointer(&addr)), uintptr(unsafe.Pointer(&addrSize)), 0)
if err != 0 {
// failed
return nil, err
}
}
return &addr, nil
}

View File

@ -0,0 +1,36 @@
package redirect
import (
"syscall"
"unsafe"
)
const (
SYS_GETSOCKOPT = 15
SO_ORIGINAL_DST = 80
IP6T_SO_ORIGINAL_DST = 80
)
type sockAddr struct {
family uint16
port [2]byte // big endian regardless of host byte order
data [24]byte // check sockaddr_in or sockaddr_in6 for more information
}
func getOrigDst(fd uintptr) (*sockAddr, error) {
var addr sockAddr
addrSize := uint32(unsafe.Sizeof(addr))
// try IPv6 first
_, _, err := syscall.Syscall6(syscall.SYS_SOCKETCALL, SYS_GETSOCKOPT, fd, syscall.SOL_IPV6, IP6T_SO_ORIGINAL_DST,
uintptr(unsafe.Pointer(&addr)), uintptr(unsafe.Pointer(&addrSize)))
if err != 0 {
// try IPv4
_, _, err = syscall.Syscall6(syscall.SYS_SOCKETCALL, SYS_GETSOCKOPT, fd, syscall.SOL_IP, SO_ORIGINAL_DST,
uintptr(unsafe.Pointer(&addr)), uintptr(unsafe.Pointer(&addrSize)))
if err != 0 {
// failed
return nil, err
}
}
return &addr, nil
}

View File

@ -8,12 +8,6 @@ import (
"net"
"syscall"
"time"
"unsafe"
)
const (
SO_ORIGINAL_DST = 80
IP6T_SO_ORIGINAL_DST = 80
)
type TCPRedirect struct {
@ -74,33 +68,15 @@ func (r *TCPRedirect) ListenAndServe() error {
}
}
type sockAddr struct {
family uint16
port [2]byte // big endian regardless of host byte order
data [24]byte // check sockaddr_in or sockaddr_in6 for more information
}
func getDestAddr(conn *net.TCPConn) (*net.TCPAddr, error) {
rc, err := conn.SyscallConn()
if err != nil {
return nil, err
}
var addr sockAddr
addrSize := uint32(unsafe.Sizeof(addr))
var addr *sockAddr
var err2 error
err = rc.Control(func(fd uintptr) {
// try IPv6 first
_, _, err := syscall.Syscall6(syscall.SYS_GETSOCKOPT, fd, syscall.SOL_IPV6, IP6T_SO_ORIGINAL_DST,
uintptr(unsafe.Pointer(&addr)), uintptr(unsafe.Pointer(&addrSize)), 0)
if err != 0 {
// try IPv4
_, _, err = syscall.Syscall6(syscall.SYS_GETSOCKOPT, fd, syscall.SOL_IP, SO_ORIGINAL_DST,
uintptr(unsafe.Pointer(&addr)), uintptr(unsafe.Pointer(&addrSize)), 0)
if err != 0 {
// failed
err2 = err
}
}
addr, err2 = getOrigDst(fd)
})
if err != nil {
return nil, err