Commit 734d4637 authored by Joel Sing's avatar Joel Sing

net: fix non-blocking connect handling on dragonfly

Performing multiple connect system calls on a non-blocking socket
under DragonFly BSD does not necessarily result in errors from earlier
connect calls being returned, particularly if we are connecting to
localhost. Instead, once netpoll tells us that the socket is ready,
get the SO_ERROR socket option to see if the connection succeeded
or failed.

Fixes #7474

LGTM=mikioh.mikioh
R=mikioh.mikioh
CC=golang-codereviews
https://golang.org/cl/69340044
parent 9a7cd11b
......@@ -96,6 +96,28 @@ func (fd *netFD) connect(la, ra syscall.Sockaddr) error {
if err = fd.pd.WaitWrite(); err != nil {
return err
}
// Performing multiple connect system calls on a non-blocking
// socket under DragonFly BSD does not necessarily result in
// earlier errors being returned, particularly if we are
// connecting to localhost. Instead, once netpoll tells us that
// the socket is ready, get the SO_ERROR socket option to see
// if the connection succeeded or failed. See issue 7474 for
// further details. At some point we may want to consider
// doing the same on other Unixes.
if runtime.GOOS == "dragonfly" {
nerr, err := syscall.GetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
if err != nil {
return err
}
if nerr == 0 {
return nil
}
err = syscall.Errno(nerr)
if err != syscall.EINPROGRESS && err != syscall.EALREADY && err != syscall.EINTR {
return err
}
}
}
return nil
}
......
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