Commit afd2d2b6 authored by Mikio Hara's avatar Mikio Hara

net: add Source field to OpError

Not only by network, transport-layer intermediaries but by
virtualization stuff in a node, it is hard to identify the root cause of
weird faults without information of packet flows after disaster
happened.

This change adds Source field to OpError to be able to represent a
5-tuple of internet transport protocols for helping dealing with
complicated systems.

Also clarifies the usage of Source and Addr fields.

Updates #4856.

Change-Id: I96a523fe391ed14406bfb21604c461d4aac2fa19
Reviewed-on: https://go-review.googlesource.com/9231Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent 35748919
...@@ -161,7 +161,7 @@ func DialTimeout(network, address string, timeout time.Duration) (Conn, error) { ...@@ -161,7 +161,7 @@ func DialTimeout(network, address string, timeout time.Duration) (Conn, error) {
func (d *Dialer) Dial(network, address string) (Conn, error) { func (d *Dialer) Dial(network, address string) (Conn, error) {
addrs, err := resolveAddrList("dial", network, address, d.deadline()) addrs, err := resolveAddrList("dial", network, address, d.deadline())
if err != nil { if err != nil {
return nil, &OpError{Op: "dial", Net: network, Addr: nil, Err: err} return nil, &OpError{Op: "dial", Net: network, Source: nil, Addr: nil, Err: err}
} }
var dialer func(deadline time.Time) (Conn, error) var dialer func(deadline time.Time) (Conn, error)
if d.DualStack && network == "tcp" { if d.DualStack && network == "tcp" {
...@@ -235,7 +235,7 @@ func dialMulti(net, addr string, la Addr, ras addrList, deadline time.Time) (Con ...@@ -235,7 +235,7 @@ func dialMulti(net, addr string, la Addr, ras addrList, deadline time.Time) (Con
// the destination address. // the destination address.
func dialSingle(net, addr string, la, ra Addr, deadline time.Time) (c Conn, err error) { func dialSingle(net, addr string, la, ra Addr, deadline time.Time) (c Conn, err error) {
if la != nil && la.Network() != ra.Network() { if la != nil && la.Network() != ra.Network() {
return nil, &OpError{Op: "dial", Net: net, Addr: ra, Err: errors.New("mismatched local address type " + la.Network())} return nil, &OpError{Op: "dial", Net: net, Source: la, Addr: ra, Err: errors.New("mismatched local address type " + la.Network())}
} }
switch ra := ra.(type) { switch ra := ra.(type) {
case *TCPAddr: case *TCPAddr:
...@@ -251,7 +251,7 @@ func dialSingle(net, addr string, la, ra Addr, deadline time.Time) (c Conn, err ...@@ -251,7 +251,7 @@ func dialSingle(net, addr string, la, ra Addr, deadline time.Time) (c Conn, err
la, _ := la.(*UnixAddr) la, _ := la.(*UnixAddr)
c, err = dialUnix(net, la, ra, deadline) c, err = dialUnix(net, la, ra, deadline)
default: default:
return nil, &OpError{Op: "dial", Net: net, Addr: ra, Err: &AddrError{Err: "unexpected address type", Addr: addr}} return nil, &OpError{Op: "dial", Net: net, Source: la, Addr: ra, Err: &AddrError{Err: "unexpected address type", Addr: addr}}
} }
if err != nil { if err != nil {
return nil, err // c is non-nil interface containing nil pointer return nil, err // c is non-nil interface containing nil pointer
...@@ -266,7 +266,7 @@ func dialSingle(net, addr string, la, ra Addr, deadline time.Time) (c Conn, err ...@@ -266,7 +266,7 @@ func dialSingle(net, addr string, la, ra Addr, deadline time.Time) (c Conn, err
func Listen(net, laddr string) (Listener, error) { func Listen(net, laddr string) (Listener, error) {
addrs, err := resolveAddrList("listen", net, laddr, noDeadline) addrs, err := resolveAddrList("listen", net, laddr, noDeadline)
if err != nil { if err != nil {
return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: err} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: nil, Err: err}
} }
var l Listener var l Listener
switch la := addrs.first(isIPv4).(type) { switch la := addrs.first(isIPv4).(type) {
...@@ -275,7 +275,7 @@ func Listen(net, laddr string) (Listener, error) { ...@@ -275,7 +275,7 @@ func Listen(net, laddr string) (Listener, error) {
case *UnixAddr: case *UnixAddr:
l, err = ListenUnix(net, la) l, err = ListenUnix(net, la)
default: default:
return nil, &OpError{Op: "listen", Net: net, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}}
} }
if err != nil { if err != nil {
return nil, err // l is non-nil interface containing nil pointer return nil, err // l is non-nil interface containing nil pointer
...@@ -290,7 +290,7 @@ func Listen(net, laddr string) (Listener, error) { ...@@ -290,7 +290,7 @@ func Listen(net, laddr string) (Listener, error) {
func ListenPacket(net, laddr string) (PacketConn, error) { func ListenPacket(net, laddr string) (PacketConn, error) {
addrs, err := resolveAddrList("listen", net, laddr, noDeadline) addrs, err := resolveAddrList("listen", net, laddr, noDeadline)
if err != nil { if err != nil {
return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: err} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: nil, Err: err}
} }
var l PacketConn var l PacketConn
switch la := addrs.first(isIPv4).(type) { switch la := addrs.first(isIPv4).(type) {
...@@ -301,7 +301,7 @@ func ListenPacket(net, laddr string) (PacketConn, error) { ...@@ -301,7 +301,7 @@ func ListenPacket(net, laddr string) (PacketConn, error) {
case *UnixAddr: case *UnixAddr:
l, err = ListenUnixgram(net, la) l, err = ListenUnixgram(net, la)
default: default:
return nil, &OpError{Op: "listen", Net: net, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}}
} }
if err != nil { if err != nil {
return nil, err // l is non-nil interface containing nil pointer return nil, err // l is non-nil interface containing nil pointer
......
...@@ -17,7 +17,7 @@ func dialChannel(net string, ra Addr, dialer func(time.Time) (Conn, error), dead ...@@ -17,7 +17,7 @@ func dialChannel(net string, ra Addr, dialer func(time.Time) (Conn, error), dead
} }
timeout := deadline.Sub(time.Now()) timeout := deadline.Sub(time.Now())
if timeout <= 0 { if timeout <= 0 {
return nil, &OpError{Op: "dial", Net: net, Addr: ra, Err: errTimeout} return nil, &OpError{Op: "dial", Net: net, Source: nil, Addr: ra, Err: errTimeout}
} }
t := time.NewTimer(timeout) t := time.NewTimer(timeout)
defer t.Stop() defer t.Stop()
...@@ -33,7 +33,7 @@ func dialChannel(net string, ra Addr, dialer func(time.Time) (Conn, error), dead ...@@ -33,7 +33,7 @@ func dialChannel(net string, ra Addr, dialer func(time.Time) (Conn, error), dead
}() }()
select { select {
case <-t.C: case <-t.C:
return nil, &OpError{Op: "dial", Net: net, Addr: ra, Err: errTimeout} return nil, &OpError{Op: "dial", Net: net, Source: nil, Addr: ra, Err: errTimeout}
case racer := <-ch: case racer := <-ch:
return racer.Conn, racer.error return racer.Conn, racer.error
} }
......
...@@ -32,34 +32,13 @@ func (e *OpError) isValid() error { ...@@ -32,34 +32,13 @@ func (e *OpError) isValid() error {
if e.Net == "" { if e.Net == "" {
return fmt.Errorf("OpError.Net is empty: %v", e) return fmt.Errorf("OpError.Net is empty: %v", e)
} }
switch addr := e.Addr.(type) { for _, addr := range []Addr{e.Source, e.Addr} {
case *TCPAddr: if addr != nil {
if addr == nil { switch addr.(type) {
return fmt.Errorf("OpError.Addr is empty: %v", e) case *TCPAddr, *UDPAddr, *IPAddr, *IPNet, *UnixAddr, *pipeAddr, fileAddr:
} default:
case *UDPAddr: return fmt.Errorf("OpError.Source or Addr is unknown type: %T, %v", addr, e)
if addr == nil { }
return fmt.Errorf("OpError.Addr is empty: %v", e)
}
case *IPAddr:
if addr == nil {
return fmt.Errorf("OpError.Addr is empty: %v", e)
}
case *IPNet:
if addr == nil {
return fmt.Errorf("OpError.Addr is empty: %v", e)
}
case *UnixAddr:
if addr == nil {
return fmt.Errorf("OpError.Addr is empty: %v", e)
}
case *pipeAddr:
if addr == nil {
return fmt.Errorf("OpError.Addr is empty: %v", e)
}
case fileAddr:
if addr == "" {
return fmt.Errorf("OpError.Addr is empty: %v", e)
} }
} }
if e.Err == nil { if e.Err == nil {
......
...@@ -18,7 +18,7 @@ func (f fileAddr) String() string { return string(f) } ...@@ -18,7 +18,7 @@ func (f fileAddr) String() string { return string(f) }
func FileConn(f *os.File) (c Conn, err error) { func FileConn(f *os.File) (c Conn, err error) {
c, err = fileConn(f) c, err = fileConn(f)
if err != nil { if err != nil {
err = &OpError{Op: "file", Net: "file+net", Addr: fileAddr(f.Name()), Err: err} err = &OpError{Op: "file", Net: "file+net", Source: nil, Addr: fileAddr(f.Name()), Err: err}
} }
return return
} }
...@@ -30,7 +30,7 @@ func FileConn(f *os.File) (c Conn, err error) { ...@@ -30,7 +30,7 @@ func FileConn(f *os.File) (c Conn, err error) {
func FileListener(f *os.File) (ln Listener, err error) { func FileListener(f *os.File) (ln Listener, err error) {
ln, err = fileListener(f) ln, err = fileListener(f)
if err != nil { if err != nil {
err = &OpError{Op: "file", Net: "file+net", Addr: fileAddr(f.Name()), Err: err} err = &OpError{Op: "file", Net: "file+net", Source: nil, Addr: fileAddr(f.Name()), Err: err}
} }
return return
} }
...@@ -42,7 +42,7 @@ func FileListener(f *os.File) (ln Listener, err error) { ...@@ -42,7 +42,7 @@ func FileListener(f *os.File) (ln Listener, err error) {
func FilePacketConn(f *os.File) (c PacketConn, err error) { func FilePacketConn(f *os.File) (c PacketConn, err error) {
c, err = filePacketConn(f) c, err = filePacketConn(f)
if err != nil { if err != nil {
err = &OpError{Op: "file", Net: "file+net", Addr: fileAddr(f.Name()), Err: err} err = &OpError{Op: "file", Net: "file+net", Source: nil, Addr: fileAddr(f.Name()), Err: err}
} }
return return
} }
...@@ -62,11 +62,11 @@ func (f Flags) String() string { ...@@ -62,11 +62,11 @@ func (f Flags) String() string {
// Addrs returns interface addresses for a specific interface. // Addrs returns interface addresses for a specific interface.
func (ifi *Interface) Addrs() ([]Addr, error) { func (ifi *Interface) Addrs() ([]Addr, error) {
if ifi == nil { if ifi == nil {
return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: errInvalidInterface} return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterface}
} }
ifat, err := interfaceAddrTable(ifi) ifat, err := interfaceAddrTable(ifi)
if err != nil { if err != nil {
err = &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err} err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
} }
return ifat, err return ifat, err
} }
...@@ -75,11 +75,11 @@ func (ifi *Interface) Addrs() ([]Addr, error) { ...@@ -75,11 +75,11 @@ func (ifi *Interface) Addrs() ([]Addr, error) {
// a specific interface. // a specific interface.
func (ifi *Interface) MulticastAddrs() ([]Addr, error) { func (ifi *Interface) MulticastAddrs() ([]Addr, error) {
if ifi == nil { if ifi == nil {
return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: errInvalidInterface} return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterface}
} }
ifat, err := interfaceMulticastAddrTable(ifi) ifat, err := interfaceMulticastAddrTable(ifi)
if err != nil { if err != nil {
err = &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err} err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
} }
return ifat, err return ifat, err
} }
...@@ -88,7 +88,7 @@ func (ifi *Interface) MulticastAddrs() ([]Addr, error) { ...@@ -88,7 +88,7 @@ func (ifi *Interface) MulticastAddrs() ([]Addr, error) {
func Interfaces() ([]Interface, error) { func Interfaces() ([]Interface, error) {
ift, err := interfaceTable(0) ift, err := interfaceTable(0)
if err != nil { if err != nil {
err = &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err} err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
} }
return ift, err return ift, err
} }
...@@ -98,7 +98,7 @@ func Interfaces() ([]Interface, error) { ...@@ -98,7 +98,7 @@ func Interfaces() ([]Interface, error) {
func InterfaceAddrs() ([]Addr, error) { func InterfaceAddrs() ([]Addr, error) {
ifat, err := interfaceAddrTable(nil) ifat, err := interfaceAddrTable(nil)
if err != nil { if err != nil {
err = &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err} err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
} }
return ifat, err return ifat, err
} }
...@@ -106,15 +106,15 @@ func InterfaceAddrs() ([]Addr, error) { ...@@ -106,15 +106,15 @@ func InterfaceAddrs() ([]Addr, error) {
// InterfaceByIndex returns the interface specified by index. // InterfaceByIndex returns the interface specified by index.
func InterfaceByIndex(index int) (*Interface, error) { func InterfaceByIndex(index int) (*Interface, error) {
if index <= 0 { if index <= 0 {
return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: errInvalidInterfaceIndex} return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterfaceIndex}
} }
ift, err := interfaceTable(index) ift, err := interfaceTable(index)
if err != nil { if err != nil {
return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err} return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
} }
ifi, err := interfaceByIndex(ift, index) ifi, err := interfaceByIndex(ift, index)
if err != nil { if err != nil {
err = &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err} err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
} }
return ifi, err return ifi, err
} }
...@@ -131,16 +131,16 @@ func interfaceByIndex(ift []Interface, index int) (*Interface, error) { ...@@ -131,16 +131,16 @@ func interfaceByIndex(ift []Interface, index int) (*Interface, error) {
// InterfaceByName returns the interface specified by name. // InterfaceByName returns the interface specified by name.
func InterfaceByName(name string) (*Interface, error) { func InterfaceByName(name string) (*Interface, error) {
if name == "" { if name == "" {
return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: errInvalidInterfaceName} return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterfaceName}
} }
ift, err := interfaceTable(0) ift, err := interfaceTable(0)
if err != nil { if err != nil {
return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err} return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
} }
for _, ifi := range ift { for _, ifi := range ift {
if name == ifi.Name { if name == ifi.Name {
return &ifi, nil return &ifi, nil
} }
} }
return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: errNoSuchInterface} return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errNoSuchInterface}
} }
...@@ -23,12 +23,12 @@ type IPConn struct { ...@@ -23,12 +23,12 @@ type IPConn struct {
// Timeout() == true after a fixed time limit; see SetDeadline and // Timeout() == true after a fixed time limit; see SetDeadline and
// SetReadDeadline. // SetReadDeadline.
func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) { func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) {
return 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9} return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
} }
// ReadFrom implements the PacketConn ReadFrom method. // ReadFrom implements the PacketConn ReadFrom method.
func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) { func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) {
return 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9} return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
} }
// ReadMsgIP reads a packet from c, copying the payload into b and the // ReadMsgIP reads a packet from c, copying the payload into b and the
...@@ -36,7 +36,7 @@ func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) { ...@@ -36,7 +36,7 @@ func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) {
// bytes copied into b, the number of bytes copied into oob, the flags // 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. // 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) { func (c *IPConn) ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err error) {
return 0, 0, 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9} return 0, 0, 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
} }
// WriteToIP writes an IP packet to addr via c, copying the payload // WriteToIP writes an IP packet to addr via c, copying the payload
...@@ -47,19 +47,19 @@ func (c *IPConn) ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err ...@@ -47,19 +47,19 @@ func (c *IPConn) ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err
// SetWriteDeadline. On packet-oriented connections, write timeouts // SetWriteDeadline. On packet-oriented connections, write timeouts
// are rare. // are rare.
func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error) { func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error) {
return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EPLAN9} return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EPLAN9}
} }
// WriteTo implements the PacketConn WriteTo method. // WriteTo implements the PacketConn WriteTo method.
func (c *IPConn) WriteTo(b []byte, addr Addr) (int, error) { func (c *IPConn) WriteTo(b []byte, addr Addr) (int, error) {
return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EPLAN9} return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EPLAN9}
} }
// WriteMsgIP writes a packet to addr via c, copying the payload from // 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 // b and the associated out-of-band data from oob. It returns the
// number of payload and out-of-band bytes written. // number of payload and out-of-band bytes written.
func (c *IPConn) WriteMsgIP(b, oob []byte, addr *IPAddr) (n, oobn int, err error) { func (c *IPConn) WriteMsgIP(b, oob []byte, addr *IPAddr) (n, oobn int, err error) {
return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EPLAN9} return 0, 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EPLAN9}
} }
// DialIP connects to the remote address raddr on the network protocol // DialIP connects to the remote address raddr on the network protocol
...@@ -70,7 +70,7 @@ func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) { ...@@ -70,7 +70,7 @@ func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) {
} }
func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, error) { func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, error) {
return nil, syscall.EPLAN9 return nil, &OpError{Op: "dial", Net: netProto, Source: laddr, Addr: raddr, Err: syscall.EPLAN9}
} }
// ListenIP listens for incoming IP packets addressed to the local // ListenIP listens for incoming IP packets addressed to the local
...@@ -78,5 +78,5 @@ func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, ...@@ -78,5 +78,5 @@ func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn,
// methods can be used to receive and send IP packets with per-packet // methods can be used to receive and send IP packets with per-packet
// addressing. // addressing.
func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) { func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) {
return nil, syscall.EPLAN9 return nil, &OpError{Op: "listen", Net: netProto, Source: nil, Addr: laddr, Err: syscall.EPLAN9}
} }
...@@ -81,7 +81,7 @@ func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) { ...@@ -81,7 +81,7 @@ func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) {
addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))} addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
} }
if err != nil { if err != nil {
err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: err} err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return n, addr, err return n, addr, err
} }
...@@ -130,7 +130,7 @@ func (c *IPConn) ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err ...@@ -130,7 +130,7 @@ func (c *IPConn) ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err
addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))} addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
} }
if err != nil { if err != nil {
err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: err} err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return return
} }
...@@ -147,18 +147,18 @@ func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error) { ...@@ -147,18 +147,18 @@ func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error) {
return 0, syscall.EINVAL return 0, syscall.EINVAL
} }
if c.fd.isConnected { if c.fd.isConnected {
return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected} return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: ErrWriteToConnected}
} }
if addr == nil { if addr == nil {
return 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress} return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: errMissingAddress}
} }
sa, err := addr.sockaddr(c.fd.family) sa, err := addr.sockaddr(c.fd.family)
if err != nil { if err != nil {
return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err} return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
} }
n, err := c.fd.writeTo(b, sa) n, err := c.fd.writeTo(b, sa)
if err != nil { if err != nil {
err = &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err} err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
} }
return n, err return n, err
} }
...@@ -170,7 +170,7 @@ func (c *IPConn) WriteTo(b []byte, addr Addr) (int, error) { ...@@ -170,7 +170,7 @@ func (c *IPConn) WriteTo(b []byte, addr Addr) (int, error) {
} }
a, ok := addr.(*IPAddr) a, ok := addr.(*IPAddr)
if !ok { if !ok {
return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EINVAL} return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
} }
return c.WriteToIP(b, a) return c.WriteToIP(b, a)
} }
...@@ -183,19 +183,19 @@ func (c *IPConn) WriteMsgIP(b, oob []byte, addr *IPAddr) (n, oobn int, err error ...@@ -183,19 +183,19 @@ func (c *IPConn) WriteMsgIP(b, oob []byte, addr *IPAddr) (n, oobn int, err error
return 0, 0, syscall.EINVAL return 0, 0, syscall.EINVAL
} }
if c.fd.isConnected { if c.fd.isConnected {
return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected} return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: ErrWriteToConnected}
} }
if addr == nil { if addr == nil {
return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress} return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: errMissingAddress}
} }
var sa syscall.Sockaddr var sa syscall.Sockaddr
sa, err = addr.sockaddr(c.fd.family) sa, err = addr.sockaddr(c.fd.family)
if err != nil { if err != nil {
return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err} return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
} }
n, oobn, err = c.fd.writeMsg(b, oob, sa) n, oobn, err = c.fd.writeMsg(b, oob, sa)
if err != nil { if err != nil {
err = &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err} err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
} }
return return
} }
...@@ -210,19 +210,19 @@ func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) { ...@@ -210,19 +210,19 @@ func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) {
func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, error) { func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, error) {
net, proto, err := parseNetwork(netProto) net, proto, err := parseNetwork(netProto)
if err != nil { if err != nil {
return nil, &OpError{Op: "dial", Net: netProto, Addr: raddr, Err: err} return nil, &OpError{Op: "dial", Net: netProto, Source: laddr, Addr: raddr, Err: err}
} }
switch net { switch net {
case "ip", "ip4", "ip6": case "ip", "ip4", "ip6":
default: default:
return nil, &OpError{Op: "dial", Net: netProto, Addr: raddr, Err: UnknownNetworkError(netProto)} return nil, &OpError{Op: "dial", Net: netProto, Source: laddr, Addr: raddr, Err: UnknownNetworkError(netProto)}
} }
if raddr == nil { if raddr == nil {
return nil, &OpError{Op: "dial", Net: netProto, Addr: nil, Err: errMissingAddress} return nil, &OpError{Op: "dial", Net: netProto, Source: laddr, Addr: raddr, Err: errMissingAddress}
} }
fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_RAW, proto, "dial") fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_RAW, proto, "dial")
if err != nil { if err != nil {
return nil, &OpError{Op: "dial", Net: netProto, Addr: raddr, Err: err} return nil, &OpError{Op: "dial", Net: netProto, Source: laddr, Addr: raddr, Err: err}
} }
return newIPConn(fd), nil return newIPConn(fd), nil
} }
...@@ -234,16 +234,16 @@ func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, ...@@ -234,16 +234,16 @@ func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn,
func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) { func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) {
net, proto, err := parseNetwork(netProto) net, proto, err := parseNetwork(netProto)
if err != nil { if err != nil {
return nil, &OpError{Op: "dial", Net: netProto, Addr: laddr, Err: err} return nil, &OpError{Op: "dial", Net: netProto, Source: nil, Addr: laddr, Err: err}
} }
switch net { switch net {
case "ip", "ip4", "ip6": case "ip", "ip4", "ip6":
default: default:
return nil, &OpError{Op: "listen", Net: netProto, Addr: laddr, Err: UnknownNetworkError(netProto)} return nil, &OpError{Op: "listen", Net: netProto, Source: nil, Addr: laddr, Err: UnknownNetworkError(netProto)}
} }
fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_RAW, proto, "listen") fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_RAW, proto, "listen")
if err != nil { if err != nil {
return nil, &OpError{Op: "listen", Net: netProto, Addr: laddr, Err: err} return nil, &OpError{Op: "listen", Net: netProto, Source: nil, Addr: laddr, Err: err}
} }
return newIPConn(fd), nil return newIPConn(fd), nil
} }
...@@ -152,23 +152,23 @@ func dialPlan9(net string, laddr, raddr Addr) (fd *netFD, err error) { ...@@ -152,23 +152,23 @@ func dialPlan9(net string, laddr, raddr Addr) (fd *netFD, err error) {
defer func() { netErr(err) }() defer func() { netErr(err) }()
f, dest, proto, name, err := startPlan9(net, raddr) f, dest, proto, name, err := startPlan9(net, raddr)
if err != nil { if err != nil {
return nil, &OpError{"dial", net, raddr, err} return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: err}
} }
_, err = f.WriteString("connect " + dest) _, err = f.WriteString("connect " + dest)
if err != nil { if err != nil {
f.Close() f.Close()
return nil, &OpError{"dial", f.Name(), raddr, err} return nil, &OpError{Op: "dial", Net: f.Name(), Source: laddr, Addr: raddr, Err: err}
} }
data, err := os.OpenFile(netdir+"/"+proto+"/"+name+"/data", os.O_RDWR, 0) data, err := os.OpenFile(netdir+"/"+proto+"/"+name+"/data", os.O_RDWR, 0)
if err != nil { if err != nil {
f.Close() f.Close()
return nil, &OpError{"dial", net, raddr, err} return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: err}
} }
laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local") laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local")
if err != nil { if err != nil {
data.Close() data.Close()
f.Close() f.Close()
return nil, &OpError{"dial", proto, raddr, err} return nil, &OpError{Op: "dial", Net: proto, Source: laddr, Addr: raddr, Err: err}
} }
return newFD(proto, name, f, data, laddr, raddr) return newFD(proto, name, f, data, laddr, raddr)
} }
...@@ -177,52 +177,52 @@ func listenPlan9(net string, laddr Addr) (fd *netFD, err error) { ...@@ -177,52 +177,52 @@ func listenPlan9(net string, laddr Addr) (fd *netFD, err error) {
defer func() { netErr(err) }() defer func() { netErr(err) }()
f, dest, proto, name, err := startPlan9(net, laddr) f, dest, proto, name, err := startPlan9(net, laddr)
if err != nil { if err != nil {
return nil, &OpError{"listen", net, laddr, err} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
} }
_, err = f.WriteString("announce " + dest) _, err = f.WriteString("announce " + dest)
if err != nil { if err != nil {
f.Close() f.Close()
return nil, &OpError{"announce", proto, laddr, err} return nil, &OpError{Op: "announce", Net: proto, Source: nil, Addr: laddr, Err: err}
} }
laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local") laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local")
if err != nil { if err != nil {
f.Close() f.Close()
return nil, &OpError{Op: "listen", Net: net, Err: err} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
} }
return newFD(proto, name, f, nil, laddr, nil) return newFD(proto, name, f, nil, laddr, nil)
} }
func (l *netFD) netFD() (*netFD, error) { func (fd *netFD) netFD() (*netFD, error) {
return newFD(l.net, l.n, l.ctl, l.data, l.laddr, l.raddr) return newFD(fd.net, fd.n, fd.ctl, fd.data, fd.laddr, fd.raddr)
} }
func (l *netFD) acceptPlan9() (fd *netFD, err error) { func (fd *netFD) acceptPlan9() (nfd *netFD, err error) {
defer func() { netErr(err) }() defer func() { netErr(err) }()
if err := l.readLock(); err != nil { if err := fd.readLock(); err != nil {
return nil, err return nil, err
} }
defer l.readUnlock() defer fd.readUnlock()
f, err := os.Open(l.dir + "/listen") f, err := os.Open(fd.dir + "/listen")
if err != nil { if err != nil {
return nil, &OpError{"accept", l.dir + "/listen", l.laddr, err} return nil, &OpError{Op: "accept", Net: fd.dir + "/listen", Source: nil, Addr: fd.laddr, Err: err}
} }
var buf [16]byte var buf [16]byte
n, err := f.Read(buf[:]) n, err := f.Read(buf[:])
if err != nil { if err != nil {
f.Close() f.Close()
return nil, &OpError{"accept", l.dir + "/listen", l.laddr, err} return nil, &OpError{Op: "accept", Net: fd.dir + "/listen", Source: nil, Addr: fd.laddr, Err: err}
} }
name := string(buf[:n]) name := string(buf[:n])
data, err := os.OpenFile(netdir+"/"+l.net+"/"+name+"/data", os.O_RDWR, 0) data, err := os.OpenFile(netdir+"/"+fd.net+"/"+name+"/data", os.O_RDWR, 0)
if err != nil { if err != nil {
f.Close() f.Close()
return nil, &OpError{"accept", l.net, l.laddr, err} return nil, &OpError{Op: "accept", Net: fd.net, Source: nil, Addr: fd.laddr, Err: err}
} }
raddr, err := readPlan9Addr(l.net, netdir+"/"+l.net+"/"+name+"/remote") raddr, err := readPlan9Addr(fd.net, netdir+"/"+fd.net+"/"+name+"/remote")
if err != nil { if err != nil {
data.Close() data.Close()
f.Close() f.Close()
return nil, &OpError{"accept", l.net, l.laddr, err} return nil, &OpError{Op: "accept", Net: fd.net, Source: nil, Addr: fd.laddr, Err: err}
} }
return newFD(l.net, name, f, data, l.laddr, raddr) return newFD(fd.net, name, f, data, fd.laddr, raddr)
} }
...@@ -123,12 +123,7 @@ func (c *conn) Read(b []byte) (int, error) { ...@@ -123,12 +123,7 @@ func (c *conn) Read(b []byte) (int, error) {
} }
n, err := c.fd.Read(b) n, err := c.fd.Read(b)
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
err = &OpError{Op: "read", Net: c.fd.net, Err: err} err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
if c.fd.raddr != nil {
err.(*OpError).Addr = c.fd.raddr
} else {
err.(*OpError).Addr = c.fd.laddr // for unconnected-mode sockets
}
} }
return n, err return n, err
} }
...@@ -140,12 +135,7 @@ func (c *conn) Write(b []byte) (int, error) { ...@@ -140,12 +135,7 @@ func (c *conn) Write(b []byte) (int, error) {
} }
n, err := c.fd.Write(b) n, err := c.fd.Write(b)
if err != nil { if err != nil {
err = &OpError{Op: "write", Net: c.fd.net, Err: err} err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
if c.fd.raddr != nil {
err.(*OpError).Addr = c.fd.raddr
} else {
err.(*OpError).Addr = c.fd.laddr // for unconnected-mode sockets
}
} }
return n, err return n, err
} }
...@@ -157,12 +147,7 @@ func (c *conn) Close() error { ...@@ -157,12 +147,7 @@ func (c *conn) Close() error {
} }
err := c.fd.Close() err := c.fd.Close()
if err != nil { if err != nil {
err = &OpError{Op: "close", Net: c.fd.net, Err: err} err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
if c.fd.raddr != nil {
err.(*OpError).Addr = c.fd.raddr
} else {
err.(*OpError).Addr = c.fd.laddr // for unconnected-mode sockets
}
} }
return err return err
} }
...@@ -193,7 +178,7 @@ func (c *conn) SetDeadline(t time.Time) error { ...@@ -193,7 +178,7 @@ func (c *conn) SetDeadline(t time.Time) error {
return syscall.EINVAL return syscall.EINVAL
} }
if err := c.fd.setDeadline(t); err != nil { if err := c.fd.setDeadline(t); err != nil {
return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err} return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
} }
return nil return nil
} }
...@@ -204,7 +189,7 @@ func (c *conn) SetReadDeadline(t time.Time) error { ...@@ -204,7 +189,7 @@ func (c *conn) SetReadDeadline(t time.Time) error {
return syscall.EINVAL return syscall.EINVAL
} }
if err := c.fd.setReadDeadline(t); err != nil { if err := c.fd.setReadDeadline(t); err != nil {
return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err} return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
} }
return nil return nil
} }
...@@ -215,7 +200,7 @@ func (c *conn) SetWriteDeadline(t time.Time) error { ...@@ -215,7 +200,7 @@ func (c *conn) SetWriteDeadline(t time.Time) error {
return syscall.EINVAL return syscall.EINVAL
} }
if err := c.fd.setWriteDeadline(t); err != nil { if err := c.fd.setWriteDeadline(t); err != nil {
return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err} return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
} }
return nil return nil
} }
...@@ -227,7 +212,7 @@ func (c *conn) SetReadBuffer(bytes int) error { ...@@ -227,7 +212,7 @@ func (c *conn) SetReadBuffer(bytes int) error {
return syscall.EINVAL return syscall.EINVAL
} }
if err := setReadBuffer(c.fd, bytes); err != nil { if err := setReadBuffer(c.fd, bytes); err != nil {
return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err} return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
} }
return nil return nil
} }
...@@ -239,7 +224,7 @@ func (c *conn) SetWriteBuffer(bytes int) error { ...@@ -239,7 +224,7 @@ func (c *conn) SetWriteBuffer(bytes int) error {
return syscall.EINVAL return syscall.EINVAL
} }
if err := setWriteBuffer(c.fd, bytes); err != nil { if err := setWriteBuffer(c.fd, bytes); err != nil {
return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err} return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
} }
return nil return nil
} }
...@@ -254,7 +239,7 @@ func (c *conn) SetWriteBuffer(bytes int) error { ...@@ -254,7 +239,7 @@ func (c *conn) SetWriteBuffer(bytes int) error {
func (c *conn) File() (f *os.File, err error) { func (c *conn) File() (f *os.File, err error) {
f, err = c.fd.dup() f, err = c.fd.dup()
if err != nil { if err != nil {
err = &OpError{Op: "file", Net: c.fd.net, Addr: c.fd.laddr, Err: err} err = &OpError{Op: "file", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return return
} }
...@@ -352,7 +337,17 @@ type OpError struct { ...@@ -352,7 +337,17 @@ type OpError struct {
// such as "tcp" or "udp6". // such as "tcp" or "udp6".
Net string Net string
// Addr is the network address on which this error occurred. // For operations involving a remote network connection, like
// Dial, Read, or Write, Source is the corresponding local
// network address.
Source Addr
// Addr is the network address for which this error occurred.
// For local operations, like Listen or SetDeadline, Addr is
// the address of the local endpoint being manipulated.
// For operations involving a remote network connection, like
// Dial, Read, or Write, Addr is the remote address of that
// connection.
Addr Addr Addr Addr
// Err is the error that occurred during the operation. // Err is the error that occurred during the operation.
...@@ -367,8 +362,16 @@ func (e *OpError) Error() string { ...@@ -367,8 +362,16 @@ func (e *OpError) Error() string {
if e.Net != "" { if e.Net != "" {
s += " " + e.Net s += " " + e.Net
} }
if e.Source != nil {
s += " " + e.Source.String()
}
if e.Addr != nil { if e.Addr != nil {
s += " " + e.Addr.String() if e.Source != nil {
s += "->"
} else {
s += " "
}
s += e.Addr.String()
} }
s += ": " + e.Err.Error() s += ": " + e.Err.Error()
return s return s
......
...@@ -55,13 +55,13 @@ func (p *pipe) RemoteAddr() Addr { ...@@ -55,13 +55,13 @@ func (p *pipe) RemoteAddr() Addr {
} }
func (p *pipe) SetDeadline(t time.Time) error { func (p *pipe) SetDeadline(t time.Time) error {
return errors.New("net.Pipe does not support deadlines") return &OpError{Op: "set", Net: "pipe", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
} }
func (p *pipe) SetReadDeadline(t time.Time) error { func (p *pipe) SetReadDeadline(t time.Time) error {
return errors.New("net.Pipe does not support deadlines") return &OpError{Op: "set", Net: "pipe", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
} }
func (p *pipe) SetWriteDeadline(t time.Time) error { func (p *pipe) SetWriteDeadline(t time.Time) error {
return errors.New("net.Pipe does not support deadlines") return &OpError{Op: "set", Net: "pipe", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
} }
...@@ -25,7 +25,7 @@ func newTCPConn(fd *netFD) *TCPConn { ...@@ -25,7 +25,7 @@ func newTCPConn(fd *netFD) *TCPConn {
func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) { func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) {
n, err := genericReadFrom(c, r) n, err := genericReadFrom(c, r)
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.raddr, Err: err} err = &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return n, err return n, err
} }
...@@ -38,7 +38,7 @@ func (c *TCPConn) CloseRead() error { ...@@ -38,7 +38,7 @@ func (c *TCPConn) CloseRead() error {
} }
err := c.fd.closeRead() err := c.fd.closeRead()
if err != nil { if err != nil {
err = &OpError{Op: "close", Net: c.fd.net, Addr: c.fd.raddr, Err: err} err = &OpError{Op: "close", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return err return err
} }
...@@ -51,7 +51,7 @@ func (c *TCPConn) CloseWrite() error { ...@@ -51,7 +51,7 @@ func (c *TCPConn) CloseWrite() error {
} }
err := c.fd.closeWrite() err := c.fd.closeWrite()
if err != nil { if err != nil {
err = &OpError{Op: "close", Net: c.fd.net, Addr: c.fd.raddr, Err: err} err = &OpError{Op: "close", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return err return err
} }
...@@ -69,7 +69,7 @@ func (c *TCPConn) CloseWrite() error { ...@@ -69,7 +69,7 @@ func (c *TCPConn) CloseWrite() error {
// some operating systems after sec seconds have elapsed any remaining // some operating systems after sec seconds have elapsed any remaining
// unsent data may be discarded. // unsent data may be discarded.
func (c *TCPConn) SetLinger(sec int) error { func (c *TCPConn) SetLinger(sec int) error {
return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9} return &OpError{Op: "set", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
} }
// SetKeepAlive sets whether the operating system should send // SetKeepAlive sets whether the operating system should send
...@@ -79,7 +79,7 @@ func (c *TCPConn) SetKeepAlive(keepalive bool) error { ...@@ -79,7 +79,7 @@ func (c *TCPConn) SetKeepAlive(keepalive bool) error {
return syscall.EPLAN9 return syscall.EPLAN9
} }
if err := setKeepAlive(c.fd, keepalive); err != nil { if err := setKeepAlive(c.fd, keepalive); err != nil {
return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err} return &OpError{Op: "set", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return nil return nil
} }
...@@ -90,7 +90,7 @@ func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error { ...@@ -90,7 +90,7 @@ func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error {
return syscall.EPLAN9 return syscall.EPLAN9
} }
if err := setKeepAlivePeriod(c.fd, d); err != nil { if err := setKeepAlivePeriod(c.fd, d); err != nil {
return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err} return &OpError{Op: "set", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return nil return nil
} }
...@@ -100,7 +100,7 @@ func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error { ...@@ -100,7 +100,7 @@ func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error {
// algorithm). The default is true (no delay), meaning that data is // algorithm). The default is true (no delay), meaning that data is
// sent as soon as possible after a Write. // sent as soon as possible after a Write.
func (c *TCPConn) SetNoDelay(noDelay bool) error { func (c *TCPConn) SetNoDelay(noDelay bool) error {
return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9} return &OpError{Op: "set", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
} }
// DialTCP connects to the remote address raddr on the network net, // DialTCP connects to the remote address raddr on the network net,
...@@ -117,10 +117,10 @@ func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, e ...@@ -117,10 +117,10 @@ func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, e
switch net { switch net {
case "tcp", "tcp4", "tcp6": case "tcp", "tcp4", "tcp6":
default: default:
return nil, &OpError{"dial", net, raddr, UnknownNetworkError(net)} return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: UnknownNetworkError(net)}
} }
if raddr == nil { if raddr == nil {
return nil, &OpError{"dial", net, nil, errMissingAddress} return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: errMissingAddress}
} }
fd, err := dialPlan9(net, laddr, raddr) fd, err := dialPlan9(net, laddr, raddr)
if err != nil { if err != nil {
...@@ -169,11 +169,11 @@ func (l *TCPListener) Close() error { ...@@ -169,11 +169,11 @@ func (l *TCPListener) Close() error {
} }
if _, err := l.fd.ctl.WriteString("hangup"); err != nil { if _, err := l.fd.ctl.WriteString("hangup"); err != nil {
l.fd.ctl.Close() l.fd.ctl.Close()
return &OpError{Op: "close", Net: l.fd.net, Addr: l.fd.laddr, Err: err} return &OpError{Op: "close", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: err}
} }
err := l.fd.ctl.Close() err := l.fd.ctl.Close()
if err != nil { if err != nil {
err = &OpError{Op: "close", Net: l.fd.net, Addr: l.fd.laddr, Err: err} err = &OpError{Op: "close", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: err}
} }
return err return err
} }
...@@ -190,7 +190,7 @@ func (l *TCPListener) SetDeadline(t time.Time) error { ...@@ -190,7 +190,7 @@ func (l *TCPListener) SetDeadline(t time.Time) error {
return syscall.EINVAL return syscall.EINVAL
} }
if err := l.fd.setDeadline(t); err != nil { if err := l.fd.setDeadline(t); err != nil {
return &OpError{Op: "set", Net: l.fd.net, Addr: l.fd.laddr, Err: err} return &OpError{Op: "set", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: err}
} }
return nil return nil
} }
...@@ -205,7 +205,7 @@ func (l *TCPListener) SetDeadline(t time.Time) error { ...@@ -205,7 +205,7 @@ func (l *TCPListener) SetDeadline(t time.Time) error {
func (l *TCPListener) File() (f *os.File, err error) { func (l *TCPListener) File() (f *os.File, err error) {
f, err = l.dup() f, err = l.dup()
if err != nil { if err != nil {
err = &OpError{Op: "file", Net: l.fd.net, Addr: l.fd.laddr, Err: err} err = &OpError{Op: "file", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: err}
} }
return return
} }
...@@ -218,7 +218,7 @@ func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) { ...@@ -218,7 +218,7 @@ func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) {
switch net { switch net {
case "tcp", "tcp4", "tcp6": case "tcp", "tcp4", "tcp6":
default: default:
return nil, &OpError{"listen", net, laddr, UnknownNetworkError(net)} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: UnknownNetworkError(net)}
} }
if laddr == nil { if laddr == nil {
laddr = &TCPAddr{} laddr = &TCPAddr{}
......
...@@ -61,13 +61,13 @@ func newTCPConn(fd *netFD) *TCPConn { ...@@ -61,13 +61,13 @@ func newTCPConn(fd *netFD) *TCPConn {
func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) { func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) {
if n, err, handled := sendFile(c.fd, r); handled { if n, err, handled := sendFile(c.fd, r); handled {
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.raddr, Err: err} err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return n, err return n, err
} }
n, err := genericReadFrom(c, r) n, err := genericReadFrom(c, r)
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.raddr, Err: err} err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return n, err return n, err
} }
...@@ -80,7 +80,7 @@ func (c *TCPConn) CloseRead() error { ...@@ -80,7 +80,7 @@ func (c *TCPConn) CloseRead() error {
} }
err := c.fd.closeRead() err := c.fd.closeRead()
if err != nil { if err != nil {
err = &OpError{Op: "close", Net: c.fd.net, Addr: c.fd.raddr, Err: err} err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return err return err
} }
...@@ -93,7 +93,7 @@ func (c *TCPConn) CloseWrite() error { ...@@ -93,7 +93,7 @@ func (c *TCPConn) CloseWrite() error {
} }
err := c.fd.closeWrite() err := c.fd.closeWrite()
if err != nil { if err != nil {
err = &OpError{Op: "close", Net: c.fd.net, Addr: c.fd.raddr, Err: err} err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return err return err
} }
...@@ -115,7 +115,7 @@ func (c *TCPConn) SetLinger(sec int) error { ...@@ -115,7 +115,7 @@ func (c *TCPConn) SetLinger(sec int) error {
return syscall.EINVAL return syscall.EINVAL
} }
if err := setLinger(c.fd, sec); err != nil { if err := setLinger(c.fd, sec); err != nil {
return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err} return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return nil return nil
} }
...@@ -127,7 +127,7 @@ func (c *TCPConn) SetKeepAlive(keepalive bool) error { ...@@ -127,7 +127,7 @@ func (c *TCPConn) SetKeepAlive(keepalive bool) error {
return syscall.EINVAL return syscall.EINVAL
} }
if err := setKeepAlive(c.fd, keepalive); err != nil { if err := setKeepAlive(c.fd, keepalive); err != nil {
return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err} return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return nil return nil
} }
...@@ -138,7 +138,7 @@ func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error { ...@@ -138,7 +138,7 @@ func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error {
return syscall.EINVAL return syscall.EINVAL
} }
if err := setKeepAlivePeriod(c.fd, d); err != nil { if err := setKeepAlivePeriod(c.fd, d); err != nil {
return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err} return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return nil return nil
} }
...@@ -152,7 +152,7 @@ func (c *TCPConn) SetNoDelay(noDelay bool) error { ...@@ -152,7 +152,7 @@ func (c *TCPConn) SetNoDelay(noDelay bool) error {
return syscall.EINVAL return syscall.EINVAL
} }
if err := setNoDelay(c.fd, noDelay); err != nil { if err := setNoDelay(c.fd, noDelay); err != nil {
return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err} return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return nil return nil
} }
...@@ -164,10 +164,10 @@ func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error) { ...@@ -164,10 +164,10 @@ func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error) {
switch net { switch net {
case "tcp", "tcp4", "tcp6": case "tcp", "tcp4", "tcp6":
default: default:
return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: UnknownNetworkError(net)} return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: UnknownNetworkError(net)}
} }
if raddr == nil { if raddr == nil {
return nil, &OpError{Op: "dial", Net: net, Addr: nil, Err: errMissingAddress} return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: errMissingAddress}
} }
return dialTCP(net, laddr, raddr, noDeadline) return dialTCP(net, laddr, raddr, noDeadline)
} }
...@@ -207,7 +207,7 @@ func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, e ...@@ -207,7 +207,7 @@ func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, e
} }
if err != nil { if err != nil {
return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: err} return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: err}
} }
return newTCPConn(fd), nil return newTCPConn(fd), nil
} }
...@@ -253,7 +253,7 @@ func (l *TCPListener) AcceptTCP() (*TCPConn, error) { ...@@ -253,7 +253,7 @@ func (l *TCPListener) AcceptTCP() (*TCPConn, error) {
} }
fd, err := l.fd.accept() fd, err := l.fd.accept()
if err != nil { if err != nil {
return nil, &OpError{Op: "accept", Net: l.fd.net, Addr: l.fd.laddr, Err: err} return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
} }
return newTCPConn(fd), nil return newTCPConn(fd), nil
} }
...@@ -276,7 +276,7 @@ func (l *TCPListener) Close() error { ...@@ -276,7 +276,7 @@ func (l *TCPListener) Close() error {
} }
err := l.fd.Close() err := l.fd.Close()
if err != nil { if err != nil {
err = &OpError{Op: "close", Net: l.fd.net, Addr: l.fd.laddr, Err: err} err = &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
} }
return err return err
} }
...@@ -293,7 +293,7 @@ func (l *TCPListener) SetDeadline(t time.Time) error { ...@@ -293,7 +293,7 @@ func (l *TCPListener) SetDeadline(t time.Time) error {
return syscall.EINVAL return syscall.EINVAL
} }
if err := l.fd.setDeadline(t); err != nil { if err := l.fd.setDeadline(t); err != nil {
return &OpError{Op: "set", Net: l.fd.net, Addr: l.fd.laddr, Err: err} return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
} }
return nil return nil
} }
...@@ -308,7 +308,7 @@ func (l *TCPListener) SetDeadline(t time.Time) error { ...@@ -308,7 +308,7 @@ func (l *TCPListener) SetDeadline(t time.Time) error {
func (l *TCPListener) File() (f *os.File, err error) { func (l *TCPListener) File() (f *os.File, err error) {
f, err = l.fd.dup() f, err = l.fd.dup()
if err != nil { if err != nil {
err = &OpError{Op: "file", Net: l.fd.net, Addr: l.fd.laddr, Err: err} err = &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
} }
return return
} }
...@@ -321,14 +321,14 @@ func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) { ...@@ -321,14 +321,14 @@ func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) {
switch net { switch net {
case "tcp", "tcp4", "tcp6": case "tcp", "tcp4", "tcp6":
default: default:
return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: UnknownNetworkError(net)}
} }
if laddr == nil { if laddr == nil {
laddr = &TCPAddr{} laddr = &TCPAddr{}
} }
fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_STREAM, 0, "listen") fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_STREAM, 0, "listen")
if err != nil { if err != nil {
return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
} }
return &TCPListener{fd}, nil return &TCPListener{fd}, nil
} }
...@@ -33,10 +33,10 @@ func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error) { ...@@ -33,10 +33,10 @@ func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error) {
buf := make([]byte, udpHeaderSize+len(b)) buf := make([]byte, udpHeaderSize+len(b))
m, err := c.fd.data.Read(buf) m, err := c.fd.data.Read(buf)
if err != nil { if err != nil {
return 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: err} return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
if m < udpHeaderSize { if m < udpHeaderSize {
return 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: errors.New("short read reading UDP header")} return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: errors.New("short read reading UDP header")}
} }
buf = buf[:m] buf = buf[:m]
...@@ -59,7 +59,7 @@ func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error) { ...@@ -59,7 +59,7 @@ func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error) {
// flags that were set on the packet and the source address of the // flags that were set on the packet and the source address of the
// packet. // packet.
func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) { func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
return 0, 0, 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9} return 0, 0, 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
} }
// WriteToUDP writes a UDP packet to addr via c, copying the payload // WriteToUDP writes a UDP packet to addr via c, copying the payload
...@@ -74,7 +74,7 @@ func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) { ...@@ -74,7 +74,7 @@ func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) {
return 0, syscall.EINVAL return 0, syscall.EINVAL
} }
if addr == nil { if addr == nil {
return 0, &OpError{Op: "write", Net: c.fd.dir, Addr: nil, Err: errMissingAddress} return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: errMissingAddress}
} }
h := new(udpHeader) h := new(udpHeader)
h.raddr = addr.IP.To16() h.raddr = addr.IP.To16()
...@@ -87,7 +87,7 @@ func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) { ...@@ -87,7 +87,7 @@ func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) {
i := copy(buf, h.Bytes()) i := copy(buf, h.Bytes())
copy(buf[i:], b) copy(buf[i:], b)
if _, err := c.fd.data.Write(buf); err != nil { if _, err := c.fd.data.Write(buf); err != nil {
return 0, &OpError{Op: "write", Net: c.fd.dir, Addr: addr, Err: err} return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: err}
} }
return len(b), nil return len(b), nil
} }
...@@ -99,7 +99,7 @@ func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) { ...@@ -99,7 +99,7 @@ func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) {
} }
a, ok := addr.(*UDPAddr) a, ok := addr.(*UDPAddr)
if !ok { if !ok {
return 0, &OpError{Op: "write", Net: c.fd.dir, Addr: addr, Err: syscall.EINVAL} return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
} }
return c.WriteToUDP(b, a) return c.WriteToUDP(b, a)
} }
...@@ -110,7 +110,7 @@ func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) { ...@@ -110,7 +110,7 @@ func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) {
// out-of-band data is copied from oob. It returns the number of // out-of-band data is copied from oob. It returns the number of
// payload and out-of-band bytes written. // payload and out-of-band bytes written.
func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) { func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
return 0, 0, &OpError{Op: "write", Net: c.fd.dir, Addr: addr, Err: syscall.EPLAN9} return 0, 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EPLAN9}
} }
// DialUDP connects to the remote address raddr on the network net, // DialUDP connects to the remote address raddr on the network net,
...@@ -127,10 +127,10 @@ func dialUDP(net string, laddr, raddr *UDPAddr, deadline time.Time) (*UDPConn, e ...@@ -127,10 +127,10 @@ func dialUDP(net string, laddr, raddr *UDPAddr, deadline time.Time) (*UDPConn, e
switch net { switch net {
case "udp", "udp4", "udp6": case "udp", "udp4", "udp6":
default: default:
return nil, UnknownNetworkError(net) return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: UnknownNetworkError(net)}
} }
if raddr == nil { if raddr == nil {
return nil, &OpError{"dial", net, nil, errMissingAddress} return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: errMissingAddress}
} }
fd, err := dialPlan9(net, laddr, raddr) fd, err := dialPlan9(net, laddr, raddr)
if err != nil { if err != nil {
...@@ -178,7 +178,7 @@ func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) { ...@@ -178,7 +178,7 @@ func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) {
switch net { switch net {
case "udp", "udp4", "udp6": case "udp", "udp4", "udp6":
default: default:
return nil, UnknownNetworkError(net) return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: UnknownNetworkError(net)}
} }
if laddr == nil { if laddr == nil {
laddr = &UDPAddr{} laddr = &UDPAddr{}
...@@ -189,11 +189,11 @@ func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) { ...@@ -189,11 +189,11 @@ func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) {
} }
_, err = l.ctl.WriteString("headers") _, err = l.ctl.WriteString("headers")
if err != nil { if err != nil {
return nil, err return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
} }
l.data, err = os.OpenFile(l.dir+"/data", os.O_RDWR, 0) l.data, err = os.OpenFile(l.dir+"/data", os.O_RDWR, 0)
if err != nil { if err != nil {
return nil, err return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
} }
fd, err := l.netFD() fd, err := l.netFD()
return newUDPConn(fd), err return newUDPConn(fd), err
...@@ -204,5 +204,5 @@ func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) { ...@@ -204,5 +204,5 @@ func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) {
// interface to join. ListenMulticastUDP uses default multicast // interface to join. ListenMulticastUDP uses default multicast
// interface if ifi is nil. // interface if ifi is nil.
func ListenMulticastUDP(net string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) { func ListenMulticastUDP(net string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
return nil, syscall.EPLAN9 return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: gaddr, Err: syscall.EPLAN9}
} }
...@@ -66,7 +66,7 @@ func (c *UDPConn) ReadFromUDP(b []byte) (int, *UDPAddr, error) { ...@@ -66,7 +66,7 @@ func (c *UDPConn) ReadFromUDP(b []byte) (int, *UDPAddr, error) {
addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))} addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
} }
if err != nil { if err != nil {
err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: err} err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return n, addr, err return n, addr, err
} }
...@@ -101,7 +101,7 @@ func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, ...@@ -101,7 +101,7 @@ func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr,
addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))} addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
} }
if err != nil { if err != nil {
err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: err} err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return return
} }
...@@ -118,18 +118,18 @@ func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) { ...@@ -118,18 +118,18 @@ func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) {
return 0, syscall.EINVAL return 0, syscall.EINVAL
} }
if c.fd.isConnected { if c.fd.isConnected {
return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected} return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: ErrWriteToConnected}
} }
if addr == nil { if addr == nil {
return 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress} return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: errMissingAddress}
} }
sa, err := addr.sockaddr(c.fd.family) sa, err := addr.sockaddr(c.fd.family)
if err != nil { if err != nil {
return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err} return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
} }
n, err := c.fd.writeTo(b, sa) n, err := c.fd.writeTo(b, sa)
if err != nil { if err != nil {
err = &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err} err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
} }
return n, err return n, err
} }
...@@ -141,7 +141,7 @@ func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) { ...@@ -141,7 +141,7 @@ func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) {
} }
a, ok := addr.(*UDPAddr) a, ok := addr.(*UDPAddr)
if !ok { if !ok {
return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EINVAL} return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
} }
return c.WriteToUDP(b, a) return c.WriteToUDP(b, a)
} }
...@@ -156,19 +156,19 @@ func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err er ...@@ -156,19 +156,19 @@ func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err er
return 0, 0, syscall.EINVAL return 0, 0, syscall.EINVAL
} }
if c.fd.isConnected && addr != nil { if c.fd.isConnected && addr != nil {
return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected} return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: ErrWriteToConnected}
} }
if !c.fd.isConnected && addr == nil { if !c.fd.isConnected && addr == nil {
return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress} return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: errMissingAddress}
} }
var sa syscall.Sockaddr var sa syscall.Sockaddr
sa, err = addr.sockaddr(c.fd.family) sa, err = addr.sockaddr(c.fd.family)
if err != nil { if err != nil {
return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err} return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
} }
n, oobn, err = c.fd.writeMsg(b, oob, sa) n, oobn, err = c.fd.writeMsg(b, oob, sa)
if err != nil { if err != nil {
err = &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err} err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
} }
return return
} }
...@@ -180,10 +180,10 @@ func DialUDP(net string, laddr, raddr *UDPAddr) (*UDPConn, error) { ...@@ -180,10 +180,10 @@ func DialUDP(net string, laddr, raddr *UDPAddr) (*UDPConn, error) {
switch net { switch net {
case "udp", "udp4", "udp6": case "udp", "udp4", "udp6":
default: default:
return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: UnknownNetworkError(net)} return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: UnknownNetworkError(net)}
} }
if raddr == nil { if raddr == nil {
return nil, &OpError{Op: "dial", Net: net, Addr: nil, Err: errMissingAddress} return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: errMissingAddress}
} }
return dialUDP(net, laddr, raddr, noDeadline) return dialUDP(net, laddr, raddr, noDeadline)
} }
...@@ -191,7 +191,7 @@ func DialUDP(net string, laddr, raddr *UDPAddr) (*UDPConn, error) { ...@@ -191,7 +191,7 @@ func DialUDP(net string, laddr, raddr *UDPAddr) (*UDPConn, error) {
func dialUDP(net string, laddr, raddr *UDPAddr, deadline time.Time) (*UDPConn, error) { func dialUDP(net string, laddr, raddr *UDPAddr, deadline time.Time) (*UDPConn, error) {
fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_DGRAM, 0, "dial") fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_DGRAM, 0, "dial")
if err != nil { if err != nil {
return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: err} return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: err}
} }
return newUDPConn(fd), nil return newUDPConn(fd), nil
} }
...@@ -207,14 +207,14 @@ func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) { ...@@ -207,14 +207,14 @@ func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) {
switch net { switch net {
case "udp", "udp4", "udp6": case "udp", "udp4", "udp6":
default: default:
return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: UnknownNetworkError(net)}
} }
if laddr == nil { if laddr == nil {
laddr = &UDPAddr{} laddr = &UDPAddr{}
} }
fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen") fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen")
if err != nil { if err != nil {
return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
} }
return newUDPConn(fd), nil return newUDPConn(fd), nil
} }
...@@ -227,25 +227,25 @@ func ListenMulticastUDP(net string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, e ...@@ -227,25 +227,25 @@ func ListenMulticastUDP(net string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, e
switch net { switch net {
case "udp", "udp4", "udp6": case "udp", "udp4", "udp6":
default: default:
return nil, &OpError{Op: "listen", Net: net, Addr: gaddr, Err: UnknownNetworkError(net)} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: gaddr, Err: UnknownNetworkError(net)}
} }
if gaddr == nil || gaddr.IP == nil { if gaddr == nil || gaddr.IP == nil {
return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: errMissingAddress} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: gaddr, Err: errMissingAddress}
} }
fd, err := internetSocket(net, gaddr, nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen") fd, err := internetSocket(net, gaddr, nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen")
if err != nil { if err != nil {
return nil, &OpError{Op: "listen", Net: net, Addr: gaddr, Err: err} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: gaddr, Err: err}
} }
c := newUDPConn(fd) c := newUDPConn(fd)
if ip4 := gaddr.IP.To4(); ip4 != nil { if ip4 := gaddr.IP.To4(); ip4 != nil {
if err := listenIPv4MulticastUDP(c, ifi, ip4); err != nil { if err := listenIPv4MulticastUDP(c, ifi, ip4); err != nil {
c.Close() c.Close()
return nil, &OpError{Op: "listen", Net: net, Addr: &IPAddr{IP: ip4}, Err: err} return nil, &OpError{Op: "listen", Net: net, Source: c.fd.laddr, Addr: &IPAddr{IP: ip4}, Err: err}
} }
} else { } else {
if err := listenIPv6MulticastUDP(c, ifi, gaddr.IP); err != nil { if err := listenIPv6MulticastUDP(c, ifi, gaddr.IP); err != nil {
c.Close() c.Close()
return nil, &OpError{Op: "listen", Net: net, Addr: &IPAddr{IP: gaddr.IP}, Err: err} return nil, &OpError{Op: "listen", Net: net, Source: c.fd.laddr, Addr: &IPAddr{IP: gaddr.IP}, Err: err}
} }
} }
return c, nil return c, nil
......
...@@ -24,12 +24,12 @@ type UnixConn struct { ...@@ -24,12 +24,12 @@ type UnixConn struct {
// Timeout() == true after a fixed time limit; see SetDeadline and // Timeout() == true after a fixed time limit; see SetDeadline and
// SetReadDeadline. // SetReadDeadline.
func (c *UnixConn) ReadFromUnix(b []byte) (int, *UnixAddr, error) { func (c *UnixConn) ReadFromUnix(b []byte) (int, *UnixAddr, error) {
return 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9} return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
} }
// ReadFrom implements the PacketConn ReadFrom method. // ReadFrom implements the PacketConn ReadFrom method.
func (c *UnixConn) ReadFrom(b []byte) (int, Addr, error) { func (c *UnixConn) ReadFrom(b []byte) (int, Addr, error) {
return 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9} return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
} }
// ReadMsgUnix reads a packet from c, copying the payload into b and // ReadMsgUnix reads a packet from c, copying the payload into b and
...@@ -37,7 +37,7 @@ func (c *UnixConn) ReadFrom(b []byte) (int, Addr, error) { ...@@ -37,7 +37,7 @@ func (c *UnixConn) ReadFrom(b []byte) (int, Addr, error) {
// bytes copied into b, the number of bytes copied into oob, the flags // 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. // that were set on the packet, and the source address of the packet.
func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error) { func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error) {
return 0, 0, 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9} return 0, 0, 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
} }
// WriteToUnix writes a packet to addr via c, copying the payload from b. // WriteToUnix writes a packet to addr via c, copying the payload from b.
...@@ -47,31 +47,31 @@ func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAdd ...@@ -47,31 +47,31 @@ func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAdd
// SetWriteDeadline. On packet-oriented connections, write timeouts // SetWriteDeadline. On packet-oriented connections, write timeouts
// are rare. // are rare.
func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (int, error) { func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (int, error) {
return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EPLAN9} return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EPLAN9}
} }
// WriteTo implements the PacketConn WriteTo method. // WriteTo implements the PacketConn WriteTo method.
func (c *UnixConn) WriteTo(b []byte, addr Addr) (int, error) { func (c *UnixConn) WriteTo(b []byte, addr Addr) (int, error) {
return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EPLAN9} return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EPLAN9}
} }
// WriteMsgUnix writes a packet to addr via c, copying the payload // WriteMsgUnix writes a packet to addr via c, copying the payload
// from b and the associated out-of-band data from oob. It returns // from b and the associated out-of-band data from oob. It returns
// the number of payload and out-of-band bytes written. // the number of payload and out-of-band bytes written.
func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err error) { func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err error) {
return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EPLAN9} return 0, 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EPLAN9}
} }
// CloseRead shuts down the reading side of the Unix domain connection. // CloseRead shuts down the reading side of the Unix domain connection.
// Most callers should just use Close. // Most callers should just use Close.
func (c *UnixConn) CloseRead() error { func (c *UnixConn) CloseRead() error {
return &OpError{Op: "close", Net: c.fd.net, Addr: c.fd.raddr, Err: syscall.EPLAN9} return &OpError{Op: "close", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
} }
// CloseWrite shuts down the writing side of the Unix domain connection. // CloseWrite shuts down the writing side of the Unix domain connection.
// Most callers should just use Close. // Most callers should just use Close.
func (c *UnixConn) CloseWrite() error { func (c *UnixConn) CloseWrite() error {
return &OpError{Op: "close", Net: c.fd.net, Addr: c.fd.raddr, Err: syscall.EPLAN9} return &OpError{Op: "close", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
} }
// DialUnix connects to the remote address raddr on the network net, // DialUnix connects to the remote address raddr on the network net,
...@@ -82,36 +82,38 @@ func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error) { ...@@ -82,36 +82,38 @@ func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error) {
} }
func dialUnix(net string, laddr, raddr *UnixAddr, deadline time.Time) (*UnixConn, error) { func dialUnix(net string, laddr, raddr *UnixAddr, deadline time.Time) (*UnixConn, error) {
return nil, syscall.EPLAN9 return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: syscall.EPLAN9}
} }
// UnixListener is a Unix domain socket listener. Clients should // UnixListener is a Unix domain socket listener. Clients should
// typically use variables of type Listener instead of assuming Unix // typically use variables of type Listener instead of assuming Unix
// domain sockets. // domain sockets.
type UnixListener struct{} type UnixListener struct {
fd *netFD
}
// ListenUnix announces on the Unix domain socket laddr and returns a // ListenUnix announces on the Unix domain socket laddr and returns a
// Unix listener. The network net must be "unix" or "unixpacket". // Unix listener. The network net must be "unix" or "unixpacket".
func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error) { func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error) {
return nil, syscall.EPLAN9 return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: syscall.EPLAN9}
} }
// AcceptUnix accepts the next incoming call and returns the new // AcceptUnix accepts the next incoming call and returns the new
// connection. // connection.
func (l *UnixListener) AcceptUnix() (*UnixConn, error) { func (l *UnixListener) AcceptUnix() (*UnixConn, error) {
return nil, &OpError{Op: "accept", Net: "<nil>", Addr: nil, Err: syscall.EPLAN9} return nil, &OpError{Op: "accept", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: syscall.EPLAN9}
} }
// Accept implements the Accept method in the Listener interface; it // Accept implements the Accept method in the Listener interface; it
// waits for the next call and returns a generic Conn. // waits for the next call and returns a generic Conn.
func (l *UnixListener) Accept() (Conn, error) { func (l *UnixListener) Accept() (Conn, error) {
return nil, &OpError{Op: "accept", Net: "<nil>", Addr: nil, Err: syscall.EPLAN9} return nil, &OpError{Op: "accept", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: syscall.EPLAN9}
} }
// Close stops listening on the Unix address. Already accepted // Close stops listening on the Unix address. Already accepted
// connections are not closed. // connections are not closed.
func (l *UnixListener) Close() error { func (l *UnixListener) Close() error {
return &OpError{Op: "close", Net: "<nil>", Addr: nil, Err: syscall.EPLAN9} return &OpError{Op: "close", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: syscall.EPLAN9}
} }
// Addr returns the listener's network address. // Addr returns the listener's network address.
...@@ -122,7 +124,7 @@ func (l *UnixListener) Addr() Addr { return nil } ...@@ -122,7 +124,7 @@ func (l *UnixListener) Addr() Addr { return nil }
// SetDeadline sets the deadline associated with the listener. // SetDeadline sets the deadline associated with the listener.
// A zero time value disables the deadline. // A zero time value disables the deadline.
func (l *UnixListener) SetDeadline(t time.Time) error { func (l *UnixListener) SetDeadline(t time.Time) error {
return &OpError{Op: "set", Net: "<nil>", Addr: nil, Err: syscall.EPLAN9} return &OpError{Op: "set", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: syscall.EPLAN9}
} }
// File returns a copy of the underlying os.File, set to blocking // File returns a copy of the underlying os.File, set to blocking
...@@ -133,7 +135,7 @@ func (l *UnixListener) SetDeadline(t time.Time) error { ...@@ -133,7 +135,7 @@ func (l *UnixListener) SetDeadline(t time.Time) error {
// connection's. Attempting to change properties of the original // connection's. Attempting to change properties of the original
// using this duplicate may or may not have the desired effect. // using this duplicate may or may not have the desired effect.
func (l *UnixListener) File() (*os.File, error) { func (l *UnixListener) File() (*os.File, error) {
return nil, &OpError{Op: "file", Net: "<nil>", Addr: nil, Err: syscall.EPLAN9} return nil, &OpError{Op: "file", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: syscall.EPLAN9}
} }
// ListenUnixgram listens for incoming Unix datagram packets addressed // ListenUnixgram listens for incoming Unix datagram packets addressed
...@@ -141,5 +143,5 @@ func (l *UnixListener) File() (*os.File, error) { ...@@ -141,5 +143,5 @@ func (l *UnixListener) File() (*os.File, error) {
// The returned connection's ReadFrom and WriteTo methods can be used // The returned connection's ReadFrom and WriteTo methods can be used
// to receive and send packets with per-packet addressing. // to receive and send packets with per-packet addressing.
func ListenUnixgram(net string, laddr *UnixAddr) (*UnixConn, error) { func ListenUnixgram(net string, laddr *UnixAddr) (*UnixConn, error) {
return nil, syscall.EPLAN9 return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: syscall.EPLAN9}
} }
...@@ -126,7 +126,7 @@ func (c *UnixConn) ReadFromUnix(b []byte) (int, *UnixAddr, error) { ...@@ -126,7 +126,7 @@ func (c *UnixConn) ReadFromUnix(b []byte) (int, *UnixAddr, error) {
} }
} }
if err != nil { if err != nil {
err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: err} err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return n, addr, err return n, addr, err
} }
...@@ -159,7 +159,7 @@ func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAdd ...@@ -159,7 +159,7 @@ func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAdd
} }
} }
if err != nil { if err != nil {
err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: err} err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return return
} }
...@@ -175,18 +175,18 @@ func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (int, error) { ...@@ -175,18 +175,18 @@ func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (int, error) {
return 0, syscall.EINVAL return 0, syscall.EINVAL
} }
if c.fd.isConnected { if c.fd.isConnected {
return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected} return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: ErrWriteToConnected}
} }
if addr == nil { if addr == nil {
return 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress} return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: errMissingAddress}
} }
if addr.Net != sotypeToNet(c.fd.sotype) { if addr.Net != sotypeToNet(c.fd.sotype) {
return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EAFNOSUPPORT} return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EAFNOSUPPORT}
} }
sa := &syscall.SockaddrUnix{Name: addr.Name} sa := &syscall.SockaddrUnix{Name: addr.Name}
n, err := c.fd.writeTo(b, sa) n, err := c.fd.writeTo(b, sa)
if err != nil { if err != nil {
err = &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err} err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
} }
return n, err return n, err
} }
...@@ -198,7 +198,7 @@ func (c *UnixConn) WriteTo(b []byte, addr Addr) (n int, err error) { ...@@ -198,7 +198,7 @@ func (c *UnixConn) WriteTo(b []byte, addr Addr) (n int, err error) {
} }
a, ok := addr.(*UnixAddr) a, ok := addr.(*UnixAddr)
if !ok { if !ok {
return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EINVAL} return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
} }
return c.WriteToUnix(b, a) return c.WriteToUnix(b, a)
} }
...@@ -211,18 +211,18 @@ func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err ...@@ -211,18 +211,18 @@ func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err
return 0, 0, syscall.EINVAL return 0, 0, syscall.EINVAL
} }
if c.fd.sotype == syscall.SOCK_DGRAM && c.fd.isConnected { if c.fd.sotype == syscall.SOCK_DGRAM && c.fd.isConnected {
return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected} return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: ErrWriteToConnected}
} }
var sa syscall.Sockaddr var sa syscall.Sockaddr
if addr != nil { if addr != nil {
if addr.Net != sotypeToNet(c.fd.sotype) { if addr.Net != sotypeToNet(c.fd.sotype) {
return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EAFNOSUPPORT} return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EAFNOSUPPORT}
} }
sa = &syscall.SockaddrUnix{Name: addr.Name} sa = &syscall.SockaddrUnix{Name: addr.Name}
} }
n, oobn, err = c.fd.writeMsg(b, oob, sa) n, oobn, err = c.fd.writeMsg(b, oob, sa)
if err != nil { if err != nil {
err = &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err} err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
} }
return return
} }
...@@ -235,7 +235,7 @@ func (c *UnixConn) CloseRead() error { ...@@ -235,7 +235,7 @@ func (c *UnixConn) CloseRead() error {
} }
err := c.fd.closeRead() err := c.fd.closeRead()
if err != nil { if err != nil {
err = &OpError{Op: "close", Net: c.fd.net, Addr: c.fd.raddr, Err: err} err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return err return err
} }
...@@ -248,7 +248,7 @@ func (c *UnixConn) CloseWrite() error { ...@@ -248,7 +248,7 @@ func (c *UnixConn) CloseWrite() error {
} }
err := c.fd.closeWrite() err := c.fd.closeWrite()
if err != nil { if err != nil {
err = &OpError{Op: "close", Net: c.fd.net, Addr: c.fd.raddr, Err: err} err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
} }
return err return err
} }
...@@ -260,7 +260,7 @@ func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error) { ...@@ -260,7 +260,7 @@ func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error) {
switch net { switch net {
case "unix", "unixgram", "unixpacket": case "unix", "unixgram", "unixpacket":
default: default:
return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: UnknownNetworkError(net)} return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: UnknownNetworkError(net)}
} }
return dialUnix(net, laddr, raddr, noDeadline) return dialUnix(net, laddr, raddr, noDeadline)
} }
...@@ -268,7 +268,7 @@ func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error) { ...@@ -268,7 +268,7 @@ func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error) {
func dialUnix(net string, laddr, raddr *UnixAddr, deadline time.Time) (*UnixConn, error) { func dialUnix(net string, laddr, raddr *UnixAddr, deadline time.Time) (*UnixConn, error) {
fd, err := unixSocket(net, laddr, raddr, "dial", deadline) fd, err := unixSocket(net, laddr, raddr, "dial", deadline)
if err != nil { if err != nil {
return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: err} return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: err}
} }
return newUnixConn(fd), nil return newUnixConn(fd), nil
} }
...@@ -287,16 +287,16 @@ func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error) { ...@@ -287,16 +287,16 @@ func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error) {
switch net { switch net {
case "unix", "unixpacket": case "unix", "unixpacket":
default: default:
return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: UnknownNetworkError(net)}
} }
if laddr == nil { if laddr == nil {
return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: errMissingAddress} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: errMissingAddress}
} }
fd, err := unixSocket(net, laddr, nil, "listen", noDeadline) fd, err := unixSocket(net, laddr, nil, "listen", noDeadline)
if err != nil { if err != nil {
return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
} }
return &UnixListener{fd, fd.laddr.String()}, nil return &UnixListener{fd: fd, path: fd.laddr.String()}, nil
} }
// AcceptUnix accepts the next incoming call and returns the new // AcceptUnix accepts the next incoming call and returns the new
...@@ -307,7 +307,7 @@ func (l *UnixListener) AcceptUnix() (*UnixConn, error) { ...@@ -307,7 +307,7 @@ func (l *UnixListener) AcceptUnix() (*UnixConn, error) {
} }
fd, err := l.fd.accept() fd, err := l.fd.accept()
if err != nil { if err != nil {
return nil, &OpError{Op: "accept", Net: l.fd.net, Addr: l.fd.laddr, Err: err} return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
} }
return newUnixConn(fd), nil return newUnixConn(fd), nil
} }
...@@ -344,7 +344,7 @@ func (l *UnixListener) Close() error { ...@@ -344,7 +344,7 @@ func (l *UnixListener) Close() error {
} }
err := l.fd.Close() err := l.fd.Close()
if err != nil { if err != nil {
err = &OpError{Op: "close", Net: l.fd.net, Addr: l.fd.laddr, Err: err} err = &OpError{Op: "close", Net: l.fd.net, Source: l.fd.laddr, Addr: l.fd.raddr, Err: err}
} }
return err return err
} }
...@@ -361,7 +361,7 @@ func (l *UnixListener) SetDeadline(t time.Time) error { ...@@ -361,7 +361,7 @@ func (l *UnixListener) SetDeadline(t time.Time) error {
return syscall.EINVAL return syscall.EINVAL
} }
if err := l.fd.setDeadline(t); err != nil { if err := l.fd.setDeadline(t); err != nil {
return &OpError{Op: "set", Net: l.fd.net, Addr: l.fd.laddr, Err: err} return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
} }
return nil return nil
} }
...@@ -376,7 +376,7 @@ func (l *UnixListener) SetDeadline(t time.Time) error { ...@@ -376,7 +376,7 @@ func (l *UnixListener) SetDeadline(t time.Time) error {
func (l *UnixListener) File() (f *os.File, err error) { func (l *UnixListener) File() (f *os.File, err error) {
f, err = l.fd.dup() f, err = l.fd.dup()
if err != nil { if err != nil {
err = &OpError{Op: "file", Net: l.fd.net, Addr: l.fd.laddr, Err: err} err = &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
} }
return return
} }
...@@ -389,14 +389,14 @@ func ListenUnixgram(net string, laddr *UnixAddr) (*UnixConn, error) { ...@@ -389,14 +389,14 @@ func ListenUnixgram(net string, laddr *UnixAddr) (*UnixConn, error) {
switch net { switch net {
case "unixgram": case "unixgram":
default: default:
return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: UnknownNetworkError(net)}
} }
if laddr == nil { if laddr == nil {
return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: errMissingAddress} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: errMissingAddress}
} }
fd, err := unixSocket(net, laddr, nil, "listen", noDeadline) fd, err := unixSocket(net, laddr, nil, "listen", noDeadline)
if err != nil { if err != nil {
return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err} return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
} }
return newUnixConn(fd), nil return newUnixConn(fd), nil
} }
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