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) {
}
}
}
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 {
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()
defer fd.wio.Unlock()
if err := fd.pd.PrepareWrite(); err != nil {
......
......@@ -364,12 +364,12 @@ func (o *connectOp) Name() string {
return "ConnectEx"
}
func (fd *netFD) connect(ra syscall.Sockaddr) error {
func (fd *netFD) connect(la, ra syscall.Sockaddr) error {
if !canUseConnectEx(fd.net) {
return syscall.Connect(fd.sysfd, ra)
}
// ConnectEx windows API requires an unconnected, previously bound socket.
var la syscall.Sockaddr
if la == nil {
switch ra.(type) {
case *syscall.SockaddrInet4:
la = &syscall.SockaddrInet4{}
......@@ -381,6 +381,7 @@ func (fd *netFD) connect(ra syscall.Sockaddr) error {
if err := syscall.Bind(fd.sysfd, la); err != nil {
return err
}
}
// Call ConnectEx API.
var o connectOp
o.Init(fd, 'w')
......
......@@ -57,7 +57,7 @@ func socket(net string, f, t, p int, ipv6only bool, ulsa, ursa syscall.Sockaddr,
if !deadline.IsZero() {
setWriteDeadline(fd, deadline)
}
if err = fd.connect(ursa); err != nil {
if err = fd.connect(ulsa, ursa); err != nil {
fd.Close()
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