private bool HandleSocks(IChannelDirectTcpip channel, Socket clientSocket, TimeSpan timeout)
{
// create eventhandler which is to be invoked to interrupt a blocking receive
// when we're closing the forwarded port
EventHandler closeClientSocket = (_, args) => CloseClientSocket(clientSocket);
Closing += closeClientSocket;
try
{
var version = SocketAbstraction.ReadByte(clientSocket, timeout);
switch (version)
{
case -1:
// SOCKS client closed connection
return false;
case 4:
return HandleSocks4(clientSocket, channel, timeout);
case 5:
return HandleSocks5(clientSocket, channel, timeout);
default:
throw new NotSupportedException(string.Format("SOCKS version {0} is not supported.", version));
}
}
catch (SocketException ex)
{
// ignore exception thrown by interrupting the blocking receive as part of closing
// the forwarded port
if (ex.SocketErrorCode != SocketError.Interrupted)
{
RaiseExceptionEvent(ex);
}
return false;
}
finally
{
// interrupt of blocking receive is now handled by channel (SOCKS4 and SOCKS5)
// or no longer necessary
Closing -= closeClientSocket;
}
}