use GetSockoptIPv6Mreq to get original ip desination

more compitable
original syscall will fail on linux/386
master
fangdingjun 8 years ago
parent 610f55b478
commit 9117932fe7

@ -16,8 +16,6 @@ const (
) )
func getOriginDst(c net.Conn) (net.Addr, error) { func getOriginDst(c net.Conn) (net.Addr, error) {
var sockaddr syscall.RawSockaddrAny
var len = unsafe.Sizeof(sockaddr)
cc, ok := c.(*net.TCPConn) cc, ok := c.(*net.TCPConn)
if !ok { if !ok {
@ -31,13 +29,11 @@ func getOriginDst(c net.Conn) (net.Addr, error) {
defer f.Close() defer f.Close()
// ipv4
level := syscall.SOL_IP
remoteIP := c.RemoteAddr().(*net.TCPAddr).IP remoteIP := c.RemoteAddr().(*net.TCPAddr).IP
if remoteIP.To4() == nil { if remoteIP.To4() == nil {
// ipv6 // ipv6
level = syscall.SOL_IPV6 // not supported, just return local socket address
return c.LocalAddr(), nil
} }
// get original ip destination, in C like this // get original ip destination, in C like this
@ -47,31 +43,21 @@ func getOriginDst(c net.Conn) (net.Addr, error) {
// int len = sizeof(addr); // int len = sizeof(addr);
// getsocketopt(fd, SOL_IP, SO_ORIGINAL_DST, &addr, &len); // getsocketopt(fd, SOL_IP, SO_ORIGINAL_DST, &addr, &len);
// //
_, _, errno := syscall.Syscall6(sysGetSockOpt, f.Fd(), //_, _, errno := syscall.Syscall6(sysGetSockOpt, f.Fd(),
uintptr(level), uintptr(soOriginalDst), // uintptr(level), uintptr(soOriginalDst),
uintptr(unsafe.Pointer(&sockaddr)), // uintptr(unsafe.Pointer(&sockaddr)),
uintptr(unsafe.Pointer(&len)), 0) // uintptr(unsafe.Pointer(&len)), 0)
maddr, err := syscall.GetsockoptIPv6Mreq(int(f.Fd()), syscall.SOL_IP, soOriginalDst)
if errno != 0 { if err != nil {
return nil, fmt.Errorf("syscall error %d", errno) return nil, err
} }
var port uint16 var port uint16
var ip net.IP var ip net.IP
rawaddr := (*syscall.RawSockaddrInet4)(unsafe.Pointer(&maddr.Multiaddr))
switch sockaddr.Addr.Family { ip = net.IP(rawaddr.Addr[0:])
case syscall.AF_INET: port = ntohs(rawaddr.Port)
a := (*syscall.RawSockaddrInet4)(unsafe.Pointer(&sockaddr))
ip = net.IP(a.Addr[0:])
port = ntohs(a.Port)
case syscall.AF_INET6:
a := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&sockaddr))
ip = net.IP(a.Addr[0:])
port = ntohs(a.Port)
default:
return nil, fmt.Errorf("unknown socket family: %d",
sockaddr.Addr.Family)
}
addr := &net.TCPAddr{IP: ip, Port: int(port)} addr := &net.TCPAddr{IP: ip, Port: int(port)}
return addr, nil return addr, nil

@ -1,5 +0,0 @@
package obfssh
// getsockopt syscall number
// refer to $GOROOT/src/syscall/syscall_linux_386.go
const sysGetSockOpt = 15

@ -1,11 +0,0 @@
// +build linux, !386
// +build linux
package obfssh
import (
"syscall"
)
// getsockopt syscall number
const sysGetSockOpt = syscall.SYS_GETSOCKOPT
Loading…
Cancel
Save