1
0
mirror of https://github.com/golang/go synced 2024-11-25 01:27:56 -07:00

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
This commit is contained in:
Alex Brainman 2013-04-30 17:47:39 -07:00 committed by Rob Pike
parent 2a1ca145cf
commit ca6b1f3eeb
4 changed files with 50 additions and 14 deletions

View File

@ -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)
}
}

View File

@ -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 {

View File

@ -364,22 +364,23 @@ 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
switch ra.(type) {
case *syscall.SockaddrInet4:
la = &syscall.SockaddrInet4{}
case *syscall.SockaddrInet6:
la = &syscall.SockaddrInet6{}
default:
panic("unexpected type in connect")
}
if err := syscall.Bind(fd.sysfd, la); err != nil {
return err
if la == nil {
switch ra.(type) {
case *syscall.SockaddrInet4:
la = &syscall.SockaddrInet4{}
case *syscall.SockaddrInet6:
la = &syscall.SockaddrInet6{}
default:
panic("unexpected type in connect")
}
if err := syscall.Bind(fd.sysfd, la); err != nil {
return err
}
}
// Call ConnectEx API.
var o connectOp

View File

@ -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
}