|  | @@ -594,15 +594,15 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |                              break;
 | 
	
		
			
				|  |  |                          case ProxyTypes.Socks4:
 | 
	
		
			
				|  |  |                              SocketConnect(ConnectionInfo.ProxyHost, ConnectionInfo.ProxyPort);
 | 
	
		
			
				|  |  | -                            ConnectSocks4();
 | 
	
		
			
				|  |  | +                            ConnectSocks4(_socket, ConnectionInfo);
 | 
	
		
			
				|  |  |                              break;
 | 
	
		
			
				|  |  |                          case ProxyTypes.Socks5:
 | 
	
		
			
				|  |  |                              SocketConnect(ConnectionInfo.ProxyHost, ConnectionInfo.ProxyPort);
 | 
	
		
			
				|  |  | -                            ConnectSocks5();
 | 
	
		
			
				|  |  | +                            ConnectSocks5(_socket, ConnectionInfo);
 | 
	
		
			
				|  |  |                              break;
 | 
	
		
			
				|  |  |                          case ProxyTypes.Http:
 | 
	
		
			
				|  |  |                              SocketConnect(ConnectionInfo.ProxyHost, ConnectionInfo.ProxyPort);
 | 
	
		
			
				|  |  | -                            ConnectHttp();
 | 
	
		
			
				|  |  | +                            ConnectHttp(_socket, ConnectionInfo);
 | 
	
		
			
				|  |  |                              break;
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -612,7 +612,7 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |                      //  ignore text lines which are sent before if any
 | 
	
		
			
				|  |  |                      while (true)
 | 
	
		
			
				|  |  |                      {
 | 
	
		
			
				|  |  | -                        var serverVersion = SocketReadLine(ConnectionInfo.Timeout);
 | 
	
		
			
				|  |  | +                        var serverVersion = SocketReadLine(_socket, ConnectionInfo.Timeout);
 | 
	
		
			
				|  |  |                          if (serverVersion == null)
 | 
	
		
			
				|  |  |                              throw new SshConnectionException("Server response does not contain SSH protocol identification.", DisconnectReason.ProtocolError);
 | 
	
		
			
				|  |  |                          versionMatch = ServerVersionRe.Match(serverVersion);
 | 
	
	
		
			
				|  | @@ -657,7 +657,7 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |                      _messageListenerCompleted.Reset();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                      //  Start incoming request listener
 | 
	
		
			
				|  |  | -                    ThreadAbstraction.ExecuteThread(MessageListener);
 | 
	
		
			
				|  |  | +                    ThreadAbstraction.ExecuteThread(() => MessageListener());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                      //  Wait for key exchange to be completed
 | 
	
		
			
				|  |  |                      WaitOnHandle(_keyExchangeCompletedWaitHandle);
 | 
	
	
		
			
				|  | @@ -1062,7 +1062,7 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |          /// <remarks>
 | 
	
		
			
				|  |  |          /// We need no locking here since all messages are read by a single thread.
 | 
	
		
			
				|  |  |          /// </remarks>
 | 
	
		
			
				|  |  | -        private Message ReceiveMessage()
 | 
	
		
			
				|  |  | +        private Message ReceiveMessage(Socket socket)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              // the length of the packet sequence field in bytes
 | 
	
		
			
				|  |  |              const int inboundPacketSequenceLength = 4;
 | 
	
	
		
			
				|  | @@ -1088,7 +1088,7 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |  #endif // FEATURE_SOCKET_POLL
 | 
	
		
			
				|  |  |                  //  Read first block - which starts with the packet length
 | 
	
		
			
				|  |  |                  var firstBlock = new byte[blockSize];
 | 
	
		
			
				|  |  | -                if (TrySocketRead(firstBlock, 0, blockSize) == 0)
 | 
	
		
			
				|  |  | +                if (TrySocketRead(socket, firstBlock, 0, blockSize) == 0)
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  |                      // connection with SSH server was closed
 | 
	
		
			
				|  |  |                      return null;
 | 
	
	
		
			
				|  | @@ -1128,7 +1128,7 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  if (bytesToRead > 0)
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  | -                    if (TrySocketRead(data, blockSize + inboundPacketSequenceLength, bytesToRead) == 0)
 | 
	
		
			
				|  |  | +                    if (TrySocketRead(socket, data, blockSize + inboundPacketSequenceLength, bytesToRead) == 0)
 | 
	
		
			
				|  |  |                      {
 | 
	
		
			
				|  |  |                          return null;
 | 
	
		
			
				|  |  |                      }
 | 
	
	
		
			
				|  | @@ -1720,6 +1720,7 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
		
			
				|  |  |          /// Performs a blocking read on the socket until <paramref name="length"/> bytes are received.
 | 
	
		
			
				|  |  |          /// </summary>
 | 
	
		
			
				|  |  | +        /// <param name="socket">The <see cref="Socket"/> to read from.</param>
 | 
	
		
			
				|  |  |          /// <param name="buffer">An array of type <see cref="byte"/> that is the storage location for the received data.</param>
 | 
	
		
			
				|  |  |          /// <param name="offset">The position in <paramref name="buffer"/> parameter to store the received data.</param>
 | 
	
		
			
				|  |  |          /// <param name="length">The number of bytes to read.</param>
 | 
	
	
		
			
				|  | @@ -1729,9 +1730,9 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |          /// <exception cref="SshConnectionException">The socket is closed.</exception>
 | 
	
		
			
				|  |  |          /// <exception cref="SshOperationTimeoutException">The read has timed-out.</exception>
 | 
	
		
			
				|  |  |          /// <exception cref="SocketException">The read failed.</exception>
 | 
	
		
			
				|  |  | -        private int SocketRead(byte[] buffer, int offset, int length)
 | 
	
		
			
				|  |  | +        private static int SocketRead(Socket socket, byte[] buffer, int offset, int length)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            var bytesRead = SocketAbstraction.Read(_socket, buffer, offset, length, InfiniteTimeSpan);
 | 
	
		
			
				|  |  | +            var bytesRead = SocketAbstraction.Read(socket, buffer, offset, length, InfiniteTimeSpan);
 | 
	
		
			
				|  |  |              if (bytesRead == 0)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  // when we're in the disconnecting state (either triggered by client or server), then the
 | 
	
	
		
			
				|  | @@ -1819,6 +1820,7 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
		
			
				|  |  |          /// Performs a blocking read on the socket until <paramref name="length"/> bytes are received.
 | 
	
		
			
				|  |  |          /// </summary>
 | 
	
		
			
				|  |  | +        /// <param name="socket">The <see cref="Socket"/> to read from.</param>
 | 
	
		
			
				|  |  |          /// <param name="buffer">An array of type <see cref="byte"/> that is the storage location for the received data.</param>
 | 
	
		
			
				|  |  |          /// <param name="offset">The position in <paramref name="buffer"/> parameter to store the received data.</param>
 | 
	
		
			
				|  |  |          /// <param name="length">The number of bytes to read.</param>
 | 
	
	
		
			
				|  | @@ -1827,21 +1829,22 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |          /// </returns>
 | 
	
		
			
				|  |  |          /// <exception cref="SshOperationTimeoutException">The read has timed-out.</exception>
 | 
	
		
			
				|  |  |          /// <exception cref="SocketException">The read failed.</exception>
 | 
	
		
			
				|  |  | -        private int TrySocketRead(byte[] buffer, int offset, int length)
 | 
	
		
			
				|  |  | +        private static int TrySocketRead(Socket socket, byte[] buffer, int offset, int length)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            return SocketAbstraction.Read(_socket, buffer, offset, length, InfiniteTimeSpan);
 | 
	
		
			
				|  |  | +            return SocketAbstraction.Read(socket, buffer, offset, length, InfiniteTimeSpan);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
		
			
				|  |  |          /// Performs a blocking read on the socket until a line is read.
 | 
	
		
			
				|  |  |          /// </summary>
 | 
	
		
			
				|  |  | +        /// <param name="socket">The <see cref="Socket"/> to read from.</param>
 | 
	
		
			
				|  |  |          /// <param name="timeout">A <see cref="TimeSpan"/> that represents the time to wait until a line is read.</param>
 | 
	
		
			
				|  |  |          /// <exception cref="SshOperationTimeoutException">The read has timed-out.</exception>
 | 
	
		
			
				|  |  |          /// <exception cref="SocketException">An error occurred when trying to access the socket.</exception>
 | 
	
		
			
				|  |  |          /// <returns>
 | 
	
		
			
				|  |  |          /// The line read from the socket, or <c>null</c> when the remote server has shutdown and all data has been received.
 | 
	
		
			
				|  |  |          /// </returns>
 | 
	
		
			
				|  |  | -        private string SocketReadLine(TimeSpan timeout)
 | 
	
		
			
				|  |  | +        private static string SocketReadLine(Socket socket, TimeSpan timeout)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              var encoding = SshData.Ascii;
 | 
	
		
			
				|  |  |              var buffer = new List<byte>();
 | 
	
	
		
			
				|  | @@ -1851,7 +1854,7 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |              // to be processed by subsequent invocations
 | 
	
		
			
				|  |  |              do
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                var bytesRead = SocketAbstraction.Read(_socket, data, 0, data.Length, timeout);
 | 
	
		
			
				|  |  | +                var bytesRead = SocketAbstraction.Read(socket, data, 0, data.Length, timeout);
 | 
	
		
			
				|  |  |                  if (bytesRead == 0)
 | 
	
		
			
				|  |  |                      // the remote server shut down the socket
 | 
	
		
			
				|  |  |                      break;
 | 
	
	
		
			
				|  | @@ -1923,63 +1926,83 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |              try
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  // remain in message loop until socket is shut down or until we're disconnecting
 | 
	
		
			
				|  |  | -                while (_socket.IsConnected())
 | 
	
		
			
				|  |  | +                while (true)
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  | -#if FEATURE_SOCKET_POLL
 | 
	
		
			
				|  |  | -                    // Block until either data is available or the socket is closed
 | 
	
		
			
				|  |  | -                    var connectionClosedOrDataAvailable = _socket.Poll(-1, SelectMode.SelectRead);
 | 
	
		
			
				|  |  | -                    if (connectionClosedOrDataAvailable && _socket.Available == 0)
 | 
	
		
			
				|  |  | +                    var socket = _socket;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                    if (socket == null || !socket.Connected)
 | 
	
		
			
				|  |  |                      {
 | 
	
		
			
				|  |  | -                        // connection with SSH server was closed or socket was disposed;
 | 
	
		
			
				|  |  | -                        // break out of the message loop
 | 
	
		
			
				|  |  |                          break;
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  | -#elif FEATURE_SOCKET_SELECT
 | 
	
		
			
				|  |  | -                    var readSockets = new List<Socket> { _socket };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    // if the socket is already disposed when Select is invoked, then a SocketException
 | 
	
		
			
				|  |  | -                    // stating "An operation was attempted on something that is not a socket" is thrown;
 | 
	
		
			
				|  |  | -                    // we attempt to avoid this exception by having an IsConnected() that can break the
 | 
	
		
			
				|  |  | -                    // message loop
 | 
	
		
			
				|  |  | -                    //
 | 
	
		
			
				|  |  | -                    // note that there's no guarantee that the socket will not be disposed between the
 | 
	
		
			
				|  |  | -                    // IsConnected() check and the Select invocation; we can't take a "dispose" lock
 | 
	
		
			
				|  |  | -                    // that includes the Select invocation as we want Dispose() to be able to interrupt
 | 
	
		
			
				|  |  | -                    // the Select
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    // perform a blocking select to determine whether there's is data available to be
 | 
	
		
			
				|  |  | -                    // read; we do not use a blocking read to allow us to use Socket.Poll to determine
 | 
	
		
			
				|  |  | -                    // if the connection is still available (in IsSocketConnected)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    Socket.Select(readSockets, null, null, -1);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    // the Select invocation will be interrupted in one of the following conditions:
 | 
	
		
			
				|  |  | -                    // * data is available to be read
 | 
	
		
			
				|  |  | -                    //   => the socket will not be removed from "readSockets"
 | 
	
		
			
				|  |  | -                    // * the socket connection is closed during the Select invocation
 | 
	
		
			
				|  |  | -                    //   => the socket will be removed from "readSockets"
 | 
	
		
			
				|  |  | -                    // * the socket is disposed during the Select invocation
 | 
	
		
			
				|  |  | -                    //   => the socket will not be removed from "readSocket"
 | 
	
		
			
				|  |  | -                    // 
 | 
	
		
			
				|  |  | -                    // since we handle the second and third condition the same way and Socket.Connected
 | 
	
		
			
				|  |  | -                    // allows us to check for both conditions, we use that instead of both checking for
 | 
	
		
			
				|  |  | -                    // the removal from "readSockets" and the Connection check
 | 
	
		
			
				|  |  | -                    if (!_socket.IsConnected())
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                    try
 | 
	
		
			
				|  |  |                      {
 | 
	
		
			
				|  |  | -                        // connection with SSH server was closed or socket was disposed;
 | 
	
		
			
				|  |  | -                        // break out of the message loop
 | 
	
		
			
				|  |  | +    #if FEATURE_SOCKET_POLL
 | 
	
		
			
				|  |  | +                        // Block until either data is available or the socket is closed
 | 
	
		
			
				|  |  | +                        var connectionClosedOrDataAvailable = socket.Poll(-1, SelectMode.SelectRead);
 | 
	
		
			
				|  |  | +                        if (connectionClosedOrDataAvailable && socket.Available == 0)
 | 
	
		
			
				|  |  | +                        {
 | 
	
		
			
				|  |  | +                            // connection with SSH server was closed or connection was reset
 | 
	
		
			
				|  |  | +                            break;
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +    #elif FEATURE_SOCKET_SELECT
 | 
	
		
			
				|  |  | +                        var readSockets = new List<Socket> { socket };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                        // if the socket is already disposed when Select is invoked, then a SocketException
 | 
	
		
			
				|  |  | +                        // stating "An operation was attempted on something that is not a socket" is thrown;
 | 
	
		
			
				|  |  | +                        // we attempt to avoid this exception by having an IsConnected() that can break the
 | 
	
		
			
				|  |  | +                        // message loop
 | 
	
		
			
				|  |  | +                        //
 | 
	
		
			
				|  |  | +                        // note that there's no guarantee that the socket will not be disposed between the
 | 
	
		
			
				|  |  | +                        // IsConnected() check and the Select invocation; we can't take a "dispose" lock
 | 
	
		
			
				|  |  | +                        // that includes the Select invocation as we want Dispose() to be able to interrupt
 | 
	
		
			
				|  |  | +                        // the Select
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                        // perform a blocking select to determine whether there's is data available to be
 | 
	
		
			
				|  |  | +                        // read; we do not use a blocking read to allow us to use Socket.Poll to determine
 | 
	
		
			
				|  |  | +                        // if the connection is still available (in IsSocketConnected)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                        Socket.Select(readSockets, null, null, -1);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                        // the Select invocation will be interrupted in one of the following conditions:
 | 
	
		
			
				|  |  | +                        // * data is available to be read
 | 
	
		
			
				|  |  | +                        //   => the socket will not be removed from "readSockets"
 | 
	
		
			
				|  |  | +                        // * the socket connection is closed during the Select invocation
 | 
	
		
			
				|  |  | +                        //   => the socket will be removed from "readSockets"
 | 
	
		
			
				|  |  | +                        // * the socket is disposed during the Select invocation
 | 
	
		
			
				|  |  | +                        //   => the socket will not be removed from "readSocket"
 | 
	
		
			
				|  |  | +                        // 
 | 
	
		
			
				|  |  | +                        // since we handle the second and third condition the same way and Socket.Connected
 | 
	
		
			
				|  |  | +                        // allows us to check for both conditions, we use that instead of both checking for
 | 
	
		
			
				|  |  | +                        // the removal from "readSockets" and the Connection check
 | 
	
		
			
				|  |  | +                        if (!socket.IsConnected())
 | 
	
		
			
				|  |  | +                        {
 | 
	
		
			
				|  |  | +                            // connection with SSH server was closed or socket was disposed;
 | 
	
		
			
				|  |  | +                            // break out of the message loop
 | 
	
		
			
				|  |  | +                            break;
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +    #else
 | 
	
		
			
				|  |  | +                        #error Blocking wait on either socket data to become available or connection to be 
 | 
	
		
			
				|  |  | +                        #error closed is not implemented.
 | 
	
		
			
				|  |  | +    #endif // FEATURE_SOCKET_SELECT
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                    catch (ObjectDisposedException)
 | 
	
		
			
				|  |  | +                    {
 | 
	
		
			
				|  |  | +                        // The socket was disposed by either:
 | 
	
		
			
				|  |  | +                        // * a call to Disconnect()
 | 
	
		
			
				|  |  | +                        // * a call to Dispose()
 | 
	
		
			
				|  |  | +                        // * a SSH_MSG_DISCONNECT received from server
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                        Console.WriteLine("B");
 | 
	
		
			
				|  |  |                          break;
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  | -#else
 | 
	
		
			
				|  |  | -                    #error Blocking wait on either socket data to become available or connection to be 
 | 
	
		
			
				|  |  | -                    #error closed is not implemented.
 | 
	
		
			
				|  |  | -#endif // FEATURE_SOCKET_SELECT
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                    var message = ReceiveMessage();
 | 
	
		
			
				|  |  | +                    var message = ReceiveMessage(socket);
 | 
	
		
			
				|  |  |                      if (message == null)
 | 
	
		
			
				|  |  |                      {
 | 
	
		
			
				|  |  |                          // connection with SSH server was closed;
 | 
	
		
			
				|  |  |                          // break out of the message loop
 | 
	
		
			
				|  |  | +                        Console.WriteLine("C");
 | 
	
		
			
				|  |  |                          break;
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1987,6 +2010,8 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |                      message.Process(this);
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +                Console.WriteLine("D");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                  // connection with SSH server was closed or socket was disposed
 | 
	
		
			
				|  |  |                  RaiseError(CreateConnectionAbortedByServerException());
 | 
	
		
			
				|  |  |              }
 | 
	
	
		
			
				|  | @@ -2005,26 +2030,26 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        private byte SocketReadByte()
 | 
	
		
			
				|  |  | +        private static byte SocketReadByte(Socket socket)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              var buffer = new byte[1];
 | 
	
		
			
				|  |  | -            SocketRead(buffer, 0, 1);
 | 
	
		
			
				|  |  | +            SocketRead(socket, buffer, 0, 1);
 | 
	
		
			
				|  |  |              return buffer[0];
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        private void ConnectSocks4()
 | 
	
		
			
				|  |  | +        private static void ConnectSocks4(Socket socket, ConnectionInfo connectionInfo)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            var connectionRequest = CreateSocks4ConnectionRequest(ConnectionInfo.Host, (ushort) ConnectionInfo.Port, ConnectionInfo.ProxyUsername);
 | 
	
		
			
				|  |  | -            SocketAbstraction.Send(_socket, connectionRequest);
 | 
	
		
			
				|  |  | +            var connectionRequest = CreateSocks4ConnectionRequest(connectionInfo.Host, (ushort)connectionInfo.Port, connectionInfo.ProxyUsername);
 | 
	
		
			
				|  |  | +            SocketAbstraction.Send(socket, connectionRequest);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              //  Read null byte
 | 
	
		
			
				|  |  | -            if (SocketReadByte() != 0)
 | 
	
		
			
				|  |  | +            if (SocketReadByte(socket) != 0)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  throw new ProxyException("SOCKS4: Null is expected.");
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              //  Read response code
 | 
	
		
			
				|  |  | -            var code = SocketReadByte();
 | 
	
		
			
				|  |  | +            var code = SocketReadByte(socket);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              switch (code)
 | 
	
		
			
				|  |  |              {
 | 
	
	
		
			
				|  | @@ -2041,10 +2066,10 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              var dummyBuffer = new byte[6]; // field 3 (2 bytes) and field 4 (4) should be ignored
 | 
	
		
			
				|  |  | -            SocketRead(dummyBuffer, 0, 6);
 | 
	
		
			
				|  |  | +            SocketRead(socket, dummyBuffer, 0, 6);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        private void ConnectSocks5()
 | 
	
		
			
				|  |  | +        private static void ConnectSocks5(Socket socket, ConnectionInfo connectionInfo)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              var greeting = new byte[]
 | 
	
		
			
				|  |  |                  {
 | 
	
	
		
			
				|  | @@ -2057,24 +2082,24 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |                      // Username/Password authentication
 | 
	
		
			
				|  |  |                      0x02
 | 
	
		
			
				|  |  |                  };
 | 
	
		
			
				|  |  | -            SocketAbstraction.Send(_socket, greeting);
 | 
	
		
			
				|  |  | +            SocketAbstraction.Send(socket, greeting);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            var socksVersion = SocketReadByte();
 | 
	
		
			
				|  |  | +            var socksVersion = SocketReadByte(socket);
 | 
	
		
			
				|  |  |              if (socksVersion != 0x05)
 | 
	
		
			
				|  |  |                  throw new ProxyException(string.Format("SOCKS Version '{0}' is not supported.", socksVersion));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            var authenticationMethod = SocketReadByte();
 | 
	
		
			
				|  |  | +            var authenticationMethod = SocketReadByte(socket);
 | 
	
		
			
				|  |  |              switch (authenticationMethod)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  case 0x00:
 | 
	
		
			
				|  |  |                      break;
 | 
	
		
			
				|  |  |                  case 0x02:
 | 
	
		
			
				|  |  |                      // Create username/password authentication request
 | 
	
		
			
				|  |  | -                    var authenticationRequest = CreateSocks5UserNameAndPasswordAuthenticationRequest(ConnectionInfo.ProxyUsername, ConnectionInfo.ProxyPassword);
 | 
	
		
			
				|  |  | +                    var authenticationRequest = CreateSocks5UserNameAndPasswordAuthenticationRequest(connectionInfo.ProxyUsername, connectionInfo.ProxyPassword);
 | 
	
		
			
				|  |  |                      // Send authentication request
 | 
	
		
			
				|  |  | -                    SocketAbstraction.Send(_socket, authenticationRequest);
 | 
	
		
			
				|  |  | +                    SocketAbstraction.Send(socket, authenticationRequest);
 | 
	
		
			
				|  |  |                      // Read authentication result
 | 
	
		
			
				|  |  | -                    var authenticationResult = SocketAbstraction.Read(_socket, 2, ConnectionInfo.Timeout);
 | 
	
		
			
				|  |  | +                    var authenticationResult = SocketAbstraction.Read(socket, 2, connectionInfo.Timeout);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                      if (authenticationResult[0] != 0x01)
 | 
	
		
			
				|  |  |                          throw new ProxyException("SOCKS5: Server authentication version is not valid.");
 | 
	
	
		
			
				|  | @@ -2085,17 +2110,17 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |                      throw new ProxyException("SOCKS5: No acceptable authentication methods were offered.");
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            var connectionRequest = CreateSocks5ConnectionRequest(ConnectionInfo.Host, (ushort) ConnectionInfo.Port);
 | 
	
		
			
				|  |  | -            SocketAbstraction.Send(_socket, connectionRequest);
 | 
	
		
			
				|  |  | +            var connectionRequest = CreateSocks5ConnectionRequest(connectionInfo.Host, (ushort)connectionInfo.Port);
 | 
	
		
			
				|  |  | +            SocketAbstraction.Send(socket, connectionRequest);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              //  Read Server SOCKS5 version
 | 
	
		
			
				|  |  | -            if (SocketReadByte() != 5)
 | 
	
		
			
				|  |  | +            if (SocketReadByte(socket) != 5)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  throw new ProxyException("SOCKS5: Version 5 is expected.");
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              //  Read response code
 | 
	
		
			
				|  |  | -            var status = SocketReadByte();
 | 
	
		
			
				|  |  | +            var status = SocketReadByte(socket);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              switch (status)
 | 
	
		
			
				|  |  |              {
 | 
	
	
		
			
				|  | @@ -2122,21 +2147,21 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              //  Read reserved byte
 | 
	
		
			
				|  |  | -            if (SocketReadByte() != 0)
 | 
	
		
			
				|  |  | +            if (SocketReadByte(socket) != 0)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  throw new ProxyException("SOCKS5: 0 byte is expected.");
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            var addressType = SocketReadByte();
 | 
	
		
			
				|  |  | +            var addressType = SocketReadByte(socket);
 | 
	
		
			
				|  |  |              switch (addressType)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  case 0x01:
 | 
	
		
			
				|  |  |                      var ipv4 = new byte[4];
 | 
	
		
			
				|  |  | -                    SocketRead(ipv4, 0, 4);
 | 
	
		
			
				|  |  | +                    SocketRead(socket, ipv4, 0, 4);
 | 
	
		
			
				|  |  |                      break;
 | 
	
		
			
				|  |  |                  case 0x04:
 | 
	
		
			
				|  |  |                      var ipv6 = new byte[16];
 | 
	
		
			
				|  |  | -                    SocketRead(ipv6, 0, 16);
 | 
	
		
			
				|  |  | +                    SocketRead(socket, ipv6, 0, 16);
 | 
	
		
			
				|  |  |                      break;
 | 
	
		
			
				|  |  |                  default:
 | 
	
		
			
				|  |  |                      throw new ProxyException(string.Format("Address type '{0}' is not supported.", addressType));
 | 
	
	
		
			
				|  | @@ -2145,7 +2170,7 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |              var port = new byte[2];
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              //  Read 2 bytes to be ignored
 | 
	
		
			
				|  |  | -            SocketRead(port, 0, 2);
 | 
	
		
			
				|  |  | +            SocketRead(socket, port, 0, 2);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -2316,30 +2341,30 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |              return address;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        private void ConnectHttp()
 | 
	
		
			
				|  |  | +        private static void ConnectHttp(Socket socket, ConnectionInfo connectionInfo)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              var httpResponseRe = new Regex(@"HTTP/(?<version>\d[.]\d) (?<statusCode>\d{3}) (?<reasonPhrase>.+)$");
 | 
	
		
			
				|  |  |              var httpHeaderRe = new Regex(@"(?<fieldName>[^\[\]()<>@,;:\""/?={} \t]+):(?<fieldValue>.+)?");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            SocketAbstraction.Send(_socket, SshData.Ascii.GetBytes(string.Format("CONNECT {0}:{1} HTTP/1.0\r\n", ConnectionInfo.Host, ConnectionInfo.Port)));
 | 
	
		
			
				|  |  | +            SocketAbstraction.Send(socket, SshData.Ascii.GetBytes(string.Format("CONNECT {0}:{1} HTTP/1.0\r\n", connectionInfo.Host, connectionInfo.Port)));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              //  Sent proxy authorization is specified
 | 
	
		
			
				|  |  | -            if (!string.IsNullOrEmpty(ConnectionInfo.ProxyUsername))
 | 
	
		
			
				|  |  | +            if (!string.IsNullOrEmpty(connectionInfo.ProxyUsername))
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  var authorization = string.Format("Proxy-Authorization: Basic {0}\r\n",
 | 
	
		
			
				|  |  | -                                                  Convert.ToBase64String(SshData.Ascii.GetBytes(string.Format("{0}:{1}", ConnectionInfo.ProxyUsername, ConnectionInfo.ProxyPassword)))
 | 
	
		
			
				|  |  | +                                                  Convert.ToBase64String(SshData.Ascii.GetBytes(string.Format("{0}:{1}", connectionInfo.ProxyUsername, connectionInfo.ProxyPassword)))
 | 
	
		
			
				|  |  |                                                    );
 | 
	
		
			
				|  |  | -                SocketAbstraction.Send(_socket, SshData.Ascii.GetBytes(authorization));
 | 
	
		
			
				|  |  | +                SocketAbstraction.Send(socket, SshData.Ascii.GetBytes(authorization));
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            SocketAbstraction.Send(_socket, SshData.Ascii.GetBytes("\r\n"));
 | 
	
		
			
				|  |  | +            SocketAbstraction.Send(socket, SshData.Ascii.GetBytes("\r\n"));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              HttpStatusCode? statusCode = null;
 | 
	
		
			
				|  |  |              var contentLength = 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              while (true)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | -                var response = SocketReadLine(ConnectionInfo.Timeout);
 | 
	
		
			
				|  |  | +                var response = SocketReadLine(socket, connectionInfo.Timeout);
 | 
	
		
			
				|  |  |                  if (response == null)
 | 
	
		
			
				|  |  |                      // server shut down socket
 | 
	
		
			
				|  |  |                      break;
 | 
	
	
		
			
				|  | @@ -2381,7 +2406,7 @@ namespace Renci.SshNet
 | 
	
		
			
				|  |  |                      if (contentLength > 0)
 | 
	
		
			
				|  |  |                      {
 | 
	
		
			
				|  |  |                          var contentBody = new byte[contentLength];
 | 
	
		
			
				|  |  | -                        SocketRead(contentBody, 0, contentLength);
 | 
	
		
			
				|  |  | +                        SocketRead(socket, contentBody, 0, contentLength);
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                      break;
 | 
	
		
			
				|  |  |                  }
 |