Commit 4b9e8415 authored by Mikio Hara's avatar Mikio Hara

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
parent 33cceb09
......@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment