From b00a45b094ffb70db90a4e67d8599e939ca6857e Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 26 May 2015 22:20:12 +0900 Subject: [PATCH] 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 --- server/sockopt.go | 17 ++++++++++++----- 1 file 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)) }