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:
parent
2a1ca145cf
commit
ca6b1f3eeb
@ -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,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
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user