Commit 66b69a17 authored by Akshat Kumar's avatar Akshat Kumar Committed by Anthony Martin

net: Plan 9: open data file and set remote-addr properly

The data file should be opened when a Conn is first
established, rather than waiting for the first Read or
Write.

Upon Close, we now make sure to try to close both, the
ctl as well as data files and set both to nil, even in
the face of errors, instead of returning early.

The Accept call was not setting the remote address
of the connection properly. Now, we read the correct
file.

Make functions that establish Conn use newTCPConn
or newUDPConn.

R=rsc, rminnich, ality, dave
CC=golang-dev
https://golang.org/cl/7228068
parent 40c2fbf4
...@@ -29,22 +29,16 @@ func dialTimeout(net, addr string, timeout time.Duration) (Conn, error) { ...@@ -29,22 +29,16 @@ func dialTimeout(net, addr string, timeout time.Duration) (Conn, error) {
return dialTimeoutRace(net, addr, timeout) return dialTimeoutRace(net, addr, timeout)
} }
func newFD(proto, name string, ctl *os.File, laddr, raddr Addr) *netFD { func newFD(proto, name string, ctl, data *os.File, laddr, raddr Addr) *netFD {
return &netFD{proto, name, "/net/" + proto + "/" + name, ctl, nil, laddr, raddr} return &netFD{proto, name, "/net/" + proto + "/" + name, ctl, data, laddr, raddr}
} }
func (fd *netFD) ok() bool { return fd != nil && fd.ctl != nil } func (fd *netFD) ok() bool { return fd != nil && fd.ctl != nil }
func (fd *netFD) Read(b []byte) (n int, err error) { func (fd *netFD) Read(b []byte) (n int, err error) {
if !fd.ok() { if !fd.ok() || fd.data == nil {
return 0, syscall.EINVAL return 0, syscall.EINVAL
} }
if fd.data == nil {
fd.data, err = os.OpenFile(fd.dir+"/data", os.O_RDWR, 0)
if err != nil {
return 0, err
}
}
n, err = fd.data.Read(b) n, err = fd.data.Read(b)
if fd.proto == "udp" && err == io.EOF { if fd.proto == "udp" && err == io.EOF {
n = 0 n = 0
...@@ -54,15 +48,9 @@ func (fd *netFD) Read(b []byte) (n int, err error) { ...@@ -54,15 +48,9 @@ func (fd *netFD) Read(b []byte) (n int, err error) {
} }
func (fd *netFD) Write(b []byte) (n int, err error) { func (fd *netFD) Write(b []byte) (n int, err error) {
if !fd.ok() { if !fd.ok() || fd.data == nil {
return 0, syscall.EINVAL return 0, syscall.EINVAL
} }
if fd.data == nil {
fd.data, err = os.OpenFile(fd.dir+"/data", os.O_RDWR, 0)
if err != nil {
return 0, err
}
}
return fd.data.Write(b) return fd.data.Write(b)
} }
...@@ -85,11 +73,10 @@ func (fd *netFD) Close() error { ...@@ -85,11 +73,10 @@ func (fd *netFD) Close() error {
return syscall.EINVAL return syscall.EINVAL
} }
err := fd.ctl.Close() err := fd.ctl.Close()
if err != nil {
return err
}
if fd.data != nil { if fd.data != nil {
err = fd.data.Close() if err1 := fd.data.Close(); err1 != nil && err == nil {
err = err1
}
} }
fd.ctl = nil fd.ctl = nil
fd.data = nil fd.data = nil
......
...@@ -114,17 +114,24 @@ func dialPlan9(net string, laddr, raddr Addr) (*netFD, error) { ...@@ -114,17 +114,24 @@ func dialPlan9(net string, laddr, raddr Addr) (*netFD, error) {
f.Close() f.Close()
return nil, err return nil, err
} }
data, err := os.OpenFile("/net/"+proto+"/"+name+"/data", os.O_RDWR, 0)
if err != nil {
f.Close()
return nil, err
}
laddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/local") laddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/local")
if err != nil { if err != nil {
data.Close()
f.Close() f.Close()
return nil, err return nil, err
} }
raddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/remote") raddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/remote")
if err != nil { if err != nil {
data.Close()
f.Close() f.Close()
return nil, err return nil, err
} }
return newFD(proto, name, f, laddr, raddr), nil return newFD(proto, name, f, data, laddr, raddr), nil
} }
func listenPlan9(net string, laddr Addr) (*netFD, error) { func listenPlan9(net string, laddr Addr) (*netFD, error) {
...@@ -142,11 +149,11 @@ func listenPlan9(net string, laddr Addr) (*netFD, error) { ...@@ -142,11 +149,11 @@ func listenPlan9(net string, laddr Addr) (*netFD, error) {
f.Close() f.Close()
return nil, err return nil, err
} }
return &netFD{proto: proto, name: name, dir: "/net/" + proto + "/" + name, ctl: f, laddr: laddr}, nil return newFD(proto, name, f, nil, laddr, nil), nil
} }
func (l *netFD) netFD() *netFD { func (l *netFD) netFD() *netFD {
return newFD(l.proto, l.name, l.ctl, l.laddr, nil) return newFD(l.proto, l.name, l.ctl, l.data, l.laddr, l.raddr)
} }
func (l *netFD) acceptPlan9() (*netFD, error) { func (l *netFD) acceptPlan9() (*netFD, error) {
...@@ -161,15 +168,16 @@ func (l *netFD) acceptPlan9() (*netFD, error) { ...@@ -161,15 +168,16 @@ func (l *netFD) acceptPlan9() (*netFD, error) {
return nil, err return nil, err
} }
name := string(buf[:n]) name := string(buf[:n])
laddr, err := readPlan9Addr(l.proto, l.dir+"/local") data, err := os.OpenFile("/net/"+l.proto+"/"+name+"/data", os.O_RDWR, 0)
if err != nil { if err != nil {
f.Close() f.Close()
return nil, err return nil, err
} }
raddr, err := readPlan9Addr(l.proto, l.dir+"/remote") raddr, err := readPlan9Addr(l.proto, "/net/"+l.proto+"/"+name+"/remote")
if err != nil { if err != nil {
data.Close()
f.Close() f.Close()
return nil, err return nil, err
} }
return newFD(l.proto, name, f, laddr, raddr), nil return newFD(l.proto, name, f, data, l.laddr, raddr), nil
} }
...@@ -98,7 +98,7 @@ func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, e ...@@ -98,7 +98,7 @@ func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, e
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &TCPConn{conn{fd}}, nil return newTCPConn(fd), nil
} }
// TCPListener is a TCP network listener. Clients should typically // TCPListener is a TCP network listener. Clients should typically
......
...@@ -19,6 +19,10 @@ type UDPConn struct { ...@@ -19,6 +19,10 @@ type UDPConn struct {
conn conn
} }
func newUDPConn(fd *netFD) *UDPConn {
return &UDPConn{conn{fd}}
}
// ReadFromUDP reads a UDP packet from c, copying the payload into b. // ReadFromUDP reads a UDP packet from c, copying the payload into b.
// It returns the number of bytes copied into b and the return address // It returns the number of bytes copied into b and the return address
// that was on the packet. // that was on the packet.
...@@ -27,15 +31,9 @@ type UDPConn struct { ...@@ -27,15 +31,9 @@ type UDPConn 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 *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error) { func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error) {
if !c.ok() { if !c.ok() || c.fd.data == nil {
return 0, nil, syscall.EINVAL return 0, nil, syscall.EINVAL
} }
if c.fd.data == nil {
c.fd.data, err = os.OpenFile(c.fd.dir+"/data", os.O_RDWR, 0)
if err != nil {
return 0, nil, err
}
}
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 {
...@@ -76,16 +74,9 @@ func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, ...@@ -76,16 +74,9 @@ func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr,
// SetWriteDeadline. On packet-oriented connections, write timeouts // SetWriteDeadline. On packet-oriented connections, write timeouts
// are rare. // are rare.
func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) { func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) {
if !c.ok() { if !c.ok() || c.fd.data == nil {
return 0, syscall.EINVAL return 0, syscall.EINVAL
} }
if c.fd.data == nil {
f, err := os.OpenFile(c.fd.dir+"/data", os.O_RDWR, 0)
if err != nil {
return 0, err
}
c.fd.data = f
}
h := new(udpHeader) h := new(udpHeader)
h.raddr = addr.IP.To16() h.raddr = addr.IP.To16()
h.laddr = c.fd.laddr.(*UDPAddr).IP.To16() h.laddr = c.fd.laddr.(*UDPAddr).IP.To16()
...@@ -141,7 +132,7 @@ func dialUDP(net string, laddr, raddr *UDPAddr, deadline time.Time) (*UDPConn, e ...@@ -141,7 +132,7 @@ func dialUDP(net string, laddr, raddr *UDPAddr, deadline time.Time) (*UDPConn, e
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &UDPConn{conn{fd}}, nil return newUDPConn(fd), nil
} }
const udpHeaderSize = 16*3 + 2*2 const udpHeaderSize = 16*3 + 2*2
...@@ -193,7 +184,11 @@ func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) { ...@@ -193,7 +184,11 @@ func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &UDPConn{conn{l.netFD()}}, nil l.data, err = os.OpenFile(l.dir+"/data", os.O_RDWR, 0)
if err != nil {
return nil, err
}
return newUDPConn(l.netFD()), nil
} }
// ListenMulticastUDP listens for incoming multicast UDP packets // ListenMulticastUDP listens for incoming multicast UDP packets
......
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