Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed31a3cab0 | ||
|
|
081bbaf011 | ||
|
|
0251130fa5 | ||
|
|
f0b196c8c3 | ||
|
|
057b148092 | ||
|
|
101c33d0f1 | ||
|
|
bbfc5d332d | ||
|
|
5d75e19c26 | ||
|
|
816651ebdc | ||
|
|
44afefed71 | ||
|
|
2eeebc29d7 | ||
|
|
0e01f8303c | ||
|
|
2fcf843bba | ||
|
|
3b3a8c9077 | ||
|
|
60a5572808 | ||
|
|
877644609b | ||
|
|
54335d4889 | ||
|
|
08f12b3b24 | ||
|
|
1c8f4168cf | ||
|
|
43672a8bda |
@@ -1,3 +1,20 @@
|
|||||||
|
4.0.5 2017-08-09
|
||||||
|
- Fix crash when user-wininet.json fail to parse. (#1178)
|
||||||
|
- Bug fixes and improvements.
|
||||||
|
|
||||||
|
4.0.4 2017-06-01
|
||||||
|
- Save user wininet settings as user-wininet.json
|
||||||
|
- Improve performance of aes-256-gcm
|
||||||
|
|
||||||
|
4.0.2 2017-05-19
|
||||||
|
- Fix legacy key derivation
|
||||||
|
- Bug fixes and improvements
|
||||||
|
|
||||||
|
4.0.1 2017-04-08
|
||||||
|
- Fix UDP relay
|
||||||
|
- Allow to add multiple servers via Shadowsocks URL
|
||||||
|
- Bug fixes and improvements
|
||||||
|
|
||||||
4.0 2017-04-04
|
4.0 2017-04-04
|
||||||
- Add AEAD ciphers support, removed OTA
|
- Add AEAD ciphers support, removed OTA
|
||||||
- I18N: add Japanese support, update Traditional Chinese strings
|
- I18N: add Japanese support, update Traditional Chinese strings
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ Shadowsocks for Windows
|
|||||||
|
|
||||||
Download the [latest release].
|
Download the [latest release].
|
||||||
|
|
||||||
|
#### Requirements
|
||||||
|
|
||||||
|
Microsoft [.NET Framework 4.6.2] or higher.
|
||||||
|
|
||||||
#### Basic
|
#### Basic
|
||||||
|
|
||||||
1. Find Shadowsocks icon in the notification tray
|
1. Find Shadowsocks icon in the notification tray
|
||||||
@@ -104,5 +108,6 @@ GPLv3
|
|||||||
[GFWList]: https://github.com/gfwlist/gfwlist
|
[GFWList]: https://github.com/gfwlist/gfwlist
|
||||||
[Servers]: https://github.com/shadowsocks/shadowsocks/wiki/Ports-and-Clients#linux--server-side
|
[Servers]: https://github.com/shadowsocks/shadowsocks/wiki/Ports-and-Clients#linux--server-side
|
||||||
[中文说明]: https://github.com/shadowsocks/shadowsocks-windows/wiki/Shadowsocks-Windows-%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E
|
[中文说明]: https://github.com/shadowsocks/shadowsocks-windows/wiki/Shadowsocks-Windows-%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E
|
||||||
|
[.NET Framework 4.6.2]: https://www.microsoft.com/en-US/download/details.aspx?id=53344
|
||||||
[Visual Studio 2015]: https://www.visualstudio.com/downloads/
|
[Visual Studio 2015]: https://www.visualstudio.com/downloads/
|
||||||
[.NET Framework 4.6.2 Developer Pack]: https://www.microsoft.com/download/details.aspx?id=53321
|
[.NET Framework 4.6.2 Developer Pack]: https://www.microsoft.com/download/details.aspx?id=53321
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ namespace Shadowsocks.Controller
|
|||||||
{
|
{
|
||||||
class PortForwarder : Listener.Service
|
class PortForwarder : Listener.Service
|
||||||
{
|
{
|
||||||
int _targetPort;
|
private readonly int _targetPort;
|
||||||
|
|
||||||
public PortForwarder(int targetPort)
|
public PortForwarder(int targetPort)
|
||||||
{
|
{
|
||||||
this._targetPort = targetPort;
|
_targetPort = targetPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Handle(byte[] firstPacket, int length, Socket socket, object state)
|
public override bool Handle(byte[] firstPacket, int length, Socket socket, object state)
|
||||||
@@ -20,11 +20,11 @@ namespace Shadowsocks.Controller
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
new Handler().Start(firstPacket, length, socket, this._targetPort);
|
new Handler().Start(firstPacket, length, socket, _targetPort);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Handler
|
private class Handler
|
||||||
{
|
{
|
||||||
private byte[] _firstPacket;
|
private byte[] _firstPacket;
|
||||||
private int _firstPacketLength;
|
private int _firstPacketLength;
|
||||||
@@ -33,7 +33,7 @@ namespace Shadowsocks.Controller
|
|||||||
private bool _closed = false;
|
private bool _closed = false;
|
||||||
private bool _localShutdown = false;
|
private bool _localShutdown = false;
|
||||||
private bool _remoteShutdown = false;
|
private bool _remoteShutdown = false;
|
||||||
public const int RecvSize = 16384;
|
private const int RecvSize = 2048;
|
||||||
// remote receive buffer
|
// remote receive buffer
|
||||||
private byte[] remoteRecvBuffer = new byte[RecvSize];
|
private byte[] remoteRecvBuffer = new byte[RecvSize];
|
||||||
// connection receive buffer
|
// connection receive buffer
|
||||||
@@ -44,9 +44,9 @@ namespace Shadowsocks.Controller
|
|||||||
|
|
||||||
public void Start(byte[] firstPacket, int length, Socket socket, int targetPort)
|
public void Start(byte[] firstPacket, int length, Socket socket, int targetPort)
|
||||||
{
|
{
|
||||||
this._firstPacket = firstPacket;
|
_firstPacket = firstPacket;
|
||||||
this._firstPacketLength = length;
|
_firstPacketLength = length;
|
||||||
this._local = socket;
|
_local = socket;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
EndPoint remoteEP = SocketUtil.GetEndPoint("127.0.0.1", targetPort);
|
EndPoint remoteEP = SocketUtil.GetEndPoint("127.0.0.1", targetPort);
|
||||||
@@ -58,7 +58,7 @@ namespace Shadowsocks.Controller
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logging.LogUsefulException(e);
|
Logging.LogUsefulException(e);
|
||||||
this.Close();
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ namespace Shadowsocks.Controller
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logging.LogUsefulException(e);
|
Logging.LogUsefulException(e);
|
||||||
this.Close();
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,12 +89,12 @@ namespace Shadowsocks.Controller
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_remote.BeginSend(_firstPacket, 0, _firstPacketLength, 0, new AsyncCallback(StartPipe), null);
|
_remote.BeginSend(_firstPacket, 0, _firstPacketLength, 0, StartPipe, null);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logging.LogUsefulException(e);
|
Logging.LogUsefulException(e);
|
||||||
this.Close();
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,14 +108,14 @@ namespace Shadowsocks.Controller
|
|||||||
{
|
{
|
||||||
_remote.EndSend(ar);
|
_remote.EndSend(ar);
|
||||||
_remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0,
|
_remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0,
|
||||||
new AsyncCallback(PipeRemoteReceiveCallback), null);
|
PipeRemoteReceiveCallback, null);
|
||||||
_local.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0,
|
_local.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0,
|
||||||
new AsyncCallback(PipeConnectionReceiveCallback), null);
|
PipeConnectionReceiveCallback, null);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logging.LogUsefulException(e);
|
Logging.LogUsefulException(e);
|
||||||
this.Close();
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,10 +128,9 @@ namespace Shadowsocks.Controller
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
int bytesRead = _remote.EndReceive(ar);
|
int bytesRead = _remote.EndReceive(ar);
|
||||||
|
|
||||||
if (bytesRead > 0)
|
if (bytesRead > 0)
|
||||||
{
|
{
|
||||||
_local.BeginSend(remoteRecvBuffer, 0, bytesRead, 0, new AsyncCallback(PipeConnectionSendCallback), null);
|
_local.BeginSend(remoteRecvBuffer, 0, bytesRead, 0, PipeConnectionSendCallback, null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -143,7 +142,7 @@ namespace Shadowsocks.Controller
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logging.LogUsefulException(e);
|
Logging.LogUsefulException(e);
|
||||||
this.Close();
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,10 +155,9 @@ namespace Shadowsocks.Controller
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
int bytesRead = _local.EndReceive(ar);
|
int bytesRead = _local.EndReceive(ar);
|
||||||
|
|
||||||
if (bytesRead > 0)
|
if (bytesRead > 0)
|
||||||
{
|
{
|
||||||
_remote.BeginSend(connetionRecvBuffer, 0, bytesRead, 0, new AsyncCallback(PipeRemoteSendCallback), null);
|
_remote.BeginSend(connetionRecvBuffer, 0, bytesRead, 0, PipeRemoteSendCallback, null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -171,7 +169,7 @@ namespace Shadowsocks.Controller
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logging.LogUsefulException(e);
|
Logging.LogUsefulException(e);
|
||||||
this.Close();
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,13 +182,13 @@ namespace Shadowsocks.Controller
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
_remote.EndSend(ar);
|
_remote.EndSend(ar);
|
||||||
_local.BeginReceive(this.connetionRecvBuffer, 0, RecvSize, 0,
|
_local.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0,
|
||||||
new AsyncCallback(PipeConnectionReceiveCallback), null);
|
PipeConnectionReceiveCallback, null);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logging.LogUsefulException(e);
|
Logging.LogUsefulException(e);
|
||||||
this.Close();
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,13 +201,13 @@ namespace Shadowsocks.Controller
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
_local.EndSend(ar);
|
_local.EndSend(ar);
|
||||||
_remote.BeginReceive(this.remoteRecvBuffer, 0, RecvSize, 0,
|
_remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0,
|
||||||
new AsyncCallback(PipeRemoteReceiveCallback), null);
|
PipeRemoteReceiveCallback, null);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logging.LogUsefulException(e);
|
Logging.LogUsefulException(e);
|
||||||
this.Close();
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +215,7 @@ namespace Shadowsocks.Controller
|
|||||||
{
|
{
|
||||||
if (_localShutdown && _remoteShutdown)
|
if (_localShutdown && _remoteShutdown)
|
||||||
{
|
{
|
||||||
this.Close();
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ namespace Shadowsocks.Controller
|
|||||||
private Socket _remote;
|
private Socket _remote;
|
||||||
|
|
||||||
private Server _server;
|
private Server _server;
|
||||||
private byte[] _buffer = new byte[1500];
|
private byte[] _buffer = new byte[65536];
|
||||||
|
|
||||||
private IPEndPoint _localEndPoint;
|
private IPEndPoint _localEndPoint;
|
||||||
private IPEndPoint _remoteEndPoint;
|
private IPEndPoint _remoteEndPoint;
|
||||||
@@ -81,7 +81,7 @@ namespace Shadowsocks.Controller
|
|||||||
IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password);
|
IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password);
|
||||||
byte[] dataIn = new byte[length - 3];
|
byte[] dataIn = new byte[length - 3];
|
||||||
Array.Copy(data, 3, dataIn, 0, length - 3);
|
Array.Copy(data, 3, dataIn, 0, length - 3);
|
||||||
byte[] dataOut = new byte[length - 3 + 16];
|
byte[] dataOut = new byte[65536]; // enough space for AEAD ciphers
|
||||||
int outlen;
|
int outlen;
|
||||||
encryptor.EncryptUDP(dataIn, length - 3, dataOut, out outlen);
|
encryptor.EncryptUDP(dataIn, length - 3, dataOut, out outlen);
|
||||||
Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay");
|
Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay");
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace Shadowsocks.Controller
|
|||||||
public string LatestVersionLocalName;
|
public string LatestVersionLocalName;
|
||||||
public event EventHandler CheckUpdateCompleted;
|
public event EventHandler CheckUpdateCompleted;
|
||||||
|
|
||||||
public const string Version = "4.0";
|
public const string Version = "4.0.5";
|
||||||
|
|
||||||
private class CheckUpdateTimer : System.Timers.Timer
|
private class CheckUpdateTimer : System.Timers.Timer
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,8 +44,6 @@ namespace Shadowsocks.Controller
|
|||||||
|
|
||||||
private bool stopped = false;
|
private bool stopped = false;
|
||||||
|
|
||||||
private bool _systemProxyIsDirty = false;
|
|
||||||
|
|
||||||
public class PathEventArgs : EventArgs
|
public class PathEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public string Path;
|
public string Path;
|
||||||
@@ -163,8 +161,13 @@ namespace Shadowsocks.Controller
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var server = new Server(ssURL);
|
if (ssURL.IsNullOrEmpty() || ssURL.IsWhiteSpace()) return false;
|
||||||
_config.configs.Add(server);
|
var servers = Server.GetServers(ssURL);
|
||||||
|
if (servers == null || servers.Count == 0) return false;
|
||||||
|
foreach (var server in servers)
|
||||||
|
{
|
||||||
|
_config.configs.Add(server);
|
||||||
|
}
|
||||||
_config.index = _config.configs.Count - 1;
|
_config.index = _config.configs.Count - 1;
|
||||||
SaveConfig(_config);
|
SaveConfig(_config);
|
||||||
return true;
|
return true;
|
||||||
@@ -505,20 +508,7 @@ namespace Shadowsocks.Controller
|
|||||||
|
|
||||||
private void UpdateSystemProxy()
|
private void UpdateSystemProxy()
|
||||||
{
|
{
|
||||||
if (_config.enabled)
|
SystemProxy.Update(_config, false, _pacServer);
|
||||||
{
|
|
||||||
SystemProxy.Update(_config, false, _pacServer);
|
|
||||||
_systemProxyIsDirty = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// only switch it off if we have switched it on
|
|
||||||
if (_systemProxyIsDirty)
|
|
||||||
{
|
|
||||||
SystemProxy.Update(_config, false, _pacServer);
|
|
||||||
_systemProxyIsDirty = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pacServer_PACFileChanged(object sender, EventArgs e)
|
private void pacServer_PACFileChanged(object sender, EventArgs e)
|
||||||
|
|||||||
@@ -4,40 +4,40 @@ Shadowsocks=Shadowsocks
|
|||||||
|
|
||||||
# Menu items
|
# Menu items
|
||||||
|
|
||||||
Enable System Proxy=システムの代理を有効にする
|
Enable System Proxy=システム プロキシを有効にする
|
||||||
Mode=モード
|
Mode=モード
|
||||||
PAC=PAC
|
PAC=PAC
|
||||||
Global=全般
|
Global=全般
|
||||||
Servers=サーバ
|
Servers=サーバー
|
||||||
Edit Servers...=サーバーを編集する...
|
Edit Servers...=サーバーの編集...
|
||||||
Statistics Config...=統計情報の設定...
|
Statistics Config...=統計情報の設定...
|
||||||
Start on Boot=システムと同時に起動
|
Start on Boot=システムと同時に起動
|
||||||
Forward Proxy...=代理を転送する...
|
Forward Proxy...=フォワードプロキシの設定...
|
||||||
Allow Clients from LAN=LANからのクライアントを許可する
|
Allow Clients from LAN=LAN からのアクセスを許可
|
||||||
Local PAC=ローカル PAC
|
Local PAC=ローカル PAC
|
||||||
Online PAC=オンライン PAC
|
Online PAC=オンライン PAC
|
||||||
Edit Local PAC File...=ローカル PAC ファイルを編集する...
|
Edit Local PAC File...=ローカル PAC ファイルの編集...
|
||||||
Update Local PAC from GFWList=GFWList から、ローカル PACを更新する
|
Update Local PAC from GFWList=GFWList からローカル PAC を更新
|
||||||
Edit User Rule for GFWList...=利用者規則を編集する...
|
Edit User Rule for GFWList...=ユーザールールの編集...
|
||||||
Secure Local PAC=安全なローカル PAC
|
Secure Local PAC=ローカル PAC を保護
|
||||||
Copy Local PAC URL=ローカルのPAC URLをコピー
|
Copy Local PAC URL=ローカル PAC URL をコピー
|
||||||
Share Server Config...=サーバーの設定を共有する...
|
Share Server Config...=サーバーの設定を共有...
|
||||||
Scan QRCode from Screen...=画面からの QRコードをスキャン...
|
Scan QRCode from Screen...=画面から QR コードをスキャン...
|
||||||
Import URL from Clipboard...=クリップボードからの URLを貼り付け...
|
Import URL from Clipboard...=クリップボードから URL をインポート...
|
||||||
Availability Statistics=可用性の統計
|
Availability Statistics=可用性の統計
|
||||||
Show Logs...=ログを表示する...
|
Show Logs...=ログの表示...
|
||||||
Verbose Logging=詳細なログ
|
Verbose Logging=詳細なログを記録
|
||||||
Updates...=更新...
|
Updates...=更新...
|
||||||
Check for Updates...=更新プログラムを確認しています...
|
Check for Updates...=更新プログラムの確認...
|
||||||
Check for Updates at Startup=起動と同時に更新プログラムを確認しています
|
Check for Updates at Startup=起動時に更新プログラムを確認
|
||||||
Check Pre-release Version=先行開発版の更新を確認しています...
|
Check Pre-release Version=先行開発版も確認
|
||||||
Edit Hotkeys...=ホットキーを編集する...
|
Edit Hotkeys...=ホットキーの編集...
|
||||||
About...=について...
|
About...=Shadowsocks について...
|
||||||
Help=ヘルプ
|
Help=ヘルプ
|
||||||
Quit=終了
|
Quit=終了
|
||||||
Edit Servers=サーバを編集する
|
Edit Servers=サーバーの編集
|
||||||
Load Balance=バランス
|
Load Balance=負荷分散
|
||||||
High Availability=高パフォーマンス
|
High Availability=高可用性
|
||||||
Choose by statistics=統計で選ぶ
|
Choose by statistics=統計で選ぶ
|
||||||
|
|
||||||
# Config Form
|
# Config Form
|
||||||
@@ -45,42 +45,42 @@ Choose by statistics=統計で選ぶ
|
|||||||
&Add=新規 (&A)
|
&Add=新規 (&A)
|
||||||
&Delete=削除 (&D)
|
&Delete=削除 (&D)
|
||||||
Dupli&cate=コピー (&C)
|
Dupli&cate=コピー (&C)
|
||||||
Server=サーバ
|
Server=サーバー
|
||||||
Server Addr=サーバーアドレス
|
Server Addr=サーバーアドレス
|
||||||
Server Port=サーバポート
|
Server Port=サーバーポート
|
||||||
Password=暗証番号
|
Password=パスワード
|
||||||
Encryption=暗号化
|
Encryption=暗号化
|
||||||
Proxy Port=代理ポート
|
Proxy Port=プロキシポート
|
||||||
Remarks=短評する
|
Remarks=付記
|
||||||
Timeout(Sec)=タイムアウト (秒)
|
Timeout(Sec)=タイムアウト (秒)
|
||||||
OK=はい
|
OK=OK
|
||||||
Cancel=いいえ
|
Cancel=キャンセル
|
||||||
New server=新規サーバ
|
New server=新規サーバー
|
||||||
Move &Up=上に移動 (&U)
|
Move &Up=上に移動 (&U)
|
||||||
Move D&own=下に移動 (&O)
|
Move D&own=下に移動 (&O)
|
||||||
|
|
||||||
# Proxy Form
|
# Proxy Form
|
||||||
|
|
||||||
Edit Proxy=代理を編集する
|
Edit Proxy=プロキシの編集
|
||||||
Use Proxy=代理を利用する
|
Use Proxy=プロキシを利用する
|
||||||
Proxy Type=代理類型
|
Proxy Type=プロキシの種類
|
||||||
Proxy Addr=代理アドレス
|
Proxy Addr=プロキシアドレス
|
||||||
Proxy Port=代理ポート
|
Proxy Port=プロキシポート
|
||||||
|
|
||||||
# Log Form
|
# Log Form
|
||||||
|
|
||||||
&File=ファイル (&F)
|
&File=ファイル (&F)
|
||||||
&Open Location=この場所を開く (&O)
|
&Open Location=ファイルの場所を開く (&O)
|
||||||
E&xit=終了 (&X)
|
E&xit=終了 (&X)
|
||||||
&View=ビュー (&V)
|
&View=表示 (&V)
|
||||||
&Clean Logs=ログを削除する (&C)
|
&Clean Logs=ログの削除 (&C)
|
||||||
Change &Font=フォントを変更する (&F)
|
Change &Font=フォント (&F)
|
||||||
&Wrap Text=文字改行 (&W)
|
&Wrap Text=右端で折り返す (&W)
|
||||||
&Top Most=一番上 (&T)
|
&Top Most=常に最前面に表示 (&T)
|
||||||
&Show Toolbar=ツールバーを表示する (&S)
|
&Show Toolbar=ツールバーの表示 (&S)
|
||||||
Log Viewer=ログビューア
|
Log Viewer=ログビューア
|
||||||
Inbound=輸入
|
Inbound=受信
|
||||||
Outbound=輸出
|
Outbound=送信
|
||||||
|
|
||||||
# QRCode Form
|
# QRCode Form
|
||||||
|
|
||||||
@@ -88,16 +88,16 @@ QRCode and URL=QR コードと URL
|
|||||||
|
|
||||||
# PAC Url Form
|
# PAC Url Form
|
||||||
|
|
||||||
Edit Online PAC URL=オンライン PAC URLを編集する
|
Edit Online PAC URL=オンライン PAC URL の編集
|
||||||
Edit Online PAC URL...=オンライン PAC URLを編集する...
|
Edit Online PAC URL...=オンライン PAC URL の編集...
|
||||||
Please input PAC Url=PAC URLを入力して下さい
|
Please input PAC Url=PAC URLを入力して下さい
|
||||||
|
|
||||||
# HotkeySettings Form
|
# HotkeySettings Form
|
||||||
|
|
||||||
Switch system proxy=代理を切換える
|
Switch system proxy=システム プロキシの状態を切り替える
|
||||||
Switch system proxy mode=代理モードを切換える
|
Switch system proxy mode=プロキシモードを切り替える
|
||||||
Switch share over LAN=LAN経由でシェアを切換える
|
Switch share over LAN=LAN からのアクセスの許可を切り替える
|
||||||
Show Logs=ログを表示する
|
Show Logs=ログの表示
|
||||||
Switch to prev server=前のサーバーに切り替える
|
Switch to prev server=前のサーバーに切り替える
|
||||||
Switch to next server=次のサーバーに切り替える
|
Switch to next server=次のサーバーに切り替える
|
||||||
Reg All=全部登録する
|
Reg All=全部登録する
|
||||||
@@ -105,38 +105,38 @@ Reg All=全部登録する
|
|||||||
# Messages
|
# Messages
|
||||||
|
|
||||||
Shadowsocks Error: {0}=Shadowsocks エラー: {0}
|
Shadowsocks Error: {0}=Shadowsocks エラー: {0}
|
||||||
Port already in use=既に使用中のポート
|
Port already in use=ポートは既に使用されています。
|
||||||
Invalid server address=違法なサーバアドレス
|
Invalid server address=サーバーアドレスが無効です。
|
||||||
Illegal port number format=不法なポート番号形式
|
Illegal port number format=ポート番号のフォーマットが無効です。
|
||||||
Illegal timeout format=不法なタイムアウト形式
|
Illegal timeout format=タイムアウト値のフォーマットが無効です。
|
||||||
Please add at least one server=少なくとも一つのサーバーを追加して下さい
|
Please add at least one server=少なくとも一つのサーバーを指定して下さい。
|
||||||
Server IP can not be blank=サーバ IP は空欄にできない
|
Server IP can not be blank=サーバー IP が指定されていません。
|
||||||
Password can not be blank=暗証番号は空欄にできない
|
Password can not be blank=パスワードが指定されていません。
|
||||||
Port out of range=ポートが範囲外
|
Port out of range=ポート番号は範囲外です。
|
||||||
Port can't be 8123=ポート8123できない
|
Port can't be 8123=8123 番以外のポート番号を指定して下さい。
|
||||||
Shadowsocks {0} Update Found=Shadowsocks {0} 更新プログラムを利用できます
|
Shadowsocks {0} Update Found=Shadowsocks バージョン {0} は利用できます。
|
||||||
No update is available=お使いのソフトウェアは最新です
|
No update is available=お使いのバージョンは最新です。
|
||||||
Click here to update=プログラムの更新
|
Click here to update=クリックしてアップデートします。
|
||||||
Shadowsocks is here=Shadowsocks 此処です
|
Shadowsocks is here=Shadowsocks はここです。
|
||||||
You can turn on/off Shadowsocks in the context menu=コンテキストメニューにshadowsocksを有効化または無効化
|
You can turn on/off Shadowsocks in the context menu=コンテキストメニューを使って、Shadowsocks を有効または無効にすることができます。
|
||||||
System Proxy Enabled=システム 代理を有効にする
|
System Proxy Enabled=システム プロキシが有効です。
|
||||||
System Proxy Disabled=システム 代理を無効にする
|
System Proxy Disabled=システム プロキシが無効です。
|
||||||
Failed to update PAC file =PAC の更新に失敗しました
|
Failed to update PAC file =PAC の更新に失敗しました。
|
||||||
PAC updated=PAC の更新に正しくインストールされました
|
PAC updated=PAC を更新しました。
|
||||||
No updates found. Please report to GFWList if you have problems with it.=お使いのソフトウェアは最新です。もし貴方は問題がある、GFWListに報告して下さい。
|
No updates found. Please report to GFWList if you have problems with it.=お使いのバージョンは最新です。問題がある場合は、GFWList に報告して下さい。
|
||||||
No QRCode found. Try to zoom in or move it to the center of the screen.=QR コードを探し当てていません。ズームインまたはそれが画面の中心に移動して下さい。
|
No QRCode found. Try to zoom in or move it to the center of the screen.=QR コードが見つかりませんでした。コードを大きくするか、画面の中央に移動して下さい。
|
||||||
Shadowsocks is already running.=Shadowsocks 実行中。
|
Shadowsocks is already running.=Shadowsocks 実行中
|
||||||
Find Shadowsocks icon in your notify tray.=shadowsocks通知トレイにアイコンを見つけて下さい。
|
Find Shadowsocks icon in your notify tray.=通知領域には Shadowsocks のアイコンがあります。
|
||||||
If you want to start multiple Shadowsocks, make a copy in another directory.=同時に起動したい場合は、別のディレクトリにコピーしてもいいと思ってます。
|
If you want to start multiple Shadowsocks, make a copy in another directory.=複数起動したい場合は、プログラムファイルを別のフォルダーにコピーしてから、もう一度実行して下さい。
|
||||||
Failed to decode QRCode=QR コードの復号化に失敗しました
|
Failed to decode QRCode=QR コードの読み取りに失敗しました。
|
||||||
Failed to update registry=登錄の更新に失敗しました
|
Failed to update registry=レジストリの更新に失敗しました。
|
||||||
System Proxy On: =システム代理をオンにする:
|
System Proxy On: =システム プロキシが有効:
|
||||||
Running: Port {0}=実行中:ポート {0}
|
Running: Port {0}=実行中:ポート {0}
|
||||||
Unexpected error, shadowsocks will exit. Please report to=予想外のエラー、Shadowsocks を終了する。この場所を報告して下さい。
|
Unexpected error, shadowsocks will exit. Please report to=予想外のエラーが発生したため、Shadowsocks を終了します。詳しくは下記までお問い合わせ下さい:
|
||||||
Unsupported operating system, use Windows Vista at least.=サポートしていないのOS、Windows Vista 以降のOSを利用して下さい。
|
Unsupported operating system, use Windows Vista at least.=お使いの OS はサポートされていません。Windows Vista 以降の OS で実行して下さい。
|
||||||
Unsupported .NET Framework, please update to 4.6.2 or later.=サポートしていないの .NET Framework、4.6.2 以降のバンジョーを利用して下さい。
|
Unsupported .NET Framework, please update to 4.6.2 or later.=お使いの .NET Framework はサポートされていません。4.6.2 以降のバンジョーをインストールして下さい。
|
||||||
Proxy request failed=代理要求が失敗した。
|
Proxy request failed=プロキシ要求が失敗しました。
|
||||||
Proxy handshake failed=代理の握手に失敗しました
|
Proxy handshake failed=プロキシ ハンドシェイクに失敗しました。
|
||||||
Register hotkey failed=ホットキーの登錄に失敗しました
|
Register hotkey failed=ホットキーの登錄に失敗しました。
|
||||||
Cannot parse hotkey: {0}=ホットキーを解析できません: {0}
|
Cannot parse hotkey: {0}=ホットキーを解析できません: {0}
|
||||||
Timeout is invalid, it should not exceed {0}=タイムアウトが無効であるか、それを超えてはならない {0}
|
Timeout is invalid, it should not exceed {0}=タイムアウト値が無効です。{0} 以下の値を指定して下さい。
|
||||||
|
|||||||
Binary file not shown.
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Cyotek.Collections.Generic;
|
using Shadowsocks.Encryption.CircularBuffer;
|
||||||
using Shadowsocks.Controller;
|
using Shadowsocks.Controller;
|
||||||
using Shadowsocks.Encryption.Exception;
|
using Shadowsocks.Encryption.Exception;
|
||||||
using Shadowsocks.Encryption.Stream;
|
using Shadowsocks.Encryption.Stream;
|
||||||
@@ -18,11 +18,11 @@ namespace Shadowsocks.Encryption.AEAD
|
|||||||
private static readonly byte[] InfoBytes = Encoding.ASCII.GetBytes(Info);
|
private static readonly byte[] InfoBytes = Encoding.ASCII.GetBytes(Info);
|
||||||
|
|
||||||
// for UDP only
|
// for UDP only
|
||||||
protected static byte[] _udpTmpBuf = new byte[MAX_INPUT_SIZE];
|
protected static byte[] _udpTmpBuf = new byte[65536];
|
||||||
|
|
||||||
// every connection should create its own buffer
|
// every connection should create its own buffer
|
||||||
private CircularBuffer<byte> _encCircularBuffer = new CircularBuffer<byte>(MAX_INPUT_SIZE * 2, false);
|
private ByteCircularBuffer _encCircularBuffer = new ByteCircularBuffer(MAX_INPUT_SIZE * 2);
|
||||||
private CircularBuffer<byte> _decCircularBuffer = new CircularBuffer<byte>(MAX_INPUT_SIZE * 2, false);
|
private ByteCircularBuffer _decCircularBuffer = new ByteCircularBuffer(MAX_INPUT_SIZE * 2);
|
||||||
|
|
||||||
public const int CHUNK_LEN_BYTES = 2;
|
public const int CHUNK_LEN_BYTES = 2;
|
||||||
public const uint CHUNK_LEN_MASK = 0x3FFFu;
|
public const uint CHUNK_LEN_MASK = 0x3FFFu;
|
||||||
@@ -88,15 +88,15 @@ namespace Shadowsocks.Encryption.AEAD
|
|||||||
byte[] passbuf = Encoding.UTF8.GetBytes(password);
|
byte[] passbuf = Encoding.UTF8.GetBytes(password);
|
||||||
// init master key
|
// init master key
|
||||||
if (_Masterkey == null) _Masterkey = new byte[keyLen];
|
if (_Masterkey == null) _Masterkey = new byte[keyLen];
|
||||||
if (_Masterkey.Length < keyLen) Array.Resize(ref _Masterkey, keyLen);
|
if (_Masterkey.Length != keyLen) Array.Resize(ref _Masterkey, keyLen);
|
||||||
DeriveKey(passbuf, _Masterkey);
|
DeriveKey(passbuf, _Masterkey, keyLen);
|
||||||
// init session key
|
// init session key
|
||||||
if (_sessionKey == null) _sessionKey = new byte[keyLen];
|
if (_sessionKey == null) _sessionKey = new byte[keyLen];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeriveKey(byte[] password, byte[] key)
|
public void DeriveKey(byte[] password, byte[] key, int keylen)
|
||||||
{
|
{
|
||||||
StreamEncryptor.LegacyDeriveKey(password, key);
|
StreamEncryptor.LegacyDeriveKey(password, key, keylen);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeriveSessionKey(byte[] salt, byte[] masterKey, byte[] sessionKey)
|
public void DeriveSessionKey(byte[] salt, byte[] masterKey, byte[] sessionKey)
|
||||||
@@ -254,7 +254,7 @@ namespace Shadowsocks.Encryption.AEAD
|
|||||||
|
|
||||||
// we have enough data to decrypt one chunk
|
// we have enough data to decrypt one chunk
|
||||||
// drop chunk len and its tag from buffer
|
// drop chunk len and its tag from buffer
|
||||||
_decCircularBuffer.Get(CHUNK_LEN_BYTES + tagLen);
|
_decCircularBuffer.Skip(CHUNK_LEN_BYTES + tagLen);
|
||||||
byte[] encChunkBytes = _decCircularBuffer.Get(chunkLen + tagLen);
|
byte[] encChunkBytes = _decCircularBuffer.Get(chunkLen + tagLen);
|
||||||
byte[] decChunkBytes = new byte[chunkLen];
|
byte[] decChunkBytes = new byte[chunkLen];
|
||||||
uint decChunkLen = 0;
|
uint decChunkLen = 0;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace Shadowsocks.Encryption.AEAD
|
|||||||
: AEADEncryptor, IDisposable
|
: AEADEncryptor, IDisposable
|
||||||
{
|
{
|
||||||
private const int CIPHER_CHACHA20IETFPOLY1305 = 1;
|
private const int CIPHER_CHACHA20IETFPOLY1305 = 1;
|
||||||
|
private const int CIPHER_AES256GCM = 2;
|
||||||
|
|
||||||
private byte[] _sodiumEncSubkey;
|
private byte[] _sodiumEncSubkey;
|
||||||
private byte[] _sodiumDecSubkey;
|
private byte[] _sodiumDecSubkey;
|
||||||
@@ -24,6 +25,7 @@ namespace Shadowsocks.Encryption.AEAD
|
|||||||
private static Dictionary<string, EncryptorInfo> _ciphers = new Dictionary<string, EncryptorInfo>
|
private static Dictionary<string, EncryptorInfo> _ciphers = new Dictionary<string, EncryptorInfo>
|
||||||
{
|
{
|
||||||
{"chacha20-ietf-poly1305", new EncryptorInfo(32, 32, 12, 16, CIPHER_CHACHA20IETFPOLY1305)},
|
{"chacha20-ietf-poly1305", new EncryptorInfo(32, 32, 12, 16, CIPHER_CHACHA20IETFPOLY1305)},
|
||||||
|
{"aes-256-gcm", new EncryptorInfo(32, 32, 12, 16, CIPHER_AES256GCM)},
|
||||||
};
|
};
|
||||||
|
|
||||||
public static List<string> SupportedCiphers()
|
public static List<string> SupportedCiphers()
|
||||||
@@ -63,6 +65,13 @@ namespace Shadowsocks.Encryption.AEAD
|
|||||||
null, _encNonce,
|
null, _encNonce,
|
||||||
_sodiumEncSubkey);
|
_sodiumEncSubkey);
|
||||||
break;
|
break;
|
||||||
|
case CIPHER_AES256GCM:
|
||||||
|
ret = Sodium.crypto_aead_aes256gcm_encrypt(ciphertext, ref encClen,
|
||||||
|
plaintext, (ulong)plen,
|
||||||
|
null, 0,
|
||||||
|
null, _encNonce,
|
||||||
|
_sodiumEncSubkey);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new System.Exception("not implemented");
|
throw new System.Exception("not implemented");
|
||||||
}
|
}
|
||||||
@@ -91,6 +100,13 @@ namespace Shadowsocks.Encryption.AEAD
|
|||||||
null, 0,
|
null, 0,
|
||||||
_decNonce, _sodiumDecSubkey);
|
_decNonce, _sodiumDecSubkey);
|
||||||
break;
|
break;
|
||||||
|
case CIPHER_AES256GCM:
|
||||||
|
ret = Sodium.crypto_aead_aes256gcm_decrypt(plaintext, ref decPlen,
|
||||||
|
null,
|
||||||
|
ciphertext, (ulong)clen,
|
||||||
|
null, 0,
|
||||||
|
_decNonce, _sodiumDecSubkey);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new System.Exception("not implemented");
|
throw new System.Exception("not implemented");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,510 @@
|
|||||||
|
#region Original License
|
||||||
|
|
||||||
|
//New BSD License(BSD)
|
||||||
|
//
|
||||||
|
//Copyright(c) 2014-2015 Cyotek Ltd
|
||||||
|
//Copyright(c) 2012, Alex Regueiro
|
||||||
|
//All rights reserved.
|
||||||
|
//
|
||||||
|
//Redistribution and use in source and binary forms, with or without
|
||||||
|
//modification, are permitted provided that the following conditions are met:
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer in the
|
||||||
|
// documentation and/or other materials provided with the distribution.
|
||||||
|
// * Neither the name of Cyotek nor the
|
||||||
|
// names of its contributors may be used to endorse or promote products
|
||||||
|
// derived from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
//DISCLAIMED.IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||||
|
//DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
//(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
//ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
//(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Shadowsocks.Encryption.CircularBuffer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a first-in, first-out collection of objects using a fixed buffer.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>The capacity of a <see cref="ByteCircularBuffer" /> is the number of elements the <see cref="ByteCircularBuffer"/> can hold. </para>
|
||||||
|
/// <para>ByteCircularBuffer accepts <c>null</c> as a valid value for reference types and allows duplicate elements.</para>
|
||||||
|
/// <para>The <see cref="Get()"/> methods will remove the items that are returned from the ByteCircularBuffer. To view the contents of the ByteCircularBuffer without removing items, use the <see cref="Peek()"/> or <see cref="PeekLast"/> methods.</para>
|
||||||
|
/// </remarks>
|
||||||
|
public class ByteCircularBuffer
|
||||||
|
{
|
||||||
|
// based on http://circularbuffer.codeplex.com/
|
||||||
|
// http://en.wikipedia.org/wiki/Circular_buffer
|
||||||
|
// modified from https://github.com/cyotek/Cyotek.Collections.Generic.CircularBuffer
|
||||||
|
// some code taken from https://github.com/xorxornop/RingBuffer
|
||||||
|
// and https://github.com/xorxornop/PerfCopy
|
||||||
|
|
||||||
|
#region Instance Fields
|
||||||
|
|
||||||
|
private byte[] _buffer;
|
||||||
|
|
||||||
|
private int _capacity;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Constructors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ByteCircularBuffer"/> class that is empty and has the specified initial capacity.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="capacity">The maximum capcity of the buffer.</param>
|
||||||
|
/// <exception cref="System.ArgumentException">Thown if the <paramref name="capacity"/> is less than zero.</exception>
|
||||||
|
public ByteCircularBuffer(int capacity)
|
||||||
|
{
|
||||||
|
if (capacity < 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("The buffer capacity must be greater than or equal to zero.",
|
||||||
|
nameof(capacity));
|
||||||
|
}
|
||||||
|
|
||||||
|
_buffer = new byte[capacity];
|
||||||
|
this.Capacity = capacity;
|
||||||
|
this.Size = 0;
|
||||||
|
this.Head = 0;
|
||||||
|
this.Tail = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Properties
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the total number of elements the internal data structure can hold.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The total number of elements that the <see cref="ByteCircularBuffer"/> can contain.</value>
|
||||||
|
/// <exception cref="System.ArgumentOutOfRangeException">Thrown if the specified new capacity is smaller than the current contents of the buffer.</exception>
|
||||||
|
public int Capacity
|
||||||
|
{
|
||||||
|
get { return _capacity; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _capacity)
|
||||||
|
{
|
||||||
|
if (value < this.Size)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(value), value,
|
||||||
|
"The new capacity must be greater than or equal to the buffer size.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var newBuffer = new byte[value];
|
||||||
|
if (this.Size > 0)
|
||||||
|
{
|
||||||
|
this.CopyTo(newBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
_buffer = newBuffer;
|
||||||
|
|
||||||
|
_capacity = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the index of the beginning of the buffer data.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The index of the first element in the buffer.</value>
|
||||||
|
public int Head { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the buffer is empty.
|
||||||
|
/// </summary>
|
||||||
|
/// <value><c>true</c> if buffer is empty; otherwise, <c>false</c>.</value>
|
||||||
|
public virtual bool IsEmpty => this.Size == 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the buffer is full.
|
||||||
|
/// </summary>
|
||||||
|
/// <value><c>true</c> if the buffer is full; otherwise, <c>false</c>.</value>
|
||||||
|
/// <remarks>The <see cref="IsFull"/> property always returns <c>false</c> if the <see cref="AllowOverwrite"/> property is set to <c>true</c>.</remarks>
|
||||||
|
public virtual bool IsFull => this.Size == this.Capacity;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of elements contained in the <see cref="ByteCircularBuffer"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The number of elements contained in the <see cref="ByteCircularBuffer"/>.</value>
|
||||||
|
public int Size { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the index of the end of the buffer data.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The index of the last element in the buffer.</value>
|
||||||
|
public int Tail { get; protected set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes all items from the <see cref="ByteCircularBuffer" />.
|
||||||
|
/// </summary>
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
this.Size = 0;
|
||||||
|
this.Head = 0;
|
||||||
|
this.Tail = 0;
|
||||||
|
_buffer = new byte[this.Capacity];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the <see cref="ByteCircularBuffer" /> contains a specific value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The object to locate in the <see cref="ByteCircularBuffer" />.</param>
|
||||||
|
/// <returns><c>true</c> if <paramref name="item" /> is found in the <see cref="ByteCircularBuffer" />; otherwise, <c>false</c>.</returns>
|
||||||
|
public bool Contains(byte item)
|
||||||
|
{
|
||||||
|
var bufferIndex = this.Head;
|
||||||
|
var comparer = EqualityComparer<byte>.Default;
|
||||||
|
var result = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < this.Size; i++, bufferIndex++)
|
||||||
|
{
|
||||||
|
if (bufferIndex == this.Capacity)
|
||||||
|
{
|
||||||
|
bufferIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comparer.Equals(_buffer[bufferIndex], item))
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies the entire <see cref="ByteCircularBuffer"/> to a compatible one-dimensional array, starting at the beginning of the target array.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="array">The one-dimensional <see cref="Array"/> that is the destination of the elements copied from <see cref="ByteCircularBuffer"/>. The <see cref="Array"/> must have zero-based indexing.</param>
|
||||||
|
public void CopyTo(byte[] array)
|
||||||
|
{
|
||||||
|
this.CopyTo(array, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies the entire <see cref="ByteCircularBuffer"/> to a compatible one-dimensional array, starting at the specified index of the target array.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="array">The one-dimensional <see cref="Array"/> that is the destination of the elements copied from <see cref="ByteCircularBuffer"/>. The <see cref="Array"/> must have zero-based indexing.</param>
|
||||||
|
/// <param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||||
|
public void CopyTo(byte[] array, int arrayIndex)
|
||||||
|
{
|
||||||
|
this.CopyTo(this.Head, array, arrayIndex, Math.Min(this.Size, array.Length - arrayIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies a range of elements from the <see cref="ByteCircularBuffer"/> to a compatible one-dimensional array, starting at the specified index of the target array.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The zero-based index in the source <see cref="ByteCircularBuffer"/> at which copying begins.</param>
|
||||||
|
/// <param name="array">The one-dimensional <see cref="Array"/> that is the destination of the elements copied from <see cref="ByteCircularBuffer"/>. The <see cref="Array"/> must have zero-based indexing.</param>
|
||||||
|
/// <param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||||
|
/// <param name="count">The number of elements to copy.</param>
|
||||||
|
public virtual void CopyTo(int index, byte[] array, int arrayIndex, int count)
|
||||||
|
{
|
||||||
|
if (count > this.Size)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(count), count,
|
||||||
|
"The read count cannot be greater than the buffer size.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var startAnchor = index;
|
||||||
|
var dstIndex = arrayIndex;
|
||||||
|
|
||||||
|
while (count > 0)
|
||||||
|
{
|
||||||
|
int chunk = Math.Min(Capacity - startAnchor, count);
|
||||||
|
Buffer.BlockCopy(_buffer, startAnchor, array, dstIndex, chunk);
|
||||||
|
startAnchor = (startAnchor + chunk == Capacity) ? 0 : startAnchor + chunk;
|
||||||
|
dstIndex += chunk;
|
||||||
|
count -= chunk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes and returns the specified number of objects from the beginning of the <see cref="ByteCircularBuffer"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="count">The number of elements to remove and return from the <see cref="ByteCircularBuffer"/>.</param>
|
||||||
|
/// <returns>The objects that are removed from the beginning of the <see cref="ByteCircularBuffer"/>.</returns>
|
||||||
|
public byte[] Get(int count)
|
||||||
|
{
|
||||||
|
if (count <= 0) throw new ArgumentOutOfRangeException("should greater than 0");
|
||||||
|
var result = new byte[count];
|
||||||
|
|
||||||
|
this.Get(result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies and removes the specified number elements from the <see cref="ByteCircularBuffer"/> to a compatible one-dimensional array, starting at the beginning of the target array.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="array">The one-dimensional <see cref="Array"/> that is the destination of the elements copied from <see cref="ByteCircularBuffer"/>. The <see cref="Array"/> must have zero-based indexing.</param>
|
||||||
|
/// <returns>The actual number of elements copied into <paramref name="array"/>.</returns>
|
||||||
|
public int Get(byte[] array)
|
||||||
|
{
|
||||||
|
if (array.Length <= 0) throw new ArgumentOutOfRangeException("should greater than 0");
|
||||||
|
return this.Get(array, 0, array.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies and removes the specified number elements from the <see cref="ByteCircularBuffer"/> to a compatible one-dimensional array, starting at the specified index of the target array.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="array">The one-dimensional <see cref="Array"/> that is the destination of the elements copied from <see cref="ByteCircularBuffer"/>. The <see cref="Array"/> must have zero-based indexing.</param>
|
||||||
|
/// <param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||||
|
/// <param name="count">The number of elements to copy.</param>
|
||||||
|
/// <returns>The actual number of elements copied into <paramref name="array"/>.</returns>
|
||||||
|
public virtual int Get(byte[] array, int arrayIndex, int count)
|
||||||
|
{
|
||||||
|
if (arrayIndex < 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(arrayIndex), "Negative offset specified. Offsets must be positive.");
|
||||||
|
}
|
||||||
|
if (count < 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(count), "Negative count specified. Count must be positive.");
|
||||||
|
}
|
||||||
|
if (count > this.Size)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Ringbuffer contents insufficient for take/read operation.", nameof(count));
|
||||||
|
}
|
||||||
|
if (array.Length < arrayIndex + count)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Destination array too small for requested output.");
|
||||||
|
}
|
||||||
|
var bytesCopied = 0;
|
||||||
|
var dstIndex = arrayIndex;
|
||||||
|
while (count > 0)
|
||||||
|
{
|
||||||
|
int chunk = Math.Min(Capacity - this.Head, count);
|
||||||
|
Buffer.BlockCopy(_buffer, this.Head, array, dstIndex, chunk);
|
||||||
|
this.Head = (this.Head + chunk == Capacity) ? 0 : this.Head + chunk;
|
||||||
|
this.Size -= chunk;
|
||||||
|
dstIndex += chunk;
|
||||||
|
bytesCopied += chunk;
|
||||||
|
count -= chunk;
|
||||||
|
}
|
||||||
|
return bytesCopied;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes and returns the object at the beginning of the <see cref="ByteCircularBuffer"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The object that is removed from the beginning of the <see cref="ByteCircularBuffer"/>.</returns>
|
||||||
|
/// <exception cref="System.InvalidOperationException">Thrown if the buffer is empty.</exception>
|
||||||
|
/// <remarks>This method is similar to the <see cref="Peek()"/> method, but <c>Peek</c> does not modify the <see cref="ByteCircularBuffer"/>.</remarks>
|
||||||
|
public virtual byte Get()
|
||||||
|
{
|
||||||
|
if (this.IsEmpty)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("The buffer is empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = _buffer[this.Head];
|
||||||
|
if (++this.Head == this.Capacity)
|
||||||
|
{
|
||||||
|
this.Head = 0;
|
||||||
|
}
|
||||||
|
this.Size--;
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the object at the beginning of the <see cref="ByteCircularBuffer"/> without removing it.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The object at the beginning of the <see cref="ByteCircularBuffer"/>.</returns>
|
||||||
|
/// <exception cref="System.InvalidOperationException">Thrown if the buffer is empty.</exception>
|
||||||
|
public virtual byte Peek()
|
||||||
|
{
|
||||||
|
if (this.IsEmpty)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("The buffer is empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = _buffer[this.Head];
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the specified number of objects from the beginning of the <see cref="ByteCircularBuffer"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="count">The number of elements to return from the <see cref="ByteCircularBuffer"/>.</param>
|
||||||
|
/// <returns>The objects that from the beginning of the <see cref="ByteCircularBuffer"/>.</returns>
|
||||||
|
/// <exception cref="System.InvalidOperationException">Thrown if the buffer is empty.</exception>
|
||||||
|
public virtual byte[] Peek(int count)
|
||||||
|
{
|
||||||
|
if (this.IsEmpty)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("The buffer is empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = new byte[count];
|
||||||
|
this.CopyTo(items);
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the object at the end of the <see cref="ByteCircularBuffer"/> without removing it.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The object at the end of the <see cref="ByteCircularBuffer"/>.</returns>
|
||||||
|
/// <exception cref="System.InvalidOperationException">Thrown if the buffer is empty.</exception>
|
||||||
|
public virtual byte PeekLast()
|
||||||
|
{
|
||||||
|
int bufferIndex;
|
||||||
|
|
||||||
|
if (this.IsEmpty)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("The buffer is empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.Tail == 0)
|
||||||
|
{
|
||||||
|
bufferIndex = this.Size - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bufferIndex = this.Tail - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = _buffer[bufferIndex];
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies an entire compatible one-dimensional array to the <see cref="ByteCircularBuffer"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="array">The one-dimensional <see cref="Array"/> that is the source of the elements copied to <see cref="ByteCircularBuffer"/>. The <see cref="Array"/> must have zero-based indexing.</param>
|
||||||
|
/// <exception cref="System.InvalidOperationException">Thrown if buffer does not have sufficient capacity to put in new items.</exception>
|
||||||
|
/// <remarks>If <see cref="Size"/> plus the size of <paramref name="array"/> exceeds the capacity of the <see cref="ByteCircularBuffer"/> and the <see cref="AllowOverwrite"/> property is <c>true</c>, the oldest items in the <see cref="ByteCircularBuffer"/> are overwritten with <paramref name="array"/>.</remarks>
|
||||||
|
public int Put(byte[] array)
|
||||||
|
{
|
||||||
|
return this.Put(array, 0, array.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies a range of elements from a compatible one-dimensional array to the <see cref="ByteCircularBuffer"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="array">The one-dimensional <see cref="Array"/> that is the source of the elements copied to <see cref="ByteCircularBuffer"/>. The <see cref="Array"/> must have zero-based indexing.</param>
|
||||||
|
/// <param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||||
|
/// <param name="count">The number of elements to copy.</param>
|
||||||
|
/// <exception cref="System.InvalidOperationException">Thrown if buffer does not have sufficient capacity to put in new items.</exception>
|
||||||
|
/// <remarks>If <see cref="Size"/> plus <paramref name="count"/> exceeds the capacity of the <see cref="ByteCircularBuffer"/> and the <see cref="AllowOverwrite"/> property is <c>true</c>, the oldest items in the <see cref="ByteCircularBuffer"/> are overwritten with <paramref name="array"/>.</remarks>
|
||||||
|
public virtual int Put(byte[] array, int arrayIndex, int count)
|
||||||
|
{
|
||||||
|
if (count <= 0) throw new ArgumentOutOfRangeException(nameof(count), "Count must be positive.");
|
||||||
|
if (this.Size + count > this.Capacity)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("The buffer does not have sufficient capacity to put new items.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array.Length < arrayIndex + count)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Source array too small for requested input.");
|
||||||
|
}
|
||||||
|
var srcIndex = arrayIndex;
|
||||||
|
var bytesToProcess = count;
|
||||||
|
while (bytesToProcess > 0)
|
||||||
|
{
|
||||||
|
int chunk = Math.Min(Capacity - Tail, bytesToProcess);
|
||||||
|
Buffer.BlockCopy(array, srcIndex, _buffer, Tail, chunk);
|
||||||
|
Tail = (Tail + chunk == Capacity) ? 0 : Tail + chunk;
|
||||||
|
this.Size += chunk;
|
||||||
|
srcIndex += chunk;
|
||||||
|
bytesToProcess -= chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a byte to the end of the <see cref="ByteCircularBuffer"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The byte to add to the <see cref="ByteCircularBuffer"/>. </param>
|
||||||
|
/// <exception cref="System.InvalidOperationException">Thrown if buffer does not have sufficient capacity to put in new items.</exception>
|
||||||
|
public virtual void Put(byte item)
|
||||||
|
{
|
||||||
|
if (IsFull)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("The buffer does not have sufficient capacity to put new items.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_buffer[this.Tail] = item;
|
||||||
|
|
||||||
|
this.Tail++;
|
||||||
|
if (this.Size == this.Capacity)
|
||||||
|
{
|
||||||
|
this.Head++;
|
||||||
|
if (this.Head >= this.Capacity)
|
||||||
|
{
|
||||||
|
this.Head -= this.Capacity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.Tail == this.Capacity)
|
||||||
|
{
|
||||||
|
this.Tail = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.Size != this.Capacity)
|
||||||
|
{
|
||||||
|
this.Size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Increments the starting index of the data buffer in the <see cref="ByteCircularBuffer"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="count">The number of elements to increment the data buffer start index by.</param>
|
||||||
|
public void Skip(int count)
|
||||||
|
{
|
||||||
|
if (count < 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(count), "Negative count specified. Count must be positive.");
|
||||||
|
}
|
||||||
|
if (count > this.Size)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Ringbuffer contents insufficient for operation.", nameof(count));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modular division gives new offset position
|
||||||
|
this.Head = (this.Head + count) % Capacity;
|
||||||
|
this.Size -= count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies the <see cref="ByteCircularBuffer"/> elements to a new array.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A new array containing elements copied from the <see cref="ByteCircularBuffer"/>.</returns>
|
||||||
|
/// <remarks>The <see cref="ByteCircularBuffer"/> is not modified. The order of the elements in the new array is the same as the order of the elements from the beginning of the <see cref="ByteCircularBuffer"/> to its end.</remarks>
|
||||||
|
public byte[] ToArray()
|
||||||
|
{
|
||||||
|
var result = new byte[this.Size];
|
||||||
|
|
||||||
|
this.CopyTo(result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -71,6 +71,8 @@
|
|||||||
public const int ATYP_DOMAIN = 0x03;
|
public const int ATYP_DOMAIN = 0x03;
|
||||||
public const int ATYP_IPv6 = 0x04;
|
public const int ATYP_IPv6 = 0x04;
|
||||||
|
|
||||||
|
public const int MD5_LEN = 16;
|
||||||
|
|
||||||
protected EncryptorBase(string method, string password)
|
protected EncryptorBase(string method, string password)
|
||||||
{
|
{
|
||||||
Method = method;
|
Method = method;
|
||||||
|
|||||||
@@ -14,6 +14,18 @@ namespace Shadowsocks.Encryption
|
|||||||
|
|
||||||
static EncryptorFactory()
|
static EncryptorFactory()
|
||||||
{
|
{
|
||||||
|
var AEADMbedTLSEncryptorSupportedCiphers = AEADMbedTLSEncryptor.SupportedCiphers();
|
||||||
|
var AEADSodiumEncryptorSupportedCiphers = AEADSodiumEncryptor.SupportedCiphers();
|
||||||
|
if (Sodium.AES256GCMAvailable)
|
||||||
|
{
|
||||||
|
// prefer to aes-256-gcm in libsodium
|
||||||
|
AEADMbedTLSEncryptorSupportedCiphers.Remove("aes-256-gcm");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AEADSodiumEncryptorSupportedCiphers.Remove("aes-256-gcm");
|
||||||
|
}
|
||||||
|
|
||||||
foreach (string method in StreamMbedTLSEncryptor.SupportedCiphers())
|
foreach (string method in StreamMbedTLSEncryptor.SupportedCiphers())
|
||||||
{
|
{
|
||||||
_registeredEncryptors.Add(method, typeof(StreamMbedTLSEncryptor));
|
_registeredEncryptors.Add(method, typeof(StreamMbedTLSEncryptor));
|
||||||
@@ -22,11 +34,11 @@ namespace Shadowsocks.Encryption
|
|||||||
{
|
{
|
||||||
_registeredEncryptors.Add(method, typeof(StreamSodiumEncryptor));
|
_registeredEncryptors.Add(method, typeof(StreamSodiumEncryptor));
|
||||||
}
|
}
|
||||||
foreach (string method in AEADMbedTLSEncryptor.SupportedCiphers())
|
foreach (string method in AEADMbedTLSEncryptorSupportedCiphers)
|
||||||
{
|
{
|
||||||
_registeredEncryptors.Add(method, typeof(AEADMbedTLSEncryptor));
|
_registeredEncryptors.Add(method, typeof(AEADMbedTLSEncryptor));
|
||||||
}
|
}
|
||||||
foreach (string method in AEADSodiumEncryptor.SupportedCiphers())
|
foreach (string method in AEADSodiumEncryptorSupportedCiphers)
|
||||||
{
|
{
|
||||||
_registeredEncryptors.Add(method, typeof(AEADSodiumEncryptor));
|
_registeredEncryptors.Add(method, typeof(AEADSodiumEncryptor));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ namespace Shadowsocks.Encryption
|
|||||||
private static bool _initialized = false;
|
private static bool _initialized = false;
|
||||||
private static readonly object _initLock = new object();
|
private static readonly object _initLock = new object();
|
||||||
|
|
||||||
|
public static bool AES256GCMAvailable { get; private set; } = false;
|
||||||
|
|
||||||
static Sodium()
|
static Sodium()
|
||||||
{
|
{
|
||||||
string dllPath = Utils.GetTempPath(DLLNAME);
|
string dllPath = Utils.GetTempPath(DLLNAME);
|
||||||
@@ -42,6 +44,9 @@ namespace Shadowsocks.Encryption
|
|||||||
{
|
{
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AES256GCMAvailable = crypto_aead_aes256gcm_is_available() == 1;
|
||||||
|
Logging.Debug($"sodium: AES256GCMAvailable is {AES256GCMAvailable}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,6 +57,9 @@ namespace Shadowsocks.Encryption
|
|||||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern int sodium_init();
|
private static extern int sodium_init();
|
||||||
|
|
||||||
|
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
private static extern int crypto_aead_aes256gcm_is_available();
|
||||||
|
|
||||||
#region AEAD
|
#region AEAD
|
||||||
|
|
||||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||||
@@ -65,6 +73,14 @@ namespace Shadowsocks.Encryption
|
|||||||
public static extern int crypto_aead_chacha20poly1305_ietf_decrypt(byte[] m, ref ulong mlen_p,
|
public static extern int crypto_aead_chacha20poly1305_ietf_decrypt(byte[] m, ref ulong mlen_p,
|
||||||
byte[] nsec, byte[] c, ulong clen, byte[] ad, ulong adlen, byte[] npub, byte[] k);
|
byte[] nsec, byte[] c, ulong clen, byte[] ad, ulong adlen, byte[] npub, byte[] k);
|
||||||
|
|
||||||
|
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int crypto_aead_aes256gcm_encrypt(byte[] c, ref ulong clen_p, byte[] m, ulong mlen,
|
||||||
|
byte[] ad, ulong adlen, byte[] nsec, byte[] npub, byte[] k);
|
||||||
|
|
||||||
|
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int crypto_aead_aes256gcm_decrypt(byte[] m, ref ulong mlen_p, byte[] nsec, byte[] c,
|
||||||
|
ulong clen, byte[] ad, ulong adlen, byte[] npub, byte[] k);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Stream
|
#region Stream
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Cyotek.Collections.Generic;
|
using Shadowsocks.Encryption.CircularBuffer;
|
||||||
using Shadowsocks.Controller;
|
using Shadowsocks.Controller;
|
||||||
|
|
||||||
namespace Shadowsocks.Encryption.Stream
|
namespace Shadowsocks.Encryption.Stream
|
||||||
@@ -11,11 +11,11 @@ namespace Shadowsocks.Encryption.Stream
|
|||||||
: EncryptorBase
|
: EncryptorBase
|
||||||
{
|
{
|
||||||
// for UDP only
|
// for UDP only
|
||||||
protected static byte[] _udpTmpBuf = new byte[MAX_INPUT_SIZE];
|
protected static byte[] _udpTmpBuf = new byte[65536];
|
||||||
|
|
||||||
// every connection should create its own buffer
|
// every connection should create its own buffer
|
||||||
private CircularBuffer<byte> _encCircularBuffer = new CircularBuffer<byte>(TCPHandler.BufferSize * 2, false);
|
private ByteCircularBuffer _encCircularBuffer = new ByteCircularBuffer(TCPHandler.BufferSize * 2);
|
||||||
private CircularBuffer<byte> _decCircularBuffer = new CircularBuffer<byte>(TCPHandler.BufferSize * 2, false);
|
private ByteCircularBuffer _decCircularBuffer = new ByteCircularBuffer(TCPHandler.BufferSize * 2);
|
||||||
|
|
||||||
protected Dictionary<string, EncryptorInfo> ciphers;
|
protected Dictionary<string, EncryptorInfo> ciphers;
|
||||||
|
|
||||||
@@ -64,25 +64,25 @@ namespace Shadowsocks.Encryption.Stream
|
|||||||
{
|
{
|
||||||
byte[] passbuf = Encoding.UTF8.GetBytes(password);
|
byte[] passbuf = Encoding.UTF8.GetBytes(password);
|
||||||
if (_key == null) _key = new byte[keyLen];
|
if (_key == null) _key = new byte[keyLen];
|
||||||
if (_key.Length < keyLen) Array.Resize(ref _key, keyLen);
|
if (_key.Length != keyLen) Array.Resize(ref _key, keyLen);
|
||||||
LegacyDeriveKey(passbuf, _key);
|
LegacyDeriveKey(passbuf, _key, keyLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LegacyDeriveKey(byte[] password, byte[] key)
|
public static void LegacyDeriveKey(byte[] password, byte[] key, int keylen)
|
||||||
{
|
{
|
||||||
byte[] result = new byte[password.Length + 16];
|
byte[] result = new byte[password.Length + MD5_LEN];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
byte[] md5sum = null;
|
byte[] md5sum = null;
|
||||||
while (i < key.Length) {
|
while (i < keylen) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
md5sum = MbedTLS.MD5(password);
|
md5sum = MbedTLS.MD5(password);
|
||||||
} else {
|
} else {
|
||||||
md5sum.CopyTo(result, 0);
|
Array.Copy(md5sum, 0, result, 0, MD5_LEN);
|
||||||
password.CopyTo(result, md5sum.Length);
|
Array.Copy(password, 0, result, MD5_LEN, password.Length);
|
||||||
md5sum = MbedTLS.MD5(result);
|
md5sum = MbedTLS.MD5(result);
|
||||||
}
|
}
|
||||||
md5sum.CopyTo(key, i);
|
Array.Copy(md5sum, 0, key, i, Math.Min(MD5_LEN, keylen - i));
|
||||||
i += md5sum.Length;
|
i += MD5_LEN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +143,8 @@ namespace Shadowsocks.Encryption.Stream
|
|||||||
}
|
}
|
||||||
byte[] cipher = _decCircularBuffer.ToArray();
|
byte[] cipher = _decCircularBuffer.ToArray();
|
||||||
cipherUpdate(false, cipher.Length, cipher, outbuf);
|
cipherUpdate(false, cipher.Length, cipher, outbuf);
|
||||||
_decCircularBuffer.Clear();
|
// move pointer only
|
||||||
|
_decCircularBuffer.Skip(_decCircularBuffer.Size);
|
||||||
outlength = cipher.Length;
|
outlength = cipher.Length;
|
||||||
// done the decryption
|
// done the decryption
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Weavers>
|
<Weavers>
|
||||||
<Caseless StringComparison="Ordinal"/>
|
<Caseless StringComparison="Ordinal" />
|
||||||
<Costura/>
|
<Costura />
|
||||||
</Weavers>
|
</Weavers>
|
||||||
@@ -89,7 +89,10 @@ namespace Shadowsocks.Model
|
|||||||
configs = new List<Server>()
|
configs = new List<Server>()
|
||||||
{
|
{
|
||||||
GetDefaultServer()
|
GetDefaultServer()
|
||||||
}
|
},
|
||||||
|
logViewer = new LogViewerConfig(),
|
||||||
|
proxy = new ProxyConfig(),
|
||||||
|
hotkey = new HotkeyConfig()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
@@ -10,9 +11,8 @@ namespace Shadowsocks.Model
|
|||||||
public class Server
|
public class Server
|
||||||
{
|
{
|
||||||
public static readonly Regex
|
public static readonly Regex
|
||||||
UrlFinder = new Regex("^(?i)ss://([A-Za-z0-9+-/=_]+)(#(.+))?$", RegexOptions.IgnoreCase),
|
UrlFinder = new Regex(@"ss://(?<base64>[A-Za-z0-9+-/=_]+)(?:#(?<tag>\S+))?", RegexOptions.IgnoreCase),
|
||||||
DetailsParser = new Regex("^((?<method>.+?):(?<password>.*)@(?<hostname>.+?)" +
|
DetailsParser = new Regex(@"^((?<method>.+?):(?<password>.*)@(?<hostname>.+?):(?<port>\d+?))$", RegexOptions.IgnoreCase);
|
||||||
":(?<port>\\d+?))$", RegexOptions.IgnoreCase);
|
|
||||||
|
|
||||||
private const int DefaultServerTimeoutSec = 5;
|
private const int DefaultServerTimeoutSec = 5;
|
||||||
public const int MaxServerTimeoutSec = 20;
|
public const int MaxServerTimeoutSec = 20;
|
||||||
@@ -43,9 +43,10 @@ namespace Shadowsocks.Model
|
|||||||
}
|
}
|
||||||
string serverStr;
|
string serverStr;
|
||||||
// CheckHostName() won't do a real DNS lookup
|
// CheckHostName() won't do a real DNS lookup
|
||||||
var hostType = Uri.CheckHostName( server );
|
var hostType = Uri.CheckHostName(server);
|
||||||
|
|
||||||
switch ( hostType ) {
|
switch (hostType)
|
||||||
|
{
|
||||||
case UriHostNameType.IPv6:
|
case UriHostNameType.IPv6:
|
||||||
serverStr = $"[{server}]:{server_port}";
|
serverStr = $"[{server}]:{server_port}";
|
||||||
break;
|
break;
|
||||||
@@ -69,20 +70,32 @@ namespace Shadowsocks.Model
|
|||||||
timeout = DefaultServerTimeoutSec;
|
timeout = DefaultServerTimeoutSec;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Server(string ssURL) : this()
|
public static List<Server> GetServers(string ssURL)
|
||||||
{
|
{
|
||||||
var match = UrlFinder.Match(ssURL);
|
var matches = UrlFinder.Matches(ssURL);
|
||||||
if (!match.Success) throw new FormatException();
|
if (matches.Count <= 0) return null;
|
||||||
var base64 = match.Groups[1].Value;
|
List<Server> servers = new List<Server>();
|
||||||
var tag = match.Groups[3].Value;
|
foreach (Match match in matches)
|
||||||
if (!tag.IsNullOrEmpty())
|
{
|
||||||
remarks = HttpUtility.UrlDecode(tag, Encoding.UTF8);
|
Server tmp = new Server();
|
||||||
match = DetailsParser.Match(Encoding.UTF8.GetString(Convert.FromBase64String(
|
var base64 = match.Groups["base64"].Value;
|
||||||
base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '='))));
|
var tag = match.Groups["tag"].Value;
|
||||||
method = match.Groups["method"].Value;
|
if (!tag.IsNullOrEmpty())
|
||||||
password = match.Groups["password"].Value;
|
{
|
||||||
server = match.Groups["hostname"].Value;
|
tmp.remarks = HttpUtility.UrlDecode(tag, Encoding.UTF8);
|
||||||
server_port = int.Parse(match.Groups["port"].Value);
|
}
|
||||||
|
Match details = DetailsParser.Match(Encoding.UTF8.GetString(Convert.FromBase64String(
|
||||||
|
base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '='))));
|
||||||
|
if (!details.Success)
|
||||||
|
continue;
|
||||||
|
tmp.method = details.Groups["method"].Value;
|
||||||
|
tmp.password = details.Groups["password"].Value;
|
||||||
|
tmp.server = details.Groups["hostname"].Value;
|
||||||
|
tmp.server_port = int.Parse(details.Groups["port"].Value);
|
||||||
|
|
||||||
|
servers.Add(tmp);
|
||||||
|
}
|
||||||
|
return servers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Identifier()
|
public string Identifier()
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Shadowsocks.Model
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Data come from WinINET
|
||||||
|
*/
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class SysproxyConfig
|
||||||
|
{
|
||||||
|
public bool UserSettingsRecorded;
|
||||||
|
public string Flags;
|
||||||
|
public string ProxyServer;
|
||||||
|
public string BypassList;
|
||||||
|
public string PacUrl;
|
||||||
|
|
||||||
|
public SysproxyConfig()
|
||||||
|
{
|
||||||
|
UserSettingsRecorded = false;
|
||||||
|
Flags = "1";
|
||||||
|
ProxyServer = "";
|
||||||
|
BypassList = "";
|
||||||
|
PacUrl = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,7 +42,10 @@ namespace Shadowsocks.Util.Sockets
|
|||||||
arg.Completed += OnTcpConnectCompleted;
|
arg.Completed += OnTcpConnectCompleted;
|
||||||
arg.UserToken = new TcpUserToken(callback, state);
|
arg.UserToken = new TcpUserToken(callback, state);
|
||||||
|
|
||||||
Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, arg);
|
if(!Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, arg))
|
||||||
|
{
|
||||||
|
OnTcpConnectCompleted(this, arg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FakeAsyncResult : IAsyncResult
|
private class FakeAsyncResult : IAsyncResult
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
|
||||||
using Shadowsocks.Controller;
|
using Shadowsocks.Controller;
|
||||||
using Shadowsocks.Properties;
|
using Shadowsocks.Properties;
|
||||||
|
using Shadowsocks.Model;
|
||||||
|
using System.Text;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Shadowsocks.Util.SystemProxy
|
namespace Shadowsocks.Util.SystemProxy
|
||||||
{
|
{
|
||||||
public static class Sysproxy
|
public static class Sysproxy
|
||||||
{
|
{
|
||||||
private static bool _userSettingsRecorded = false;
|
private const string _userWininetConfigFile = "user-wininet.json";
|
||||||
|
|
||||||
|
private static string _queryStr;
|
||||||
|
|
||||||
// In general, this won't change
|
// In general, this won't change
|
||||||
// format:
|
// format:
|
||||||
@@ -17,7 +21,7 @@ namespace Shadowsocks.Util.SystemProxy
|
|||||||
// <proxy-server><CR-LF>
|
// <proxy-server><CR-LF>
|
||||||
// <bypass-list><CR-LF>
|
// <bypass-list><CR-LF>
|
||||||
// <pac-url>
|
// <pac-url>
|
||||||
private static string[] _userSettings = new string[4];
|
private static SysproxyConfig _userSettings = null;
|
||||||
|
|
||||||
enum RET_ERRORS : int
|
enum RET_ERRORS : int
|
||||||
{
|
{
|
||||||
@@ -31,8 +35,7 @@ namespace Shadowsocks.Util.SystemProxy
|
|||||||
|
|
||||||
static Sysproxy()
|
static Sysproxy()
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
FileManager.UncompressFile(Utils.GetTempPath("sysproxy.exe"),
|
FileManager.UncompressFile(Utils.GetTempPath("sysproxy.exe"),
|
||||||
Environment.Is64BitOperatingSystem ? Resources.sysproxy64_exe : Resources.sysproxy_exe);
|
Environment.Is64BitOperatingSystem ? Resources.sysproxy64_exe : Resources.sysproxy_exe);
|
||||||
}
|
}
|
||||||
@@ -44,16 +47,16 @@ namespace Shadowsocks.Util.SystemProxy
|
|||||||
|
|
||||||
public static void SetIEProxy(bool enable, bool global, string proxyServer, string pacURL)
|
public static void SetIEProxy(bool enable, bool global, string proxyServer, string pacURL)
|
||||||
{
|
{
|
||||||
string str;
|
Read();
|
||||||
if (_userSettingsRecorded == false)
|
|
||||||
|
if (!_userSettings.UserSettingsRecorded)
|
||||||
{
|
{
|
||||||
// record user settings
|
// record user settings
|
||||||
ExecSysproxy("query", out str);
|
ExecSysproxy("query");
|
||||||
ParseQueryStr(str);
|
ParseQueryStr(_queryStr);
|
||||||
_userSettingsRecorded = true;
|
|
||||||
}
|
}
|
||||||
string arguments;
|
|
||||||
|
|
||||||
|
string arguments;
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
arguments = global
|
arguments = global
|
||||||
@@ -63,20 +66,21 @@ namespace Shadowsocks.Util.SystemProxy
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// restore user settings
|
// restore user settings
|
||||||
var flags = _userSettings[0];
|
var flags = _userSettings.Flags;
|
||||||
var proxy_server = _userSettings[1] ?? "-";
|
var proxy_server = _userSettings.ProxyServer ?? "-";
|
||||||
var bypass_list = _userSettings[2] ?? "-";
|
var bypass_list = _userSettings.BypassList ?? "-";
|
||||||
var pac_url = _userSettings[3] ?? "-";
|
var pac_url = _userSettings.PacUrl ?? "-";
|
||||||
arguments = $"set {flags} {proxy_server} {bypass_list} {pac_url}";
|
arguments = $"set {flags} {proxy_server} {bypass_list} {pac_url}";
|
||||||
|
|
||||||
// have to get new settings
|
// have to get new settings
|
||||||
_userSettingsRecorded = false;
|
_userSettings.UserSettingsRecorded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecSysproxy(arguments, out str);
|
Save();
|
||||||
|
ExecSysproxy(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ExecSysproxy(string arguments, out string queryStr)
|
private static void ExecSysproxy(string arguments)
|
||||||
{
|
{
|
||||||
using (var process = new Process())
|
using (var process = new Process())
|
||||||
{
|
{
|
||||||
@@ -107,24 +111,55 @@ namespace Shadowsocks.Util.SystemProxy
|
|||||||
throw new ProxyException(stderr);
|
throw new ProxyException(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments == "query" && stdout.IsNullOrWhiteSpace())
|
if (arguments == "query") {
|
||||||
{
|
if (stdout.IsNullOrWhiteSpace() || stdout.IsNullOrEmpty()) {
|
||||||
// we cannot get user settings
|
// we cannot get user settings
|
||||||
throw new ProxyException("failed to query wininet settings");
|
throw new ProxyException("failed to query wininet settings");
|
||||||
|
}
|
||||||
|
_queryStr = stdout;
|
||||||
}
|
}
|
||||||
queryStr = stdout;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Save()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
using (StreamWriter sw = new StreamWriter(File.Open(_userWininetConfigFile, FileMode.Create))) {
|
||||||
|
string jsonString = JsonConvert.SerializeObject(_userSettings, Formatting.Indented);
|
||||||
|
sw.Write(jsonString);
|
||||||
|
sw.Flush();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Logging.LogUsefulException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Read()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
string configContent = File.ReadAllText(_userWininetConfigFile);
|
||||||
|
_userSettings = JsonConvert.DeserializeObject<SysproxyConfig>(configContent);
|
||||||
|
} catch(Exception) {
|
||||||
|
// Suppress all exceptions. finally block will initialize new user config settings.
|
||||||
|
} finally {
|
||||||
|
if (_userSettings == null) _userSettings = new SysproxyConfig();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ParseQueryStr(string str)
|
private static void ParseQueryStr(string str)
|
||||||
{
|
{
|
||||||
_userSettings = str.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
|
string[] userSettingsArr = str.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
for (var i = 0; i < 4; i++)
|
_userSettings.Flags = userSettingsArr[0];
|
||||||
{
|
|
||||||
// handle output from WinINET
|
// handle output from WinINET
|
||||||
if (_userSettings[i] == "(null)")
|
if (userSettingsArr[1] == "(null)") _userSettings.ProxyServer = null;
|
||||||
_userSettings[i] = null;
|
else _userSettings.ProxyServer = userSettingsArr[1];
|
||||||
}
|
if (userSettingsArr[2] == "(null)") _userSettings.BypassList = null;
|
||||||
|
else _userSettings.BypassList = userSettingsArr[2];
|
||||||
|
if (userSettingsArr[3] == "(null)") _userSettings.PacUrl = null;
|
||||||
|
else _userSettings.PacUrl = userSettingsArr[3];
|
||||||
|
|
||||||
|
_userSettings.UserSettingsRecorded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Caseless.Fody" version="1.4.2" targetFramework="net462" developmentDependency="true" />
|
<package id="Caseless.Fody" version="1.5.0" targetFramework="net462" developmentDependency="true" />
|
||||||
<package id="Costura.Fody" version="1.3.3.0" targetFramework="net462" developmentDependency="true" />
|
<package id="Costura.Fody" version="1.4.1" targetFramework="net462" developmentDependency="true" />
|
||||||
<package id="Cyotek.CircularBuffer" version="1.0.2" targetFramework="net462" />
|
<package id="Fody" version="2.0.9" targetFramework="net462" developmentDependency="true" />
|
||||||
<package id="Fody" version="1.29.4" targetFramework="net462" developmentDependency="true" />
|
|
||||||
<package id="GlobalHotKey" version="1.1.0" targetFramework="net462" />
|
<package id="GlobalHotKey" version="1.1.0" targetFramework="net462" />
|
||||||
<package id="Newtonsoft.Json" version="10.0.1" targetFramework="net462" />
|
<package id="Newtonsoft.Json" version="10.0.2" targetFramework="net462" />
|
||||||
<package id="StringEx.CS" version="0.3.1" targetFramework="net462" developmentDependency="true" />
|
<package id="StringEx.CS" version="0.3.1" targetFramework="net462" developmentDependency="true" />
|
||||||
<package id="ZXing.Net" version="0.15.0" targetFramework="net462" />
|
<package id="ZXing.Net" version="0.15.0" targetFramework="net462" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -66,9 +66,6 @@
|
|||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Cyotek.Collections.Generic.CircularBuffer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=58daa28b0b2de221, processorArchitecture=MSIL">
|
|
||||||
<HintPath>3rd\Cyotek.CircularBuffer.1.0.2\lib\net20\Cyotek.Collections.Generic.CircularBuffer.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="GlobalHotKey, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="GlobalHotKey, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>3rd\GlobalHotKey.1.1.0\lib\GlobalHotKey.dll</HintPath>
|
<HintPath>3rd\GlobalHotKey.1.1.0\lib\GlobalHotKey.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
@@ -76,7 +73,7 @@
|
|||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="Microsoft.VisualBasic" />
|
<Reference Include="Microsoft.VisualBasic" />
|
||||||
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<HintPath>3rd\Newtonsoft.Json.10.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
<HintPath>3rd\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
@@ -100,6 +97,7 @@
|
|||||||
<Compile Include="Encryption\AEAD\AEADEncryptor.cs" />
|
<Compile Include="Encryption\AEAD\AEADEncryptor.cs" />
|
||||||
<Compile Include="Encryption\AEAD\AEADMbedTLSEncryptor.cs" />
|
<Compile Include="Encryption\AEAD\AEADMbedTLSEncryptor.cs" />
|
||||||
<Compile Include="Encryption\AEAD\AEADSodiumEncryptor.cs" />
|
<Compile Include="Encryption\AEAD\AEADSodiumEncryptor.cs" />
|
||||||
|
<Compile Include="Encryption\CircularBuffer\ByteCircularBuffer.cs" />
|
||||||
<Compile Include="Encryption\EncryptorBase.cs" />
|
<Compile Include="Encryption\EncryptorBase.cs" />
|
||||||
<Compile Include="Encryption\EncryptorFactory.cs" />
|
<Compile Include="Encryption\EncryptorFactory.cs" />
|
||||||
<Compile Include="Encryption\Exception\CryptoException.cs" />
|
<Compile Include="Encryption\Exception\CryptoException.cs" />
|
||||||
@@ -112,6 +110,7 @@
|
|||||||
<Compile Include="Encryption\Stream\StreamSodiumEncryptor.cs" />
|
<Compile Include="Encryption\Stream\StreamSodiumEncryptor.cs" />
|
||||||
<Compile Include="Model\HotKeyConfig.cs" />
|
<Compile Include="Model\HotKeyConfig.cs" />
|
||||||
<Compile Include="Model\ProxyConfig.cs" />
|
<Compile Include="Model\ProxyConfig.cs" />
|
||||||
|
<Compile Include="Model\SysproxyConfig.cs" />
|
||||||
<Compile Include="Properties\Settings.Designer.cs">
|
<Compile Include="Properties\Settings.Designer.cs">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
@@ -266,9 +265,9 @@
|
|||||||
<Content Include="Data\ja.txt" />
|
<Content Include="Data\ja.txt" />
|
||||||
<Content Include="Data\privoxy_conf.txt" />
|
<Content Include="Data\privoxy_conf.txt" />
|
||||||
<Content Include="Data\user-rule.txt" />
|
<Content Include="Data\user-rule.txt" />
|
||||||
<Content Include="FodyWeavers.xml">
|
<None Include="FodyWeavers.xml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Content>
|
</None>
|
||||||
<Content Include="Resources\ssIn24.png" />
|
<Content Include="Resources\ssIn24.png" />
|
||||||
<Content Include="Resources\ssOut24.png" />
|
<Content Include="Resources\ssOut24.png" />
|
||||||
<Content Include="shadowsocks.ico" />
|
<Content Include="shadowsocks.ico" />
|
||||||
@@ -342,12 +341,12 @@ foreach (var item in filesToCleanup)
|
|||||||
<Target Name="CleanReferenceCopyLocalPaths" AfterTargets="AfterBuild;NonWinFodyTarget">
|
<Target Name="CleanReferenceCopyLocalPaths" AfterTargets="AfterBuild;NonWinFodyTarget">
|
||||||
<CosturaCleanup Config="FodyWeavers.xml" Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />
|
<CosturaCleanup Config="FodyWeavers.xml" Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />
|
||||||
</Target>
|
</Target>
|
||||||
<Import Project="3rd\Fody.1.29.4\build\dotnet\Fody.targets" Condition="Exists('3rd\Fody.1.29.4\build\dotnet\Fody.targets')" />
|
<Import Project="3rd\Fody.2.0.9\build\netstandard1.4\Fody.targets" Condition="Exists('3rd\Fody.2.0.9\build\netstandard1.4\Fody.targets')" />
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
|
<ErrorText>此项目引用这台计算机上缺少的 NuGet 程序包。使用 NuGet 程序包还原可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Error Condition="!Exists('3rd\Fody.1.29.4\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '3rd\Fody.1.29.4\build\dotnet\Fody.targets'))" />
|
<Error Condition="!Exists('3rd\Fody.2.0.9\build\netstandard1.4\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '3rd\Fody.2.0.9\build\netstandard1.4\Fody.targets'))" />
|
||||||
</Target>
|
</Target>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|||||||
Reference in New Issue
Block a user