client.go | 5 +++++ client_test.go | 22 ++++++++++++++++++++++ diff --git a/client.go b/client.go index c3e99d0c511b934d255707980be8f3e6ad21c0de..d1d25288e400fa979109cd2bff402a6259439542 100644 --- a/client.go +++ b/client.go @@ -387,6 +387,10 @@ return } } +func reducedDialTimeout(max time.Duration, halfOpenLimit int, pendingPeers int) time.Duration { + return max / time.Duration((pendingPeers+halfOpenLimit)/halfOpenLimit) +} + // Start the process of connecting to the given peer for the given torrent if // appropriate. func (me *Client) initiateConn(peer Peer, t *torrent) { @@ -405,6 +409,7 @@ // "address in use" error. It seems it's not possible to dial out from // this address so that peers associate our local address with our // listen address. + dialTimeout := reducedDialTimeout(dialTimeout, me.halfOpenLimit, len(t.Peers)) // Initiate connections via TCP and UTP simultaneously. Use the first // one that succeeds. left := 2 diff --git a/client_test.go b/client_test.go index 3dcb6c34a1419d8793a9932f5c7509bbcb448480..05d08e694dfaea7f42bb0f59ffc4d7e91ae0ca60 100644 --- a/client_test.go +++ b/client_test.go @@ -3,6 +3,7 @@ import ( "os" "testing" + "time" "bitbucket.org/anacrolix/go.torrent/testutil" "bitbucket.org/anacrolix/go.torrent/util" @@ -75,3 +76,24 @@ if m.Added[0].Port != 0x506 { t.FailNow() } } + +func TestReducedDialTimeout(t *testing.T) { + for _, _case := range []struct { + Max time.Duration + HalfOpenLimit int + PendingPeers int + ExpectedReduced time.Duration + }{ + {dialTimeout, 40, 0, dialTimeout}, + {dialTimeout, 40, 1, dialTimeout}, + {dialTimeout, 40, 39, dialTimeout}, + {dialTimeout, 40, 40, dialTimeout / 2}, + {dialTimeout, 40, 80, dialTimeout / 3}, + {dialTimeout, 40, 4000, dialTimeout / 101}, + } { + reduced := reducedDialTimeout(_case.Max, _case.HalfOpenLimit, _case.PendingPeers) + if reduced != _case.ExpectedReduced { + t.Fatalf("expected %s, got %s", _case.ExpectedReduced, reduced) + } + } +}