Skip to content

Commit 9387469

Browse files
committed
Cancel async connection request when timeout has elapsed.
Dispose all managed resources. Fixes issue #87.
1 parent 1711d5a commit 9387469

File tree

1 file changed

+36
-6
lines changed

1 file changed

+36
-6
lines changed

src/Renci.SshNet/Abstractions/SocketAbstraction.cs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,51 @@ public static Socket Connect(IPEndPoint remoteEndpoint, TimeSpan connectTimeout)
5454
#if FEATURE_SOCKET_EAP
5555
var connectCompleted = new ManualResetEvent(false);
5656
var args = new SocketAsyncEventArgs
57-
{
58-
UserToken = connectCompleted,
59-
RemoteEndPoint = remoteEndpoint
60-
};
57+
{
58+
UserToken = connectCompleted,
59+
RemoteEndPoint = remoteEndpoint
60+
};
6161
args.Completed += ConnectCompleted;
6262

6363
if (socket.ConnectAsync(args))
6464
{
6565
if (!connectCompleted.WaitOne(connectTimeout))
66+
{
67+
// avoid ObjectDisposedException in ConnectCompleted
68+
args.Completed -= ConnectCompleted;
69+
// avoid leaking threads and /Device/Afd handles
70+
Socket.CancelConnectAsync(args);
71+
// dispose Socket
72+
socket.Dispose();
73+
// dispose ManualResetEvent
74+
connectCompleted.Dispose();
75+
// dispose SocketAsyncEventArgs
76+
args.Dispose();
77+
6678
throw new SshOperationTimeoutException(string.Format(CultureInfo.InvariantCulture,
67-
"Connection failed to establish within {0:F0} milliseconds.", connectTimeout.TotalMilliseconds));
79+
"Connection failed to establish within {0:F0} milliseconds.",
80+
connectTimeout.TotalMilliseconds));
81+
}
6882
}
6983

84+
// dispose ManualResetEvent
85+
connectCompleted.Dispose();
86+
7087
if (args.SocketError != SocketError.Success)
71-
throw new SocketException((int) args.SocketError);
88+
{
89+
var socketError = (int) args.SocketError;
90+
91+
// dispose Socket
92+
socket.Dispose();
93+
// dispose SocketAsyncEventArgs
94+
args.Dispose();
95+
96+
throw new SocketException(socketError);
97+
}
98+
99+
// dispose SocketAsyncEventArgs
100+
args.Dispose();
101+
72102
return socket;
73103
#elif FEATURE_SOCKET_APM
74104
var connectResult = socket.BeginConnect(remoteEndpoint, null, null);

0 commit comments

Comments
 (0)