mirror of
https://github.com/golang/net.git
synced 2026-03-31 10:27:08 +09:00
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
This commit is contained in:
23
ipv6/sys.go
23
ipv6/sys.go
@@ -1,23 +0,0 @@
|
||||
// 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
|
||||
type sysSockoptLen int32
|
||||
|
||||
// See /usr/include/netinet6/in6.h.
|
||||
sysSockoptICMPFilter = 0x12 // syscall.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},
|
||||
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
|
||||
|
||||
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},
|
||||
}
|
||||
)
|
||||
|
||||
// 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
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// See /usr/include/netinet6/in6.h.
|
||||
sysSockoptICMPFilter = 0x12 // ICMP6_FILTER
|
||||
)
|
||||
|
||||
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,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)
|
||||
}
|
||||
|
||||
13
ipv6/sys_stub.go
Normal file
13
ipv6/sys_stub.go
Normal file
@@ -0,0 +1,13 @@
|
||||
// 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{}
|
||||
)
|
||||
@@ -1,26 +0,0 @@
|
||||
// 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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user