Browse Source

reduce cache size

tags/3.2
clowwindy 9 years ago
parent
commit
3bc77d212a
2 changed files with 65 additions and 43 deletions
  1. +21
    -1
      shadowsocks-csharp/Controller/Service/TCPRelay.cs
  2. +44
    -42
      shadowsocks-csharp/Encryption/SodiumEncryptor.cs

+ 21
- 1
shadowsocks-csharp/Controller/Service/TCPRelay.cs View File

@@ -14,9 +14,16 @@ namespace Shadowsocks.Controller
class TCPRelay : Listener.Service
{
private ShadowsocksController _controller;
public ISet<Handler> Handlers
{
get; set;
}
public TCPRelay(ShadowsocksController controller)
{
this._controller = controller;
this.Handlers = new HashSet<Handler>();
}
public bool Handle(byte[] firstPacket, int length, Socket socket, object state)
@@ -33,8 +40,14 @@ namespace Shadowsocks.Controller
Handler handler = new Handler();
handler.connection = socket;
handler.controller = _controller;
handler.relay = this;
handler.Start(firstPacket, length);
lock (this.Handlers)
{
this.Handlers.Add(handler);
Logging.Debug($"connections: {Handlers.Count}");
}
return true;
}
}
@@ -48,6 +61,8 @@ namespace Shadowsocks.Controller
public Socket remote;
public Socket connection;
public ShadowsocksController controller;
public TCPRelay relay;
private int retryCount = 0;
private bool connected;
@@ -55,7 +70,7 @@ namespace Shadowsocks.Controller
private byte[] _firstPacket;
private int _firstPacketLength;
// Size of receive buffer.
public const int RecvSize = 16384;
public const int RecvSize = 8192;
public const int BufferSize = RecvSize + 32;
private int totalRead = 0;
@@ -108,6 +123,11 @@ namespace Shadowsocks.Controller
public void Close()
{
lock (relay.Handlers)
{
Logging.Debug($"connections: {relay.Handlers.Count}");
relay.Handlers.Remove(this);
}
lock (this)
{
if (closed)


+ 44
- 42
shadowsocks-csharp/Encryption/SodiumEncryptor.cs View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace Shadowsocks.Encryption
{
@@ -12,19 +13,17 @@ namespace Shadowsocks.Encryption
const int SODIUM_BLOCK_SIZE = 64;
static byte[] sodiumBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE];
protected int _encryptBytesRemaining;
protected int _decryptBytesRemaining;
protected ulong _encryptIC;
protected ulong _decryptIC;
protected byte[] _encryptBuf;
protected byte[] _decryptBuf;
public SodiumEncryptor(string method, string password)
: base(method, password)
{
InitKey(method, password);
_encryptBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE];
_decryptBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE];
}
private static Dictionary<string, int[]> _ciphers = new Dictionary<string, int[]> {
@@ -47,48 +46,51 @@ namespace Shadowsocks.Encryption
// TODO write a unidirection cipher so we don't have to if if if
int bytesRemaining;
ulong ic;
byte[] sodiumBuf;
byte[] iv;
if (isCipher)
{
bytesRemaining = _encryptBytesRemaining;
ic = _encryptIC;
sodiumBuf = _encryptBuf;
iv = _encryptIV;
}
else
{
bytesRemaining = _decryptBytesRemaining;
ic = _decryptIC;
sodiumBuf = _decryptBuf;
iv = _decryptIV;
}
int padding = bytesRemaining;
Buffer.BlockCopy(buf, 0, sodiumBuf, padding, length);
switch (_cipher)
// I'm tired. just add a big lock
// let's optimize for RAM instead of CPU
lock(sodiumBuf)
{
case CIPHER_SALSA20:
Sodium.crypto_stream_salsa20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key);
break;
case CIPHER_CHACHA20:
Sodium.crypto_stream_chacha20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key);
break;
}
Buffer.BlockCopy(sodiumBuf, padding, outbuf, 0, length);
padding += length;
ic += (ulong)padding / SODIUM_BLOCK_SIZE;
bytesRemaining = padding % SODIUM_BLOCK_SIZE;
if (isCipher)
{
bytesRemaining = _encryptBytesRemaining;
ic = _encryptIC;
iv = _encryptIV;
}
else
{
bytesRemaining = _decryptBytesRemaining;
ic = _decryptIC;
iv = _decryptIV;
}
int padding = bytesRemaining;
Buffer.BlockCopy(buf, 0, sodiumBuf, padding, length);
if (isCipher)
{
_encryptBytesRemaining = bytesRemaining;
_encryptIC = ic;
}
else
{
_decryptBytesRemaining = bytesRemaining;
_decryptIC = ic;
switch (_cipher)
{
case CIPHER_SALSA20:
Sodium.crypto_stream_salsa20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key);
break;
case CIPHER_CHACHA20:
Sodium.crypto_stream_chacha20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key);
break;
}
Buffer.BlockCopy(sodiumBuf, padding, outbuf, 0, length);
padding += length;
ic += (ulong)padding / SODIUM_BLOCK_SIZE;
bytesRemaining = padding % SODIUM_BLOCK_SIZE;
if (isCipher)
{
_encryptBytesRemaining = bytesRemaining;
_encryptIC = ic;
}
else
{
_decryptBytesRemaining = bytesRemaining;
_decryptIC = ic;
}
}
}


Loading…
Cancel
Save