mirror of
https://github.com/golang/go
synced 2024-11-25 01:17: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
|
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,22 +364,23 @@ 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{}
|
||||||
case *syscall.SockaddrInet6:
|
case *syscall.SockaddrInet6:
|
||||||
la = &syscall.SockaddrInet6{}
|
la = &syscall.SockaddrInet6{}
|
||||||
default:
|
default:
|
||||||
panic("unexpected type in connect")
|
panic("unexpected type in connect")
|
||||||
}
|
}
|
||||||
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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user