mirror of
https://github.com/golang/net.git
synced 2026-03-31 10:27:08 +09:00
go.net/ipv4: restructure ancillary data socket option handling
This CL chops existing ancillary data socket option handlers and puts them into platform dependent ancillary data socket option binding table for code readability. Fixes golang/go#6710. LGTM=iant R=iant CC=golang-codereviews https://golang.org/cl/153860043
This commit is contained in:
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
type rawOpt struct {
|
||||
sync.Mutex
|
||||
sync.RWMutex
|
||||
cflags ControlFlags
|
||||
}
|
||||
|
||||
@@ -50,3 +50,21 @@ func (cm *ControlMessage) String() string {
|
||||
}
|
||||
return fmt.Sprintf("ttl: %v, src: %v, dst: %v, ifindex: %v", cm.TTL, cm.Src, cm.Dst, cm.IfIndex)
|
||||
}
|
||||
|
||||
// Ancillary data socket options
|
||||
const (
|
||||
ctlTTL = iota // header field
|
||||
ctlSrc // header field
|
||||
ctlDst // header field
|
||||
ctlInterface // inbound or outbound interface
|
||||
ctlPacketInfo // inbound or outbound packet path
|
||||
ctlMax
|
||||
)
|
||||
|
||||
// A ctlOpt represents a binding for ancillary data socket option.
|
||||
type ctlOpt struct {
|
||||
name int // option name, must be equal or greater than 1
|
||||
length int // option length
|
||||
marshal func([]byte, *ControlMessage) []byte
|
||||
parse func(*ControlMessage, []byte)
|
||||
}
|
||||
|
||||
@@ -12,131 +12,27 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
|
||||
opt.Lock()
|
||||
defer opt.Unlock()
|
||||
if cf&FlagTTL != 0 {
|
||||
if err := setInt(fd, &sockOpts[ssoReceiveTTL], boolint(on)); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(FlagTTL)
|
||||
} else {
|
||||
opt.clear(FlagTTL)
|
||||
}
|
||||
}
|
||||
if sockOpts[ssoPacketInfo].name > 0 {
|
||||
if cf&(FlagSrc|FlagDst|FlagInterface) != 0 {
|
||||
if err := setInt(fd, &sockOpts[ssoPacketInfo], boolint(on)); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(cf & (FlagSrc | FlagDst | FlagInterface))
|
||||
} else {
|
||||
opt.clear(cf & (FlagSrc | FlagDst | FlagInterface))
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if cf&FlagDst != 0 {
|
||||
if err := setInt(fd, &sockOpts[ssoReceiveDst], boolint(on)); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(FlagDst)
|
||||
} else {
|
||||
opt.clear(FlagDst)
|
||||
}
|
||||
}
|
||||
if cf&FlagInterface != 0 {
|
||||
if err := setInt(fd, &sockOpts[ssoReceiveInterface], boolint(on)); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(FlagInterface)
|
||||
} else {
|
||||
opt.clear(FlagInterface)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
func marshalDst(b []byte, cm *ControlMessage) []byte {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||
m.Level = ianaProtocolIP
|
||||
m.Type = sysIP_RECVDSTADDR
|
||||
m.SetLen(syscall.CmsgLen(net.IPv4len))
|
||||
return b[syscall.CmsgSpace(net.IPv4len):]
|
||||
}
|
||||
|
||||
func (opt *rawOpt) oobLen() (l int) {
|
||||
if opt.isset(FlagTTL) {
|
||||
l += syscall.CmsgSpace(1)
|
||||
}
|
||||
if sockOpts[ssoPacketInfo].name > 0 {
|
||||
if opt.isset(FlagSrc | FlagDst | FlagInterface) {
|
||||
l += syscall.CmsgSpace(sysSizeofInetPktinfo)
|
||||
}
|
||||
} else {
|
||||
if opt.isset(FlagDst) {
|
||||
l += syscall.CmsgSpace(net.IPv4len)
|
||||
}
|
||||
if opt.isset(FlagInterface) {
|
||||
l += syscall.CmsgSpace(syscall.SizeofSockaddrDatalink)
|
||||
}
|
||||
}
|
||||
return
|
||||
func parseDst(cm *ControlMessage, b []byte) {
|
||||
cm.Dst = b[:net.IPv4len]
|
||||
}
|
||||
|
||||
func (opt *rawOpt) marshalControlMessage() (oob []byte) {
|
||||
var off int
|
||||
oob = make([]byte, opt.oobLen())
|
||||
if opt.isset(FlagTTL) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIP
|
||||
m.Type = sysIP_RECVTTL
|
||||
m.SetLen(syscall.CmsgLen(1))
|
||||
off += syscall.CmsgSpace(1)
|
||||
}
|
||||
if sockOpts[ssoPacketInfo].name > 0 {
|
||||
if opt.isset(FlagSrc | FlagDst | FlagInterface) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIP
|
||||
m.Type = sysIP_PKTINFO
|
||||
m.SetLen(syscall.CmsgLen(sysSizeofInetPktinfo))
|
||||
off += syscall.CmsgSpace(sysSizeofInetPktinfo)
|
||||
}
|
||||
} else {
|
||||
if opt.isset(FlagDst) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIP
|
||||
m.Type = sysIP_RECVDSTADDR
|
||||
m.SetLen(syscall.CmsgLen(net.IPv4len))
|
||||
off += syscall.CmsgSpace(net.IPv4len)
|
||||
}
|
||||
if opt.isset(FlagInterface) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIP
|
||||
m.Type = sysIP_RECVIF
|
||||
m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrDatalink))
|
||||
off += syscall.CmsgSpace(syscall.SizeofSockaddrDatalink)
|
||||
}
|
||||
}
|
||||
return
|
||||
func marshalInterface(b []byte, cm *ControlMessage) []byte {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||
m.Level = ianaProtocolIP
|
||||
m.Type = sysIP_RECVIF
|
||||
m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrDatalink))
|
||||
return b[syscall.CmsgSpace(syscall.SizeofSockaddrDatalink):]
|
||||
}
|
||||
|
||||
func (cm *ControlMessage) oobLen() (l int) {
|
||||
if sockOpts[ssoPacketInfo].name > 0 && (cm.Src.To4() != nil || cm.IfIndex != 0) {
|
||||
l += syscall.CmsgSpace(sysSizeofInetPktinfo)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (cm *ControlMessage) parseControlMessage(m *syscall.SocketControlMessage) {
|
||||
switch m.Header.Type {
|
||||
case sysIP_RECVTTL:
|
||||
cm.TTL = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
|
||||
case sysIP_RECVDSTADDR:
|
||||
cm.Dst = m.Data[:net.IPv4len]
|
||||
case sysIP_RECVIF:
|
||||
sadl := (*syscall.SockaddrDatalink)(unsafe.Pointer(&m.Data[0]))
|
||||
cm.IfIndex = int(sadl.Index)
|
||||
case sysIP_PKTINFO:
|
||||
pi := (*sysInetPktinfo)(unsafe.Pointer(&m.Data[0]))
|
||||
cm.IfIndex = int(pi.Ifindex)
|
||||
cm.Dst = pi.Addr[:]
|
||||
}
|
||||
func parseInterface(cm *ControlMessage, b []byte) {
|
||||
sadl := (*syscall.SockaddrDatalink)(unsafe.Pointer(&b[0]))
|
||||
cm.IfIndex = int(sadl.Index)
|
||||
}
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
// Copyright 2012 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 ipv4
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
|
||||
opt.Lock()
|
||||
defer opt.Unlock()
|
||||
if cf&FlagTTL != 0 {
|
||||
if err := setInt(fd, &sockOpts[ssoReceiveTTL], boolint(on)); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(FlagTTL)
|
||||
} else {
|
||||
opt.clear(FlagTTL)
|
||||
}
|
||||
}
|
||||
if cf&(FlagSrc|FlagDst|FlagInterface) != 0 {
|
||||
if err := setInt(fd, &sockOpts[ssoPacketInfo], boolint(on)); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(cf & (FlagSrc | FlagDst | FlagInterface))
|
||||
} else {
|
||||
opt.clear(cf & (FlagSrc | FlagDst | FlagInterface))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (opt *rawOpt) oobLen() (l int) {
|
||||
if opt.isset(FlagTTL) {
|
||||
l += syscall.CmsgSpace(1)
|
||||
}
|
||||
if opt.isset(FlagSrc | FlagDst | FlagInterface) {
|
||||
l += syscall.CmsgSpace(sysSizeofInetPktinfo)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (opt *rawOpt) marshalControlMessage() (oob []byte) {
|
||||
var off int
|
||||
oob = make([]byte, opt.oobLen())
|
||||
if opt.isset(FlagTTL) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
|
||||
m.Level = ianaProtocolIP
|
||||
m.Type = sysIP_RECVTTL
|
||||
m.SetLen(syscall.CmsgLen(1))
|
||||
off += syscall.CmsgSpace(1)
|
||||
}
|
||||
if opt.isset(FlagSrc | FlagDst | FlagInterface) {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[0]))
|
||||
m.Level = ianaProtocolIP
|
||||
m.Type = sysIP_PKTINFO
|
||||
m.SetLen(syscall.CmsgLen(sysSizeofInetPktinfo))
|
||||
off += syscall.CmsgSpace(sysSizeofInetPktinfo)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (cm *ControlMessage) oobLen() (l int) {
|
||||
if cm.Src.To4() != nil || cm.IfIndex != 0 {
|
||||
l += syscall.CmsgSpace(sysSizeofInetPktinfo)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (cm *ControlMessage) parseControlMessage(m *syscall.SocketControlMessage) {
|
||||
switch m.Header.Type {
|
||||
case sysIP_TTL:
|
||||
cm.TTL = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
|
||||
case sysIP_PKTINFO:
|
||||
pi := (*sysInetPktinfo)(unsafe.Pointer(&m.Data[0]))
|
||||
cm.IfIndex = int(pi.Ifindex)
|
||||
cm.Dst = pi.Addr[:]
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
// 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 !darwin,!linux
|
||||
|
||||
package ipv4
|
||||
|
||||
func (cm *ControlMessage) marshalPacketInfo() (oob []byte) {
|
||||
return nil
|
||||
}
|
||||
@@ -11,20 +11,25 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func (cm *ControlMessage) marshalPacketInfo() (oob []byte) {
|
||||
if l := cm.oobLen(); l > 0 {
|
||||
oob = make([]byte, l)
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[0]))
|
||||
m.Level = ianaProtocolIP
|
||||
m.Type = sysIP_PKTINFO
|
||||
m.SetLen(syscall.CmsgLen(sysSizeofInetPktinfo))
|
||||
pi := (*sysInetPktinfo)(unsafe.Pointer(&oob[syscall.CmsgLen(0)]))
|
||||
func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||
m.Level = ianaProtocolIP
|
||||
m.Type = sysIP_PKTINFO
|
||||
m.SetLen(syscall.CmsgLen(sysSizeofInetPktinfo))
|
||||
if cm != nil {
|
||||
pi := (*sysInetPktinfo)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
|
||||
if ip := cm.Src.To4(); ip != nil {
|
||||
copy(pi.Addr[:], ip)
|
||||
copy(pi.Spec_dst[:], ip)
|
||||
}
|
||||
if cm.IfIndex != 0 {
|
||||
pi.setIfindex(cm.IfIndex)
|
||||
}
|
||||
}
|
||||
return
|
||||
return b[syscall.CmsgSpace(sysSizeofInetPktinfo):]
|
||||
}
|
||||
|
||||
func parsePacketInfo(cm *ControlMessage, b []byte) {
|
||||
pi := (*sysInetPktinfo)(unsafe.Pointer(&b[0]))
|
||||
cm.IfIndex = int(pi.Ifindex)
|
||||
cm.Dst = pi.Addr[:]
|
||||
}
|
||||
|
||||
@@ -9,12 +9,97 @@ package ipv4
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func newControlMessage(opt *rawOpt) (oob []byte) {
|
||||
func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
|
||||
opt.Lock()
|
||||
defer opt.Unlock()
|
||||
return opt.marshalControlMessage()
|
||||
if cf&FlagTTL != 0 {
|
||||
if err := setInt(fd, &sockOpts[ssoReceiveTTL], boolint(on)); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(FlagTTL)
|
||||
} else {
|
||||
opt.clear(FlagTTL)
|
||||
}
|
||||
}
|
||||
if sockOpts[ssoPacketInfo].name > 0 {
|
||||
if cf&(FlagSrc|FlagDst|FlagInterface) != 0 {
|
||||
if err := setInt(fd, &sockOpts[ssoPacketInfo], boolint(on)); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(cf & (FlagSrc | FlagDst | FlagInterface))
|
||||
} else {
|
||||
opt.clear(cf & (FlagSrc | FlagDst | FlagInterface))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if cf&FlagDst != 0 {
|
||||
if err := setInt(fd, &sockOpts[ssoReceiveDst], boolint(on)); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(FlagDst)
|
||||
} else {
|
||||
opt.clear(FlagDst)
|
||||
}
|
||||
}
|
||||
if cf&FlagInterface != 0 {
|
||||
if err := setInt(fd, &sockOpts[ssoReceiveInterface], boolint(on)); err != nil {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
opt.set(FlagInterface)
|
||||
} else {
|
||||
opt.clear(FlagInterface)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newControlMessage(opt *rawOpt) (oob []byte) {
|
||||
opt.RLock()
|
||||
var l int
|
||||
if opt.isset(FlagTTL) {
|
||||
l += syscall.CmsgSpace(ctlOpts[ctlTTL].length)
|
||||
}
|
||||
if ctlOpts[ctlPacketInfo].name > 0 {
|
||||
if opt.isset(FlagSrc | FlagDst | FlagInterface) {
|
||||
l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length)
|
||||
}
|
||||
} else {
|
||||
if opt.isset(FlagDst) {
|
||||
l += syscall.CmsgSpace(ctlOpts[ctlDst].length)
|
||||
}
|
||||
if opt.isset(FlagInterface) {
|
||||
l += syscall.CmsgSpace(ctlOpts[ctlInterface].length)
|
||||
}
|
||||
}
|
||||
if l > 0 {
|
||||
oob = make([]byte, l)
|
||||
b := oob
|
||||
if opt.isset(FlagTTL) {
|
||||
b = ctlOpts[ctlTTL].marshal(b, nil)
|
||||
}
|
||||
if ctlOpts[ctlPacketInfo].name > 0 {
|
||||
if opt.isset(FlagSrc | FlagDst | FlagInterface) {
|
||||
b = ctlOpts[ctlPacketInfo].marshal(b, nil)
|
||||
}
|
||||
} else {
|
||||
if opt.isset(FlagDst) {
|
||||
b = ctlOpts[ctlDst].marshal(b, nil)
|
||||
}
|
||||
if opt.isset(FlagInterface) {
|
||||
b = ctlOpts[ctlInterface].marshal(b, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
opt.RUnlock()
|
||||
return
|
||||
}
|
||||
|
||||
func parseControlMessage(b []byte) (*ControlMessage, error) {
|
||||
@@ -30,7 +115,16 @@ func parseControlMessage(b []byte) (*ControlMessage, error) {
|
||||
if m.Header.Level != ianaProtocolIP {
|
||||
continue
|
||||
}
|
||||
cm.parseControlMessage(&m)
|
||||
switch int(m.Header.Type) {
|
||||
case ctlOpts[ctlTTL].name:
|
||||
ctlOpts[ctlTTL].parse(cm, m.Data[:])
|
||||
case ctlOpts[ctlDst].name:
|
||||
ctlOpts[ctlDst].parse(cm, m.Data[:])
|
||||
case ctlOpts[ctlInterface].name:
|
||||
ctlOpts[ctlInterface].parse(cm, m.Data[:])
|
||||
case ctlOpts[ctlPacketInfo].name:
|
||||
ctlOpts[ctlPacketInfo].parse(cm, m.Data[:])
|
||||
}
|
||||
}
|
||||
return cm, nil
|
||||
}
|
||||
@@ -39,5 +133,32 @@ func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
||||
if cm == nil {
|
||||
return nil
|
||||
}
|
||||
return cm.marshalPacketInfo()
|
||||
var l int
|
||||
if ctlOpts[ctlPacketInfo].name > 0 {
|
||||
if cm.Src.To4() != nil || cm.IfIndex != 0 {
|
||||
l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length)
|
||||
}
|
||||
}
|
||||
if l > 0 {
|
||||
oob = make([]byte, l)
|
||||
b := oob
|
||||
if ctlOpts[ctlPacketInfo].name > 0 {
|
||||
if cm.Src.To4() != nil || cm.IfIndex != 0 {
|
||||
b = ctlOpts[ctlPacketInfo].marshal(b, cm)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func marshalTTL(b []byte, cm *ControlMessage) []byte {
|
||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||
m.Level = ianaProtocolIP
|
||||
m.Type = sysIP_RECVTTL
|
||||
m.SetLen(syscall.CmsgLen(1))
|
||||
return b[syscall.CmsgSpace(1):]
|
||||
}
|
||||
|
||||
func parseTTL(cm *ControlMessage, b []byte) {
|
||||
cm.TTL = int(*(*byte)(unsafe.Pointer(&b[:1][0])))
|
||||
}
|
||||
|
||||
@@ -6,21 +6,20 @@
|
||||
|
||||
package ipv4
|
||||
|
||||
type sysSockoptLen int32
|
||||
|
||||
const (
|
||||
sysIP_PKTINFO = 0
|
||||
|
||||
sysSizeofInetPktinfo = 0xc
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type sysInetPktinfo struct {
|
||||
Ifindex uint32
|
||||
Spec_dst [4]byte /* in_addr */
|
||||
Addr [4]byte /* in_addr */
|
||||
}
|
||||
type sysSockoptLen int32
|
||||
|
||||
var (
|
||||
ctlOpts = [ctlMax]ctlOpt{
|
||||
ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL},
|
||||
ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
|
||||
ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
|
||||
}
|
||||
|
||||
sockOpts = [ssoMax]sockOpt{
|
||||
ssoTOS: {sysIP_TOS, ssoTypeInt},
|
||||
ssoTTL: {sysIP_TTL, ssoTypeInt},
|
||||
|
||||
@@ -4,11 +4,20 @@
|
||||
|
||||
package ipv4
|
||||
|
||||
import "syscall"
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type sysSockoptLen int32
|
||||
|
||||
var (
|
||||
ctlOpts = [ctlMax]ctlOpt{
|
||||
ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL},
|
||||
ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
|
||||
ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
|
||||
}
|
||||
|
||||
sockOpts = [ssoMax]sockOpt{
|
||||
ssoTOS: {sysIP_TOS, ssoTypeInt},
|
||||
ssoTTL: {sysIP_TTL, ssoTypeInt},
|
||||
@@ -40,6 +49,10 @@ func init() {
|
||||
// The IP_PKTINFO was 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' {
|
||||
ctlOpts[ctlPacketInfo].name = sysIP_PKTINFO
|
||||
ctlOpts[ctlPacketInfo].length = sysSizeofInetPktinfo
|
||||
ctlOpts[ctlPacketInfo].marshal = marshalPacketInfo
|
||||
ctlOpts[ctlPacketInfo].parse = parsePacketInfo
|
||||
sockOpts[ssoPacketInfo].name = sysIP_RECVPKTINFO
|
||||
sockOpts[ssoPacketInfo].typ = ssoTypeInt
|
||||
sockOpts[ssoMulticastInterface].typ = ssoTypeIPMreqn
|
||||
|
||||
@@ -4,23 +4,20 @@
|
||||
|
||||
package ipv4
|
||||
|
||||
import "syscall"
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type sysSockoptLen int32
|
||||
|
||||
const (
|
||||
sysIP_PKTINFO = 0
|
||||
|
||||
sysSizeofInetPktinfo = 0xc
|
||||
)
|
||||
|
||||
type sysInetPktinfo struct {
|
||||
Ifindex uint32
|
||||
Spec_dst [4]byte /* in_addr */
|
||||
Addr [4]byte /* in_addr */
|
||||
}
|
||||
|
||||
var (
|
||||
ctlOpts = [ctlMax]ctlOpt{
|
||||
ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL},
|
||||
ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
|
||||
ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
|
||||
}
|
||||
|
||||
sockOpts = [ssoMax]sockOpt{
|
||||
ssoTOS: {sysIP_TOS, ssoTypeInt},
|
||||
ssoTTL: {sysIP_TTL, ssoTypeInt},
|
||||
|
||||
@@ -7,6 +7,11 @@ package ipv4
|
||||
type sysSockoptLen int32
|
||||
|
||||
var (
|
||||
ctlOpts = [ctlMax]ctlOpt{
|
||||
ctlTTL: {sysIP_TTL, 1, marshalTTL, parseTTL},
|
||||
ctlPacketInfo: {sysIP_PKTINFO, sysSizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
|
||||
}
|
||||
|
||||
sockOpts = [ssoMax]sockOpt{
|
||||
ssoTOS: {sysIP_TOS, ssoTypeInt},
|
||||
ssoTTL: {sysIP_TTL, ssoTypeInt},
|
||||
|
||||
@@ -9,5 +9,7 @@ package ipv4
|
||||
type sysSockoptLen int32
|
||||
|
||||
var (
|
||||
ctlOpts = [ctlMax]ctlOpt{}
|
||||
|
||||
sockOpts = [ssoMax]sockOpt{}
|
||||
)
|
||||
|
||||
@@ -43,6 +43,8 @@ type sysIPMreqSource struct {
|
||||
|
||||
// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms738586(v=vs.85).aspx
|
||||
var (
|
||||
ctlOpts = [ctlMax]ctlOpt{}
|
||||
|
||||
sockOpts = [ssoMax]sockOpt{
|
||||
ssoTOS: {sysIP_TOS, ssoTypeInt},
|
||||
ssoTTL: {sysIP_TTL, ssoTypeInt},
|
||||
|
||||
Reference in New Issue
Block a user