Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
dms3
go-unixfs
Commits
9062b9fe
Commit
9062b9fe
authored
Jan 19, 2015
by
Juan Batiz-Benet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
connect timing fixes to reuseport
parent
7a3e0cdc
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
31 additions
and
16 deletions
+31
-16
Godeps/Godeps.json
Godeps/Godeps.json
+1
-1
Godeps/_workspace/src/github.com/jbenet/go-reuseport/impl_unix.go
...workspace/src/github.com/jbenet/go-reuseport/impl_unix.go
+26
-11
Godeps/_workspace/src/github.com/jbenet/go-reuseport/interface.go
...workspace/src/github.com/jbenet/go-reuseport/interface.go
+4
-4
No files found.
Godeps/Godeps.json
View file @
9062b9fe
...
...
@@ -160,7 +160,7 @@
},
{
"ImportPath"
:
"github.com/jbenet/go-reuseport"
,
"Rev"
:
"
f2ab96a83e1b33b66478eedd314884755d771933
"
"Rev"
:
"
1e1968c4744fef51234e83f015aa0187b4bd796b
"
},
{
"ImportPath"
:
"github.com/jbenet/go-sockaddr/net"
,
...
...
Godeps/_workspace/src/github.com/jbenet/go-reuseport/impl_unix.go
View file @
9062b9fe
...
...
@@ -106,18 +106,27 @@ func dial(dialer net.Dialer, netw, addr string) (c net.Conn, err error) {
}
}
if
fd
,
err
=
socket
(
rfamily
,
socktype
,
rprotocol
);
err
!=
nil
{
return
nil
,
err
}
// look at dialTCP in http://golang.org/src/net/tcpsock_posix.go .... !
// here we just try again 3 times.
for
i
:=
0
;
i
<
3
;
i
++
{
if
fd
,
err
=
socket
(
rfamily
,
socktype
,
rprotocol
);
err
!=
nil
{
return
nil
,
err
}
if
err
=
syscall
.
Bind
(
fd
,
localSockaddr
);
err
!=
nil
{
// fmt.Println("bind failed")
syscall
.
Close
(
fd
)
return
nil
,
err
if
err
=
syscall
.
Bind
(
fd
,
localSockaddr
);
err
!=
nil
{
// fmt.Println("bind failed")
syscall
.
Close
(
fd
)
return
nil
,
err
}
if
err
=
connect
(
fd
,
remoteSockaddr
);
err
!=
nil
{
syscall
.
Close
(
fd
)
// fmt.Println("connect failed", localSockaddr, err)
continue
// try again.
}
break
}
if
err
=
connect
(
fd
,
remoteSockaddr
);
err
!=
nil
{
syscall
.
Close
(
fd
)
// fmt.Println("connect failed", localSockaddr, err)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -314,6 +323,7 @@ func connect(fd int, ra syscall.Sockaddr) error {
}
var
err
error
start
:=
time
.
Now
()
for
{
// if err := fd.pd.WaitWrite(); err != nil {
// return err
...
...
@@ -321,7 +331,8 @@ func connect(fd int, ra syscall.Sockaddr) error {
// i'd use the above fd.pd.WaitWrite to poll io correctly, just like net sockets...
// but of course, it uses fucking runtime_* functions that _cannot_ be used by
// non-go-stdlib source... seriously guys, what kind of bullshit is that!?
<-
time
.
After
(
20
*
time
.
Microsecond
)
// we're relegated to using syscall.Select (what nightmare that is) or using
// a simple but totally bogus time-based wait. garbage.
var
nerr
int
nerr
,
err
=
syscall
.
GetsockoptInt
(
fd
,
syscall
.
SOL_SOCKET
,
syscall
.
SO_ERROR
)
if
err
!=
nil
{
...
...
@@ -329,6 +340,10 @@ func connect(fd int, ra syscall.Sockaddr) error {
}
switch
err
=
syscall
.
Errno
(
nerr
);
err
{
case
syscall
.
EINPROGRESS
,
syscall
.
EALREADY
,
syscall
.
EINTR
:
if
time
.
Now
()
.
Sub
(
start
)
>
time
.
Second
{
return
err
}
<-
time
.
After
(
20
*
time
.
Microsecond
)
case
syscall
.
Errno
(
0
),
syscall
.
EISCONN
:
return
nil
default
:
...
...
Godeps/_workspace/src/github.com/jbenet/go-reuseport/interface.go
View file @
9062b9fe
...
...
@@ -71,16 +71,16 @@ type Dialer struct {
// Returns a net.Conn created from a file discriptor for a socket
// with SO_REUSEPORT and SO_REUSEADDR option set.
func
(
d
*
Dialer
)
Dial
(
network
,
address
string
)
(
net
.
Conn
,
error
)
{
// there's a rare case where dial returns successfully but for some reason the
// RemoteAddr is not yet set. We wait here a while until it is, and if too long
// passes, we fail.
c
,
err
:=
dial
(
d
.
D
,
network
,
address
)
if
err
!=
nil
{
return
nil
,
err
}
// there's a rare case where dial returns successfully but for some reason the
// RemoteAddr is not yet set. We wait here a while until it is, and if too long
// passes, we fail. This is horrendous.
for
start
:=
time
.
Now
();
c
.
RemoteAddr
()
==
nil
;
{
if
time
.
Now
()
.
Sub
(
start
)
>
time
.
Second
{
if
time
.
Now
()
.
Sub
(
start
)
>
(
time
.
Millisecond
*
500
)
{
c
.
Close
()
return
nil
,
ErrReuseFailed
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment