mirror of
https://github.com/cmz0228/hysteria-dev.git
synced 2025-07-03 17:59:51 +00:00
fix(redirect_tcp): client got reset under i386
it seems like syscall.Syscall6(SYS_SOCKETCALL, SYS_GETSOCKOPT, ...) always failed with EFAULT. so we call syscall.socketcall() instead. close: #583
This commit is contained in:
parent
1b3b038728
commit
779e962d49
17
app/redirect/getsockopt_linux.go
Normal file
17
app/redirect/getsockopt_linux.go
Normal file
@ -0,0 +1,17 @@
|
||||
//go:build !386
|
||||
// +build !386
|
||||
|
||||
package redirect
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func getsockopt(s uintptr, level uintptr, name uintptr, val unsafe.Pointer, vallen *uint32) (err error) {
|
||||
_, _, e := syscall.Syscall6(syscall.SYS_GETSOCKOPT, s, level, name, uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
|
||||
if e != 0 {
|
||||
err = e
|
||||
}
|
||||
return
|
||||
}
|
22
app/redirect/getsockopt_linux_386.go
Normal file
22
app/redirect/getsockopt_linux_386.go
Normal file
@ -0,0 +1,22 @@
|
||||
package redirect
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
SYS_GETSOCKOPT = 15
|
||||
)
|
||||
|
||||
// we cannot call socketcall with syscall.Syscall6, it always fails with EFAULT.
|
||||
// we have to call syscall.socketcall with this trick.
|
||||
func syscall_socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)
|
||||
|
||||
func getsockopt(s uintptr, level uintptr, name uintptr, val unsafe.Pointer, vallen *uint32) (err error) {
|
||||
_, e := syscall_socketcall(SYS_GETSOCKOPT, s, level, name, uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
|
||||
if e != 0 {
|
||||
err = e
|
||||
}
|
||||
return
|
||||
}
|
@ -1,6 +1,3 @@
|
||||
//go:build !386
|
||||
// +build !386
|
||||
|
||||
package redirect
|
||||
|
||||
import (
|
||||
@ -23,13 +20,11 @@ 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 {
|
||||
err := getsockopt(fd, syscall.SOL_IPV6, IP6T_SO_ORIGINAL_DST, unsafe.Pointer(&addr), &addrSize)
|
||||
if err != nil {
|
||||
// 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 {
|
||||
err = getsockopt(fd, syscall.SOL_IP, SO_ORIGINAL_DST, unsafe.Pointer(&addr), &addrSize)
|
||||
if err != nil {
|
||||
// failed
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1,36 +0,0 @@
|
||||
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
|
||||
}
|
7
app/redirect/syscall_socketcall_linux_386.s
Normal file
7
app/redirect/syscall_socketcall_linux_386.s
Normal file
@ -0,0 +1,7 @@
|
||||
//go:build gc
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
TEXT ·syscall_socketcall(SB),NOSPLIT,$0-36
|
||||
JMP syscall·socketcall(SB)
|
Loading…
x
Reference in New Issue
Block a user