Commit ca6b1f3e authored by Alex Brainman's avatar Alex Brainman Committed by Rob Pike

net: do not call syscall.Bind twice on windows

Fixes #5355.

R=golang-dev, mikioh.mikioh, bradfitz, r
CC=golang-dev
https://golang.org/cl/8966046
parent 2a1ca145
...@@ -372,3 +372,38 @@ func TestDialFailPDLeak(t *testing.T) { ...@@ -372,3 +372,38 @@ func TestDialFailPDLeak(t *testing.T) {
} }
} }
} }
func TestDialer(t *testing.T) {
ln, err := Listen("tcp4", "127.0.0.1:0")
if err != nil {
t.Fatalf("Listen failed: %v", err)
}
defer ln.Close()
ch := make(chan error, 1)
go func() {
var err error
c, err := ln.Accept()
if err != nil {
ch <- fmt.Errorf("Accept failed: %v", err)
return
}
defer c.Close()
ch <- nil
}()
laddr, err := ResolveTCPAddr("tcp4", "127.0.0.1:0")
if err != nil {
t.Fatalf("ResolveTCPAddr failed: %v", err)
}
d := &Dialer{LocalAddr: laddr}
c, err := d.Dial("tcp4", ln.Addr().String())
if err != nil {
t.Fatalf("Dial failed: %v", err)
}
defer c.Close()
c.Read(make([]byte, 1))
err = <-ch
if err != nil {
t.Error(err)
}
}
...@@ -79,7 +79,7 @@ func (fd *netFD) name() string { ...@@ -79,7 +79,7 @@ func (fd *netFD) name() string {
return fd.net + ":" + ls + "->" + rs return fd.net + ":" + ls + "->" + rs
} }
func (fd *netFD) connect(ra syscall.Sockaddr) error { func (fd *netFD) connect(la, ra syscall.Sockaddr) error {
fd.wio.Lock() fd.wio.Lock()
defer fd.wio.Unlock() defer fd.wio.Unlock()
if err := fd.pd.PrepareWrite(); err != nil { if err := fd.pd.PrepareWrite(); err != nil {
......
...@@ -364,12 +364,12 @@ func (o *connectOp) Name() string { ...@@ -364,12 +364,12 @@ func (o *connectOp) Name() string {
return "ConnectEx" return "ConnectEx"
} }
func (fd *netFD) connect(ra syscall.Sockaddr) error { func (fd *netFD) connect(la, ra syscall.Sockaddr) error {
if !canUseConnectEx(fd.net) { if !canUseConnectEx(fd.net) {
return syscall.Connect(fd.sysfd, ra) return syscall.Connect(fd.sysfd, ra)
} }
// ConnectEx windows API requires an unconnected, previously bound socket. // ConnectEx windows API requires an unconnected, previously bound socket.
var la syscall.Sockaddr if la == nil {
switch ra.(type) { switch ra.(type) {
case *syscall.SockaddrInet4: case *syscall.SockaddrInet4:
la = &syscall.SockaddrInet4{} la = &syscall.SockaddrInet4{}
...@@ -381,6 +381,7 @@ func (fd *netFD) connect(ra syscall.Sockaddr) error { ...@@ -381,6 +381,7 @@ func (fd *netFD) connect(ra syscall.Sockaddr) error {
if err := syscall.Bind(fd.sysfd, la); err != nil { if err := syscall.Bind(fd.sysfd, la); err != nil {
return err return err
} }
}
// Call ConnectEx API. // Call ConnectEx API.
var o connectOp var o connectOp
o.Init(fd, 'w') o.Init(fd, 'w')
......
...@@ -57,7 +57,7 @@ func socket(net string, f, t, p int, ipv6only bool, ulsa, ursa syscall.Sockaddr, ...@@ -57,7 +57,7 @@ func socket(net string, f, t, p int, ipv6only bool, ulsa, ursa syscall.Sockaddr,
if !deadline.IsZero() { if !deadline.IsZero() {
setWriteDeadline(fd, deadline) setWriteDeadline(fd, deadline)
} }
if err = fd.connect(ursa); err != nil { if err = fd.connect(ulsa, ursa); err != nil {
fd.Close() fd.Close()
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