Browse Source

Merge branch 'log_connect_to' of https://github.com/kimw/shadowsocks-windows into kimw-log_connect_to

tags/3.2
Syrone Wong 8 years ago
parent
commit
0494f95fbb
2 changed files with 155 additions and 243 deletions
  1. +151
    -241
      shadowsocks-csharp/Controller/Service/TCPRelay.cs
  2. +4
    -2
      shadowsocks-csharp/Util/Util.cs

+ 151
- 241
shadowsocks-csharp/Controller/Service/TCPRelay.cs View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Timers; using System.Timers;
@@ -15,10 +16,7 @@ namespace Shadowsocks.Controller
private ShadowsocksController _controller; private ShadowsocksController _controller;
private DateTime _lastSweepTime; private DateTime _lastSweepTime;
public ISet<TCPHandler> Handlers
{
get; set;
}
public ISet<TCPHandler> Handlers { get; set; }
public TCPRelay(ShadowsocksController controller) public TCPRelay(ShadowsocksController controller)
{ {
@@ -29,44 +27,37 @@ namespace Shadowsocks.Controller
public bool Handle(byte[] firstPacket, int length, Socket socket, object state) public bool Handle(byte[] firstPacket, int length, Socket socket, object state)
{ {
if (socket.ProtocolType != ProtocolType.Tcp)
{
if (socket.ProtocolType != ProtocolType.Tcp
|| (length < 2 || firstPacket[0] != 5))
return false; return false;
}
if (length < 2 || firstPacket[0] != 5)
{
return false;
}
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
TCPHandler handler = new TCPHandler(this);
handler.connection = socket;
handler.controller = _controller;
handler.relay = this;
handler.Start(firstPacket, length);
IList<TCPHandler> handlersToClose = new List<TCPHandler>();
lock (Handlers)
else
{ {
Handlers.Add(handler);
DateTime now = DateTime.Now;
if (now - _lastSweepTime > TimeSpan.FromSeconds(1))
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
TCPHandler handler = new TCPHandler(this);
handler.connection = socket;
handler.controller = _controller;
handler.tcprelay = this;
handler.Start(firstPacket, length);
IList<TCPHandler> handlersToClose = new List<TCPHandler>();
lock (Handlers)
{ {
_lastSweepTime = now;
foreach (TCPHandler handler1 in Handlers)
Handlers.Add(handler);
DateTime now = DateTime.Now;
if (now - _lastSweepTime > TimeSpan.FromSeconds(1))
{ {
if (now - handler1.lastActivity > TimeSpan.FromSeconds(900))
{
handlersToClose.Add(handler1);
}
_lastSweepTime = now;
foreach (TCPHandler handler1 in Handlers)
if (now - handler1.lastActivity > TimeSpan.FromSeconds(900))
handlersToClose.Add(handler1);
} }
} }
foreach (TCPHandler handler1 in handlersToClose)
{
Logging.Debug("Closing timed out TCP connection.");
handler1.Close();
}
return true;
} }
foreach (TCPHandler handler1 in handlersToClose)
{
Logging.Debug("Closing timed out TCP connection.");
handler1.Close();
}
return true;
} }
public void UpdateInboundCounter(Server server, long n) public void UpdateInboundCounter(Server server, long n)
@@ -87,6 +78,11 @@ namespace Shadowsocks.Controller
class TCPHandler class TCPHandler
{ {
// Size of receive buffer.
static public readonly int RecvSize = 8192;
static public readonly int RecvReserveSize = IVEncryptor.ONETIMEAUTH_BYTES + IVEncryptor.AUTH_BYTES; // reserve for one-time auth
static public readonly int BufferSize = RecvSize + RecvReserveSize + 32;
// public Encryptor encryptor; // public Encryptor encryptor;
public IEncryptor encryptor; public IEncryptor encryptor;
public Server server; public Server server;
@@ -94,60 +90,43 @@ namespace Shadowsocks.Controller
public Socket remote; public Socket remote;
public Socket connection; public Socket connection;
public ShadowsocksController controller; public ShadowsocksController controller;
public TCPRelay relay;
public TCPRelay tcprelay;
public DateTime lastActivity; public DateTime lastActivity;
private const int maxRetry = 4;
private int retryCount = 0;
private bool connected;
private byte command;
private const int _maxRetry = 4;
private int _retryCount = 0;
private bool _connected;
private byte _command;
private byte[] _firstPacket; private byte[] _firstPacket;
private int _firstPacketLength; private int _firstPacketLength;
// Size of receive buffer.
public const int RecvSize = 8192;
public const int RecvReserveSize = IVEncryptor.ONETIMEAUTH_BYTES + IVEncryptor.AUTH_BYTES; // reserve for one-time auth
public const int BufferSize = RecvSize + RecvReserveSize + 32;
private int totalRead = 0;
private int totalWrite = 0;
// remote receive buffer
private byte[] remoteRecvBuffer = new byte[BufferSize];
// remote send buffer
private byte[] remoteSendBuffer = new byte[BufferSize];
// connection receive buffer
private byte[] connetionRecvBuffer = new byte[BufferSize];
// connection send buffer
private byte[] connetionSendBuffer = new byte[BufferSize];
// Received data string.
private bool connectionShutdown = false;
private bool remoteShutdown = false;
private bool closed = false;
private object encryptionLock = new object();
private object decryptionLock = new object();
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 bool _connectionShutdown = false;
private bool _remoteShutdown = false;
private bool _closed = false;
private object _encryptionLock = new object();
private object _decryptionLock = new object();
private DateTime _startConnectTime; private DateTime _startConnectTime;
private DateTime _startReceivingTime; private DateTime _startReceivingTime;
private DateTime _startSendingTime; private DateTime _startSendingTime;
private int _bytesToSend; private int _bytesToSend;
private TCPRelay tcprelay; // TODO: tcprelay ?= relay
private TCPRelay _tcprelay; // TODO: is _tcprelay equals tcprelay declared above?
public TCPHandler(TCPRelay tcprelay) public TCPHandler(TCPRelay tcprelay)
{ {
this.tcprelay = tcprelay;
_tcprelay = tcprelay;
} }
public void CreateRemote() 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 == "") if (server == null || server.server == "")
{
throw new ArgumentException("No server configured"); throw new ArgumentException("No server configured");
}
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;
} }
@@ -162,72 +141,56 @@ namespace Shadowsocks.Controller
private void CheckClose() private void CheckClose()
{ {
if (connectionShutdown && remoteShutdown)
{
if (_connectionShutdown && _remoteShutdown)
Close(); Close();
}
} }
public void Close() public void Close()
{ {
lock (relay.Handlers)
lock (tcprelay.Handlers)
{ {
relay.Handlers.Remove(this);
tcprelay.Handlers.Remove(this);
} }
lock (this) lock (this)
{ {
if (closed)
{
if (_closed)
return; return;
}
closed = true;
else
_closed = true;
} }
if (connection != null)
try
{ {
try
{
connection.Shutdown(SocketShutdown.Both);
connection.Close();
}
catch (Exception e)
{
Logging.LogUsefulException(e);
}
connection?.Shutdown(SocketShutdown.Both);
connection?.Close();
} }
if (remote != null)
catch (Exception e)
{ {
try
{
remote.Shutdown(SocketShutdown.Both);
remote.Close();
}
catch (Exception e)
{
Logging.LogUsefulException(e);
}
Logging.LogUsefulException(e);
}
try
{
remote?.Shutdown(SocketShutdown.Both);
remote?.Close();
}
catch (Exception e)
{
Logging.LogUsefulException(e);
} }
lock (encryptionLock)
lock (_encryptionLock)
{ {
lock (decryptionLock)
lock (_decryptionLock)
{ {
if (encryptor != null)
{
((IDisposable)encryptor).Dispose();
}
encryptor?.Dispose();
} }
} }
} }
private void HandshakeReceive() private void HandshakeReceive()
{ {
if (closed)
{
return;
}
if (_closed) return;
try try
{ {
int bytesRead = _firstPacketLength; int bytesRead = _firstPacketLength;
if (bytesRead > 1) if (bytesRead > 1)
{ {
byte[] response = { 5, 0 }; byte[] response = { 5, 0 };
@@ -237,12 +200,10 @@ namespace Shadowsocks.Controller
response = new byte[] { 0, 91 }; response = new byte[] { 0, 91 };
Logging.Error("socks 5 protocol error"); Logging.Error("socks 5 protocol error");
} }
connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(HandshakeSendCallback), null);
connection.BeginSend(response, 0, response.Length, SocketFlags.None, new AsyncCallback(HandshakeSendCallback), null);
} }
else else
{
Close(); Close();
}
} }
catch (Exception e) catch (Exception e)
{ {
@@ -253,10 +214,7 @@ namespace Shadowsocks.Controller
private void HandshakeSendCallback(IAsyncResult ar) private void HandshakeSendCallback(IAsyncResult ar)
{ {
if (closed)
{
return;
}
if (_closed) return;
try try
{ {
connection.EndSend(ar); connection.EndSend(ar);
@@ -268,7 +226,7 @@ namespace Shadowsocks.Controller
// +-----+-----+-------+------+----------+----------+ // +-----+-----+-------+------+----------+----------+
// Skip first 3 bytes // Skip first 3 bytes
// TODO validate // TODO validate
connection.BeginReceive(connetionRecvBuffer, 0, 3, 0, new AsyncCallback(handshakeReceive2Callback), null);
connection.BeginReceive(_connetionRecvBuffer, 0, 3, SocketFlags.None, new AsyncCallback(handshakeReceive2Callback), null);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -279,26 +237,20 @@ namespace Shadowsocks.Controller
private void handshakeReceive2Callback(IAsyncResult ar) private void handshakeReceive2Callback(IAsyncResult ar)
{ {
if (closed)
{
return;
}
if (_closed) return;
try try
{ {
int bytesRead = connection.EndReceive(ar); int bytesRead = connection.EndReceive(ar);
if (bytesRead >= 3) if (bytesRead >= 3)
{ {
command = connetionRecvBuffer[1];
if (command == 1)
_command = _connetionRecvBuffer[1];
if (_command == 1)
{ {
byte[] response = { 5, 0, 0, 1, 0, 0, 0, 0, 0, 0 }; byte[] response = { 5, 0, 0, 1, 0, 0, 0, 0, 0, 0 };
connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(ResponseCallback), null);
connection.BeginSend(response, 0, response.Length, SocketFlags.None, new AsyncCallback(ResponseCallback), null);
} }
else if (command == 3)
{
else if (_command == 3)
HandleUDPAssociate(); HandleUDPAssociate();
}
} }
else else
{ {
@@ -320,33 +272,31 @@ namespace Shadowsocks.Controller
int port = endPoint.Port; int port = endPoint.Port;
byte[] response = new byte[4 + address.Length + 2]; byte[] response = new byte[4 + address.Length + 2];
response[0] = 5; response[0] = 5;
if (endPoint.AddressFamily == AddressFamily.InterNetwork)
{
response[3] = 1;
}
else if (endPoint.AddressFamily == AddressFamily.InterNetworkV6)
switch (endPoint.AddressFamily)
{ {
response[3] = 4;
case AddressFamily.InterNetwork:
response[3] = 1;
break;
case AddressFamily.InterNetworkV6:
response[3] = 4;
break;
} }
address.CopyTo(response, 4); address.CopyTo(response, 4);
response[response.Length - 1] = (byte)(port & 0xFF); response[response.Length - 1] = (byte)(port & 0xFF);
response[response.Length - 2] = (byte)((port >> 8) & 0xFF); response[response.Length - 2] = (byte)((port >> 8) & 0xFF);
connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(ReadAll), true);
connection.BeginSend(response, 0, response.Length, SocketFlags.None, new AsyncCallback(ReadAll), true);
} }
private void ReadAll(IAsyncResult ar) private void ReadAll(IAsyncResult ar)
{ {
if (closed)
{
return;
}
if (_closed) return;
try try
{ {
if (ar.AsyncState != null) if (ar.AsyncState != null)
{ {
connection.EndSend(ar); connection.EndSend(ar);
Logging.Debug(remote, RecvSize, "TCP Relay"); Logging.Debug(remote, RecvSize, "TCP Relay");
connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0, new AsyncCallback(ReadAll), null);
connection.BeginReceive(_connetionRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(ReadAll), null);
} }
else else
{ {
@@ -354,12 +304,10 @@ namespace Shadowsocks.Controller
if (bytesRead > 0) if (bytesRead > 0)
{ {
Logging.Debug(remote, RecvSize, "TCP Relay"); Logging.Debug(remote, RecvSize, "TCP Relay");
connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0, new AsyncCallback(ReadAll), null);
connection.BeginReceive(_connetionRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(ReadAll), null);
} }
else else
{
Close(); Close();
}
} }
} }
catch (Exception e) catch (Exception e)
@@ -374,10 +322,8 @@ namespace Shadowsocks.Controller
try try
{ {
connection.EndSend(ar); connection.EndSend(ar);
StartConnect(); StartConnect();
} }
catch (Exception e) catch (Exception e)
{ {
Logging.LogUsefulException(e); Logging.LogUsefulException(e);
@@ -389,10 +335,7 @@ namespace Shadowsocks.Controller
private class ServerTimer : Timer private class ServerTimer : Timer
{ {
public Server Server; public Server Server;
public ServerTimer(int p) : base(p)
{
}
public ServerTimer(int p) : base(p) { }
} }
private void StartConnect() private void StartConnect()
@@ -411,8 +354,7 @@ namespace Shadowsocks.Controller
} }
IPEndPoint remoteEP = new IPEndPoint(ipAddress, server.server_port); IPEndPoint remoteEP = new IPEndPoint(ipAddress, server.server_port);
remote = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
remote = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
remote.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); remote.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
_startConnectTime = DateTime.Now; _startConnectTime = DateTime.Now;
@@ -422,7 +364,7 @@ namespace Shadowsocks.Controller
connectTimer.Enabled = true; connectTimer.Enabled = true;
connectTimer.Server = server; connectTimer.Server = server;
connected = false;
_connected = false;
// Connect to the remote endpoint. // Connect to the remote endpoint.
remote.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), connectTimer); remote.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), connectTimer);
} }
@@ -435,16 +377,10 @@ namespace Shadowsocks.Controller
private void connectTimer_Elapsed(object sender, ElapsedEventArgs e) private void connectTimer_Elapsed(object sender, ElapsedEventArgs e)
{ {
if (connected)
{
return;
}
if (_connected) return;
Server server = ((ServerTimer)sender).Server; Server server = ((ServerTimer)sender).Server;
IStrategy strategy = controller.GetCurrentStrategy(); IStrategy strategy = controller.GetCurrentStrategy();
if (strategy != null)
{
strategy.SetFailure(server);
}
strategy?.SetFailure(server);
Logging.Info($"{server.FriendlyName()} timed out"); Logging.Info($"{server.FriendlyName()} timed out");
remote.Close(); remote.Close();
RetryConnect(); RetryConnect();
@@ -452,29 +388,23 @@ namespace Shadowsocks.Controller
private void RetryConnect() private void RetryConnect()
{ {
if (retryCount < maxRetry)
if (_retryCount < _maxRetry)
{ {
Logging.Debug($"Connection failed, retry ({retryCount})");
Logging.Debug($"Connection failed, retry ({_retryCount})");
StartConnect(); StartConnect();
retryCount++;
_retryCount++;
} }
else else
{
Close(); Close();
}
} }
private void ConnectCallback(IAsyncResult ar) private void ConnectCallback(IAsyncResult ar)
{ {
Server server = null;
if (closed)
{
return;
}
if (_closed) return;
try try
{ {
ServerTimer timer = (ServerTimer)ar.AsyncState; ServerTimer timer = (ServerTimer)ar.AsyncState;
server = timer.Server;
Server server = timer.Server;
timer.Elapsed -= connectTimer_Elapsed; timer.Elapsed -= connectTimer_Elapsed;
timer.Enabled = false; timer.Enabled = false;
timer.Dispose(); timer.Dispose();
@@ -482,14 +412,12 @@ namespace Shadowsocks.Controller
// Complete the connection. // Complete the connection.
remote.EndConnect(ar); remote.EndConnect(ar);
connected = true;
Logging.Debug($"Socket connected to {remote.RemoteEndPoint}");
_connected = true;
var latency = DateTime.Now - _startConnectTime; var latency = DateTime.Now - _startConnectTime;
IStrategy strategy = controller.GetCurrentStrategy(); IStrategy strategy = controller.GetCurrentStrategy();
strategy?.UpdateLatency(server, latency); strategy?.UpdateLatency(server, latency);
tcprelay.UpdateLatency(server, latency);
_tcprelay.UpdateLatency(server, latency);
StartPipe(); StartPipe();
} }
@@ -501,10 +429,7 @@ namespace Shadowsocks.Controller
if (server != null) if (server != null)
{ {
IStrategy strategy = controller.GetCurrentStrategy(); IStrategy strategy = controller.GetCurrentStrategy();
if (strategy != null)
{
strategy.SetFailure(server);
}
strategy?.SetFailure(server);
} }
Logging.LogUsefulException(e); Logging.LogUsefulException(e);
RetryConnect(); RetryConnect();
@@ -513,15 +438,12 @@ namespace Shadowsocks.Controller
private void StartPipe() private void StartPipe()
{ {
if (closed)
{
return;
}
if (_closed) return;
try try
{ {
_startReceivingTime = DateTime.Now; _startReceivingTime = DateTime.Now;
remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0, new AsyncCallback(PipeRemoteReceiveCallback), null);
connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0, new AsyncCallback(PipeConnectionReceiveCallback), null);
remote.BeginReceive(_remoteRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(PipeRemoteReceiveCallback), null);
connection.BeginReceive(_connetionRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(PipeConnectionReceiveCallback), null);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -532,49 +454,30 @@ namespace Shadowsocks.Controller
private void PipeRemoteReceiveCallback(IAsyncResult ar) private void PipeRemoteReceiveCallback(IAsyncResult ar)
{ {
if (closed)
{
return;
}
if (_closed) return;
try try
{ {
int bytesRead = remote.EndReceive(ar); int bytesRead = remote.EndReceive(ar);
totalRead += bytesRead;
tcprelay.UpdateInboundCounter(server, bytesRead);
_totalRead += bytesRead;
_tcprelay.UpdateInboundCounter(server, bytesRead);
if (bytesRead > 0) if (bytesRead > 0)
{ {
lastActivity = DateTime.Now; lastActivity = DateTime.Now;
int bytesToSend; int bytesToSend;
lock (decryptionLock)
lock (_decryptionLock)
{ {
if (closed)
{
return;
}
encryptor.Decrypt(remoteRecvBuffer, bytesRead, remoteSendBuffer, out bytesToSend);
if (_closed) return;
encryptor.Decrypt(_remoteRecvBuffer, bytesRead, _remoteSendBuffer, out bytesToSend);
} }
Logging.Debug(remote, bytesToSend, "TCP Relay", "@PipeRemoteReceiveCallback() (download)");
connection.BeginSend(remoteSendBuffer, 0, bytesToSend, 0, new AsyncCallback(PipeConnectionSendCallback), null);
connection.BeginSend(_remoteSendBuffer, 0, bytesToSend, SocketFlags.None, new AsyncCallback(PipeConnectionSendCallback), null);
IStrategy strategy = controller.GetCurrentStrategy(); IStrategy strategy = controller.GetCurrentStrategy();
if (strategy != null)
{
strategy.UpdateLastRead(server);
}
strategy?.UpdateLastRead(server);
} }
else else
{ {
connection.Shutdown(SocketShutdown.Send); connection.Shutdown(SocketShutdown.Send);
connectionShutdown = true;
_connectionShutdown = true;
CheckClose(); CheckClose();
//if (totalRead == 0)
//{
// // closed before anything received, reports as failure
// // disable this feature
// controller.GetCurrentStrategy().SetFailure(this.server);
//}
} }
} }
catch (Exception e) catch (Exception e)
@@ -586,39 +489,52 @@ namespace Shadowsocks.Controller
private void PipeConnectionReceiveCallback(IAsyncResult ar) private void PipeConnectionReceiveCallback(IAsyncResult ar)
{ {
if (closed)
{
return;
}
if (_closed) return;
try try
{ {
int bytesRead = connection.EndReceive(ar); int bytesRead = connection.EndReceive(ar);
totalWrite += bytesRead;
_totalWrite += bytesRead;
if (bytesRead > 0) if (bytesRead > 0)
{ {
int atyp = _connetionRecvBuffer[0];
string dst_addr;
int dst_port;
switch (atyp)
{
case 1: // IPv4 address, 4 bytes
dst_addr = new IPAddress(_connetionRecvBuffer.Skip(1).Take(4).ToArray()).ToString();
dst_port = (_connetionRecvBuffer[5] << 8) + _connetionRecvBuffer[6];
Logging.Debug($"connect to {dst_addr}:{dst_port}");
break;
case 3: // domain name, length + str
int len = _connetionRecvBuffer[1];
dst_addr = System.Text.Encoding.UTF8.GetString(_connetionRecvBuffer, 2, len);
dst_port = (_connetionRecvBuffer[len + 2] << 8) + _connetionRecvBuffer[len + 3];
Logging.Debug($"connect to {dst_addr}:{dst_port}");
break;
case 4: // IPv6 address, 16 bytes
dst_addr = new IPAddress(_connetionRecvBuffer.Skip(1).Take(16).ToArray()).ToString();
dst_port = (_connetionRecvBuffer[17] << 8) + _connetionRecvBuffer[18];
Logging.Debug($"connect to [{dst_addr}]:{dst_port}");
break;
}
int bytesToSend; int bytesToSend;
lock (encryptionLock)
lock (_encryptionLock)
{ {
if (closed)
{
return;
}
encryptor.Encrypt(connetionRecvBuffer, bytesRead, connetionSendBuffer, out bytesToSend);
if (_closed) return;
encryptor.Encrypt(_connetionRecvBuffer, bytesRead, _connetionSendBuffer, out bytesToSend);
} }
Logging.Debug(remote, bytesToSend, "TCP Relay", "@PipeConnectionReceiveCallback() (upload)");
tcprelay.UpdateOutboundCounter(server, bytesToSend);
_tcprelay.UpdateOutboundCounter(server, bytesToSend);
_startSendingTime = DateTime.Now; _startSendingTime = DateTime.Now;
_bytesToSend = bytesToSend; _bytesToSend = bytesToSend;
remote.BeginSend(connetionSendBuffer, 0, bytesToSend, 0, new AsyncCallback(PipeRemoteSendCallback), null);
remote.BeginSend(_connetionSendBuffer, 0, bytesToSend, SocketFlags.None, new AsyncCallback(PipeRemoteSendCallback), null);
IStrategy strategy = controller.GetCurrentStrategy(); IStrategy strategy = controller.GetCurrentStrategy();
strategy?.UpdateLastWrite(server); strategy?.UpdateLastWrite(server);
} }
else else
{ {
remote.Shutdown(SocketShutdown.Send); remote.Shutdown(SocketShutdown.Send);
remoteShutdown = true;
_remoteShutdown = true;
CheckClose(); CheckClose();
} }
} }
@@ -631,14 +547,11 @@ namespace Shadowsocks.Controller
private void PipeRemoteSendCallback(IAsyncResult ar) private void PipeRemoteSendCallback(IAsyncResult ar)
{ {
if (closed)
{
return;
}
if (_closed) return;
try try
{ {
remote.EndSend(ar); remote.EndSend(ar);
connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0, new AsyncCallback(PipeConnectionReceiveCallback), null);
connection.BeginReceive(_connetionRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(PipeConnectionReceiveCallback), null);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -649,14 +562,11 @@ namespace Shadowsocks.Controller
private void PipeConnectionSendCallback(IAsyncResult ar) private void PipeConnectionSendCallback(IAsyncResult ar)
{ {
if (closed)
{
return;
}
if (_closed) return;
try try
{ {
connection.EndSend(ar); connection.EndSend(ar);
remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0, new AsyncCallback(PipeRemoteReceiveCallback), null);
remote.BeginReceive(_remoteRecvBuffer, 0, RecvSize, SocketFlags.None, new AsyncCallback(PipeRemoteReceiveCallback), null);
} }
catch (Exception e) catch (Exception e)
{ {


+ 4
- 2
shadowsocks-csharp/Util/Util.cs View File

@@ -76,7 +76,8 @@ namespace Shadowsocks.Util
// //
// just kidding // just kidding
SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle,
(UIntPtr)0xFFFFFFFF, (UIntPtr)0xFFFFFFFF);
(UIntPtr)0xFFFFFFFF,
(UIntPtr)0xFFFFFFFF);
} }
} }
@@ -87,7 +88,8 @@ namespace Shadowsocks.Util
using (MemoryStream sb = new MemoryStream()) using (MemoryStream sb = new MemoryStream())
{ {
using (GZipStream input = new GZipStream(new MemoryStream(buf), using (GZipStream input = new GZipStream(new MemoryStream(buf),
CompressionMode.Decompress, false))
CompressionMode.Decompress,
false))
{ {
while ((n = input.Read(buffer, 0, buffer.Length)) > 0) while ((n = input.Read(buffer, 0, buffer.Length)) > 0)
{ {


Loading…
Cancel
Save