payload_cmsg.go (2592B)
1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos 6 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos 7 8 package ipv6 9 10 import ( 11 "net" 12 13 "golang.org/x/net/internal/socket" 14 ) 15 16 // ReadFrom reads a payload of the received IPv6 datagram, from the 17 // endpoint c, copying the payload into b. It returns the number of 18 // bytes copied into b, the control message cm and the source address 19 // src of the received datagram. 20 func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { 21 if !c.ok() { 22 return 0, nil, nil, errInvalidConn 23 } 24 c.rawOpt.RLock() 25 m := socket.Message{ 26 Buffers: [][]byte{b}, 27 OOB: NewControlMessage(c.rawOpt.cflags), 28 } 29 c.rawOpt.RUnlock() 30 switch c.PacketConn.(type) { 31 case *net.UDPConn: 32 if err := c.RecvMsg(&m, 0); err != nil { 33 return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} 34 } 35 case *net.IPConn: 36 if err := c.RecvMsg(&m, 0); err != nil { 37 return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} 38 } 39 default: 40 return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType} 41 } 42 if m.NN > 0 { 43 cm = new(ControlMessage) 44 if err := cm.Parse(m.OOB[:m.NN]); err != nil { 45 return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} 46 } 47 cm.Src = netAddrToIP16(m.Addr) 48 } 49 return m.N, cm, m.Addr, nil 50 } 51 52 // WriteTo writes a payload of the IPv6 datagram, to the destination 53 // address dst through the endpoint c, copying the payload from b. It 54 // returns the number of bytes written. The control message cm allows 55 // the IPv6 header fields and the datagram path to be specified. The 56 // cm may be nil if control of the outgoing datagram is not required. 57 func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { 58 if !c.ok() { 59 return 0, errInvalidConn 60 } 61 m := socket.Message{ 62 Buffers: [][]byte{b}, 63 OOB: cm.Marshal(), 64 Addr: dst, 65 } 66 err = c.SendMsg(&m, 0) 67 if err != nil { 68 err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Addr: opAddr(dst), Err: err} 69 } 70 return m.N, err 71 }