diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-05-26 22:20:12 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-05-26 22:35:53 +0900 |
commit | b00a45b094ffb70db90a4e67d8599e939ca6857e (patch) | |
tree | 6d605631ce498fc9137d461e506690e2737b0bed /server/sockopt.go | |
parent | 349f74e4e7e990a221d747243a7810a0bf31f8f0 (diff) |
server: fix File() misuse for syscall's setsockopt
We use TCPConn.File() for syscal.SetsockoptInt but File() sets the
underlying os.File to blocking mode and returns a copy. It's not what
we don't want. Instead, we access to private members with reflect...
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'server/sockopt.go')
-rw-r--r-- | server/sockopt.go | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/server/sockopt.go b/server/sockopt.go index 2392cdf4..2d26c588 100644 --- a/server/sockopt.go +++ b/server/sockopt.go @@ -2,6 +2,8 @@ package server import ( "net" + "os" + "reflect" "strings" "syscall" "unsafe" @@ -45,6 +47,15 @@ func SetTcpMD5SigSockopts(fd int, address string, key string) error { return e } +func TCPConnToFd(tcp *net.TCPConn) int { + n := reflect.ValueOf(*tcp) + conn := n.FieldByName("conn") + fd := conn.FieldByName("fd") + p := reflect.Indirect(fd) + sysfd := p.FieldByName("sysfd") + return int(sysfd.Int()) +} + func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error { level := syscall.IPPROTO_IP name := syscall.IP_TTL @@ -52,9 +63,5 @@ func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error { level = syscall.IPPROTO_IPV6 name = syscall.IPV6_UNICAST_HOPS } - file, _ := conn.File() - _, _, e := syscall.Syscall6(syscall.SYS_SETSOCKOPT, uintptr(int(file.Fd())), - uintptr(level), uintptr(name), - uintptr(unsafe.Pointer(&ttl)), unsafe.Sizeof(ttl), 0) - return e + return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(TCPConnToFd(conn), level, name, ttl)) } |