Commit 5c055e74 authored by Mikio Hara's avatar Mikio Hara

net: consolidate sockaddrToAddr functions

This CL removes sockaddrToAddr functions from socket creation
operations to avoid the bug like issue 7183.

LGTM=bradfitz
R=golang-codereviews, bradfitz
CC=golang-codereviews
https://golang.org/cl/105100046
parent fdaeec58
...@@ -401,7 +401,7 @@ func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oob ...@@ -401,7 +401,7 @@ func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oob
return return
} }
func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err error) { func (fd *netFD) accept() (netfd *netFD, err error) {
if err := fd.readLock(); err != nil { if err := fd.readLock(); err != nil {
return nil, err return nil, err
} }
...@@ -438,7 +438,7 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err e ...@@ -438,7 +438,7 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err e
return nil, err return nil, err
} }
lsa, _ := syscall.Getsockname(netfd.sysfd) lsa, _ := syscall.Getsockname(netfd.sysfd)
netfd.setAddr(toAddr(lsa), toAddr(rsa)) netfd.setAddr(netfd.addrFunc()(lsa), netfd.addrFunc()(rsa))
return netfd, nil return netfd, nil
} }
......
...@@ -520,7 +520,7 @@ func (fd *netFD) writeTo(buf []byte, sa syscall.Sockaddr) (int, error) { ...@@ -520,7 +520,7 @@ func (fd *netFD) writeTo(buf []byte, sa syscall.Sockaddr) (int, error) {
}) })
} }
func (fd *netFD) acceptOne(toAddr func(syscall.Sockaddr) Addr, rawsa []syscall.RawSockaddrAny, o *operation) (*netFD, error) { func (fd *netFD) acceptOne(rawsa []syscall.RawSockaddrAny, o *operation) (*netFD, error) {
// Get new socket. // Get new socket.
s, err := sysSocket(fd.family, fd.sotype, 0) s, err := sysSocket(fd.family, fd.sotype, 0)
if err != nil { if err != nil {
...@@ -559,7 +559,7 @@ func (fd *netFD) acceptOne(toAddr func(syscall.Sockaddr) Addr, rawsa []syscall.R ...@@ -559,7 +559,7 @@ func (fd *netFD) acceptOne(toAddr func(syscall.Sockaddr) Addr, rawsa []syscall.R
return netfd, nil return netfd, nil
} }
func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) { func (fd *netFD) accept() (*netFD, error) {
if err := fd.readLock(); err != nil { if err := fd.readLock(); err != nil {
return nil, err return nil, err
} }
...@@ -570,7 +570,7 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) { ...@@ -570,7 +570,7 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) {
var err error var err error
var rawsa [2]syscall.RawSockaddrAny var rawsa [2]syscall.RawSockaddrAny
for { for {
netfd, err = fd.acceptOne(toAddr, rawsa[:], o) netfd, err = fd.acceptOne(rawsa[:], o)
if err == nil { if err == nil {
break break
} }
...@@ -603,7 +603,7 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) { ...@@ -603,7 +603,7 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) {
lsa, _ := lrsa.Sockaddr() lsa, _ := lrsa.Sockaddr()
rsa, _ := rrsa.Sockaddr() rsa, _ := rrsa.Sockaddr()
netfd.setAddr(toAddr(lsa), toAddr(rsa)) netfd.setAddr(netfd.addrFunc()(lsa), netfd.addrFunc()(rsa))
return netfd, nil return netfd, nil
} }
......
...@@ -198,7 +198,7 @@ func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, ...@@ -198,7 +198,7 @@ func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn,
if raddr == nil { if raddr == nil {
return nil, &OpError{Op: "dial", Net: netProto, Addr: nil, Err: errMissingAddress} return nil, &OpError{Op: "dial", Net: netProto, Addr: nil, Err: errMissingAddress}
} }
fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_RAW, proto, "dial", sockaddrToIP) 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, Addr: raddr, Err: err}
} }
...@@ -219,7 +219,7 @@ func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) { ...@@ -219,7 +219,7 @@ func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) {
default: default:
return nil, &OpError{Op: "listen", Net: netProto, Addr: laddr, Err: UnknownNetworkError(netProto)} return nil, &OpError{Op: "listen", Net: netProto, Addr: laddr, Err: UnknownNetworkError(netProto)}
} }
fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_RAW, proto, "listen", sockaddrToIP) 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, Addr: laddr, Err: err}
} }
......
...@@ -132,9 +132,9 @@ func favoriteAddrFamily(net string, laddr, raddr sockaddr, mode string) (family ...@@ -132,9 +132,9 @@ func favoriteAddrFamily(net string, laddr, raddr sockaddr, mode string) (family
// Internet sockets (TCP, UDP, IP) // Internet sockets (TCP, UDP, IP)
func internetSocket(net string, laddr, raddr sockaddr, deadline time.Time, sotype, proto int, mode string, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) { func internetSocket(net string, laddr, raddr sockaddr, deadline time.Time, sotype, proto int, mode string) (fd *netFD, err error) {
family, ipv6only := favoriteAddrFamily(net, laddr, raddr, mode) family, ipv6only := favoriteAddrFamily(net, laddr, raddr, mode)
return socket(net, family, sotype, proto, ipv6only, laddr, raddr, deadline, toAddr) return socket(net, family, sotype, proto, ipv6only, laddr, raddr, deadline)
} }
func ipToSockaddr(family int, ip IP, port int, zone string) (syscall.Sockaddr, error) { func ipToSockaddr(family int, ip IP, port int, zone string) (syscall.Sockaddr, error) {
......
...@@ -36,7 +36,7 @@ type sockaddr interface { ...@@ -36,7 +36,7 @@ type sockaddr interface {
// socket returns a network file descriptor that is ready for // socket returns a network file descriptor that is ready for
// asynchronous I/O using the network poller. // asynchronous I/O using the network poller.
func socket(net string, family, sotype, proto int, ipv6only bool, laddr, raddr sockaddr, deadline time.Time, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) { func socket(net string, family, sotype, proto int, ipv6only bool, laddr, raddr sockaddr, deadline time.Time) (fd *netFD, err error) {
s, err := sysSocket(family, sotype, proto) s, err := sysSocket(family, sotype, proto)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -75,27 +75,51 @@ func socket(net string, family, sotype, proto int, ipv6only bool, laddr, raddr s ...@@ -75,27 +75,51 @@ func socket(net string, family, sotype, proto int, ipv6only bool, laddr, raddr s
if laddr != nil && raddr == nil { if laddr != nil && raddr == nil {
switch sotype { switch sotype {
case syscall.SOCK_STREAM, syscall.SOCK_SEQPACKET: case syscall.SOCK_STREAM, syscall.SOCK_SEQPACKET:
if err := fd.listenStream(laddr, listenerBacklog, toAddr); err != nil { if err := fd.listenStream(laddr, listenerBacklog); err != nil {
fd.Close() fd.Close()
return nil, err return nil, err
} }
return fd, nil return fd, nil
case syscall.SOCK_DGRAM: case syscall.SOCK_DGRAM:
if err := fd.listenDatagram(laddr, toAddr); err != nil { if err := fd.listenDatagram(laddr); err != nil {
fd.Close() fd.Close()
return nil, err return nil, err
} }
return fd, nil return fd, nil
} }
} }
if err := fd.dial(laddr, raddr, deadline, toAddr); err != nil { if err := fd.dial(laddr, raddr, deadline); err != nil {
fd.Close() fd.Close()
return nil, err return nil, err
} }
return fd, nil return fd, nil
} }
func (fd *netFD) dial(laddr, raddr sockaddr, deadline time.Time, toAddr func(syscall.Sockaddr) Addr) error { func (fd *netFD) addrFunc() func(syscall.Sockaddr) Addr {
switch fd.family {
case syscall.AF_INET, syscall.AF_INET6:
switch fd.sotype {
case syscall.SOCK_STREAM:
return sockaddrToTCP
case syscall.SOCK_DGRAM:
return sockaddrToUDP
case syscall.SOCK_RAW:
return sockaddrToIP
}
case syscall.AF_UNIX:
switch fd.sotype {
case syscall.SOCK_STREAM:
return sockaddrToUnix
case syscall.SOCK_DGRAM:
return sockaddrToUnixgram
case syscall.SOCK_SEQPACKET:
return sockaddrToUnixpacket
}
}
return func(syscall.Sockaddr) Addr { return nil }
}
func (fd *netFD) dial(laddr, raddr sockaddr, deadline time.Time) error {
var err error var err error
var lsa syscall.Sockaddr var lsa syscall.Sockaddr
if laddr != nil { if laddr != nil {
...@@ -123,14 +147,14 @@ func (fd *netFD) dial(laddr, raddr sockaddr, deadline time.Time, toAddr func(sys ...@@ -123,14 +147,14 @@ func (fd *netFD) dial(laddr, raddr sockaddr, deadline time.Time, toAddr func(sys
} }
lsa, _ = syscall.Getsockname(fd.sysfd) lsa, _ = syscall.Getsockname(fd.sysfd)
if rsa, _ = syscall.Getpeername(fd.sysfd); rsa != nil { if rsa, _ = syscall.Getpeername(fd.sysfd); rsa != nil {
fd.setAddr(toAddr(lsa), toAddr(rsa)) fd.setAddr(fd.addrFunc()(lsa), fd.addrFunc()(rsa))
} else { } else {
fd.setAddr(toAddr(lsa), raddr) fd.setAddr(fd.addrFunc()(lsa), raddr)
} }
return nil return nil
} }
func (fd *netFD) listenStream(laddr sockaddr, backlog int, toAddr func(syscall.Sockaddr) Addr) error { func (fd *netFD) listenStream(laddr sockaddr, backlog int) error {
if err := setDefaultListenerSockopts(fd.sysfd); err != nil { if err := setDefaultListenerSockopts(fd.sysfd); err != nil {
return err return err
} }
...@@ -148,11 +172,11 @@ func (fd *netFD) listenStream(laddr sockaddr, backlog int, toAddr func(syscall.S ...@@ -148,11 +172,11 @@ func (fd *netFD) listenStream(laddr sockaddr, backlog int, toAddr func(syscall.S
return err return err
} }
lsa, _ := syscall.Getsockname(fd.sysfd) lsa, _ := syscall.Getsockname(fd.sysfd)
fd.setAddr(toAddr(lsa), nil) fd.setAddr(fd.addrFunc()(lsa), nil)
return nil return nil
} }
func (fd *netFD) listenDatagram(laddr sockaddr, toAddr func(syscall.Sockaddr) Addr) error { func (fd *netFD) listenDatagram(laddr sockaddr) error {
switch addr := laddr.(type) { switch addr := laddr.(type) {
case *UDPAddr: case *UDPAddr:
// We provide a socket that listens to a wildcard // We provide a socket that listens to a wildcard
...@@ -187,6 +211,6 @@ func (fd *netFD) listenDatagram(laddr sockaddr, toAddr func(syscall.Sockaddr) Ad ...@@ -187,6 +211,6 @@ func (fd *netFD) listenDatagram(laddr sockaddr, toAddr func(syscall.Sockaddr) Ad
return err return err
} }
lsa, _ := syscall.Getsockname(fd.sysfd) lsa, _ := syscall.Getsockname(fd.sysfd)
fd.setAddr(toAddr(lsa), nil) fd.setAddr(fd.addrFunc()(lsa), nil)
return nil return nil
} }
...@@ -153,7 +153,7 @@ func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error) { ...@@ -153,7 +153,7 @@ func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error) {
} }
func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, error) { func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, error) {
fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP) fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_STREAM, 0, "dial")
// TCP has a rarely used mechanism called a 'simultaneous connection' in // TCP has a rarely used mechanism called a 'simultaneous connection' in
// which Dial("tcp", addr1, addr2) run on the machine at addr1 can // which Dial("tcp", addr1, addr2) run on the machine at addr1 can
...@@ -183,7 +183,7 @@ func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, e ...@@ -183,7 +183,7 @@ func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, e
if err == nil { if err == nil {
fd.Close() fd.Close()
} }
fd, err = internetSocket(net, laddr, raddr, deadline, syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP) fd, err = internetSocket(net, laddr, raddr, deadline, syscall.SOCK_STREAM, 0, "dial")
} }
if err != nil { if err != nil {
...@@ -231,7 +231,7 @@ func (l *TCPListener) AcceptTCP() (*TCPConn, error) { ...@@ -231,7 +231,7 @@ func (l *TCPListener) AcceptTCP() (*TCPConn, error) {
if l == nil || l.fd == nil { if l == nil || l.fd == nil {
return nil, syscall.EINVAL return nil, syscall.EINVAL
} }
fd, err := l.fd.accept(sockaddrToTCP) fd, err := l.fd.accept()
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -291,7 +291,7 @@ func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) { ...@@ -291,7 +291,7 @@ func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) {
if laddr == nil { if laddr == nil {
laddr = &TCPAddr{} laddr = &TCPAddr{}
} }
fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_STREAM, 0, "listen", sockaddrToTCP) 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, Addr: laddr, Err: err}
} }
......
...@@ -175,7 +175,7 @@ func DialUDP(net string, laddr, raddr *UDPAddr) (*UDPConn, error) { ...@@ -175,7 +175,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", sockaddrToUDP) 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, Addr: raddr, Err: err}
} }
...@@ -198,7 +198,7 @@ func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) { ...@@ -198,7 +198,7 @@ func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) {
if laddr == nil { if laddr == nil {
laddr = &UDPAddr{} laddr = &UDPAddr{}
} }
fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen", sockaddrToUDP) 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, Addr: laddr, Err: err}
} }
...@@ -218,7 +218,7 @@ func ListenMulticastUDP(net string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, e ...@@ -218,7 +218,7 @@ func ListenMulticastUDP(net string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, e
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, Addr: nil, Err: errMissingAddress}
} }
fd, err := internetSocket(net, gaddr, nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen", sockaddrToUDP) 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, Addr: gaddr, Err: err}
} }
......
...@@ -42,14 +42,7 @@ func unixSocket(net string, laddr, raddr sockaddr, mode string, deadline time.Ti ...@@ -42,14 +42,7 @@ func unixSocket(net string, laddr, raddr sockaddr, mode string, deadline time.Ti
return nil, errors.New("unknown mode: " + mode) return nil, errors.New("unknown mode: " + mode)
} }
f := sockaddrToUnix fd, err := socket(net, syscall.AF_UNIX, sotype, 0, false, laddr, raddr, deadline)
if sotype == syscall.SOCK_DGRAM {
f = sockaddrToUnixgram
} else if sotype == syscall.SOCK_SEQPACKET {
f = sockaddrToUnixpacket
}
fd, err := socket(net, syscall.AF_UNIX, sotype, 0, false, laddr, raddr, deadline, f)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -286,11 +279,7 @@ func (l *UnixListener) AcceptUnix() (*UnixConn, error) { ...@@ -286,11 +279,7 @@ func (l *UnixListener) AcceptUnix() (*UnixConn, error) {
if l == nil || l.fd == nil { if l == nil || l.fd == nil {
return nil, syscall.EINVAL return nil, syscall.EINVAL
} }
toAddr := sockaddrToUnix fd, err := l.fd.accept()
if l.fd.sotype == syscall.SOCK_SEQPACKET {
toAddr = sockaddrToUnixpacket
}
fd, err := l.fd.accept(toAddr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
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