Commit 235e8821 authored by Mikio Hara's avatar Mikio Hara

go.net/ipv6: implement each platform's sticky socket option binding table

Also adds helper methods for platform-dependent types.

LGTM=iant
R=iant
CC=golang-codereviews
https://golang.org/cl/165920044
parent 97775bb4
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ipv6
type sysSockoptLen uint32
const (
sysSizeofPacketInfo = 0x14
sysSizeofMulticastReq = 0x14
sysSizeofICMPFilter = 0x20
)
type sysPacketInfo struct {
IP [16]byte
IfIndex uint32
}
type sysMulticastReq struct {
IP [16]byte
IfIndex uint32
}
......@@ -11,27 +11,38 @@ import (
"syscall"
)
// RFC 3542 options
const (
// See /usr/include/netinet6/in6.h.
sysSockoptReceiveTrafficClass = syscall.IPV6_RECVTCLASS
sysSockoptTrafficClass = syscall.IPV6_TCLASS
sysSockoptReceiveHopLimit = syscall.IPV6_RECVHOPLIMIT
sysSockoptHopLimit = syscall.IPV6_HOPLIMIT
sysSockoptReceivePacketInfo = syscall.IPV6_RECVPKTINFO
sysSockoptPacketInfo = syscall.IPV6_PKTINFO
sysSockoptReceivePathMTU = syscall.IPV6_RECVPATHMTU
sysSockoptPathMTU = syscall.IPV6_PATHMTU
sysSockoptNextHop = syscall.IPV6_NEXTHOP
sysSockoptChecksum = syscall.IPV6_CHECKSUM
// See /usr/include/netinet6/in6.h.
sysSockoptICMPFilter = 0x12 // syscall.ICMP6_FILTER
type sysSockoptLen int32
var (
sockOpts = [ssoMax]sockOpt{
ssoTrafficClass: {ianaProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt},
ssoHopLimit: {ianaProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt},
ssoMulticastInterface: {ianaProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface},
ssoMulticastHopLimit: {ianaProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt},
ssoMulticastLoopback: {ianaProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt},
ssoReceiveTrafficClass: {ianaProtocolIPv6, sysIPV6_RECVTCLASS, ssoTypeInt},
ssoReceiveHopLimit: {ianaProtocolIPv6, sysIPV6_RECVHOPLIMIT, ssoTypeInt},
ssoReceivePacketInfo: {ianaProtocolIPv6, sysIPV6_RECVPKTINFO, ssoTypeInt},
ssoReceivePathMTU: {ianaProtocolIPv6, sysIPV6_RECVPATHMTU, ssoTypeInt},
ssoPathMTU: {ianaProtocolIPv6, sysIPV6_PATHMTU, ssoTypeMTUInfo},
ssoChecksum: {ianaProtocolIPv6, sysIPV6_CHECKSUM, ssoTypeInt},
ssoICMPFilter: {ianaProtocolIPv6ICMP, sysICMP6_FILTER, ssoTypeICMPFilter},
ssoJoinGroup: {ianaProtocolIPv6, sysIPV6_JOIN_GROUP, ssoTypeIPMreq},
ssoLeaveGroup: {ianaProtocolIPv6, sysIPV6_LEAVE_GROUP, ssoTypeIPMreq},
}
)
func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
sa.Len = syscall.SizeofSockaddrInet6
func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) {
sa.Len = sysSizeofSockaddrInet6
sa.Family = syscall.AF_INET6
copy(sa.Addr[:], ip)
sa.Scope_id = uint32(ifindex)
sa.Scope_id = uint32(i)
}
func (pi *sysInet6Pktinfo) setIfindex(i int) {
pi.Ifindex = uint32(i)
}
func (mreq *sysIPv6Mreq) setIfindex(i int) {
mreq.Interface = uint32(i)
}
......@@ -9,35 +9,63 @@ import (
"syscall"
)
// RFC 2292 options
const (
// See /usr/include/netinet6/in6.h.
sysSockopt2292HopLimit = syscall.IPV6_2292HOPLIMIT
sysSockopt2292PacketInfo = syscall.IPV6_2292PKTINFO
sysSockopt2292NextHop = syscall.IPV6_2292NEXTHOP
)
type sysSockoptLen int32
// RFC 3542 options
const (
// See /usr/include/netinet6/in6.h.
sysSockoptReceiveTrafficClass = 0x23 // IPV6_RECVTCLASS
sysSockoptTrafficClass = 0x24 // IPV6_TCLASS
sysSockoptReceiveHopLimit = 0x25 // IPV6_RECVHOPLIMIT
sysSockoptHopLimit = 0x2f // IPV6_HOPLIMIT
sysSockoptReceivePacketInfo = 0x3d // IPV6_RECVPKTINFO
sysSockoptPacketInfo = 0x2e // IPV6_PKTINFO
sysSockoptReceivePathMTU = 0x2b // IPV6_RECVPATHMTU
sysSockoptPathMTU = 0x2c // IPV6_PATHMTU
sysSockoptNextHop = 0x30 // IPV6_NEXTHOP
sysSockoptChecksum = 0x1a // IPV6_CHECKSUM
// See /usr/include/netinet6/in6.h.
sysSockoptICMPFilter = 0x12 // ICMP6_FILTER
var (
sockOpts = [ssoMax]sockOpt{
ssoTrafficClass: {ianaProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt},
ssoHopLimit: {ianaProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt},
ssoMulticastInterface: {ianaProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface},
ssoMulticastHopLimit: {ianaProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt},
ssoMulticastLoopback: {ianaProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt},
ssoReceiveHopLimit: {ianaProtocolIPv6, sysIPV6_2292HOPLIMIT, ssoTypeInt},
ssoReceivePacketInfo: {ianaProtocolIPv6, sysIPV6_2292PKTINFO, ssoTypeInt},
ssoChecksum: {ianaProtocolIPv6, sysIPV6_CHECKSUM, ssoTypeInt},
ssoICMPFilter: {ianaProtocolIPv6ICMP, sysICMP6_FILTER, ssoTypeICMPFilter},
ssoJoinGroup: {ianaProtocolIPv6, sysIPV6_JOIN_GROUP, ssoTypeIPMreq},
ssoLeaveGroup: {ianaProtocolIPv6, sysIPV6_LEAVE_GROUP, ssoTypeIPMreq},
}
)
func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
sa.Len = syscall.SizeofSockaddrInet6
func init() {
// Seems like kern.osreldate is veiled on latest OS X. We use
// kern.osrelease instead.
osver, err := syscall.Sysctl("kern.osrelease")
if err != nil {
return
}
var i int
for i = range osver {
if osver[i] != '.' {
continue
}
}
// The IPV6_RECVPATHMTU and IPV6_PATHMTU options were
// introduced in OS X 10.7 (Darwin 11.0.0).
// See http://support.apple.com/kb/HT1633.
if i > 2 || i == 2 && osver[0] >= '1' && osver[1] >= '1' {
sockOpts[ssoReceivePathMTU].level = ianaProtocolIPv6
sockOpts[ssoReceivePathMTU].name = sysIPV6_RECVPATHMTU
sockOpts[ssoReceivePathMTU].typ = ssoTypeInt
// Please be informed that IPV6_PATHMTU option will be
// a cause of kernel crash on 10.9 and earlier.
//sockOpts[ssoPathMTU].level = ianaProtocolIPv6
//sockOpts[ssoPathMTU].name = sysIPV6_PATHMTU
//sockOpts[ssoPathMTU].typ = ssoTypeMTUInfo
}
}
func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) {
sa.Len = sysSizeofSockaddrInet6
sa.Family = syscall.AF_INET6
copy(sa.Addr[:], ip)
sa.Scope_id = uint32(ifindex)
sa.Scope_id = uint32(i)
}
func (pi *sysInet6Pktinfo) setIfindex(i int) {
pi.Ifindex = uint32(i)
}
func (mreq *sysIPv6Mreq) setIfindex(i int) {
mreq.Interface = uint32(i)
}
......@@ -9,26 +9,37 @@ import (
"syscall"
)
// RFC 3542 options
const (
// See /usr/include/linux/ipv6.h,in6.h.
sysSockoptReceiveTrafficClass = syscall.IPV6_RECVTCLASS
sysSockoptTrafficClass = syscall.IPV6_TCLASS
sysSockoptReceiveHopLimit = syscall.IPV6_RECVHOPLIMIT
sysSockoptHopLimit = syscall.IPV6_HOPLIMIT
sysSockoptReceivePacketInfo = syscall.IPV6_RECVPKTINFO
sysSockoptPacketInfo = syscall.IPV6_PKTINFO
sysSockoptReceivePathMTU = 0x3c // IPV6_RECVPATHMTU
sysSockoptPathMTU = 0x3d // IPV6_PATHMTU
sysSockoptNextHop = syscall.IPV6_NEXTHOP
sysSockoptChecksum = syscall.IPV6_CHECKSUM
type sysSockoptLen int32
// See /usr/include/linux/icmpv6.h.
sysSockoptICMPFilter = 0x1 // syscall.ICMPV6_FILTER
var (
sockOpts = [ssoMax]sockOpt{
ssoTrafficClass: {ianaProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt},
ssoHopLimit: {ianaProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt},
ssoMulticastInterface: {ianaProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface},
ssoMulticastHopLimit: {ianaProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt},
ssoMulticastLoopback: {ianaProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt},
ssoReceiveTrafficClass: {ianaProtocolIPv6, sysIPV6_RECVTCLASS, ssoTypeInt},
ssoReceiveHopLimit: {ianaProtocolIPv6, sysIPV6_RECVHOPLIMIT, ssoTypeInt},
ssoReceivePacketInfo: {ianaProtocolIPv6, sysIPV6_RECVPKTINFO, ssoTypeInt},
ssoReceivePathMTU: {ianaProtocolIPv6, sysIPV6_RECVPATHMTU, ssoTypeInt},
ssoPathMTU: {ianaProtocolIPv6, sysIPV6_PATHMTU, ssoTypeMTUInfo},
ssoChecksum: {ianaProtocolReserved, sysIPV6_CHECKSUM, ssoTypeInt},
ssoICMPFilter: {ianaProtocolIPv6ICMP, sysICMPV6_FILTER, ssoTypeICMPFilter},
ssoJoinGroup: {ianaProtocolIPv6, sysIPV6_ADD_MEMBERSHIP, ssoTypeIPMreq},
ssoLeaveGroup: {ianaProtocolIPv6, sysIPV6_DROP_MEMBERSHIP, ssoTypeIPMreq},
}
)
func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) {
sa.Family = syscall.AF_INET6
copy(sa.Addr[:], ip)
sa.Scope_id = uint32(ifindex)
sa.Scope_id = uint32(i)
}
func (pi *sysInet6Pktinfo) setIfindex(i int) {
pi.Ifindex = int32(i)
}
func (mreq *sysIPv6Mreq) setIfindex(i int) {
mreq.Ifindex = int32(i)
}
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build nacl plan9 solaris
package ipv6
type sysSockoptLen int32
var (
sockOpts = [ssoMax]sockOpt{}
)
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd
package ipv6
import "syscall"
// RFC 3493 options
const (
sysSockoptUnicastHopLimit = syscall.IPV6_UNICAST_HOPS
sysSockoptMulticastHopLimit = syscall.IPV6_MULTICAST_HOPS
sysSockoptMulticastInterface = syscall.IPV6_MULTICAST_IF
sysSockoptMulticastLoopback = syscall.IPV6_MULTICAST_LOOP
sysSockoptJoinGroup = syscall.IPV6_JOIN_GROUP
sysSockoptLeaveGroup = syscall.IPV6_LEAVE_GROUP
)
const sysSizeofMTUInfo = 0x20
type sysMTUInfo struct {
Addr syscall.RawSockaddrInet6
MTU uint32
}
......@@ -9,25 +9,51 @@ import (
"syscall"
)
// RFC 3493 options
const (
// See ws2tcpip.h.
sysSockoptUnicastHopLimit = syscall.IPV6_UNICAST_HOPS
sysSockoptMulticastHopLimit = syscall.IPV6_MULTICAST_HOPS
sysSockoptMulticastInterface = syscall.IPV6_MULTICAST_IF
sysSockoptMulticastLoopback = syscall.IPV6_MULTICAST_LOOP
sysSockoptJoinGroup = syscall.IPV6_JOIN_GROUP
sysSockoptLeaveGroup = syscall.IPV6_LEAVE_GROUP
sysIPV6_UNICAST_HOPS = 0x4
sysIPV6_MULTICAST_IF = 0x9
sysIPV6_MULTICAST_HOPS = 0xa
sysIPV6_MULTICAST_LOOP = 0xb
sysIPV6_JOIN_GROUP = 0xc
sysIPV6_LEAVE_GROUP = 0xd
sysIPV6_PKTINFO = 0x13
sysSizeofSockaddrInet6 = 0x1c
sysSizeofIPv6Mreq = 0x14
)
// RFC 3542 options
const (
// See ws2tcpip.h.
sysSockoptPacketInfo = 0x13 // IPV6_PKTINFO
type sysSockaddrInet6 struct {
Family uint16
Port uint16
Flowinfo uint32
Addr [16]byte /* in6_addr */
Scope_id uint32
}
type sysIPv6Mreq struct {
Multiaddr [16]byte /* in6_addr */
Interface uint32
}
var (
sockOpts = [ssoMax]sockOpt{
ssoHopLimit: {ianaProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt},
ssoMulticastInterface: {ianaProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface},
ssoMulticastHopLimit: {ianaProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt},
ssoMulticastLoopback: {ianaProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt},
ssoJoinGroup: {ianaProtocolIPv6, sysIPV6_JOIN_GROUP, ssoTypeIPMreq},
ssoLeaveGroup: {ianaProtocolIPv6, sysIPV6_LEAVE_GROUP, ssoTypeIPMreq},
}
)
func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) {
sa.Family = syscall.AF_INET6
copy(sa.Addr[:], ip)
sa.Scope_id = uint32(ifindex)
sa.Scope_id = uint32(i)
}
func (mreq *sysIPv6Mreq) setIfindex(i int) {
mreq.Interface = uint32(i)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment