mirror of
https://github.com/golang/go
synced 2024-11-26 14:36:52 -07:00
net: add read, write message methods to IPConn, UDPConn
Both methods allow to access the IP ancillary data through socket control messages. This CL is required for CL 6482044; go.net/ipv4: new package. R=rsc, r, dave CC=golang-dev https://golang.org/cl/6426047
This commit is contained in:
parent
33cceb09e2
commit
4b9e8415de
@ -98,6 +98,25 @@ func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) {
|
||||
return n, uaddr.toAddr(), err
|
||||
}
|
||||
|
||||
// ReadMsgIP reads a packet from c, copying the payload into b and the
|
||||
// associdated out-of-band data into oob. It returns the number of
|
||||
// bytes copied into b, the number of bytes copied into oob, the flags
|
||||
// that were set on the packet and the source address of the packet.
|
||||
func (c *IPConn) ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err error) {
|
||||
if !c.ok() {
|
||||
return 0, 0, 0, nil, syscall.EINVAL
|
||||
}
|
||||
var sa syscall.Sockaddr
|
||||
n, oobn, flags, sa, err = c.fd.ReadMsg(b, oob)
|
||||
switch sa := sa.(type) {
|
||||
case *syscall.SockaddrInet4:
|
||||
addr = &IPAddr{sa.Addr[0:]}
|
||||
case *syscall.SockaddrInet6:
|
||||
addr = &IPAddr{sa.Addr[0:]}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// WriteToIP writes an IP packet to addr via c, copying the payload from b.
|
||||
//
|
||||
// WriteToIP can be made to time out and return
|
||||
@ -127,6 +146,20 @@ func (c *IPConn) WriteTo(b []byte, addr Addr) (int, error) {
|
||||
return c.WriteToIP(b, a)
|
||||
}
|
||||
|
||||
// WriteMsgIP writes a packet to addr via c, copying the payload from
|
||||
// b and the associated out-of-band data from oob. It returns the
|
||||
// number of payload and out-of-band bytes written.
|
||||
func (c *IPConn) WriteMsgIP(b, oob []byte, addr *IPAddr) (n, oobn int, err error) {
|
||||
if !c.ok() {
|
||||
return 0, 0, syscall.EINVAL
|
||||
}
|
||||
sa, err := addr.sockaddr(c.fd.family)
|
||||
if err != nil {
|
||||
return 0, 0, &OpError{"write", c.fd.net, addr, err}
|
||||
}
|
||||
return c.fd.WriteMsg(b, oob, sa)
|
||||
}
|
||||
|
||||
// DialIP connects to the remote address raddr on the network protocol netProto,
|
||||
// which must be "ip", "ip4", or "ip6" followed by a colon and a protocol number or name.
|
||||
func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) {
|
||||
|
@ -87,6 +87,26 @@ func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error) {
|
||||
return n, uaddr.toAddr(), err
|
||||
}
|
||||
|
||||
// ReadMsgUDP reads a packet from c, copying the payload into b and
|
||||
// the associdated out-of-band data into oob. It returns the number
|
||||
// of bytes copied into b, the number of bytes copied into oob, the
|
||||
// flags that were set on the packet and the source address of the
|
||||
// packet.
|
||||
func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
|
||||
if !c.ok() {
|
||||
return 0, 0, 0, nil, syscall.EINVAL
|
||||
}
|
||||
var sa syscall.Sockaddr
|
||||
n, oobn, flags, sa, err = c.fd.ReadMsg(b, oob)
|
||||
switch sa := sa.(type) {
|
||||
case *syscall.SockaddrInet4:
|
||||
addr = &UDPAddr{sa.Addr[0:], sa.Port}
|
||||
case *syscall.SockaddrInet6:
|
||||
addr = &UDPAddr{sa.Addr[0:], sa.Port}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// WriteToUDP writes a UDP packet to addr via c, copying the payload from b.
|
||||
//
|
||||
// WriteToUDP can be made to time out and return
|
||||
@ -119,6 +139,23 @@ func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) {
|
||||
return c.WriteToUDP(b, a)
|
||||
}
|
||||
|
||||
// WriteMsgUDP writes a packet to addr via c, copying the payload from
|
||||
// b and the associated out-of-band data from oob. It returns the
|
||||
// number of payload and out-of-band bytes written.
|
||||
func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
|
||||
if !c.ok() {
|
||||
return 0, 0, syscall.EINVAL
|
||||
}
|
||||
if c.fd.isConnected {
|
||||
return 0, 0, &OpError{"write", c.fd.net, addr, ErrWriteToConnected}
|
||||
}
|
||||
sa, err := addr.sockaddr(c.fd.family)
|
||||
if err != nil {
|
||||
return 0, 0, &OpError{"write", c.fd.net, addr, err}
|
||||
}
|
||||
return c.fd.WriteMsg(b, oob, sa)
|
||||
}
|
||||
|
||||
// DialUDP connects to the remote address raddr on the network net,
|
||||
// which must be "udp", "udp4", or "udp6". If laddr is not nil, it is used
|
||||
// as the local address for the connection.
|
||||
|
Loading…
Reference in New Issue
Block a user