transparent-proxy/server/hack_linux.go

71 lines
1.8 KiB
Go

package server
/**
* WARNING WARNING WARNING
* This file contains MANY DIRTY HACKS, and most of them made much assume to go internal code layout.
* For every new go version, you MUST try to use every function, make sure they didn't panic for you.
*/
// WARZONE BEGINS HERE! MIND YOUR HEAD!
import (
"golang.org/x/sys/unix"
"net"
"reflect"
)
const (
SO_ORIGINAL_DST = 80
)
func GetFDFromTCPConn(conn *net.TCPConn) int {
// Actual fd is stored at: (*(*TCPConn).conn.fd).pfd.Sysfd
v := reflect.ValueOf(*conn)
c := v.FieldByName("conn")
fdp := c.FieldByName("fd")
fd := reflect.Indirect(fdp)
pfd := fd.FieldByName("pfd")
Sysfd := pfd.FieldByName("Sysfd")
return int(Sysfd.Int())
}
func GetAddr4FromFD(fd int) *net.TCPAddr {
mtuinfo, err := unix.GetsockoptIPv6MTUInfo(fd, unix.IPPROTO_IP, SO_ORIGINAL_DST)
if err != nil {
panic(err)
}
addr := mtuinfo.Addr
/*
RawSockaddrInet6 layout:
Family 2byte ignore or assert == AF_INET
Port 2byte ipv4 port
Flowinfo 4byte ipv4 address
Addr 16byte ignore for ipv4
Scope_id 4byte ignore for ipv4
*/
addr.Flowinfo = be32toh(addr.Flowinfo)
a, b, c, d := byte(addr.Flowinfo>>24), byte((addr.Flowinfo>>16)&255), byte((addr.Flowinfo>>8)&255), byte(addr.Flowinfo&255)
ip := net.IPv4(a, b, c, d)
return &net.TCPAddr{IP: ip, Port: int(be16toh(addr.Port)), Zone: ""}
}
func GetAddr6FromFD(fd int) *net.TCPAddr {
mtuinfo, err := unix.GetsockoptIPv6MTUInfo(fd, unix.IPPROTO_IPV6, SO_ORIGINAL_DST)
if err != nil {
panic(err)
}
addr := mtuinfo.Addr
/*
RawSockaddrInet6 layout:
Family 2byte ignore or assert == AF_INET6
Port 2byte ipv6 port
Flowinfo 4byte ipv6 flowinfo ignore
Addr 16byte ipv6 addr
Scope_id 4byte ipv6 scope id ignore
*/
v6addr := make(net.IP, 16)
// Make GC happy?
copy(v6addr, addr.Addr[:])
return &net.TCPAddr{IP: v6addr, Port: int(be16toh(addr.Port)), Zone: ""}
}