Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(201)

Delta Between Two Patch Sets: ipv4/control_linux.go

Issue 97800043: code review 97800043: go.net/ipv4: add support for dragonfly (Closed)
Left Patch Set: diff -r 424a15ce8b2f https://code.google.com/p/go.net Created 9 years, 11 months ago
Right Patch Set: diff -r 9c33002573cb https://code.google.com/p/go.net Created 9 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « ipv4/control_bsd.go ('k') | ipv4/control_nonpktinfo.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2012 The Go Authors. All rights reserved. 1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 package ipv4 5 package ipv4
6 6
7 import ( 7 import (
8 "os"
9 "syscall" 8 "syscall"
10 "unsafe" 9 "unsafe"
11 ) 10 )
12
13 // Linux provides a convenient path control option IP_PKTINFO that
14 // contains IP_SENDSRCADDR, IP_RECVDSTADDR, IP_RECVIF and IP_SENDIF.
15 const pktinfo = FlagSrc | FlagDst | FlagInterface
16 11
17 func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error { 12 func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
18 opt.Lock() 13 opt.Lock()
19 defer opt.Unlock() 14 defer opt.Unlock()
20 if cf&FlagTTL != 0 { 15 if cf&FlagTTL != 0 {
21 if err := setIPv4ReceiveTTL(fd, on); err != nil { 16 if err := setIPv4ReceiveTTL(fd, on); err != nil {
22 return err 17 return err
23 } 18 }
24 if on { 19 if on {
25 opt.set(FlagTTL) 20 opt.set(FlagTTL)
26 } else { 21 } else {
27 opt.clear(FlagTTL) 22 opt.clear(FlagTTL)
28 } 23 }
29 } 24 }
30 » if cf&pktinfo != 0 { 25 » if cf&(FlagSrc|FlagDst|FlagInterface) != 0 {
31 if err := setIPv4PacketInfo(fd, on); err != nil { 26 if err := setIPv4PacketInfo(fd, on); err != nil {
32 return err 27 return err
33 } 28 }
34 if on { 29 if on {
35 » » » opt.set(cf & pktinfo) 30 » » » opt.set(cf & (FlagSrc | FlagDst | FlagInterface))
36 } else { 31 } else {
37 » » » opt.clear(cf & pktinfo) 32 » » » opt.clear(cf & (FlagSrc | FlagDst | FlagInterface))
38 } 33 }
39 } 34 }
40 return nil 35 return nil
41 } 36 }
42 37
43 func newControlMessage(opt *rawOpt) (oob []byte) { 38 func (opt *rawOpt) oobLen() (l int) {
44 » opt.Lock()
45 » defer opt.Unlock()
46 » l, off := 0, 0
47 if opt.isset(FlagTTL) { 39 if opt.isset(FlagTTL) {
48 l += syscall.CmsgSpace(1) 40 l += syscall.CmsgSpace(1)
49 } 41 }
50 » if opt.isset(pktinfo) { 42 » if opt.isset(FlagSrc | FlagDst | FlagInterface) {
51 l += syscall.CmsgSpace(sysSizeofPacketInfo) 43 l += syscall.CmsgSpace(sysSizeofPacketInfo)
52 }
53 if l > 0 {
54 oob = make([]byte, l)
55 if opt.isset(FlagTTL) {
56 m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
57 m.Level = ianaProtocolIP
58 m.Type = sysSockoptReceiveTTL
59 m.SetLen(syscall.CmsgLen(1))
60 off += syscall.CmsgSpace(1)
61 }
62 if opt.isset(pktinfo) {
63 m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
64 m.Level = ianaProtocolIP
65 m.Type = sysSockoptPacketInfo
66 m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
67 off += syscall.CmsgSpace(sysSizeofPacketInfo)
68 }
69 } 44 }
70 return 45 return
71 } 46 }
72 47
73 func parseControlMessage(b []byte) (*ControlMessage, error) { 48 func (opt *rawOpt) marshalControlMessage() (oob []byte) {
74 » if len(b) == 0 { 49 » var off int
75 » » return nil, nil 50 » oob = make([]byte, opt.oobLen())
51 » if opt.isset(FlagTTL) {
52 » » m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
53 » » m.Level = ianaProtocolIP
54 » » m.Type = sysSockoptReceiveTTL
55 » » m.SetLen(syscall.CmsgLen(1))
56 » » off += syscall.CmsgSpace(1)
76 } 57 }
77 » cmsgs, err := syscall.ParseSocketControlMessage(b) 58 » if opt.isset(FlagSrc | FlagDst | FlagInterface) {
78 » if err != nil { 59 » » m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[0]))
79 » » return nil, os.NewSyscallError("parse socket control message", e rr) 60 » » m.Level = ianaProtocolIP
80 » } 61 » » m.Type = sysSockoptPacketInfo
81 » cm := &ControlMessage{} 62 » » m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
82 » for _, m := range cmsgs { 63 » » off += syscall.CmsgSpace(sysSizeofPacketInfo)
83 » » if m.Header.Level != ianaProtocolIP {
84 » » » continue
85 » » }
86 » » switch m.Header.Type {
87 » » case sysSockoptTTL:
88 » » » cm.TTL = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
89 » » case sysSockoptPacketInfo:
90 » » » pi := (*sysPacketInfo)(unsafe.Pointer(&m.Data[0]))
91 » » » cm.IfIndex = int(pi.IfIndex)
92 » » » cm.Dst = pi.IP[:]
93 » » }
94 » }
95 » return cm, nil
96 }
97
98 func marshalControlMessage(cm *ControlMessage) (oob []byte) {
99 » if cm == nil {
100 » » return
101 » }
102 » l, off := 0, 0
103 » pion := false
104 » if cm.Src.To4() != nil || cm.IfIndex != 0 {
105 » » pion = true
106 » » l += syscall.CmsgSpace(sysSizeofPacketInfo)
107 » }
108 » if l > 0 {
109 » » oob = make([]byte, l)
110 » » if pion {
111 » » » m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
112 » » » m.Level = ianaProtocolIP
113 » » » m.Type = sysSockoptPacketInfo
114 » » » m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
115 » » » pi := (*sysPacketInfo)(unsafe.Pointer(&oob[off+syscall.C msgLen(0)]))
116 » » » if ip := cm.Src.To4(); ip != nil {
117 » » » » copy(pi.IP[:], ip)
118 » » » }
119 » » » if cm.IfIndex != 0 {
120 » » » » pi.IfIndex = int32(cm.IfIndex)
121 » » » }
122 » » » off += syscall.CmsgSpace(sysSizeofPacketInfo)
123 » » }
124 } 64 }
125 return 65 return
126 } 66 }
67
68 func (cm *ControlMessage) oobLen() (l int) {
69 if cm.Src.To4() != nil || cm.IfIndex != 0 {
70 l += syscall.CmsgSpace(sysSizeofPacketInfo)
71 }
72 return
73 }
74
75 func (cm *ControlMessage) parseControlMessage(m *syscall.SocketControlMessage) {
76 switch m.Header.Type {
77 case sysSockoptTTL:
78 cm.TTL = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
79 case sysSockoptPacketInfo:
80 pi := (*sysPacketInfo)(unsafe.Pointer(&m.Data[0]))
81 cm.IfIndex = int(pi.IfIndex)
82 cm.Dst = pi.IP[:]
83 }
84 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b