mirror of
https://github.com/golang/go
synced 2024-11-23 13:00:07 -07:00
net: make sure failed Dial returns nil Conn
Fixes #6614. R=golang-dev, bradfitz, mikioh.mikioh CC=golang-dev https://golang.org/cl/14950045
This commit is contained in:
parent
f6329700ae
commit
66f49f78a5
@ -215,26 +215,30 @@ func dialMulti(net, addr string, la Addr, ras addrList, deadline time.Time) (Con
|
||||
|
||||
// dialSingle attempts to establish and returns a single connection to
|
||||
// the destination address.
|
||||
func dialSingle(net, addr string, la, ra Addr, deadline time.Time) (Conn, error) {
|
||||
func dialSingle(net, addr string, la, ra Addr, deadline time.Time) (c Conn, err error) {
|
||||
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())}
|
||||
}
|
||||
switch ra := ra.(type) {
|
||||
case *TCPAddr:
|
||||
la, _ := la.(*TCPAddr)
|
||||
return dialTCP(net, la, ra, deadline)
|
||||
c, err = dialTCP(net, la, ra, deadline)
|
||||
case *UDPAddr:
|
||||
la, _ := la.(*UDPAddr)
|
||||
return dialUDP(net, la, ra, deadline)
|
||||
c, err = dialUDP(net, la, ra, deadline)
|
||||
case *IPAddr:
|
||||
la, _ := la.(*IPAddr)
|
||||
return dialIP(net, la, ra, deadline)
|
||||
c, err = dialIP(net, la, ra, deadline)
|
||||
case *UnixAddr:
|
||||
la, _ := la.(*UnixAddr)
|
||||
return dialUnix(net, la, ra, deadline)
|
||||
c, err = dialUnix(net, la, ra, deadline)
|
||||
default:
|
||||
return nil, &OpError{Op: "dial", Net: net, Addr: ra, Err: &AddrError{Err: "unexpected address type", Addr: addr}}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err // c is non-nil interface containing nil pointer
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Listen announces on the local network address laddr.
|
||||
@ -246,14 +250,19 @@ func Listen(net, laddr string) (Listener, error) {
|
||||
if err != nil {
|
||||
return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: err}
|
||||
}
|
||||
var l Listener
|
||||
switch la := la.toAddr().(type) {
|
||||
case *TCPAddr:
|
||||
return ListenTCP(net, la)
|
||||
l, err = ListenTCP(net, la)
|
||||
case *UnixAddr:
|
||||
return ListenUnix(net, la)
|
||||
l, err = ListenUnix(net, la)
|
||||
default:
|
||||
return nil, &OpError{Op: "listen", Net: net, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err // l is non-nil interface containing nil pointer
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
|
||||
// ListenPacket announces on the local network address laddr.
|
||||
@ -265,14 +274,19 @@ func ListenPacket(net, laddr string) (PacketConn, error) {
|
||||
if err != nil {
|
||||
return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: err}
|
||||
}
|
||||
var l PacketConn
|
||||
switch la := la.toAddr().(type) {
|
||||
case *UDPAddr:
|
||||
return ListenUDP(net, la)
|
||||
l, err = ListenUDP(net, la)
|
||||
case *IPAddr:
|
||||
return ListenIP(net, la)
|
||||
l, err = ListenIP(net, la)
|
||||
case *UnixAddr:
|
||||
return ListenUnixgram(net, la)
|
||||
l, err = ListenUnixgram(net, la)
|
||||
default:
|
||||
return nil, &OpError{Op: "listen", Net: net, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err // l is non-nil interface containing nil pointer
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
|
@ -218,3 +218,41 @@ func TestTCPClose(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorNil(t *testing.T) {
|
||||
c, err := Dial("tcp", "127.0.0.1:65535")
|
||||
if err == nil {
|
||||
t.Fatal("Dial 127.0.0.1:65535 succeeded")
|
||||
}
|
||||
if c != nil {
|
||||
t.Fatalf("Dial returned non-nil interface %T(%v) with err != nil", c, c)
|
||||
}
|
||||
|
||||
// Make Listen fail by relistening on the same address.
|
||||
l, err := Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatal("Listen 127.0.0.1:0: %v", err)
|
||||
}
|
||||
defer l.Close()
|
||||
l1, err := Listen("tcp", l.Addr().String())
|
||||
if err == nil {
|
||||
t.Fatal("second Listen %v: %v", l.Addr(), err)
|
||||
}
|
||||
if l1 != nil {
|
||||
t.Fatalf("Listen returned non-nil interface %T(%v) with err != nil", l1, l1)
|
||||
}
|
||||
|
||||
// Make ListenPacket fail by relistening on the same address.
|
||||
lp, err := ListenPacket("udp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatal("Listen 127.0.0.1:0: %v", err)
|
||||
}
|
||||
defer lp.Close()
|
||||
lp1, err := ListenPacket("udp", lp.LocalAddr().String())
|
||||
if err == nil {
|
||||
t.Fatal("second Listen %v: %v", lp.LocalAddr(), err)
|
||||
}
|
||||
if lp1 != nil {
|
||||
t.Fatalf("ListenPacket returned non-nil interface %T(%v) with err != nil", lp1, lp1)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user