Commit e4389c00 authored by Mikio Hara's avatar Mikio Hara

undo CL 6395055 / 2518eee18c4f

Broke TCP selfConnect

««« original CL description
net: avoid nil pointer dereference when RemoteAddr.String method chain is called

Fixes #3721.

R=dave, rsc
CC=golang-dev
https://golang.org/cl/6395055
»»»

R=rsc
CC=golang-dev
https://golang.org/cl/6533043
parent e93891f3
...@@ -615,7 +615,8 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err e ...@@ -615,7 +615,8 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err e
closesocket(s) closesocket(s)
return nil, err return nil, err
} }
netfd.setAddr(localSockname(fd, toAddr), toAddr(rsa)) lsa, _ := syscall.Getsockname(netfd.sysfd)
netfd.setAddr(toAddr(lsa), toAddr(rsa))
return netfd, nil return netfd, nil
} }
......
...@@ -58,13 +58,15 @@ func newFileFD(f *os.File) (*netFD, error) { ...@@ -58,13 +58,15 @@ func newFileFD(f *os.File) (*netFD, error) {
} }
} }
laddr := toAddr(lsa) laddr := toAddr(lsa)
rsa, _ := syscall.Getpeername(fd)
raddr := toAddr(rsa)
netfd, err := newFD(fd, family, sotype, laddr.Network()) netfd, err := newFD(fd, family, sotype, laddr.Network())
if err != nil { if err != nil {
closesocket(fd) closesocket(fd)
return nil, err return nil, err
} }
netfd.setAddr(laddr, remoteSockname(netfd, toAddr)) netfd.setAddr(laddr, raddr)
return netfd, nil return netfd, nil
} }
......
...@@ -14,55 +14,6 @@ import ( ...@@ -14,55 +14,6 @@ import (
"time" "time"
) )
var ipConnAddrStringTests = []struct {
net string
laddr string
raddr string
ipv6 bool
}{
{"ip:icmp", "127.0.0.1", "", false},
{"ip:icmp", "::1", "", true},
{"ip:icmp", "", "127.0.0.1", false},
{"ip:icmp", "", "::1", true},
}
func TestIPConnAddrString(t *testing.T) {
if os.Getuid() != 0 {
t.Logf("skipping test; must be root")
return
}
for i, tt := range ipConnAddrStringTests {
if tt.ipv6 && !supportsIPv6 {
continue
}
var (
err error
c *IPConn
mode string
)
if tt.raddr == "" {
mode = "listen"
la, _ := ResolveIPAddr(tt.net, tt.laddr)
c, err = ListenIP(tt.net, la)
if err != nil {
t.Fatalf("ListenIP(%q, %q) failed: %v", tt.net, la.String(), err)
}
} else {
mode = "dial"
la, _ := ResolveIPAddr(tt.net, tt.laddr)
ra, _ := ResolveIPAddr(tt.net, tt.raddr)
c, err = DialIP(tt.net, la, ra)
if err != nil {
t.Fatalf("DialIP(%q, %q) failed: %v", tt.net, ra.String(), err)
}
}
t.Logf("%s-%v: LocalAddr: %q, %q", mode, i, c.LocalAddr(), c.LocalAddr().String())
t.Logf("%s-%v: RemoteAddr: %q, %q", mode, i, c.RemoteAddr(), c.RemoteAddr().String())
c.Close()
}
}
var icmpTests = []struct { var icmpTests = []struct {
net string net string
laddr string laddr string
......
...@@ -58,13 +58,16 @@ func socket(net string, f, t, p int, ipv6only bool, ulsa, ursa syscall.Sockaddr, ...@@ -58,13 +58,16 @@ func socket(net string, f, t, p int, ipv6only bool, ulsa, ursa syscall.Sockaddr,
fd.isConnected = true fd.isConnected = true
} }
lsa, _ := syscall.Getsockname(s)
var laddr Addr var laddr Addr
if ulsa != nil && blsa != ulsa { if ulsa != nil && blsa != ulsa {
laddr = toAddr(ulsa) laddr = toAddr(ulsa)
} else { } else {
laddr = localSockname(fd, toAddr) laddr = toAddr(lsa)
} }
fd.setAddr(laddr, remoteSockname(fd, toAddr)) rsa, _ := syscall.Getpeername(s)
raddr := toAddr(rsa)
fd.setAddr(laddr, raddr)
return fd, nil return fd, nil
} }
...@@ -78,39 +81,3 @@ func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) { ...@@ -78,39 +81,3 @@ func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) {
// Use wrapper to hide existing r.ReadFrom from io.Copy. // Use wrapper to hide existing r.ReadFrom from io.Copy.
return io.Copy(writerOnly{w}, r) return io.Copy(writerOnly{w}, r)
} }
func localSockname(fd *netFD, toAddr func(syscall.Sockaddr) Addr) Addr {
sa, _ := syscall.Getsockname(fd.sysfd)
if sa == nil {
return nullProtocolAddr(fd.family, fd.sotype)
}
return toAddr(sa)
}
func remoteSockname(fd *netFD, toAddr func(syscall.Sockaddr) Addr) Addr {
sa, _ := syscall.Getpeername(fd.sysfd)
if sa == nil {
return nullProtocolAddr(fd.family, fd.sotype)
}
return toAddr(sa)
}
func nullProtocolAddr(f, t int) Addr {
switch f {
case syscall.AF_INET, syscall.AF_INET6:
switch t {
case syscall.SOCK_STREAM:
return (*TCPAddr)(nil)
case syscall.SOCK_DGRAM:
return (*UDPAddr)(nil)
case syscall.SOCK_RAW:
return (*IPAddr)(nil)
}
case syscall.AF_UNIX:
switch t {
case syscall.SOCK_STREAM, syscall.SOCK_DGRAM, syscall.SOCK_SEQPACKET:
return (*UnixAddr)(nil)
}
}
panic("unreachable")
}
...@@ -9,33 +9,6 @@ import ( ...@@ -9,33 +9,6 @@ import (
"testing" "testing"
) )
var udpConnAddrStringTests = []struct {
net string
laddr string
raddr string
ipv6 bool
}{
{"udp", "127.0.0.1:0", "", false},
{"udp", "[::1]:0", "", true},
}
func TestUDPConnAddrString(t *testing.T) {
for i, tt := range udpConnAddrStringTests {
if tt.ipv6 && !supportsIPv6 {
continue
}
mode := "listen"
la, _ := ResolveUDPAddr(tt.net, tt.laddr)
c, err := ListenUDP(tt.net, la)
if err != nil {
t.Fatalf("ListenUDP(%q, %q) failed: %v", tt.net, la.String(), err)
}
t.Logf("%s-%v: LocalAddr: %q, %q", mode, i, c.LocalAddr(), c.LocalAddr().String())
t.Logf("%s-%v: RemoteAddr: %q, %q", mode, i, c.RemoteAddr(), c.RemoteAddr().String())
c.Close()
}
}
func TestWriteToUDP(t *testing.T) { func TestWriteToUDP(t *testing.T) {
switch runtime.GOOS { switch runtime.GOOS {
case "plan9": case "plan9":
......
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