From 477b035bf4c053980f6e43cf446847a63d4bb010 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 15 Aug 2016 16:35:50 +0900 Subject: server: move linux specific functions to sockopt_linux.go Signed-off-by: FUJITA Tomonori --- server/sockopt.go | 73 +++++--------------------------------------- server/sockopt_linux.go | 68 +++++++++++++++++++++++++++++++++++++++++ server/sockopt_linux_test.go | 68 +++++++++++++++++++++++++++++++++++++++++ server/sockopt_nonlinux.go | 27 ---------------- server/sockopt_test.go | 52 ------------------------------- 5 files changed, 144 insertions(+), 144 deletions(-) create mode 100644 server/sockopt_linux_test.go delete mode 100644 server/sockopt_nonlinux.go delete mode 100644 server/sockopt_test.go diff --git a/server/sockopt.go b/server/sockopt.go index 6361a7ae..34d9ed5e 100644 --- a/server/sockopt.go +++ b/server/sockopt.go @@ -12,80 +12,23 @@ // implied. // See the License for the specific language governing permissions and // limitations under the License. +// +build !linux,!dragonfly,!freebsd,!netbsd,!openbsd package server import ( + "fmt" "net" - "os" - "strings" - "syscall" - "unsafe" ) -const ( - TCP_MD5SIG = 14 -) - -type tcpmd5sig struct { - ss_family uint16 - ss [126]byte - pad1 uint16 - keylen uint16 - pad2 uint32 - key [80]byte -} - -func buildTcpMD5Sig(address string, key string) (tcpmd5sig, error) { - t := tcpmd5sig{} - addr := net.ParseIP(address) - if addr.To4() != nil { - t.ss_family = syscall.AF_INET - copy(t.ss[2:], addr.To4()) - } else { - t.ss_family = syscall.AF_INET6 - copy(t.ss[6:], addr.To16()) - } - - t.keylen = uint16(len(key)) - copy(t.key[0:], []byte(key)) - - return t, nil -} - func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error { - t, _ := buildTcpMD5Sig(address, key) - fi, err := l.File() - defer fi.Close() - if err != nil { - return err - } - if l, err := net.FileListener(fi); err == nil { - defer l.Close() - } - _, _, e := syscall.Syscall6(syscall.SYS_SETSOCKOPT, fi.Fd(), - uintptr(syscall.IPPROTO_TCP), uintptr(TCP_MD5SIG), - uintptr(unsafe.Pointer(&t)), unsafe.Sizeof(t), 0) - if e > 0 { - return e - } - return nil + return fmt.Errorf("md5 not supported") } func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error { - level := syscall.IPPROTO_IP - name := syscall.IP_TTL - if strings.Contains(conn.RemoteAddr().String(), "[") { - level = syscall.IPPROTO_IPV6 - name = syscall.IPV6_UNICAST_HOPS - } - fi, err := conn.File() - defer fi.Close() - if err != nil { - return err - } - if conn, err := net.FileConn(fi); err == nil { - defer conn.Close() - } - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(int(fi.Fd()), level, name, ttl)) + return fmt.Errorf("setting ttl is not supported") +} + +func DialTCPTimeoutWithMD5Sig(host string, port int, localAddr, key string, msec int) (*net.TCPConn, error) { + return nil, fmt.Errorf("md5 active connection unsupported") } diff --git a/server/sockopt_linux.go b/server/sockopt_linux.go index d1b08ace..cbe461d4 100644 --- a/server/sockopt_linux.go +++ b/server/sockopt_linux.go @@ -20,10 +20,78 @@ import ( "fmt" "net" "os" + "strings" "syscall" "unsafe" ) +const ( + TCP_MD5SIG = 14 +) + +type tcpmd5sig struct { + ss_family uint16 + ss [126]byte + pad1 uint16 + keylen uint16 + pad2 uint32 + key [80]byte +} + +func buildTcpMD5Sig(address string, key string) (tcpmd5sig, error) { + t := tcpmd5sig{} + addr := net.ParseIP(address) + if addr.To4() != nil { + t.ss_family = syscall.AF_INET + copy(t.ss[2:], addr.To4()) + } else { + t.ss_family = syscall.AF_INET6 + copy(t.ss[6:], addr.To16()) + } + + t.keylen = uint16(len(key)) + copy(t.key[0:], []byte(key)) + + return t, nil +} + +func SetTcpMD5SigSockopts(l *net.TCPListener, address string, key string) error { + t, _ := buildTcpMD5Sig(address, key) + fi, err := l.File() + defer fi.Close() + if err != nil { + return err + } + if l, err := net.FileListener(fi); err == nil { + defer l.Close() + } + _, _, e := syscall.Syscall6(syscall.SYS_SETSOCKOPT, fi.Fd(), + uintptr(syscall.IPPROTO_TCP), uintptr(TCP_MD5SIG), + uintptr(unsafe.Pointer(&t)), unsafe.Sizeof(t), 0) + if e > 0 { + return e + } + return nil +} + +func SetTcpTTLSockopts(conn *net.TCPConn, ttl int) error { + level := syscall.IPPROTO_IP + name := syscall.IP_TTL + if strings.Contains(conn.RemoteAddr().String(), "[") { + level = syscall.IPPROTO_IPV6 + name = syscall.IPV6_UNICAST_HOPS + } + fi, err := conn.File() + defer fi.Close() + if err != nil { + return err + } + if conn, err := net.FileConn(fi); err == nil { + defer conn.Close() + } + return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(int(fi.Fd()), level, name, ttl)) +} + func DialTCPTimeoutWithMD5Sig(host string, port int, localAddr, key string, msec int) (*net.TCPConn, error) { var family int var ra, la syscall.Sockaddr diff --git a/server/sockopt_linux_test.go b/server/sockopt_linux_test.go new file mode 100644 index 00000000..e3ef65d9 --- /dev/null +++ b/server/sockopt_linux_test.go @@ -0,0 +1,68 @@ +// Copyright (C) 2016 Nippon Telegraph and Telephone Corporation. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +// implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +build linux + +package server + +import ( + "bytes" + "syscall" + "testing" + "unsafe" +) + +func Test_buildTcpMD5Sig(t *testing.T) { + s, _ := buildTcpMD5Sig("1.2.3.4", "hello") + + if unsafe.Sizeof(s) != 216 { + t.Error("TCPM5Sig struct size is wrong", unsafe.Sizeof(s)) + } + + buf1 := make([]uint8, 216) + p := unsafe.Pointer(&s) + src := uintptr(p) + for i := uintptr(0); i < 216; i++ { + buf1[i] = *(*byte)(unsafe.Pointer(src + i)) + } + + buf2 := []uint8{2, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 104, 101, 108, 108, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + + if bytes.Compare(buf1, buf2) == 0 { + t.Log("OK") + } else { + t.Error("Something wrong v4") + } +} + +func Test_buildTcpMD5Sigv6(t *testing.T) { + s, _ := buildTcpMD5Sig("fe80::4850:31ff:fe01:fc55", "helloworld") + + buf1 := make([]uint8, 216) + p := unsafe.Pointer(&s) + src := uintptr(p) + for i := uintptr(0); i < 216; i++ { + buf1[i] = *(*byte)(unsafe.Pointer(src + i)) + } + + buf2 := []uint8{10, 0, 0, 0, 0, 0, 0, 0, 254, 128, 0, 0, 0, 0, 0, 0, 72, 80, 49, 255, 254, 1, 252, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 104, 101, 108, 108, 111, 119, 111, 114, 108, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + + buf2[0] = syscall.AF_INET6 + + if bytes.Compare(buf1, buf2) == 0 { + t.Log("OK") + } else { + t.Error("Something wrong v6") + } +} diff --git a/server/sockopt_nonlinux.go b/server/sockopt_nonlinux.go deleted file mode 100644 index 4ac4e44d..00000000 --- a/server/sockopt_nonlinux.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2016 Nippon Telegraph and Telephone Corporation. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// +build !linux - -package server - -import ( - "fmt" - "net" -) - -func DialTCPTimeoutWithMD5Sig(host string, port int, localAddr, key string, msec int) (*net.TCPConn, error) { - return nil, fmt.Errorf("md5 active connection unsupported") -} diff --git a/server/sockopt_test.go b/server/sockopt_test.go deleted file mode 100644 index 7167b4e8..00000000 --- a/server/sockopt_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package server - -import ( - "bytes" - "syscall" - "testing" - "unsafe" -) - -func Test_buildTcpMD5Sig(t *testing.T) { - s, _ := buildTcpMD5Sig("1.2.3.4", "hello") - - if unsafe.Sizeof(s) != 216 { - t.Error("TCPM5Sig struct size is wrong", unsafe.Sizeof(s)) - } - - buf1 := make([]uint8, 216) - p := unsafe.Pointer(&s) - src := uintptr(p) - for i := uintptr(0); i < 216; i++ { - buf1[i] = *(*byte)(unsafe.Pointer(src + i)) - } - - buf2 := []uint8{2, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 104, 101, 108, 108, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - - if bytes.Compare(buf1, buf2) == 0 { - t.Log("OK") - } else { - t.Error("Something wrong v4") - } -} - -func Test_buildTcpMD5Sigv6(t *testing.T) { - s, _ := buildTcpMD5Sig("fe80::4850:31ff:fe01:fc55", "helloworld") - - buf1 := make([]uint8, 216) - p := unsafe.Pointer(&s) - src := uintptr(p) - for i := uintptr(0); i < 216; i++ { - buf1[i] = *(*byte)(unsafe.Pointer(src + i)) - } - - buf2 := []uint8{10, 0, 0, 0, 0, 0, 0, 0, 254, 128, 0, 0, 0, 0, 0, 0, 72, 80, 49, 255, 254, 1, 252, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 104, 101, 108, 108, 111, 119, 111, 114, 108, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - - buf2[0] = syscall.AF_INET6 - - if bytes.Compare(buf1, buf2) == 0 { - t.Log("OK") - } else { - t.Error("Something wrong v6") - } -} -- cgit v1.2.3