go.net/ipv6: make it work with Go 1.1 This CL makes use of built-in syscall stuff to allow go.net/ipv6 to work together with Go 1.1. Also it's able to improve the package without churning the Go standard library. Fixes golang/go#6548. R=golang-dev, dave CC=golang-dev https://golang.org/cl/15040044
diff --git a/ipv6/sockopt_rfc3542_unix.go b/ipv6/sockopt_rfc3542_unix.go index 463f426..da9111c 100644 --- a/ipv6/sockopt_rfc3542_unix.go +++ b/ipv6/sockopt_rfc3542_unix.go
@@ -8,41 +8,83 @@ import ( "os" - "syscall" + "unsafe" ) func ipv6ReceiveTrafficClass(fd int) (bool, error) { - v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVTCLASS) - if err != nil { + var v int32 + l := sysSockoptLen(4) + if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveTrafficClass, uintptr(unsafe.Pointer(&v)), &l); err != nil { return false, os.NewSyscallError("getsockopt", err) } return v == 1, nil } func setIPv6ReceiveTrafficClass(fd int, v bool) error { - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVTCLASS, boolint(v))) + vv := int32(boolint(v)) + return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveTrafficClass, uintptr(unsafe.Pointer(&vv)), 4)) } func ipv6ReceiveHopLimit(fd int) (bool, error) { - v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVHOPLIMIT) - if err != nil { + var v int32 + l := sysSockoptLen(4) + if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveHopLimit, uintptr(unsafe.Pointer(&v)), &l); err != nil { return false, os.NewSyscallError("getsockopt", err) } return v == 1, nil } func setIPv6ReceiveHopLimit(fd int, v bool) error { - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVHOPLIMIT, boolint(v))) + vv := int32(boolint(v)) + return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveHopLimit, uintptr(unsafe.Pointer(&vv)), 4)) } func ipv6ReceivePacketInfo(fd int) (bool, error) { - v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVPKTINFO) - if err != nil { + var v int32 + l := sysSockoptLen(4) + if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptReceivePacketInfo, uintptr(unsafe.Pointer(&v)), &l); err != nil { return false, os.NewSyscallError("getsockopt", err) } return v == 1, nil } func setIPv6ReceivePacketInfo(fd int, v bool) error { - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVPKTINFO, boolint(v))) + vv := int32(boolint(v)) + return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceivePacketInfo, uintptr(unsafe.Pointer(&vv)), 4)) +} + +func ipv6PathMTU(fd int) (int, error) { + var v sysMTUInfo + l := sysSockoptLen(sysSizeofMTUInfo) + if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptPathMTU, uintptr(unsafe.Pointer(&v)), &l); err != nil { + return 0, os.NewSyscallError("getsockopt", err) + } + return int(v.MTU), nil +} + +func ipv6ReceivePathMTU(fd int) (bool, error) { + var v int32 + l := sysSockoptLen(4) + if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptReceivePathMTU, uintptr(unsafe.Pointer(&v)), &l); err != nil { + return false, os.NewSyscallError("getsockopt", err) + } + return v == 1, nil +} + +func setIPv6ReceivePathMTU(fd int, v bool) error { + vv := int32(boolint(v)) + return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceivePathMTU, uintptr(unsafe.Pointer(&vv)), 4)) +} + +func ipv6ICMPFilter(fd int) (*ICMPFilter, error) { + var v ICMPFilter + l := sysSockoptLen(sysSizeofICMPFilter) + if err := getsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, uintptr(unsafe.Pointer(&v.sysICMPFilter)), &l); err != nil { + return nil, os.NewSyscallError("getsockopt", err) + } + return &v, nil +} + +func setIPv6ICMPFilter(fd int, f *ICMPFilter) error { + return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, uintptr(unsafe.Pointer(&f.sysICMPFilter)), sysSizeofICMPFilter)) }