Browse Source

Fix #710 by @breakwa11

- Drop irrelevant changes
- Closes #723

Signed-off-by: Syrone Wong <wong.syrone@gmail.com>
tags/3.3.1
Syrone Wong 8 years ago
parent
commit
6e6be823ad
1 changed files with 81 additions and 85 deletions
  1. +81
    -85
      shadowsocks-csharp/Controller/Service/TCPRelay.cs

+ 81
- 85
shadowsocks-csharp/Controller/Service/TCPRelay.cs View File

@@ -35,10 +35,7 @@ namespace Shadowsocks.Controller
|| (length < 2 || firstPacket[0] != 5))
return false;
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
TCPHandler handler = new TCPHandler(this, _config);
handler.connection = socket;
handler.controller = _controller;
handler.tcprelay = this;
TCPHandler handler = new TCPHandler(_controller, _config, this, socket);
handler.Start(firstPacket, length);
IList<TCPHandler> handlersToClose = new List<TCPHandler>();
@@ -122,68 +119,67 @@ namespace Shadowsocks.Controller
public static readonly int RecvReserveSize = IVEncryptor.ONETIMEAUTH_BYTES + IVEncryptor.AUTH_BYTES; // reserve for one-time auth
public static readonly int BufferSize = RecvSize + RecvReserveSize + 32;
// public Encryptor encryptor;
public IEncryptor encryptor;
public Server server;
// Client socket.
private AsyncSession _currentRemoteSession;
public DateTime lastActivity;
public Socket connection;
public ShadowsocksController controller;
public TCPRelay tcprelay;
private ShadowsocksController _controller;
private Configuration _config;
private TCPRelay _tcprelay;
private Socket _connection;
public DateTime lastActivity;
private IEncryptor _encryptor;
private Server _server;
private const int MaxRetry = 4;
private int _retryCount = 0;
private bool _proxyConnected;
private bool _destConnected;
private AsyncSession _currentRemoteSession;
private const int MaxRetry = 4;
private int _retryCount = 0;
private bool _proxyConnected;
private bool _destConnected;
private byte _command;
private byte[] _firstPacket;
private int _firstPacketLength;
private byte _command;
private byte[] _firstPacket;
private int _firstPacketLength;
private int _totalRead = 0;
private int _totalWrite = 0;
private int _totalRead = 0;
private int _totalWrite = 0;
private byte[] _remoteRecvBuffer = new byte[BufferSize];
private byte[] _remoteSendBuffer = new byte[BufferSize];
private byte[] _connetionRecvBuffer = new byte[BufferSize];
private byte[] _connetionSendBuffer = new byte[BufferSize];
private byte[] _remoteRecvBuffer = new byte[BufferSize];
private byte[] _remoteSendBuffer = new byte[BufferSize];
private byte[] _connetionRecvBuffer = new byte[BufferSize];
private byte[] _connetionSendBuffer = new byte[BufferSize];
private bool _connectionShutdown = false;
private bool _remoteShutdown = false;
private bool _closed = false;
private bool _connectionShutdown = false;
private bool _remoteShutdown = false;
private bool _closed = false;
private object _encryptionLock = new object();
private object _decryptionLock = new object();
private object _encryptionLock = new object();
private object _decryptionLock = new object();
private DateTime _startConnectTime;
private DateTime _startReceivingTime;
private DateTime _startSendingTime;
private int _bytesToSend;
private TCPRelay _tcprelay; // TODO: is _tcprelay equals tcprelay declared above?
private Configuration _config;
public TCPHandler(TCPRelay tcprelay, Configuration config)
public TCPHandler(ShadowsocksController controller, Configuration config, TCPRelay tcprelay, Socket socket)
{
this._tcprelay = tcprelay;
this._controller = controller;
this._config = config;
this._tcprelay = tcprelay;
this._connection = socket;
}
public void CreateRemote()
{
Server server = controller.GetAServer(IStrategyCallerType.TCP, (IPEndPoint)connection.RemoteEndPoint);
Server server = _controller.GetAServer(IStrategyCallerType.TCP, (IPEndPoint)_connection.RemoteEndPoint);
if (server == null || server.server == "")
throw new ArgumentException("No server configured");
lock (_encryptionLock)
{
lock (_decryptionLock)
{
encryptor = EncryptorFactory.GetEncryptor(server.method, server.password, server.auth, false);
_encryptor = EncryptorFactory.GetEncryptor(server.method, server.password, server.auth, false);
}
}
this.server = server;
this._server = server;
}
public void Start(byte[] firstPacket, int length)
@@ -202,18 +198,19 @@ namespace Shadowsocks.Controller
public void Close()
{
lock (tcprelay.Handlers)
lock (this)
{
tcprelay.Handlers.Remove(this);
}
lock (this) {
if (_closed) return;
_closed = true;
}
lock (_tcprelay.Handlers)
{
_tcprelay.Handlers.Remove(this);
}
try
{
connection?.Shutdown(SocketShutdown.Both);
connection?.Close();
_connection?.Shutdown(SocketShutdown.Both);
_connection?.Close();
}
catch (Exception e)
{
@@ -233,7 +230,7 @@ namespace Shadowsocks.Controller
{
lock (_decryptionLock)
{
encryptor?.Dispose();
_encryptor?.Dispose();
}
}
}
@@ -253,7 +250,7 @@ namespace Shadowsocks.Controller
response = new byte[] { 0, 91 };
Logging.Error("socks 5 protocol error");
}
connection?.BeginSend(response, 0, response.Length, SocketFlags.None, new AsyncCallback(HandshakeSendCallback), null);
_connection?.BeginSend(response, 0, response.Length, SocketFlags.None, new AsyncCallback(HandshakeSendCallback), null);
}
else
Close();
@@ -270,7 +267,7 @@ namespace Shadowsocks.Controller
if (_closed) return;
try
{
connection.EndSend(ar);
_connection.EndSend(ar);
// +-----+-----+-------+------+----------+----------+
// | VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
@@ -279,7 +276,7 @@ namespace Shadowsocks.Controller
// +-----+-----+-------+------+----------+----------+
// Skip first 3 bytes
// TODO validate
connection.BeginReceive(_connetionRecvBuffer, 0, 3, SocketFlags.None, new AsyncCallback(handshakeReceive2Callback), null);
_connection.BeginReceive(_connetionRecvBuffer, 0, 3, SocketFlags.None, new AsyncCallback(handshakeReceive2Callback), null);
}
catch (Exception e)
{
@@ -293,14 +290,14 @@ namespace Shadowsocks.Controller
if (_closed) return;
try
{
int bytesRead = connection.EndReceive(ar);
int bytesRead = _connection.EndReceive(ar);
if (bytesRead >= 3)
{
_command = _connetionRecvBuffer[1];
if (_command == 1)
{
byte[] response = { 5, 0, 0, 1, 0, 0, 0, 0, 0, 0 };
connection.BeginSend(response, 0, response.Length, SocketFlags.None, new AsyncCallback(ResponseCallback), null);
_connection.BeginSend(response, 0, response.Length, SocketFlags.None, new AsyncCallback(ResponseCallback), null);
}
else if (_command == 3)
HandleUDPAssociate();
@@ -320,7 +317,7 @@ namespace Shadowsocks.Controller
private void HandleUDPAssociate()
{
IPEndPoint endPoint = (IPEndPoint)connection.LocalEndPoint;
IPEndPoint endPoint = (IPEndPoint)_connection.LocalEndPoint;
byte[] address = endPoint.Address.GetAddressBytes();
int port = endPoint.Port;
byte[] response = new byte[4 + address.Length + 2];
@@ -337,7 +334,7 @@ namespace Shadowsocks.Controller
address.CopyTo(response, 4);
response[response.Length - 1] = (byte)(port & 0xFF);
response[response.Length - 2] = (byte)((port >> 8) & 0xFF);
connection.BeginSend(response, 0, response.Length, SocketFlags.None, new AsyncCallback(ReadAll), true);
_connection.BeginSend(response, 0, response.Length, SocketFlags.None, new AsyncCallback(ReadAll), true);
}
private void ReadAll(IAsyncResult ar)
@@ -347,15 +344,15 @@ namespace Shadowsocks.Controller
{
if (ar.AsyncState != null)
{
connection.EndSend(ar);
connection.BeginReceive(_connetionRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(ReadAll), null);
_connection.EndSend(ar);
_connection.BeginReceive(_connetionRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(ReadAll), null);
}
else
{
int bytesRead = connection.EndReceive(ar);
int bytesRead = _connection.EndReceive(ar);
if (bytesRead > 0)
{
connection.BeginReceive(_connetionRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(ReadAll), null);
_connection.BeginReceive(_connetionRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(ReadAll), null);
}
else
Close();
@@ -372,7 +369,7 @@ namespace Shadowsocks.Controller
{
try
{
connection?.EndSend(ar);
_connection?.EndSend(ar);
StartConnect();
}
catch (Exception e)
@@ -432,8 +429,8 @@ namespace Shadowsocks.Controller
proxyTimer.Enabled = true;
proxyTimer.Session = session;
proxyTimer.DestEndPoint = SocketUtil.GetEndPoint(server.server, server.server_port);
proxyTimer.Server = server;
proxyTimer.DestEndPoint = SocketUtil.GetEndPoint(_server.server, _server.server_port);
proxyTimer.Server = _server;
_proxyConnected = false;
@@ -534,7 +531,7 @@ namespace Shadowsocks.Controller
var session = timer.Session;
Server server = timer.Server;
IStrategy strategy = controller.GetCurrentStrategy();
IStrategy strategy = _controller.GetCurrentStrategy();
strategy?.SetFailure(server);
Logging.Info($"{server.FriendlyName()} timed out");
session.Remote.Close();
@@ -560,7 +557,7 @@ namespace Shadowsocks.Controller
{
var session = (AsyncSession<ServerTimer>) ar.AsyncState;
ServerTimer timer = session.State;
server = timer.Server;
_server = timer.Server;
timer.Elapsed -= destConnectTimer_Elapsed;
timer.Enabled = false;
timer.Dispose();
@@ -573,13 +570,13 @@ namespace Shadowsocks.Controller
if (_config.isVerboseLogging)
{
Logging.Info($"Socket connected to ss server: {server.FriendlyName()}");
Logging.Info($"Socket connected to ss server: {_server.FriendlyName()}");
}
var latency = DateTime.Now - _startConnectTime;
IStrategy strategy = controller.GetCurrentStrategy();
strategy?.UpdateLatency(server, latency);
_tcprelay.UpdateLatency(server, latency);
IStrategy strategy = _controller.GetCurrentStrategy();
strategy?.UpdateLatency(_server, latency);
_tcprelay.UpdateLatency(_server, latency);
StartPipe(session);
}
@@ -588,10 +585,10 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
if (server != null)
if (_server != null)
{
IStrategy strategy = controller.GetCurrentStrategy();
strategy?.SetFailure(server);
IStrategy strategy = _controller.GetCurrentStrategy();
strategy?.SetFailure(_server);
}
Logging.LogUsefulException(e);
RetryConnect();
@@ -605,7 +602,7 @@ namespace Shadowsocks.Controller
{
_startReceivingTime = DateTime.Now;
session.Remote.BeginReceive(_remoteRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(PipeRemoteReceiveCallback), session);
connection?.BeginReceive(_connetionRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(PipeConnectionReceiveCallback),
_connection?.BeginReceive(_connetionRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(PipeConnectionReceiveCallback),
new AsyncSession<bool>(session, true) /* to tell the callback this is the first time reading packet, and we haven't found the header yet. */);
}
catch (Exception e)
@@ -623,7 +620,7 @@ namespace Shadowsocks.Controller
var session = (AsyncSession) ar.AsyncState;
int bytesRead = session.Remote.EndReceive(ar);
_totalRead += bytesRead;
_tcprelay.UpdateInboundCounter(server, bytesRead);
_tcprelay.UpdateInboundCounter(_server, bytesRead);
if (bytesRead > 0)
{
lastActivity = DateTime.Now;
@@ -631,15 +628,15 @@ namespace Shadowsocks.Controller
lock (_decryptionLock)
{
if (_closed) return;
encryptor.Decrypt(_remoteRecvBuffer, bytesRead, _remoteSendBuffer, out bytesToSend);
_encryptor.Decrypt(_remoteRecvBuffer, bytesRead, _remoteSendBuffer, out bytesToSend);
}
connection.BeginSend(_remoteSendBuffer, 0, bytesToSend, SocketFlags.None, new AsyncCallback(PipeConnectionSendCallback), session);
IStrategy strategy = controller.GetCurrentStrategy();
strategy?.UpdateLastRead(server);
_connection.BeginSend(_remoteSendBuffer, 0, bytesToSend, SocketFlags.None, new AsyncCallback(PipeConnectionSendCallback), session);
IStrategy strategy = _controller.GetCurrentStrategy();
strategy?.UpdateLastRead(_server);
}
else
{
connection.Shutdown(SocketShutdown.Send);
_connection.Shutdown(SocketShutdown.Send);
_connectionShutdown = true;
CheckClose();
}
@@ -656,8 +653,8 @@ namespace Shadowsocks.Controller
if (_closed) return;
try
{
if(connection == null) return;
int bytesRead = connection.EndReceive(ar);
if(_connection == null) return;
int bytesRead = _connection.EndReceive(ar);
_totalWrite += bytesRead;
var session = (AsyncSession<bool>) ar.AsyncState;
@@ -705,14 +702,13 @@ namespace Shadowsocks.Controller
lock (_encryptionLock)
{
if (_closed) return;
encryptor.Encrypt(_connetionRecvBuffer, bytesRead, _connetionSendBuffer, out bytesToSend);
_encryptor.Encrypt(_connetionRecvBuffer, bytesRead, _connetionSendBuffer, out bytesToSend);
}
_tcprelay.UpdateOutboundCounter(server, bytesToSend);
_tcprelay.UpdateOutboundCounter(_server, bytesToSend);
_startSendingTime = DateTime.Now;
_bytesToSend = bytesToSend;
remote.BeginSend(_connetionSendBuffer, 0, bytesToSend, SocketFlags.None, new AsyncCallback(PipeRemoteSendCallback), session);
IStrategy strategy = controller.GetCurrentStrategy();
strategy?.UpdateLastWrite(server);
IStrategy strategy = _controller.GetCurrentStrategy();
strategy?.UpdateLastWrite(_server);
}
else
{
@@ -735,7 +731,7 @@ namespace Shadowsocks.Controller
{
var session = (AsyncSession)ar.AsyncState;
session.Remote.EndSend(ar);
connection?.BeginReceive(_connetionRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(PipeConnectionReceiveCallback), session);
_connection?.BeginReceive(_connetionRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(PipeConnectionReceiveCallback), session);
}
catch (Exception e)
{
@@ -750,7 +746,7 @@ namespace Shadowsocks.Controller
try
{
var session = (AsyncSession)ar.AsyncState;
connection?.EndSend(ar);
_connection?.EndSend(ar);
session.Remote.BeginReceive(_remoteRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(PipeRemoteReceiveCallback), session);
}
catch (Exception e)


Loading…
Cancel
Save