diff options
| author | Andrew Gerrand <adg@golang.org> | 2014-08-13 13:18:02 +1000 |
|---|---|---|
| committer | Andrew Gerrand <adg@golang.org> | 2014-08-13 13:18:02 +1000 |
| commit | 1657de2d6dbb020e15908668f209f3be7dcef151 (patch) | |
| tree | 62367a9618b6054f567e629f2a09492f0576e7d1 /src/pkg/net/fd_unix.go | |
| parent | f36546bc1078796716dcd8028f0d8210e366d80e (diff) | |
| download | go1.3.1.tar.xz | |
[release-branch.go1.3] net: prevent spurious on-connect events via epoll on linuxgo1.3.1
««« CL 120820043 / 06a4b59c1393
net: prevent spurious on-connect events via epoll on linux
On Linux, adding a socket descriptor to epoll instance before getting
the EINPROGRESS return value from connect system call could be a root
cause of spurious on-connect events.
See golang.org/issue/8276, golang.org/issue/8426 for further information.
All credit to Jason Eggleston <jason@eggnet.com>
Fixes #8276.
Fixes #8426.
LGTM=dvyukov
R=dvyukov, golang-codereviews, adg, dave, iant, alex.brainman
CC=golang-codereviews
https://golang.org/cl/120820043
»»»
TBR=r, rsc
CC=golang-codereviews
https://golang.org/cl/128110045
Diffstat (limited to 'src/pkg/net/fd_unix.go')
| -rw-r--r-- | src/pkg/net/fd_unix.go | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/src/pkg/net/fd_unix.go b/src/pkg/net/fd_unix.go index b82ecd11c1..e22861abbd 100644 --- a/src/pkg/net/fd_unix.go +++ b/src/pkg/net/fd_unix.go @@ -68,16 +68,19 @@ func (fd *netFD) name() string { return fd.net + ":" + ls + "->" + rs } -func (fd *netFD) connect(la, ra syscall.Sockaddr) error { +func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error { // Do not need to call fd.writeLock here, // because fd is not yet accessible to user, // so no concurrent operations are possible. - if err := fd.pd.PrepareWrite(); err != nil { - return err - } switch err := syscall.Connect(fd.sysfd, ra); err { case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR: case nil, syscall.EISCONN: + if !deadline.IsZero() && deadline.Before(time.Now()) { + return errTimeout + } + if err := fd.init(); err != nil { + return err + } return nil case syscall.EINVAL: // On Solaris we can see EINVAL if the socket has @@ -92,6 +95,13 @@ func (fd *netFD) connect(la, ra syscall.Sockaddr) error { default: return err } + if err := fd.init(); err != nil { + return err + } + if !deadline.IsZero() { + fd.setWriteDeadline(deadline) + defer fd.setWriteDeadline(noDeadline) + } for { // Performing multiple connect system calls on a // non-blocking socket under Unix variants does not |
