gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/net/ipv6/payload_cmsg.go (about)

     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  	"gitee.com/ks-custle/core-gm/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  }