Browse Source

Merge branch 'check-updated' into no-builtin-blob

tags/4.1.9.3-nbbnu
Student Main 5 years ago
parent
commit
07166baea2
43 changed files with 1101 additions and 762 deletions
  1. +6
    -3
      shadowsocks-csharp/Controller/FileManager.cs
  2. +3
    -2
      shadowsocks-csharp/Controller/HotkeyReg.cs
  3. +6
    -3
      shadowsocks-csharp/Controller/I18N.cs
  4. +119
    -0
      shadowsocks-csharp/Controller/LoggerExtension.cs
  5. +0
    -198
      shadowsocks-csharp/Controller/Logging.cs
  6. +23
    -18
      shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs
  7. +5
    -3
      shadowsocks-csharp/Controller/Service/GfwListUpdater.cs
  8. +9
    -10
      shadowsocks-csharp/Controller/Service/Listener.cs
  9. +6
    -3
      shadowsocks-csharp/Controller/Service/PACDaemon.cs
  10. +5
    -2
      shadowsocks-csharp/Controller/Service/PACServer.cs
  11. +13
    -10
      shadowsocks-csharp/Controller/Service/PortForwarder.cs
  12. +7
    -4
      shadowsocks-csharp/Controller/Service/PrivoxyRunner.cs
  13. +41
    -46
      shadowsocks-csharp/Controller/Service/TCPRelay.cs
  14. +6
    -3
      shadowsocks-csharp/Controller/Service/UDPRelay.cs
  15. +11
    -9
      shadowsocks-csharp/Controller/Service/UpdateChecker.cs
  16. +35
    -5
      shadowsocks-csharp/Controller/ShadowsocksController.cs
  17. +10
    -7
      shadowsocks-csharp/Controller/Strategy/HighAvailabilityStrategy.cs
  18. +7
    -5
      shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs
  19. +11
    -8
      shadowsocks-csharp/Controller/System/AutoStartup.cs
  20. +4
    -1
      shadowsocks-csharp/Controller/System/SystemProxy.cs
  21. +13
    -0
      shadowsocks-csharp/Data/NLog.config
  22. +209
    -207
      shadowsocks-csharp/Data/i18n.csv
  23. +20
    -18
      shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs
  24. +11
    -8
      shadowsocks-csharp/Encryption/AEAD/AEADSodiumEncryptor.cs
  25. +3
    -0
      shadowsocks-csharp/Encryption/MbedTLS.cs
  26. +3
    -0
      shadowsocks-csharp/Encryption/OpenSSL.cs
  27. +4
    -1
      shadowsocks-csharp/Encryption/Sodium.cs
  28. +56
    -5
      shadowsocks-csharp/Model/Configuration.cs
  29. +122
    -0
      shadowsocks-csharp/Model/NlogConfig.cs
  30. +5
    -3
      shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs
  31. +15
    -12
      shadowsocks-csharp/Program.cs
  32. +4
    -1
      shadowsocks-csharp/Proxy/HttpProxy.cs
  33. +4
    -1
      shadowsocks-csharp/Util/ProcessManagement/Job.cs
  34. +5
    -2
      shadowsocks-csharp/Util/SystemProxy/Sysproxy.cs
  35. +11
    -9
      shadowsocks-csharp/Util/Util.cs
  36. +123
    -116
      shadowsocks-csharp/View/ConfigForm.Designer.cs
  37. +80
    -2
      shadowsocks-csharp/View/ConfigForm.cs
  38. +35
    -10
      shadowsocks-csharp/View/LogForm.cs
  39. +23
    -24
      shadowsocks-csharp/View/MenuViewController.cs
  40. +1
    -0
      shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs
  41. +1
    -0
      shadowsocks-csharp/packages.config
  42. +15
    -1
      shadowsocks-csharp/shadowsocks-csharp.csproj
  43. +11
    -2
      shadowsocks-windows.sln

+ 6
- 3
shadowsocks-csharp/Controller/FileManager.cs View File

@@ -1,4 +1,5 @@
using System;
using NLog;
using System;
using System.IO;
using System.IO.Compression;
using System.Text;
@@ -7,6 +8,8 @@ namespace Shadowsocks.Controller
{
public static class FileManager
{
private static Logger logger = LogManager.GetCurrentClassLogger();
public static bool ByteArrayToFile(string fileName, byte[] content)
{
try
@@ -17,7 +20,7 @@ namespace Shadowsocks.Controller
}
catch (Exception ex)
{
Logging.Error(ex);
logger.Error(ex);
}
return false;
}
@@ -39,7 +42,7 @@ namespace Shadowsocks.Controller
}
catch (Exception ex)
{
Logging.Error(ex);
logger.Error(ex);
throw ex;
}
}


+ 3
- 2
shadowsocks-csharp/Controller/HotkeyReg.cs View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using NLog;
using Shadowsocks.Controller.Hotkeys;
using Shadowsocks.Model;

@@ -9,6 +9,7 @@ namespace Shadowsocks.Controller
{
static class HotkeyReg
{
private static Logger logger = LogManager.GetCurrentClassLogger();
public static void RegAllHotkeys()
{
var hotkeyConfig = Configuration.Load().hotkey;
@@ -60,7 +61,7 @@ namespace Shadowsocks.Controller
var hotkey = HotKeys.Str2HotKey(hotkeyStr);
if (hotkey == null)
{
Logging.Error($"Cannot parse hotkey: {hotkeyStr}");
logger.Error($"Cannot parse hotkey: {hotkeyStr}");
onComplete?.Invoke(RegResult.ParseError);
return false;
}


+ 6
- 3
shadowsocks-csharp/Controller/I18N.cs View File

@@ -1,4 +1,5 @@
using Microsoft.VisualBasic.FileIO;
using NLog;
using Shadowsocks.Properties;
using Shadowsocks.Util;
using System.Collections.Generic;
@@ -11,6 +12,8 @@ namespace Shadowsocks.Controller
{
public static class I18N
{
private static Logger logger = LogManager.GetCurrentClassLogger();
public const string I18N_FILE = "i18n.csv";
private static Dictionary<string, string> _strings = new Dictionary<string, string>();
@@ -46,12 +49,12 @@ namespace Shadowsocks.Controller
}
if (targetIndex != -1 && enIndex != targetIndex)
{
Logging.Info($"Using {localeNames[targetIndex]} translation for {locale}");
logger.Info($"Using {localeNames[targetIndex]} translation for {locale}");
}
else
{
// Still not found, exit
Logging.Info($"Translation for {locale} not found");
logger.Info($"Translation for {locale} not found");
return;
}
}
@@ -77,7 +80,7 @@ namespace Shadowsocks.Controller
{
string locale = CultureInfo.CurrentCulture.Name;
string i18n = File.ReadAllText(I18N_FILE, Encoding.UTF8);
Logging.Info("Current language is: " + locale);
logger.Info("Current language is: " + locale);
Init(i18n, locale);
}


+ 119
- 0
shadowsocks-csharp/Controller/LoggerExtension.cs View File

@@ -0,0 +1,119 @@
using System;
using System.ComponentModel;
using System.IO;
using System.Net.Sockets;
using System.Net;
using System.Diagnostics;
using System.Text;
using Shadowsocks.Util.SystemProxy;
namespace NLog
{
public static class LoggerExtension
{
public static void Dump(this Logger logger, string tag, byte[] arr, int length)
{
if (logger.IsTraceEnabled)
{
var sb = new StringBuilder($"{Environment.NewLine}{tag}: ");
for (int i = 0; i < length - 1; i++)
{
sb.Append($"0x{arr[i]:X2}, ");
}
sb.Append($"0x{arr[length - 1]:X2}");
sb.Append(Environment.NewLine);
logger.Trace(sb.ToString());
}
}
public static void Debug(this Logger logger, EndPoint local, EndPoint remote, int len, string header = null, string tailer = null)
{
if (logger.IsDebugEnabled)
{
if (header == null && tailer == null)
logger.Debug($"{local} => {remote} (size={len})");
else if (header == null && tailer != null)
logger.Debug($"{local} => {remote} (size={len}), {tailer}");
else if (header != null && tailer == null)
logger.Debug($"{header}: {local} => {remote} (size={len})");
else
logger.Debug($"{header}: {local} => {remote} (size={len}), {tailer}");
}
}
public static void Debug(this Logger logger, Socket sock, int len, string header = null, string tailer = null)
{
if (logger.IsDebugEnabled)
{
logger.Debug(sock.LocalEndPoint, sock.RemoteEndPoint, len, header, tailer);
}
}
public static void LogUsefulException(this Logger logger, Exception e)
{
// just log useful exceptions, not all of them
if (e is SocketException)
{
SocketException se = (SocketException)e;
if (se.SocketErrorCode == SocketError.ConnectionAborted)
{
// closed by browser when sending
// normally happens when download is canceled or a tab is closed before page is loaded
}
else if (se.SocketErrorCode == SocketError.ConnectionReset)
{
// received rst
}
else if (se.SocketErrorCode == SocketError.NotConnected)
{
// The application tried to send or receive data, and the System.Net.Sockets.Socket is not connected.
}
else if (se.SocketErrorCode == SocketError.HostUnreachable)
{
// There is no network route to the specified host.
}
else if (se.SocketErrorCode == SocketError.TimedOut)
{
// The connection attempt timed out, or the connected host has failed to respond.
}
else
{
logger.Warn(e);
}
}
else if (e is ObjectDisposedException)
{
}
else if (e is Win32Exception)
{
var ex = (Win32Exception)e;
// Win32Exception (0x80004005): A 32 bit processes cannot access modules of a 64 bit process.
if ((uint)ex.ErrorCode != 0x80004005)
{
logger.Warn(e);
}
}
else if (e is ProxyException)
{
var ex = (ProxyException)e;
switch (ex.Type)
{
case ProxyExceptionType.FailToRun:
case ProxyExceptionType.QueryReturnMalformed:
case ProxyExceptionType.SysproxyExitError:
logger.Error($"sysproxy - {ex.Type.ToString()}:{ex.Message}");
break;
case ProxyExceptionType.QueryReturnEmpty:
case ProxyExceptionType.Unspecific:
logger.Error($"sysproxy - {ex.Type.ToString()}");
break;
}
}
else
{
logger.Warn(e);
}
}
}
}

+ 0
- 198
shadowsocks-csharp/Controller/Logging.cs View File

@@ -1,198 +0,0 @@
using System;
using System.ComponentModel;
using System.IO;
using System.Net.Sockets;
using System.Net;
using System.Diagnostics;
using System.Text;
using Shadowsocks.Util;
using Shadowsocks.Util.SystemProxy;
namespace Shadowsocks.Controller
{
public class Logging
{
public static string LogFilePath;
private static FileStream _fs;
private static StreamWriterWithTimestamp _sw;
public static bool OpenLogFile()
{
try
{
LogFilePath = Utils.GetTempPath("shadowsocks.log");
_fs = new FileStream(LogFilePath, FileMode.Append);
_sw = new StreamWriterWithTimestamp(_fs);
_sw.AutoFlush = true;
Console.SetOut(_sw);
Console.SetError(_sw);
return true;
}
catch (IOException e)
{
Console.WriteLine(e.ToString());
return false;
}
}
private static void WriteToLogFile(object o)
{
try {
Console.WriteLine(o);
} catch(ObjectDisposedException) {
}
}
public static void Error(object o)
{
WriteToLogFile("[E] " + o);
}
public static void Info(object o)
{
WriteToLogFile(o);
}
public static void Clear() {
_sw.Close();
_sw.Dispose();
_fs.Close();
_fs.Dispose();
File.Delete(LogFilePath);
OpenLogFile();
}
[Conditional("DEBUG")]
public static void Debug(object o)
{
WriteToLogFile("[D] " + o);
}
[Conditional("DEBUG")]
public static void Dump(string tag, byte[] arr, int length)
{
var sb = new StringBuilder($"{Environment.NewLine}{tag}: ");
for (int i = 0; i < length - 1; i++) {
sb.Append($"0x{arr[i]:X2}, ");
}
sb.Append($"0x{arr[length - 1]:X2}");
sb.Append(Environment.NewLine);
Debug(sb.ToString());
}
[Conditional("DEBUG")]
public static void Debug(EndPoint local, EndPoint remote, int len, string header = null, string tailer = null)
{
if (header == null && tailer == null)
Debug($"{local} => {remote} (size={len})");
else if (header == null && tailer != null)
Debug($"{local} => {remote} (size={len}), {tailer}");
else if (header != null && tailer == null)
Debug($"{header}: {local} => {remote} (size={len})");
else
Debug($"{header}: {local} => {remote} (size={len}), {tailer}");
}
[Conditional("DEBUG")]
public static void Debug(Socket sock, int len, string header = null, string tailer = null)
{
Debug(sock.LocalEndPoint, sock.RemoteEndPoint, len, header, tailer);
}
public static void LogUsefulException(Exception e)
{
// just log useful exceptions, not all of them
if (e is SocketException)
{
SocketException se = (SocketException)e;
if (se.SocketErrorCode == SocketError.ConnectionAborted)
{
// closed by browser when sending
// normally happens when download is canceled or a tab is closed before page is loaded
}
else if (se.SocketErrorCode == SocketError.ConnectionReset)
{
// received rst
}
else if (se.SocketErrorCode == SocketError.NotConnected)
{
// The application tried to send or receive data, and the System.Net.Sockets.Socket is not connected.
}
else if (se.SocketErrorCode == SocketError.HostUnreachable)
{
// There is no network route to the specified host.
}
else if (se.SocketErrorCode == SocketError.TimedOut)
{
// The connection attempt timed out, or the connected host has failed to respond.
}
else
{
Info(e);
}
}
else if (e is ObjectDisposedException)
{
}
else if (e is Win32Exception)
{
var ex = (Win32Exception) e;
// Win32Exception (0x80004005): A 32 bit processes cannot access modules of a 64 bit process.
if ((uint) ex.ErrorCode != 0x80004005)
{
Info(e);
}
}
else if (e is ProxyException)
{
var ex = (ProxyException)e;
switch (ex.Type)
{
case ProxyExceptionType.FailToRun:
case ProxyExceptionType.QueryReturnMalformed:
case ProxyExceptionType.SysproxyExitError:
Error($"sysproxy - {ex.Type.ToString()}:{ex.Message}");
break;
case ProxyExceptionType.QueryReturnEmpty:
case ProxyExceptionType.Unspecific:
Error($"sysproxy - {ex.Type.ToString()}");
break;
}
}
else
{
Info(e);
}
}
}
// Simply extended System.IO.StreamWriter for adding timestamp workaround
public class StreamWriterWithTimestamp : StreamWriter
{
public StreamWriterWithTimestamp(Stream stream) : base(stream)
{
}
private string GetTimestamp()
{
return "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "] ";
}
public override void WriteLine(string value)
{
base.WriteLine(GetTimestamp() + value);
}
public override void Write(string value)
{
base.Write(GetTimestamp() + value);
}
}
}

+ 23
- 18
shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs View File

@@ -9,6 +9,7 @@ using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using NLog;
using Shadowsocks.Model;
using Shadowsocks.Util;

@@ -18,6 +19,8 @@ namespace Shadowsocks.Controller

public sealed class AvailabilityStatistics : IDisposable
{
private static Logger logger = LogManager.GetCurrentClassLogger();

public const string DateTimePattern = "yyyy-MM-dd HH:mm:ss";
private const string StatisticsFilesName = "shadowsocks.availability.json";
public static string AvailabilityStatisticsFile;
@@ -111,7 +114,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
}
}

@@ -155,7 +158,7 @@ namespace Shadowsocks.Controller
inR.Add(inboundSpeed);
outR.Add(outboundSpeed);

Logging.Debug(
logger.Debug(
$"{id}: current/max inbound {inboundSpeed}/{inR.Max()} KiB/s, current/max outbound {outboundSpeed}/{outR.Max()} KiB/s");
}
}
@@ -213,7 +216,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.Debug("config changed asynchrously, just ignore this server");
logger.Debug("config changed asynchrously, just ignore this server");
}
}

@@ -235,7 +238,7 @@ namespace Shadowsocks.Controller
{
AppendRecord(server.Identifier(), record);
}
Logging.Debug($"Ping {server.FriendlyName()} {e.RoundtripTime.Count} times, {(100 - record.PackageLoss * 100)}% packages loss, min {record.MinResponse} ms, max {record.MaxResponse} ms, avg {record.AverageResponse} ms");
logger.Debug($"Ping {server.FriendlyName()} {e.RoundtripTime.Count} times, {(100 - record.PackageLoss * 100)}% packages loss, min {record.MinResponse} ms, max {record.MaxResponse} ms, avg {record.AverageResponse} ms");
if (Interlocked.Decrement(ref state.counter) == 0)
{
Save();
@@ -260,13 +263,13 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
}
}

private void Save()
{
Logging.Debug($"save statistics to {AvailabilityStatisticsFile}");
logger.Debug($"save statistics to {AvailabilityStatisticsFile}");
if (RawStatistics.Count == 0)
{
return;
@@ -283,7 +286,7 @@ namespace Shadowsocks.Controller
}
catch (IOException e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
}
}

@@ -300,7 +303,7 @@ namespace Shadowsocks.Controller
{
try
{
Logging.Debug("filter raw statistics");
logger.Debug("filter raw statistics");
if (RawStatistics == null) return;
var filteredStatistics = new Statistics();

@@ -315,7 +318,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
}
}

@@ -324,7 +327,7 @@ namespace Shadowsocks.Controller
try
{
var path = AvailabilityStatisticsFile;
Logging.Debug($"loading statistics from {path}");
logger.Debug($"loading statistics from {path}");
if (!File.Exists(path))
{
using (File.Create(path))
@@ -337,7 +340,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
Console.WriteLine($"failed to load statistics; use runtime statistics, some data may be lost");
}
}
@@ -411,6 +414,8 @@ namespace Shadowsocks.Controller

class MyPing
{
private static Logger logger = LogManager.GetCurrentClassLogger();

//arguments for ICMP tests
public const int TimeoutMilliseconds = 500;

@@ -445,7 +450,7 @@ namespace Shadowsocks.Controller
{
try
{
Logging.Debug($"Ping {server.FriendlyName()}");
logger.Debug($"Ping {server.FriendlyName()}");
if (ip == null)
{
ip = Dns.GetHostAddresses(server.server)
@@ -461,8 +466,8 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.Error($"An exception occured while eveluating {server.FriendlyName()}");
Logging.LogUsefulException(e);
logger.Error($"An exception occured while eveluating {server.FriendlyName()}");
logger.LogUsefulException(e);
FireCompleted(e, userstate);
}
}
@@ -473,20 +478,20 @@ namespace Shadowsocks.Controller
{
if (e.Reply.Status == IPStatus.Success)
{
Logging.Debug($"Ping {server.FriendlyName()} {e.Reply.RoundtripTime} ms");
logger.Debug($"Ping {server.FriendlyName()} {e.Reply.RoundtripTime} ms");
RoundtripTime.Add((int?)e.Reply.RoundtripTime);
}
else
{
Logging.Debug($"Ping {server.FriendlyName()} timeout");
logger.Debug($"Ping {server.FriendlyName()} timeout");
RoundtripTime.Add(null);
}
TestNext(e.UserState);
}
catch (Exception ex)
{
Logging.Error($"An exception occured while eveluating {server.FriendlyName()}");
Logging.LogUsefulException(ex);
logger.Error($"An exception occured while eveluating {server.FriendlyName()}");
logger.LogUsefulException(ex);
FireCompleted(ex, e.UserState);
}
}


+ 5
- 3
shadowsocks-csharp/Controller/Service/GfwListUpdater.cs View File

@@ -5,7 +5,7 @@ using System.Net;
using System.Text;

using Newtonsoft.Json;
using NLog;
using Shadowsocks.Model;
using Shadowsocks.Properties;
using Shadowsocks.Util;
@@ -14,6 +14,8 @@ namespace Shadowsocks.Controller
{
public class GFWListUpdater
{
private static Logger logger = LogManager.GetCurrentClassLogger();

private const string GFWLIST_URL = "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt";

public event EventHandler<ResultEventArgs> UpdateCompleted;
@@ -93,10 +95,10 @@ var __RULES__ = {JsonConvert.SerializeObject(gfwLines, Formatting.Indented)};
string gfwListUrl = GFWLIST_URL;
if (!string.IsNullOrWhiteSpace(config.gfwListUrl))
{
Logging.Info("Found custom GFWListURL in config file");
logger.Info("Found custom GFWListURL in config file");
gfwListUrl = config.gfwListUrl;
}
Logging.Info($"Checking GFWList from {gfwListUrl}");
logger.Info($"Checking GFWList from {gfwListUrl}");
WebClient http = new WebClient();
if (config.enabled)
{


+ 9
- 10
shadowsocks-csharp/Controller/Service/Listener.cs View File

@@ -4,13 +4,15 @@ using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using NLog;
using Shadowsocks.Model;
namespace Shadowsocks.Controller
{
public class Listener
{
private static Logger logger = LogManager.GetCurrentClassLogger();
public interface IService
{
bool Handle(byte[] firstPacket, int length, Socket socket, object state);
@@ -80,11 +82,8 @@ namespace Shadowsocks.Controller
_tcpSocket.Listen(1024);
// Start an asynchronous socket to listen for connections.
Logging.Info($"Shadowsocks started ({UpdateChecker.Version})");
if (_config.isVerboseLogging)
{
Logging.Info(Encryption.EncryptorFactory.DumpRegisteredEncryptor());
}
logger.Info($"Shadowsocks started ({UpdateChecker.Version})");
logger.Debug(Encryption.EncryptorFactory.DumpRegisteredEncryptor());
_tcpSocket.BeginAccept(new AsyncCallback(AcceptCallback), _tcpSocket);
UDPState udpState = new UDPState(_udpSocket);
_udpSocket.BeginReceiveFrom(udpState.buffer, 0, udpState.buffer.Length, 0, ref udpState.remoteEndPoint, new AsyncCallback(RecvFromCallback), udpState);
@@ -132,7 +131,7 @@ namespace Shadowsocks.Controller
}
catch (Exception ex)
{
Logging.Debug(ex);
logger.Debug(ex);
}
finally
{
@@ -171,7 +170,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
}
finally
{
@@ -187,7 +186,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
}
}
}
@@ -218,7 +217,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
conn.Close();
}
}


+ 6
- 3
shadowsocks-csharp/Controller/Service/PACDaemon.cs View File

@@ -1,4 +1,5 @@
using Shadowsocks.Properties;
using NLog;
using Shadowsocks.Properties;
using Shadowsocks.Util;
using System;
using System.Collections.Generic;
@@ -15,6 +16,8 @@ namespace Shadowsocks.Controller
/// </summary>
public class PACDaemon
{
private static Logger logger = LogManager.GetCurrentClassLogger();
public const string PAC_FILE = "pac.txt";
public const string USER_RULE_FILE = "user-rule.txt";
public const string USER_ABP_FILE = "abp.txt";
@@ -101,7 +104,7 @@ namespace Shadowsocks.Controller
{
if (PACFileChanged != null)
{
Logging.Info($"Detected: PAC file '{e.Name}' was {e.ChangeType.ToString().ToLower()}.");
logger.Info($"Detected: PAC file '{e.Name}' was {e.ChangeType.ToString().ToLower()}.");
Task.Factory.StartNew(() =>
{
((FileSystemWatcher)sender).EnableRaisingEvents = false;
@@ -116,7 +119,7 @@ namespace Shadowsocks.Controller
{
if (UserRuleFileChanged != null)
{
Logging.Info($"Detected: User Rule file '{e.Name}' was {e.ChangeType.ToString().ToLower()}.");
logger.Info($"Detected: User Rule file '{e.Name}' was {e.ChangeType.ToString().ToLower()}.");
Task.Factory.StartNew(() =>
{
((FileSystemWatcher)sender).EnableRaisingEvents = false;


+ 5
- 2
shadowsocks-csharp/Controller/Service/PACServer.cs View File

@@ -6,11 +6,14 @@ using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Web;
using NLog;
namespace Shadowsocks.Controller
{
public class PACServer : Listener.Service
{
private static Logger logger = LogManager.GetCurrentClassLogger();
public const string RESOURCE_NAME = "pac";
private string PacSecret
@@ -43,7 +46,7 @@ namespace Shadowsocks.Controller
string usedSecret = _config.secureLocalPac ? $"&secret={PacSecret}" : "";
string contentHash = GetHash(_pacDaemon.GetPACContent());
PacUrl = $"http://{config.localHost}:{config.localPort}/{RESOURCE_NAME}?hash={contentHash}{usedSecret}";
Logging.Debug("Set PAC URL:" + PacUrl);
logger.Debug("Set PAC URL:" + PacUrl);
}
private static string GetHash(string content)
@@ -177,7 +180,7 @@ Connection: Close
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
socket.Close();
}
}


+ 13
- 10
shadowsocks-csharp/Controller/Service/PortForwarder.cs View File

@@ -1,6 +1,7 @@
using System;
using System.Net;
using System.Net.Sockets;
using NLog;
using Shadowsocks.Util.Sockets;
namespace Shadowsocks.Controller
@@ -26,6 +27,8 @@ namespace Shadowsocks.Controller
private class Handler
{
private static Logger logger = LogManager.GetCurrentClassLogger();
private byte[] _firstPacket;
private int _firstPacketLength;
private Socket _local;
@@ -58,7 +61,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
Close();
}
}
@@ -77,7 +80,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
Close();
}
}
@@ -94,7 +97,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
Close();
}
}
@@ -115,7 +118,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
Close();
}
}
@@ -142,7 +145,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
Close();
}
}
@@ -169,7 +172,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
Close();
}
}
@@ -188,7 +191,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
Close();
}
}
@@ -207,7 +210,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
Close();
}
}
@@ -239,7 +242,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
}
}
if (_remote != null)
@@ -251,7 +254,7 @@ namespace Shadowsocks.Controller
}
catch (SocketException e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
}
}
}


+ 7
- 4
shadowsocks-csharp/Controller/Service/PrivoxyRunner.cs View File

@@ -6,6 +6,7 @@ using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
using NLog;
using Shadowsocks.Model;
using Shadowsocks.Util;
using Shadowsocks.Util.ProcessManagement;
@@ -14,6 +15,8 @@ namespace Shadowsocks.Controller
{
class PrivoxyRunner
{
private static Logger logger = LogManager.GetCurrentClassLogger();
private static int _uid;
private static string _uniqueConfigFile;
private static Job _privoxyJob;
@@ -31,7 +34,7 @@ namespace Shadowsocks.Controller
}
catch (IOException e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
}
}
@@ -104,7 +107,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
}
}
@@ -137,7 +140,7 @@ namespace Shadowsocks.Controller
* are already dead, and that will cause exceptions here.
* We could simply ignore those exceptions.
*/
Logging.LogUsefulException(ex);
logger.LogUsefulException(ex);
return false;
}
}
@@ -157,7 +160,7 @@ namespace Shadowsocks.Controller
catch (Exception e)
{
// in case access denied
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
return defaultPort;
}
}


+ 41
- 46
shadowsocks-csharp/Controller/Service/TCPRelay.cs View File

@@ -1,4 +1,5 @@
using System;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
@@ -17,6 +18,7 @@ namespace Shadowsocks.Controller
{
class TCPRelay : Listener.Service
{
private static Logger logger = LogManager.GetCurrentClassLogger();
private ShadowsocksController _controller;
private DateTime _lastSweepTime;
private Configuration _config;
@@ -54,7 +56,7 @@ namespace Shadowsocks.Controller
}
foreach (TCPHandler handler1 in handlersToClose)
{
Logging.Debug("Closing timed out TCP connection.");
logger.Debug("Closing timed out TCP connection.");
handler1.Close();
}
@@ -122,6 +124,8 @@ namespace Shadowsocks.Controller
}
}
private static Logger Logger = LogManager.GetCurrentClassLogger();
private readonly int _serverTimeout;
private readonly int _proxyTimeout;
@@ -217,7 +221,7 @@ namespace Shadowsocks.Controller
this._server = server;
/* prepare address buffer length for AEAD */
Logging.Debug($"_addrBufLength={_addrBufLength}");
Logger.Debug($"_addrBufLength={_addrBufLength}");
_encryptor.AddrBufLength = _addrBufLength;
}
@@ -252,7 +256,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
Logger.LogUsefulException(e);
}
if (_currentRemoteSession != null)
@@ -265,7 +269,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
Logger.LogUsefulException(e);
}
}
@@ -291,7 +295,7 @@ namespace Shadowsocks.Controller
{
// reject socks 4
response = new byte[] { 0, 91 };
Logging.Error("socks 5 protocol error");
Logger.Error("socks 5 protocol error");
}
_connection.BeginSend(response, 0, response.Length, SocketFlags.None,
HandshakeSendCallback, null);
@@ -301,7 +305,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
Logger.LogUsefulException(e);
Close();
}
}
@@ -326,7 +330,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
Logger.LogUsefulException(e);
Close();
}
}
@@ -358,21 +362,21 @@ namespace Shadowsocks.Controller
break;
case CMD_BIND: // not implemented
default:
Logging.Debug("Unsupported CMD=" + _command);
Logger.Debug("Unsupported CMD=" + _command);
Close();
break;
}
}
else
{
Logging.Debug(
Logger.Debug(
"failed to recv data in Shadowsocks.Controller.TCPHandler.handshakeReceive2Callback()");
Close();
}
}
catch (Exception e)
{
Logging.LogUsefulException(e);
Logger.LogUsefulException(e);
Close();
}
}
@@ -387,7 +391,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
Logger.LogUsefulException(e);
Close();
}
}
@@ -409,7 +413,7 @@ namespace Shadowsocks.Controller
ReadAddress(16 + ADDR_PORT_LEN - 1, onSuccess);
break;
default:
Logging.Debug("Unsupported ATYP=" + atyp);
Logger.Debug("Unsupported ATYP=" + atyp);
Close();
break;
}
@@ -468,10 +472,7 @@ namespace Shadowsocks.Controller
break;
}
if (_config.isVerboseLogging)
{
Logging.Info($"connect to {dstAddr}:{dstPort}");
}
Logger.Debug($"connect to {dstAddr}:{dstPort}");
_destEndPoint = SocketUtil.GetEndPoint(dstAddr, dstPort);
@@ -479,13 +480,13 @@ namespace Shadowsocks.Controller
}
else
{
Logging.Debug("failed to recv data in Shadowsocks.Controller.TCPHandler.OnAddressFullyRead()");
Logger.Debug("failed to recv data in Shadowsocks.Controller.TCPHandler.OnAddressFullyRead()");
Close();
}
}
catch (Exception e)
{
Logging.LogUsefulException(e);
Logger.LogUsefulException(e);
Close();
}
}
@@ -537,7 +538,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
Logger.LogUsefulException(e);
Close();
}
}
@@ -631,7 +632,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
Logger.LogUsefulException(e);
Close();
}
}
@@ -650,7 +651,7 @@ namespace Shadowsocks.Controller
}
var proxy = timer.Session.Remote;
Logging.Info($"Proxy {proxy.ProxyEndPoint} timed out");
Logger.Info($"Proxy {proxy.ProxyEndPoint} timed out");
proxy.Close();
Close();
}
@@ -678,12 +679,9 @@ namespace Shadowsocks.Controller
_proxyConnected = true;
if (_config.isVerboseLogging)
if (!(remote is DirectConnect))
{
if (!(remote is DirectConnect))
{
Logging.Info($"Socket connected to proxy {remote.ProxyEndPoint}");
}
Logger.Debug($"Socket connected to proxy {remote.ProxyEndPoint}");
}
_startConnectTime = DateTime.Now;
@@ -710,7 +708,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
Logger.LogUsefulException(e);
Close();
}
}
@@ -731,7 +729,7 @@ namespace Shadowsocks.Controller
Server server = timer.Server;
IStrategy strategy = _controller.GetCurrentStrategy();
strategy?.SetFailure(server);
Logging.Info($"{server.FriendlyName()} timed out");
Logger.Info($"{server.FriendlyName()} timed out");
session.Remote.Close();
Close();
}
@@ -754,10 +752,7 @@ namespace Shadowsocks.Controller
_destConnected = true;
if (_config.isVerboseLogging)
{
Logging.Info($"Socket connected to ss server: {_server.FriendlyName()}");
}
Logger.Debug($"Socket connected to ss server: {_server.FriendlyName()}");
var latency = DateTime.Now - _startConnectTime;
IStrategy strategy = _controller.GetCurrentStrategy();
@@ -776,7 +771,7 @@ namespace Shadowsocks.Controller
IStrategy strategy = _controller.GetCurrentStrategy();
strategy?.SetFailure(_server);
}
Logging.LogUsefulException(e);
Logger.LogUsefulException(e);
Close();
}
}
@@ -803,12 +798,12 @@ namespace Shadowsocks.Controller
PipeRemoteReceiveCallback, session);
TryReadAvailableData();
Logging.Debug($"_firstPacketLength = {_firstPacketLength}");
Logger.Debug($"_firstPacketLength = {_firstPacketLength}");
SendToServer(_firstPacketLength, session);
}
catch (Exception e)
{
Logging.LogUsefulException(e);
Logger.LogUsefulException(e);
Close();
}
}
@@ -834,7 +829,7 @@ namespace Shadowsocks.Controller
}
catch (CryptoErrorException)
{
Logging.Error("decryption error");
Logger.Error("decryption error");
Close();
return;
}
@@ -842,12 +837,12 @@ namespace Shadowsocks.Controller
if (bytesToSend == 0)
{
// need more to decrypt
Logging.Debug("Need more to decrypt");
Logger.Debug("Need more to decrypt");
session.Remote.BeginReceive(_remoteRecvBuffer, 0, RecvSize, SocketFlags.None,
PipeRemoteReceiveCallback, session);
return;
}
Logging.Debug($"start sending {bytesToSend}");
Logger.Debug($"start sending {bytesToSend}");
_connection.BeginSend(_remoteSendBuffer, 0, bytesToSend, SocketFlags.None,
PipeConnectionSendCallback, new object[] { session, bytesToSend });
IStrategy strategy = _controller.GetCurrentStrategy();
@@ -862,7 +857,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
Logger.LogUsefulException(e);
Close();
}
}
@@ -890,7 +885,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
Logger.LogUsefulException(e);
Close();
}
}
@@ -907,7 +902,7 @@ namespace Shadowsocks.Controller
}
catch (CryptoErrorException)
{
Logging.Debug("encryption error");
Logger.Debug("encryption error");
Close();
return;
}
@@ -932,7 +927,7 @@ namespace Shadowsocks.Controller
int bytesRemaining = bytesShouldSend - bytesSent;
if (bytesRemaining > 0)
{
Logging.Info("reconstruct _connetionSendBuffer to re-send");
Logger.Info("reconstruct _connetionSendBuffer to re-send");
Buffer.BlockCopy(_connetionSendBuffer, bytesSent, _connetionSendBuffer, 0, bytesRemaining);
session.Remote.BeginSend(_connetionSendBuffer, 0, bytesRemaining, SocketFlags.None,
PipeRemoteSendCallback, new object[] { session, bytesRemaining });
@@ -943,7 +938,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
Logger.LogUsefulException(e);
Close();
}
}
@@ -960,7 +955,7 @@ namespace Shadowsocks.Controller
var bytesRemaining = bytesShouldSend - bytesSent;
if (bytesRemaining > 0)
{
Logging.Info("reconstruct _remoteSendBuffer to re-send");
Logger.Info("reconstruct _remoteSendBuffer to re-send");
Buffer.BlockCopy(_remoteSendBuffer, bytesSent, _remoteSendBuffer, 0, bytesRemaining);
_connection.BeginSend(_remoteSendBuffer, 0, bytesRemaining, SocketFlags.None,
PipeConnectionSendCallback, new object[] { session, bytesRemaining });
@@ -971,7 +966,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
Logger.LogUsefulException(e);
Close();
}
}


+ 6
- 3
shadowsocks-csharp/Controller/Service/UDPRelay.cs View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using NLog;
using Shadowsocks.Controller.Strategy;
using Shadowsocks.Encryption;
using Shadowsocks.Model;
@@ -49,6 +50,8 @@ namespace Shadowsocks.Controller
public class UDPHandler
{
private static Logger logger = LogManager.GetCurrentClassLogger();
private Socket _local;
private Socket _remote;
@@ -98,14 +101,14 @@ namespace Shadowsocks.Controller
byte[] dataOut = new byte[65536]; // enough space for AEAD ciphers
int outlen;
encryptor.EncryptUDP(dataIn, length - 3, dataOut, out outlen);
Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay");
logger.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay");
_remote?.SendTo(dataOut, outlen, SocketFlags.None, _remoteEndPoint);
}
public void Receive()
{
EndPoint remoteEndPoint = new IPEndPoint(GetIPAddress(), 0);
Logging.Debug($"++++++Receive Server Port, size:" + _buffer.Length);
logger.Debug($"++++++Receive Server Port, size:" + _buffer.Length);
_remote?.BeginReceiveFrom(_buffer, 0, _buffer.Length, 0, ref remoteEndPoint, new AsyncCallback(RecvFromCallback), null);
}
@@ -126,7 +129,7 @@ namespace Shadowsocks.Controller
byte[] sendBuf = new byte[outlen + 3];
Array.Copy(dataOut, 0, sendBuf, 3, outlen);
Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay");
logger.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay");
_local?.SendTo(sendBuf, outlen + 3, 0, _localEndPoint);
Receive();


+ 11
- 9
shadowsocks-csharp/Controller/Service/UpdateChecker.cs View File

@@ -4,7 +4,7 @@ using System.Net;
using System.Text.RegularExpressions;
using Newtonsoft.Json.Linq;
using NLog;
using Shadowsocks.Model;
using Shadowsocks.Util;
@@ -12,6 +12,8 @@ namespace Shadowsocks.Controller
{
public class UpdateChecker
{
private static Logger logger = LogManager.GetCurrentClassLogger();
private const string UpdateURL = "https://api.github.com/repos/shadowsocks/shadowsocks-windows/releases";
private const string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36";
@@ -60,14 +62,14 @@ namespace Shadowsocks.Controller
try
{
Logging.Debug("Checking updates...");
logger.Debug("Checking updates...");
WebClient http = CreateWebClient();
http.DownloadStringCompleted += http_DownloadStringCompleted;
http.DownloadStringAsync(new Uri(UpdateURL));
}
catch (Exception ex)
{
Logging.LogUsefulException(ex);
logger.LogUsefulException(ex);
}
}
@@ -117,7 +119,7 @@ namespace Shadowsocks.Controller
}
else
{
Logging.Debug("No update is available");
logger.Debug("No update is available");
if (CheckUpdateCompleted != null)
{
CheckUpdateCompleted(this, new EventArgs());
@@ -126,7 +128,7 @@ namespace Shadowsocks.Controller
}
catch (Exception ex)
{
Logging.LogUsefulException(ex);
logger.LogUsefulException(ex);
}
}
@@ -141,7 +143,7 @@ namespace Shadowsocks.Controller
}
catch (Exception ex)
{
Logging.LogUsefulException(ex);
logger.LogUsefulException(ex);
}
}
@@ -151,10 +153,10 @@ namespace Shadowsocks.Controller
{
if (e.Error != null)
{
Logging.LogUsefulException(e.Error);
logger.LogUsefulException(e.Error);
return;
}
Logging.Debug($"New version {LatestVersionNumber}{LatestVersionSuffix} found: {LatestVersionLocalName}");
logger.Debug($"New version {LatestVersionNumber}{LatestVersionSuffix} found: {LatestVersionLocalName}");
if (CheckUpdateCompleted != null)
{
CheckUpdateCompleted(this, new EventArgs());
@@ -162,7 +164,7 @@ namespace Shadowsocks.Controller
}
catch (Exception ex)
{
Logging.LogUsefulException(ex);
logger.LogUsefulException(ex);
}
}


+ 35
- 5
shadowsocks-csharp/Controller/ShadowsocksController.cs View File

@@ -9,7 +9,7 @@ using System.Text;
using System.Threading;
using System.Web;
using System.Windows.Forms;
using NLog;
using Shadowsocks.Controller.Service;
using Shadowsocks.Controller.Strategy;
using Shadowsocks.Model;
@@ -19,6 +19,8 @@ namespace Shadowsocks.Controller
{
public class ShadowsocksController
{
private static Logger logger = LogManager.GetCurrentClassLogger();
// controller:
// handle user actions
// manipulates UI
@@ -52,6 +54,12 @@ namespace Shadowsocks.Controller
public string Path;
}
public class UpdatedEventArgs : EventArgs
{
public string OldVersion;
public string NewVersion;
}
public class TrafficPerSecond
{
public long inboundCounter;
@@ -78,6 +86,9 @@ namespace Shadowsocks.Controller
public event ErrorEventHandler Errored;
// Invoked when controller.Start();
public event EventHandler<UpdatedEventArgs> ProgramUpdated;
public ShadowsocksController()
{
_config = Configuration.Load();
@@ -86,10 +97,25 @@ namespace Shadowsocks.Controller
_pluginsByServer = new ConcurrentDictionary<Server, Sip003Plugin>();
StartReleasingMemory();
StartTrafficStatistics(61);
ProgramUpdated += (o, e) =>
{
logger.Info($"Updated from {e.OldVersion} to {e.NewVersion}");
};
}
public void Start(bool regHotkeys = true)
{
if (_config.updated && regHotkeys)
{
_config.updated = false;
ProgramUpdated.Invoke(this, new UpdatedEventArgs()
{
OldVersion = _config.version,
NewVersion = UpdateChecker.Version,
});
Configuration.Save(_config);
}
Reload();
if (regHotkeys)
{
@@ -165,13 +191,13 @@ namespace Shadowsocks.Controller
{
if (plugin.StartIfNeeded())
{
Logging.Info(
logger.Info(
$"Started SIP003 plugin for {server.Identifier()} on {plugin.LocalEndPoint} - PID: {plugin.ProcessId}");
}
}
catch (Exception ex)
{
Logging.Error("Failed to start SIP003 plugin: " + ex.Message);
logger.Error("Failed to start SIP003 plugin: " + ex.Message);
throw;
}
@@ -213,7 +239,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
return false;
}
}
@@ -252,6 +278,7 @@ namespace Shadowsocks.Controller
{
_config.isVerboseLogging = enabled;
SaveConfig(_config);
NLogConfig.LoadConfiguration(); // reload nlog
VerboseLoggingStatusChanged?.Invoke(this, new EventArgs());
}
@@ -475,6 +502,9 @@ namespace Shadowsocks.Controller
Encryption.RNG.Reload();
// some logic in configuration updated the config when saving, we need to read it again
_config = Configuration.Load();
NLogConfig.LoadConfiguration();
StatisticsConfiguration = StatisticsStrategyConfiguration.Load();
privoxyRunner = privoxyRunner ?? new PrivoxyRunner();
@@ -533,7 +563,7 @@ namespace Shadowsocks.Controller
e = new Exception(I18N.GetString("Port {0} is reserved by system", _config.localPort), e);
}
}
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
ReportError(e);
}


+ 10
- 7
shadowsocks-csharp/Controller/Strategy/HighAvailabilityStrategy.cs View File

@@ -1,4 +1,5 @@
using Shadowsocks.Model;
using NLog;
using Shadowsocks.Model;
using System;
using System.Collections.Generic;
using System.Net;
@@ -8,6 +9,8 @@ namespace Shadowsocks.Controller.Strategy
{
class HighAvailabilityStrategy : IStrategy
{
private static Logger logger = LogManager.GetCurrentClassLogger();
protected ServerStatus _currentServer;
protected Dictionary<Server, ServerStatus> _serverStatus;
ShadowsocksController _controller;
@@ -111,7 +114,7 @@ namespace Shadowsocks.Controller.Strategy
100 * 1000 * Math.Min(5 * 60, (now - status.lastFailure).TotalSeconds)
-2 * 5 * (Math.Min(2000, status.latency.TotalMilliseconds) / (1 + (now - status.lastTimeDetectLatency).TotalSeconds / 30 / 10) +
-0.5 * 200 * Math.Min(5, (status.lastRead - status.lastWrite).TotalSeconds));
Logging.Debug(String.Format("server: {0} latency:{1} score: {2}", status.server.FriendlyName(), status.latency, status.score));
logger.Debug(String.Format("server: {0} latency:{1} score: {2}", status.server.FriendlyName(), status.latency, status.score));
}
ServerStatus max = null;
foreach (var status in servers)
@@ -133,14 +136,14 @@ namespace Shadowsocks.Controller.Strategy
if (_currentServer == null || max.score - _currentServer.score > 200)
{
_currentServer = max;
Logging.Info($"HA switching to server: {_currentServer.server.FriendlyName()}");
logger.Info($"HA switching to server: {_currentServer.server.FriendlyName()}");
}
}
}
public void UpdateLatency(Model.Server server, TimeSpan latency)
{
Logging.Debug($"latency: {server.FriendlyName()} {latency}");
logger.Debug($"latency: {server.FriendlyName()} {latency}");
ServerStatus status;
if (_serverStatus.TryGetValue(server, out status))
@@ -152,7 +155,7 @@ namespace Shadowsocks.Controller.Strategy
public void UpdateLastRead(Model.Server server)
{
Logging.Debug($"last read: {server.FriendlyName()}");
logger.Debug($"last read: {server.FriendlyName()}");
ServerStatus status;
if (_serverStatus.TryGetValue(server, out status))
@@ -163,7 +166,7 @@ namespace Shadowsocks.Controller.Strategy
public void UpdateLastWrite(Model.Server server)
{
Logging.Debug($"last write: {server.FriendlyName()}");
logger.Debug($"last write: {server.FriendlyName()}");
ServerStatus status;
if (_serverStatus.TryGetValue(server, out status))
@@ -174,7 +177,7 @@ namespace Shadowsocks.Controller.Strategy
public void SetFailure(Model.Server server)
{
Logging.Debug($"failure: {server.FriendlyName()}");
logger.Debug($"failure: {server.FriendlyName()}");
ServerStatus status;
if (_serverStatus.TryGetValue(server, out status))


+ 7
- 5
shadowsocks-csharp/Controller/Strategy/StatisticsStrategy.cs View File

@@ -5,7 +5,7 @@ using System.Net;
using System.Threading;

using Newtonsoft.Json;
using NLog;
using Shadowsocks.Model;

namespace Shadowsocks.Controller.Strategy
@@ -14,6 +14,8 @@ namespace Shadowsocks.Controller.Strategy

internal class StatisticsStrategy : IStrategy, IDisposable
{
private static Logger logger = LogManager.GetCurrentClassLogger();

private readonly ShadowsocksController _controller;
private Server _currentServer;
private readonly Timer _timer;
@@ -34,7 +36,7 @@ namespace Shadowsocks.Controller.Strategy

private void ReloadStatisticsAndChooseAServer(object obj)
{
Logging.Debug("Reloading statistics and choose a new server....");
logger.Debug("Reloading statistics and choose a new server....");
var servers = _controller.GetCurrentConfiguration().configs;
LoadStatistics();
ChooseNewServer(servers);
@@ -74,7 +76,7 @@ namespace Shadowsocks.Controller.Strategy

if (score != null)
{
Logging.Debug($"Highest score: {score} {JsonConvert.SerializeObject(averageRecord, Formatting.Indented)}");
logger.Debug($"Highest score: {score} {JsonConvert.SerializeObject(averageRecord, Formatting.Indented)}");
}
return score;
}
@@ -112,7 +114,7 @@ namespace Shadowsocks.Controller.Strategy
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
}
}

@@ -145,7 +147,7 @@ namespace Shadowsocks.Controller.Strategy

public void SetFailure(Server server)
{
Logging.Debug($"failure: {server.FriendlyName()}");
logger.Debug($"failure: {server.FriendlyName()}");
}

public void UpdateLastRead(Server server)


+ 11
- 8
shadowsocks-csharp/Controller/System/AutoStartup.cs View File

@@ -5,12 +5,15 @@ using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.Win32;
using NLog;
using Shadowsocks.Util;
namespace Shadowsocks.Controller
{
static class AutoStartup
{
private static Logger logger = LogManager.GetCurrentClassLogger();
// Don't use Application.ExecutablePath
// see https://stackoverflow.com/questions/12945805/odd-c-sharp-path-issue
private static readonly string ExecutablePath = Assembly.GetEntryAssembly().Location;
@@ -25,7 +28,7 @@ namespace Shadowsocks.Controller
runKey = Utils.OpenRegKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true);
if (runKey == null)
{
Logging.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run");
logger.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run");
return false;
}
if (enabled)
@@ -42,7 +45,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
return false;
}
finally
@@ -55,7 +58,7 @@ namespace Shadowsocks.Controller
runKey.Dispose();
}
catch (Exception e)
{ Logging.LogUsefulException(e); }
{ logger.LogUsefulException(e); }
}
}
}
@@ -68,7 +71,7 @@ namespace Shadowsocks.Controller
runKey = Utils.OpenRegKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true);
if (runKey == null)
{
Logging.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run");
logger.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run");
return false;
}
string[] runList = runKey.GetValueNames();
@@ -91,7 +94,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
return false;
}
finally
@@ -104,7 +107,7 @@ namespace Shadowsocks.Controller
runKey.Dispose();
}
catch (Exception e)
{ Logging.LogUsefulException(e); }
{ logger.LogUsefulException(e); }
}
}
}
@@ -140,13 +143,13 @@ namespace Shadowsocks.Controller
// first parameter is process command line parameter
// needn't include the name of the executable in the command line
RegisterApplicationRestart(cmdline, (int)(ApplicationRestartFlags.RESTART_NO_CRASH | ApplicationRestartFlags.RESTART_NO_HANG));
Logging.Debug("Register restart after system reboot, command line:" + cmdline);
logger.Debug("Register restart after system reboot, command line:" + cmdline);
}
// requested unregister, which has no side effect
else if (!register)
{
UnregisterApplicationRestart();
Logging.Debug("Unregister restart after system reboot");
logger.Debug("Unregister restart after system reboot");
}
}
}


+ 4
- 1
shadowsocks-csharp/Controller/System/SystemProxy.cs View File

@@ -1,5 +1,6 @@
using System;
using System.Windows.Forms;
using NLog;
using Shadowsocks.Model;
using Shadowsocks.Util.SystemProxy;
@@ -7,6 +8,8 @@ namespace Shadowsocks.Controller
{
public static class SystemProxy
{
private static Logger logger = LogManager.GetCurrentClassLogger();
private static string GetTimestamp(DateTime value)
{
return value.ToString("yyyyMMddHHmmssfff");
@@ -52,7 +55,7 @@ namespace Shadowsocks.Controller
}
catch (ProxyException ex)
{
Logging.LogUsefulException(ex);
logger.LogUsefulException(ex);
if (ex.Type != ProxyExceptionType.Unspecific && !noRetry)
{
var ret = MessageBox.Show(I18N.GetString("Error occured when process proxy setting, do you want reset current setting and retry?"), I18N.GetString("Shadowsocks"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning);


+ 13
- 0
shadowsocks-csharp/Data/NLog.config View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Warning: Configuration may reset after shadowsocks upgrade. -->
<!-- If you messed it up, delete this file and Shadowsocks will create a new one. -->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<!-- This line is managed by Shadowsocks. Do not modify it unless you know what you are doing.-->
<target name="file" xsi:type="File" fileName="ss_win_temp\shadowsocks.log" writeBom="false" encoding="utf-8"/>
</targets>
<rules>
<!-- This line is managed by Shadowsocks. Do not modify it unless you know what you are doing. -->
<logger name="*" minlevel="Info" writeTo="file"/>
</rules>
</nlog>

+ 209
- 207
shadowsocks-csharp/Data/i18n.csv View File

@@ -1,207 +1,209 @@
en,zh-CN,zh-TW,ja
#Restart program to apply translation,,,
#This is comment line,,,
#Always keep language name at head of file,,,
#Language name is output in log,,,
"#You can find it by search ""Current language is:""",,,
#Please use UTF-8 with BOM encoding so we can edit it in Excel,,,
,,,
Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks
,,,
#Menu,,,
,,,
System Proxy,系统代理,系統代理,システムプロキシ
Disable,禁用,禁用,無効
PAC,PAC 模式,PAC 模式,PAC
Global,全局模式,全局模式,全般
Servers,服务器,伺服器,サーバー
Edit Servers...,编辑服务器...,編輯伺服器...,サーバーの編集...
Statistics Config...,统计配置...,統計設定檔...,統計情報の設定...
Start on Boot,开机启动,開機啟動,システムと同時に起動
Forward Proxy...,正向代理设置...,正向 Proxy 設定...,フォワードプロキシの設定...
Allow other Devices to connect,允许其他设备连入,允許其他裝置連入,他のデバイスからの接続を許可する
Local PAC,使用本地 PAC,使用本機 PAC,ローカル PAC
Online PAC,使用在线 PAC,使用線上 PAC,オンライン PAC
Edit Local PAC File...,编辑本地 PAC 文件...,編輯本機 PAC 檔案...,ローカル PAC ファイルの編集...
Update Local PAC from GFWList,从 GFWList 更新本地 PAC,從 GFWList 更新本機 PAC,GFWList からローカル PAC を更新
Edit User Rule for GFWList...,编辑 GFWList 的用户规则...,編輯 GFWList 的使用者規則...,ユーザールールの編集...
Secure Local PAC,保护本地 PAC,安全本機 PAC,ローカル PAC を保護
Copy Local PAC URL,复制本地 PAC 网址,複製本機 PAC 網址,ローカル PAC URL をコピー
Share Server Config...,分享服务器配置...,分享伺服器設定檔...,サーバーの設定を共有...
Scan QRCode from Screen...,扫描屏幕上的二维码...,掃描螢幕上的 QR 碼...,画面から QR コードをスキャン...
Import URL from Clipboard...,从剪贴板导入URL...,從剪貼簿匯入 URL...,クリップボードから URL をインポート...
Availability Statistics,统计可用性,統計可用性,可用性の統計
Show Logs...,显示日志...,顯示記錄檔...,ログの表示...
Verbose Logging,详细记录日志,詳細資訊記錄,詳細なログを記録
Updates...,更新...,更新...,更新...
Check for Updates...,检查更新,檢查更新,更新プログラムの確認...
Check for Updates at Startup,启动时检查更新,啟動時檢查更新,起動時に更新プログラムを確認
Check Pre-release Version,检查测试版更新,檢查發行前版本更新,先行開発版も確認
Edit Hotkeys...,编辑快捷键...,編輯快速鍵...,ホットキーの編集...
About...,关于...,關於...,Shadowsocks について...
Help,帮助,說明,ヘルプ
Quit,退出,結束,終了
Edit Servers,编辑服务器,編輯伺服器,サーバーの編集
Load Balance,负载均衡,負載平衡,負荷分散
High Availability,高可用,高可用性,高可用性
Choose by statistics,根据统计,根據統計,統計で選ぶ
Show Plugin Output,显示插件输出,,
Write translation template,写入翻译模板,,
,,,
# Config Form,,,
,,,
&Add,添加(&A),新增 (&A),新規 (&A)
&Delete,删除(&D),移除 (&D),削除 (&D)
Dupli&cate,复制(&C),複製 (&C),コピー (&C)
Server,服务器,伺服器,サーバー
Server IP,服务器地址,伺服器位址,サーバーアドレス
Server Port,服务器端口,伺服器連接埠,サーバーポート
Password,密码,密碼,パスワード
Show Password,显示密码,顯示密碼,パスワードを表示する
Encryption,加密,加密,暗号化
Plugin Program,插件程序,外掛程式,プラグインプログラム
Plugin Options,插件选项,外掛程式選項,プラグインのオプション
Need Plugin Argument,需要命令行参数,,
Plugin Arguments,插件参数,外掛程式參數,プラグインの引数
Proxy Port,代理端口,Proxy 連接埠,プロキシポート
Portable Mode,便携模式,便攜模式,ポータブルモード
Restart required,需要重新启动SS,需要重新啟動SS,再起動SSが必要
Remarks,备注,註解,付記
Timeout(Sec),超时(秒),逾時 (秒),タイムアウト (秒)
OK,确定,確定,OK
Cancel,取消,取消,キャンセル
Apply,应用,應用,適用
New server,未配置的服务器,新伺服器,新規サーバー
Move &Up,上移(&U),上移 (&U),上に移動 (&U)
Move D&own,下移(&O),下移 (&O),下に移動 (&O)
,,,
#Statistics Config,,,
,,,
Enable Statistics,启用统计,,
Ping Test,Ping测试,,
packages everytime,个包/次,,
By hour of day,按照每天的小时数统计,,
Collect data per,收集数据每,,
Keep choice for,保持选择每,,
minutes,分钟,,
Final Score:,总分:,,
AverageLatency,平均延迟,,
MinLatency,最小延迟,,
MaxLatency,最大延迟,,
AverageInboundSpeed,平均入站速度,,
MinInboundSpeed,最小入站速度,,
MaxInboundSpeed,最大入站速度,,
AverageOutboundSpeed,平均出站速度,,
MinOutboundSpeed,最小出站速度,,
MaxOutboundSpeed,最大出站速度,,
AverageResponse,平均响应速度,,
MinResponse,最小响应速度,,
MaxResponse,最大响应速度,,
PackageLoss,丢包率,,
Speed,速度,,
Package Loss,丢包率,,
Ping,网络延迟,,
Chart Mode,图表模式,,
24h,24小时,,
all,全部,,
,,,
# Proxy Form,,,
,,,
Edit Proxy,代理设置,編輯 Proxy,プロキシの編集
Use Proxy,使用代理,使用 Proxy,プロキシを利用する
Proxy Type,代理类型,Proxy 類型,プロキシの種類
Proxy Addr,代理地址,Proxy 位址,プロキシアドレス
Proxy Port,代理端口,Proxy 連接埠,プロキシポート
"If server has a plugin, proxy will not be used",若服务器含有插件,代理将不被使用,若伺服器含有外掛程式,Proxy 將不被使用,サーバーにプラグインがある場合、プロキシは利用されません
Use Auth,使用认证,使用認證,認証を利用する
User Name,用户名,認證用戶,認証ユーザ
Auth Pwd,认证密码,認證口令,認証パスワード
,,,
# Log Form,,,
,,,
&File,文件(&F),檔案 (&F),ファイル (&F)
&Open Location,在资源管理器中打开(&O),在檔案總管中開啟 (&O),ファイルの場所を開く (&O)
E&xit,退出(&X),結束 (&X),終了 (&X)
&View,视图(&V),檢視 (&V),表示 (&V)
&Clear Logs,清空日志(&C),清除記錄檔 (&C),ログの削除 (&C)
Change &Font,设置字体(&F),變更字型 (&F),フォント (&F)
&Wrap Text,自动换行(&W),自動換行 (&W),右端で折り返す (&W)
&Top Most,置顶(&T),置頂 (&T),常に最前面に表示 (&T)
&Show Toolbar,显示工具栏(&S),顯示工具列 (&S),ツールバーの表示 (&S)
Log Viewer,日志查看器,記錄檔檢視器,ログビューア
Inbound,入站,輸入,受信
Outbound,出站,輸出,送信
,,,
# QRCode Form,,,
,,,
QRCode and URL,二维码与 URL,QR 碼與 URL,QR コードと URL
,,,
# PAC Url Form,,,
,,,
Edit Online PAC URL,编辑在线 PAC 网址,編輯線上 PAC 網址,オンライン PAC URL の編集
Edit Online PAC URL...,编辑在线 PAC 网址...,編輯線上 PAC 網址...,オンライン PAC URL の編集...
Please input PAC Url,请输入 PAC 网址,請輸入 PAC 網址,PAC URLを入力して下さい
,,,
# HotkeySettings Form,,,
,,,
Switch system proxy,切换系统代理状态,切換系統 Proxy 狀態,システム プロキシの状態を切り替える
Switch system proxy mode,切换系统代理模式,切換系統 Proxy 模式,プロキシモードを切り替える
Allow Clients from LAN,切换局域网共享,切換區域網路共用,LAN からのアクセスの許可を切り替える
Show Logs...,显示日志,顯示記錄檔,ログの表示
Switch to previous server,切换上个服务器,切換上一個伺服器,前のサーバーに切り替える
Switch to next server,切换下个服务器,切換下一個伺服器,次のサーバーに切り替える
Reg All,注册全部快捷键,註冊所有快速鍵,全部登録する
Reg Hotkeys At Startup,启动时注册快捷键,啟動時註冊快速鍵,起動時にホットキーを登録する
,,,
# Messages,,,
,,,
Shadowsocks Error: {0},Shadowsocks 错误: {0},Shadowsocks 錯誤: {0},Shadowsocks エラー: {0}
Port {0} already in use,端口 {0} 已被占用,連接埠號碼 {0} 已被使用,ポート番号 {0} は既に使用されています。
Port {0} is reserved by system,端口 {0} 是系统保留端口,連接埠號碼 {0} 由系統保留, ポート番号 {0} はシステムによって予約されています
Invalid server address,非法服务器地址,無效伺服器位址,サーバーアドレスが無効です。
Illegal port number format,非法端口格式,無效連接埠號碼格式,ポート番号のフォーマットが無効です。
Illegal timeout format,非法超时格式,無效逾時格式,タイムアウト値のフォーマットが無効です。
Server IP can not be blank,服务器 IP 不能为空,伺服器 IP 不能為空,サーバー IP が指定されていません。
Password can not be blank,密码不能为空,密碼不能為空,パスワードが指定されていません。
Port out of range,端口超出范围,連接埠號碼超出範圍,ポート番号は範囲外です。
Port can't be 8123,端口不能为 8123,連接埠號碼不能為 8123,8123 番以外のポート番号を指定して下さい。
Shadowsocks {0} Update Found,Shadowsocks {0} 更新,Shadowsocks {0} 更新,Shadowsocks バージョン {0} は利用できます。
No update is available,没有可用的更新,沒有可用的更新,お使いのバージョンは最新です。
Click here to update,点击这里升级,點按此處升級,クリックしてアップデートします。
Shadowsocks is here,Shadowsocks 在这里,Shadowsocks 在這裡,Shadowsocks はここです。
You can turn on/off Shadowsocks in the context menu,可以在右键菜单中开关 Shadowsocks,可以在右鍵選項單中開關 Shadowsocks,コンテキストメニューを使って、Shadowsocks を有効または無効にすることができます。
System Proxy Enabled,系统代理已启用,系統 Proxy 已啟用,システム プロキシが有効です。
System Proxy Disabled,系统代理未启用,系統 Proxy 未啟用,システム プロキシが無効です。
Failed to update PAC file ,更新 PAC 文件失败,更新 PAC 檔案失敗,PAC の更新に失敗しました。
PAC updated,更新 PAC 成功,更新 PAC 成功,PAC を更新しました。
No updates found. Please report to GFWList if you have problems with it.,未发现更新。如有问题请提交给 GFWList。,未發現更新。如有問題請報告至 GFWList。,お使いのバージョンは最新です。問題がある場合は、GFWList に報告して下さい。
No QRCode found. Try to zoom in or move it to the center of the screen.,未发现二维码,尝试把它放大或移动到靠近屏幕中间的位置,未發現 QR 碼,嘗試把它放大或移動到靠近熒幕中間的位置,QR コードが見つかりませんでした。コードを大きくするか、画面の中央に移動して下さい。
Shadowsocks is already running.,Shadowsocks 已经在运行。,Shadowsocks 已經在執行。,Shadowsocks 実行中
Find Shadowsocks icon in your notify tray.,请在任务栏里寻找 Shadowsocks 图标。,請在工作列裡尋找 Shadowsocks 圖示。,通知領域には Shadowsocks のアイコンがあります。
"If you want to start multiple Shadowsocks, make a copy in another directory.",如果想同时启动多个,可以另外复制一份到别的目录。,如果想同時啟動多個,可以另外複製一份至別的目錄。,複数起動したい場合は、プログラムファイルを別のフォルダーにコピーしてから、もう一度実行して下さい。
Failed to decode QRCode,无法解析二维码,QR 碼解碼失敗,QR コードの読み取りに失敗しました。
Failed to update registry,无法修改注册表,無法修改登錄檔,レジストリの更新に失敗しました。
System Proxy On: ,系统代理已启用:,系統 Proxy 已啟用:,システム プロキシが有効:
Running: Port {0},正在运行:端口 {0},正在執行:連接埠號碼 {0},実行中:ポート {0}
"Unexpected error, shadowsocks will exit. Please report to",非预期错误,Shadowsocks将退出。请提交此错误到,非預期錯誤,Shadowsocks 將結束。請報告此錯誤至,予想外のエラーが発生したため、Shadowsocks を終了します。詳しくは下記までお問い合わせ下さい:
"Unsupported operating system, use Windows Vista at least.",不支持的操作系统版本,最低需求为Windows Vista。,不支援的作業系統版本,最低需求為 Windows Vista。,お使いの OS はサポートされていません。Windows Vista 以降の OS で実行して下さい。
"Unsupported .NET Framework, please update to {0} or later.",当前 .NET Framework 版本过低,请升级至{0}或更新版本。,目前 .NET Framework 版本過低,最低需求為{0}。,お使いの .NET Framework はサポートされていません。{0} 以降のバンジョーをインストールして下さい。
Proxy request failed,代理请求失败,Proxy 要求失敗,プロキシ要求が失敗しました。
Proxy handshake failed,代理握手失败,Proxy 交握失敗,プロキシ ハンドシェイクに失敗しました。
Register hotkey failed,注册快捷键失败,註冊快速鍵失敗,ホットキーの登錄に失敗しました。
Cannot parse hotkey: {0},解析快捷键失败: {0},剖析快速鍵失敗: {0},ホットキーを解析できません: {0}
"Timeout is invalid, it should not exceed {0}",超时无效,不应超过 {0},逾時無效,不應超過 {0},タイムアウト値が無効です。{0} 以下の値を指定して下さい。
Cannot find the plugin program file,找不到插件程序文件,找不到外掛程式文件,
,,,
Operation failure,操作失败,,
Auto save failed,自动保存失败,,
Whether to discard unconfigured servers,是否丢弃未配置的服务器,,
"Invalid server address, Cannot automatically save or discard changes",非法服务器地址,无法自动保存,是否丢弃修改,,
"Illegal port number format, Cannot automatically save or discard changes",非法端口格式,无法自动保存,是否丢弃修改,,
"Password can not be blank, Cannot automatically save or discard changes",密码不能为空,无法自动保存,是否丢弃修改,,
"Illegal timeout format, Cannot automatically save or discard changes",非法超时格式,无法自动保存,是否丢弃修改,,
,,,
"Error occured when process proxy setting, do you want reset current setting and retry?",处理代理设置时发生错误,是否重置当前代理设置并重试?,,
"Unrecoverable proxy setting error occured, see log for detail",发生不可恢复的代理设置错误,查看日志以取得详情,,
Auth user can not be blank,认证用户不能为空,認證用戶不能為空,認証ユーザが指定されていません。
Auth pwd can not be blank,认证密码不能为空,認證口令不能為空,認証パスワードが指定されていません。
en,ru-RU,zh-CN,zh-TW,ja
#Restart program to apply translation,,,,
#This is comment line,,,,
#Always keep language name at head of file,,,,
#Language name is output in log,,,,
"#You can find it by search ""Current language is:""",,,,
#Please use UTF-8 with BOM encoding so we can edit it in Excel,,,,
,,,,
Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks,Shadowsocks
,,,,
#Menu,,,,
,,,,
System Proxy,Системный прокси-сервер,系统代理,系統代理,システムプロキシ
Disable,Отключен,禁用,禁用,無効
PAC,Сценарий настройки (PAC),PAC 模式,PAC 模式,PAC
Global,Для всей системы,全局模式,全局模式,全般
Servers,Серверы,服务器,伺服器,サーバー
Edit Servers...,Редактировать серверы…,编辑服务器...,編輯伺服器...,サーバーの編集...
Statistics Config...,Настройки статистики…,统计配置...,統計設定檔...,統計情報の設定...
Start on Boot,Автозагрузка,开机启动,開機啟動,システムと同時に起動
Forward Proxy...,Прямой прокси…,正向代理设置...,正向 Proxy 設定...,フォワードプロキシの設定...
Allow other Devices to connect,Общий доступ к подключению,允许其他设备连入,允許其他裝置連入,他のデバイスからの接続を許可する
Local PAC,Локальный PAC,使用本地 PAC,使用本機 PAC,ローカル PAC
Online PAC,Удаленный PAC,使用在线 PAC,使用線上 PAC,オンライン PAC
Edit Local PAC File...,Редактировать локальный PAC…,编辑本地 PAC 文件...,編輯本機 PAC 檔案...,ローカル PAC ファイルの編集...
Update Local PAC from GFWList,Обновить локальный PAC из GFWList,从 GFWList 更新本地 PAC,從 GFWList 更新本機 PAC,GFWList からローカル PAC を更新
Edit User Rule for GFWList...,Редактировать свои правила для GFWList,编辑 GFWList 的用户规则...,編輯 GFWList 的使用者規則...,ユーザールールの編集...
Secure Local PAC,Безопасный URL локального PAC,保护本地 PAC,安全本機 PAC,ローカル PAC を保護
Copy Local PAC URL,Копировать URL локального PAC,复制本地 PAC 网址,複製本機 PAC 網址,ローカル PAC URL をコピー
Share Server Config...,Поделиться конфигурацией сервера…,分享服务器配置...,分享伺服器設定檔...,サーバーの設定を共有...
Scan QRCode from Screen...,Сканировать QRCode с экрана…,扫描屏幕上的二维码...,掃描螢幕上的 QR 碼...,画面から QR コードをスキャン...
Import URL from Clipboard...,Импорт адреса из буфера обмена…,从剪贴板导入URL...,從剪貼簿匯入 URL...,クリップボードから URL をインポート...
Availability Statistics,Статистика доступности,统计可用性,統計可用性,可用性の統計
Show Logs...,Показать журнал…,显示日志...,顯示記錄檔...,ログの表示...
Verbose Logging,Подробный журнал,详细记录日志,詳細資訊記錄,詳細なログを記録
Updates...,Обновления…,更新...,更新...,更新...
Check for Updates...,Проверить обновления…,检查更新,檢查更新,更新プログラムの確認...
Check for Updates at Startup,Проверять при запуске,启动时检查更新,啟動時檢查更新,起動時に更新プログラムを確認
Check Pre-release Version,Проверять предрелизные версии,检查测试版更新,檢查發行前版本更新,先行開発版も確認
Edit Hotkeys...,Горячие клавиши…,编辑快捷键...,編輯快速鍵...,ホットキーの編集...
About...,О программе…,关于...,關於...,Shadowsocks について...
Help,Помощь,帮助,說明,ヘルプ
Quit,Выход,退出,結束,終了
Edit Servers,Редактирование серверов,编辑服务器,編輯伺服器,サーバーの編集
Load Balance,Балансировка нагрузки,负载均衡,負載平衡,負荷分散
High Availability,Высокая доступность,高可用,高可用性,高可用性
Choose by statistics,На основе статистики,根据统计,根據統計,統計で選ぶ
Show Plugin Output,События плагинов в журнале,显示插件输出,,
Write translation template,Создать шаблон для перевода,写入翻译模板,,
,,,,
# Config Form,,,,
,,,,
Statistics configuration,Настройки статистики,统计配置,,
&Add,Добавить,添加(&A),新增 (&A),新規 (&A)
&Delete,Удалить,删除(&D),移除 (&D),削除 (&D)
Dupli&cate,Дублир-ть,复制(&C),複製 (&C),コピー (&C)
Server,Сервер,服务器,伺服器,サーバー
Server IP,IP-адрес,服务器地址,伺服器位址,サーバーアドレス
Server Port,Порт,服务器端口,伺服器連接埠,サーバーポート
Password,Пароль,密码,密碼,パスワード
Show Password,Показать пароль,显示密码,顯示密碼,パスワードを表示する
Encryption,Шифрование,加密,加密,暗号化
Plugin Program,Плагин,插件程序,外掛程式,プラグインプログラム
Plugin Options,Опции плагина,插件选项,外掛程式選項,プラグインのオプション
Need Plugin Argument,Требуются аргументы,需要命令行参数,,
Plugin Arguments,Аргументы,插件参数,外掛程式參數,プラグインの引数
Proxy Port,Порт прокси,代理端口,Proxy 連接埠,プロキシポート
Portable Mode,Переносимый режим,便携模式,便攜模式,ポータブルモード
Restart required,Требуется перезапуск программы,需要重新启动SS,需要重新啟動SS,再起動SSが必要
Remarks,Примечания,备注,註解,付記
Timeout(Sec),Таймаут(сек),超时(秒),逾時 (秒),タイムアウト (秒)
OK,ОК,确定,確定,OK
Cancel,Отмена,取消,取消,キャンセル
Apply,Применить,应用,應用,適用
New server,Новый сервер,未配置的服务器,新伺服器,新規サーバー
Move &Up,Выше,上移(&U),上移 (&U),上に移動 (&U)
Move D&own,Ниже,下移(&O),下移 (&O),下に移動 (&O)
deprecated,Устаревшее,不推荐,不推薦,非推奨
,,,,
#Statistics Config,,,,
,,,,
Enable Statistics,Включить сбор статистики,启用统计,,
Ping Test,Проверка связи (Ping),Ping测试,,
packages everytime,пакета на проверку,个包/次,,
By hour of day,Ежечасно,按照每天的小时数统计,,
Collect data per,Собирать данные за,收集数据每,,
Keep choice for,Хранить отбор данных за,保持选择每,,
minutes,мин.,分钟,,
Final Score:,Финальная оценка:,总分:,,
AverageLatency,СредЗадержка,平均延迟,,
MinLatency,МинЗадержка,最小延迟,,
MaxLatency,МаксЗадержка,最大延迟,,
AverageInboundSpeed,СредВходСкорость,平均入站速度,,
MinInboundSpeed,МинВходСкорость,最小入站速度,,
MaxInboundSpeed,СредВходСкорость,最大入站速度,,
AverageOutboundSpeed,СредИсхСкорость,平均出站速度,,
MinOutboundSpeed,МинИсхСкорость,最小出站速度,,
MaxOutboundSpeed,МаксИсхСкорость,最大出站速度,,
AverageResponse,СредВремяОтвета,平均响应速度,,
MinResponse,МинВремяОтвета,最小响应速度,,
MaxResponse,МаксВремяОтвета,最大响应速度,,
PackageLoss,ПотериПакетов,丢包率,,
Speed,Скорость,速度,,
Package Loss,Потери пакетов,丢包率,,
Ping,Ping,网络延迟,,
Chart Mode,График,图表模式,,
24h,24ч,24小时,,
all,За все время,全部,,
,,,,
# Proxy Form,,,,
,,,,
Edit Proxy,Редактирование прокси,代理设置,編輯 Proxy,プロキシの編集
Use Proxy,Использовать прокси,使用代理,使用 Proxy,プロキシを利用する
Proxy Type,Тип прокси,代理类型,Proxy 類型,プロキシの種類
Proxy Addr,Адрес прокси,代理地址,Proxy 位址,プロキシアドレス
Proxy Port,Порт прокси,代理端口,Proxy 連接埠,プロキシポート
"If server has a plugin, proxy will not be used","Если сервер использует плагины, прокси НЕ будет использоваться",若服务器含有插件,代理将不被使用,若伺服器含有外掛程式,Proxy 將不被使用,サーバーにプラグインがある場合、プロキシは利用されません
Use Auth,Требуется авторизация,使用认证,使用認證,認証を利用する
User Name,Пользователь,用户名,認證用戶,認証ユーザ
Auth Pwd,Пароль,认证密码,認證口令,認証パスワード
,,,,
# Log Form,,,,
,,,,
&File,Файл,文件(&F),檔案 (&F),ファイル (&F)
&Open Location,Расположение файла,在资源管理器中打开(&O),在檔案總管中開啟 (&O),ファイルの場所を開く (&O)
E&xit,Выход,退出(&X),結束 (&X),終了 (&X)
&View,Вид,视图(&V),檢視 (&V),表示 (&V)
&Clear Logs,Очистить журнал,清空日志(&C),清除記錄檔 (&C),ログの削除 (&C)
Change &Font,Шрифт…,设置字体(&F),變更字型 (&F),フォント (&F)
&Wrap Text,Перенос строк,自动换行(&W),自動換行 (&W),右端で折り返す (&W)
&Top Most,Поверх всех окон,置顶(&T),置頂 (&T),常に最前面に表示 (&T)
&Show Toolbar,Панель инструментов,显示工具栏(&S),顯示工具列 (&S),ツールバーの表示 (&S)
Log Viewer,Просмотр журнала,日志查看器,記錄檔檢視器,ログビューア
Inbound,Входящая,入站,輸入,受信
Outbound,Исходящая,出站,輸出,送信
,,,,
# QRCode Form,,,,
,,,,
QRCode and URL,QRCode и URL,二维码与 URL,QR 碼與 URL,QR コードと URL
,,,,
# PAC Url Form,,,,
,,,,
Edit Online PAC URL,Изменение URL удаленного PAC,编辑在线 PAC 网址,編輯線上 PAC 網址,オンライン PAC URL の編集
Edit Online PAC URL...,Редактировать URL удаленного PAC…,编辑在线 PAC 网址...,編輯線上 PAC 網址...,オンライン PAC URL の編集...
Please input PAC Url,Введите URL адрес для PAC-файла,请输入 PAC 网址,請輸入 PAC 網址,PAC URLを入力して下さい
,,,,
# HotkeySettings Form,,,,
,,,,
Switch system proxy,ВКЛ/ВЫКЛ системный прокси-сервер,切换系统代理状态,切換系統 Proxy 狀態,システム プロキシの状態を切り替える
Switch system proxy mode,Переключение режима прокси-сервера,切换系统代理模式,切換系統 Proxy 模式,プロキシモードを切り替える
Allow Clients from LAN,Общий доступ к подключению,切换局域网共享,切換區域網路共用,LAN からのアクセスの許可を切り替える
Show Logs...,Просмотр журналов,显示日志,顯示記錄檔,ログの表示
Switch to previous server,Переключить на пред. сервер,切换上个服务器,切換上一個伺服器,前のサーバーに切り替える
Switch to next server,Переключить на след. сервер,切换下个服务器,切換下一個伺服器,次のサーバーに切り替える
Reg All,Применить все,注册全部快捷键,註冊所有快速鍵,全部登録する
Reg Hotkeys At Startup,Применять при запуске программы,启动时注册快捷键,啟動時註冊快速鍵,起動時にホットキーを登録する
,,,,
# Messages,,,,
,,,,
Shadowsocks Error: {0},Ошибка Shadowsocks: {0},Shadowsocks 错误: {0},Shadowsocks 錯誤: {0},Shadowsocks エラー: {0}
Port {0} already in use,Порт {0} уже используется,端口 {0} 已被占用,連接埠號碼 {0} 已被使用,ポート番号 {0} は既に使用されています。
Port {0} is reserved by system,Порт {0} зарезервирован системой,端口 {0} 是系统保留端口,連接埠號碼 {0} 由系統保留, ポート番号 {0} はシステムによって予約されています
Invalid server address,Неверный адрес сервера,非法服务器地址,無效伺服器位址,サーバーアドレスが無効です。
Illegal port number format,Неверный числовой формат порта,非法端口格式,無效連接埠號碼格式,ポート番号のフォーマットが無効です。
Illegal timeout format,Неверный формат таймаута,非法超时格式,無效逾時格式,タイムアウト値のフォーマットが無効です。
Server IP can not be blank,IP-адрес сервера не может быть пустым,服务器 IP 不能为空,伺服器 IP 不能為空,サーバー IP が指定されていません。
Password can not be blank,Пароль не может быть пустым,密码不能为空,密碼不能為空,パスワードが指定されていません。
Port out of range,Порт выходит за допустимый диапазон,端口超出范围,連接埠號碼超出範圍,ポート番号は範囲外です。
Port can't be 8123,Адрес порта 8123 не может быть использован,端口不能为 8123,連接埠號碼不能為 8123,8123 番以外のポート番号を指定して下さい。
Shadowsocks {0} Update Found,Обнаружена новая версия Shadowsocks: {0},Shadowsocks {0} 更新,Shadowsocks {0} 更新,Shadowsocks バージョン {0} は利用できます。
No update is available,Обновлений не обнаружено,没有可用的更新,沒有可用的更新,お使いのバージョンは最新です。
Click here to update,Нажмите сюда для обновления,点击这里升级,點按此處升級,クリックしてアップデートします。
Shadowsocks is here,Shadowsocks находится здесь,Shadowsocks 在这里,Shadowsocks 在這裡,Shadowsocks はここです。
You can turn on/off Shadowsocks in the context menu,Вы можете управлять Shadowsocks из контекстного меню,可以在右键菜单中开关 Shadowsocks,可以在右鍵選項單中開關 Shadowsocks,コンテキストメニューを使って、Shadowsocks を有効または無効にすることができます。
System Proxy Enabled,Системный прокси включен,系统代理已启用,系統 Proxy 已啟用,システム プロキシが有効です。
System Proxy Disabled,Системный прокси отключен,系统代理未启用,系統 Proxy 未啟用,システム プロキシが無効です。
Failed to update PAC file ,Не удалось обновить PAC файл,更新 PAC 文件失败,更新 PAC 檔案失敗,PAC の更新に失敗しました。
PAC updated,PAC файл обновлен,更新 PAC 成功,更新 PAC 成功,PAC を更新しました。
No updates found. Please report to GFWList if you have problems with it.,Обновлений не найдено. Сообщите авторам GFWList если у вас возникли проблемы.,未发现更新。如有问题请提交给 GFWList。,未發現更新。如有問題請報告至 GFWList。,お使いのバージョンは最新です。問題がある場合は、GFWList に報告して下さい。
No QRCode found. Try to zoom in or move it to the center of the screen.,QRCode не обнаружен. Попробуйте увеличить изображение или переместить его в центр экрана.,未发现二维码,尝试把它放大或移动到靠近屏幕中间的位置,未發現 QR 碼,嘗試把它放大或移動到靠近熒幕中間的位置,QR コードが見つかりませんでした。コードを大きくするか、画面の中央に移動して下さい。
Shadowsocks is already running.,Shadowsocks уже запущен.,Shadowsocks 已经在运行。,Shadowsocks 已經在執行。,Shadowsocks 実行中
Find Shadowsocks icon in your notify tray.,Значок Shadowsocks можно найти в области уведомлений.,请在任务栏里寻找 Shadowsocks 图标。,請在工作列裡尋找 Shadowsocks 圖示。,通知領域には Shadowsocks のアイコンがあります。
"If you want to start multiple Shadowsocks, make a copy in another directory.","Если вы хотите запустить несколько копий Shadowsocks одновременно, создайте отдельную папку на каждую копию.",如果想同时启动多个,可以另外复制一份到别的目录。,如果想同時啟動多個,可以另外複製一份至別的目錄。,複数起動したい場合は、プログラムファイルを別のフォルダーにコピーしてから、もう一度実行して下さい。
Failed to decode QRCode,Не удалось распознать QRCode,无法解析二维码,QR 碼解碼失敗,QR コードの読み取りに失敗しました。
Failed to update registry,Не удалось обновить запись в реестре,无法修改注册表,無法修改登錄檔,レジストリの更新に失敗しました。
System Proxy On: ,Системный прокси:,系统代理已启用:,系統 Proxy 已啟用:,システム プロキシが有効:
Running: Port {0},Запущен на порту {0},正在运行:端口 {0},正在執行:連接埠號碼 {0},実行中:ポート {0}
"Unexpected error, shadowsocks will exit. Please report to","Непредвиденная ошибка, пожалуйста сообщите на",非预期错误,Shadowsocks将退出。请提交此错误到,非預期錯誤,Shadowsocks 將結束。請報告此錯誤至,予想外のエラーが発生したため、Shadowsocks を終了します。詳しくは下記までお問い合わせ下さい:
"Unsupported operating system, use Windows Vista at least.","Операционная система не поддерживается, минимальные системные требования: Windows Vista или выше.",不支持的操作系统版本,最低需求为Windows Vista。,不支援的作業系統版本,最低需求為 Windows Vista。,お使いの OS はサポートされていません。Windows Vista 以降の OS で実行して下さい。
"Unsupported .NET Framework, please update to {0} or later.","Версия .NET Framework не поддерживается, минимальные системные требования: {0} или выше.",当前 .NET Framework 版本过低,请升级至{0}或更新版本。,目前 .NET Framework 版本過低,最低需求為{0}。,お使いの .NET Framework はサポートされていません。{0} 以降のバンジョーをインストールして下さい。
Proxy request failed,Не удалось выполнить запрос,代理请求失败,Proxy 要求失敗,プロキシ要求が失敗しました。
Proxy handshake failed,Не удалось выполнить хэндшейк,代理握手失败,Proxy 交握失敗,プロキシ ハンドシェイクに失敗しました。
Register hotkey failed,Не удалось применить настройки горячих клавиш,注册快捷键失败,註冊快速鍵失敗,ホットキーの登錄に失敗しました。
Cannot parse hotkey: {0},Не удалось распознать следующие горячие клавиши: {0},解析快捷键失败: {0},剖析快速鍵失敗: {0},ホットキーを解析できません: {0}
"Timeout is invalid, it should not exceed {0}",Таймаут не может превышать значение {0},超时无效,不应超过 {0},逾時無效,不應超過 {0},タイムアウト値が無効です。{0} 以下の値を指定して下さい。
Cannot find the plugin program file,Файл плагина не найден,找不到插件程序文件,找不到外掛程式文件,
,,,,
Operation failure,Операция завершилась неудачей,操作失败,,
Auto save failed,Автоматическое сохранение не удалось,自动保存失败,,
Whether to discard unconfigured servers,Внесенные изменения будут утеряны,是否丢弃未配置的服务器,,
"Invalid server address, Cannot automatically save or discard changes",Неверный адрес сервера. Невозможно сохранить или отменить изменения,非法服务器地址,无法自动保存,是否丢弃修改,,
"Illegal port number format, Cannot automatically save or discard changes",Неверный числовой адрес порта. Невозможно сохранить или отменить изменения,非法端口格式,无法自动保存,是否丢弃修改,,
"Password can not be blank, Cannot automatically save or discard changes",Пароль не может быть пустым. Невозможно сохранить или отменить изменения,密码不能为空,无法自动保存,是否丢弃修改,,
"Illegal timeout format, Cannot automatically save or discard changes",Неверный формат таймаута. Невозможно сохранить или отменить изменения,非法超时格式,无法自动保存,是否丢弃修改,,
,,,,
"Error occured when process proxy setting, do you want reset current setting and retry?",Произошла ошибка при обработке настроек. Хотите сбросить текущие настройки и попробовать снова?,处理代理设置时发生错误,是否重置当前代理设置并重试?,,
"Unrecoverable proxy setting error occured, see log for detail","Произошла серьезная ошибка, подробности можно узнать в журналах",发生不可恢复的代理设置错误,查看日志以取得详情,,
Auth user can not be blank,Пользователь не может быть пустым,认证用户不能为空,認證用戶不能為空,認証ユーザが指定されていません。
Auth pwd can not be blank,Пароль не может быть пустым,认证密码不能为空,認證口令不能為空,認証パスワードが指定されていません。

+ 20
- 18
shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs View File

@@ -1,4 +1,5 @@
using System;
using NLog;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
@@ -13,6 +14,7 @@ namespace Shadowsocks.Encryption.AEAD
public abstract class AEADEncryptor
: EncryptorBase
{
private static Logger logger = LogManager.GetCurrentClassLogger();
// We are using the same saltLen and keyLen
private const string Info = "ss-subkey";
private static readonly byte[] InfoBytes = Encoding.ASCII.GetBytes(Info);
@@ -122,7 +124,7 @@ namespace Shadowsocks.Encryption.AEAD
_decryptSalt = new byte[saltLen];
Array.Copy(salt, _decryptSalt, saltLen);
}
Logging.Dump("Salt", salt, saltLen);
logger.Dump("Salt", salt, saltLen);
}
public static void randBytes(byte[] buf, int length) { RNG.GetBytes(buf, length); }
@@ -139,7 +141,7 @@ namespace Shadowsocks.Encryption.AEAD
_encCircularBuffer.Put(buf, 0, length);
outlength = 0;
Logging.Debug("---Start Encryption");
logger.Debug("---Start Encryption");
if (! _encryptSaltSent) {
_encryptSaltSent = true;
// Generate salt
@@ -148,7 +150,7 @@ namespace Shadowsocks.Encryption.AEAD
InitCipher(saltBytes, true, false);
Array.Copy(saltBytes, 0, outbuf, 0, saltLen);
outlength = saltLen;
Logging.Debug($"_encryptSaltSent outlength {outlength}");
logger.Debug($"_encryptSaltSent outlength {outlength}");
}
if (! _tcpRequestSent) {
@@ -161,7 +163,7 @@ namespace Shadowsocks.Encryption.AEAD
Debug.Assert(encAddrBufLength == AddrBufLength + tagLen * 2 + CHUNK_LEN_BYTES);
Array.Copy(encAddrBufBytes, 0, outbuf, outlength, encAddrBufLength);
outlength += encAddrBufLength;
Logging.Debug($"_tcpRequestSent outlength {outlength}");
logger.Debug($"_tcpRequestSent outlength {outlength}");
}
// handle other chunks
@@ -176,15 +178,15 @@ namespace Shadowsocks.Encryption.AEAD
Debug.Assert(encChunkLength == chunklength + tagLen * 2 + CHUNK_LEN_BYTES);
Buffer.BlockCopy(encChunkBytes, 0, outbuf, outlength, encChunkLength);
outlength += encChunkLength;
Logging.Debug("chunks enc outlength " + outlength);
logger.Debug("chunks enc outlength " + outlength);
// check if we have enough space for outbuf
if (outlength + TCPHandler.ChunkOverheadSize > TCPHandler.BufferSize) {
Logging.Debug("enc outbuf almost full, giving up");
logger.Debug("enc outbuf almost full, giving up");
return;
}
bufSize = (uint)_encCircularBuffer.Size;
if (bufSize <= 0) {
Logging.Debug("No more data to encrypt, leaving");
logger.Debug("No more data to encrypt, leaving");
return;
}
}
@@ -199,7 +201,7 @@ namespace Shadowsocks.Encryption.AEAD
// drop all into buffer
_decCircularBuffer.Put(buf, 0, length);
Logging.Debug("---Start Decryption");
logger.Debug("---Start Decryption");
if (! _decryptSaltReceived) {
bufSize = _decCircularBuffer.Size;
// check if we get the leading salt
@@ -210,7 +212,7 @@ namespace Shadowsocks.Encryption.AEAD
_decryptSaltReceived = true;
byte[] salt = _decCircularBuffer.Get(saltLen);
InitCipher(salt, false, false);
Logging.Debug("get salt len " + saltLen);
logger.Debug("get salt len " + saltLen);
}
// handle chunks
@@ -218,7 +220,7 @@ namespace Shadowsocks.Encryption.AEAD
bufSize = _decCircularBuffer.Size;
// check if we have any data
if (bufSize <= 0) {
Logging.Debug("No data in _decCircularBuffer");
logger.Debug("No data in _decCircularBuffer");
return;
}
@@ -241,13 +243,13 @@ namespace Shadowsocks.Encryption.AEAD
if (chunkLen > CHUNK_LEN_MASK)
{
// we get invalid chunk
Logging.Error($"Invalid chunk length: {chunkLen}");
logger.Error($"Invalid chunk length: {chunkLen}");
throw new CryptoErrorException();
}
Logging.Debug("Get the real chunk len:" + chunkLen);
logger.Debug("Get the real chunk len:" + chunkLen);
bufSize = _decCircularBuffer.Size;
if (bufSize < CHUNK_LEN_BYTES + tagLen /* we haven't remove them */+ chunkLen + tagLen) {
Logging.Debug("No more data to decrypt one chunk");
logger.Debug("No more data to decrypt one chunk");
return;
}
IncrementNonce(false);
@@ -267,16 +269,16 @@ namespace Shadowsocks.Encryption.AEAD
// output to outbuf
Buffer.BlockCopy(decChunkBytes, 0, outbuf, outlength, (int) decChunkLen);
outlength += (int)decChunkLen;
Logging.Debug("aead dec outlength " + outlength);
logger.Debug("aead dec outlength " + outlength);
if (outlength + 100 > TCPHandler.BufferSize)
{
Logging.Debug("dec outbuf almost full, giving up");
logger.Debug("dec outbuf almost full, giving up");
return;
}
bufSize = _decCircularBuffer.Size;
// check if we already done all of them
if (bufSize <= 0) {
Logging.Debug("No data in _decCircularBuffer, already all done");
logger.Debug("No data in _decCircularBuffer, already all done");
return;
}
}
@@ -319,7 +321,7 @@ namespace Shadowsocks.Encryption.AEAD
private void ChunkEncrypt(byte[] plaintext, int plainLen, byte[] ciphertext, out int cipherLen)
{
if (plainLen > CHUNK_LEN_MASK) {
Logging.Error("enc chunk too big");
logger.Error("enc chunk too big");
throw new CryptoErrorException();
}


+ 11
- 8
shadowsocks-csharp/Encryption/AEAD/AEADSodiumEncryptor.cs View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using NLog;
using Shadowsocks.Controller;
using Shadowsocks.Encryption.Exception;
@@ -9,6 +10,8 @@ namespace Shadowsocks.Encryption.AEAD
public class AEADSodiumEncryptor
: AEADEncryptor, IDisposable
{
private static Logger logger = LogManager.GetCurrentClassLogger();
private const int CIPHER_CHACHA20IETFPOLY1305 = 1;
private const int CIPHER_XCHACHA20IETFPOLY1305 = 2;
private const int CIPHER_AES256GCM = 3;
@@ -55,9 +58,9 @@ namespace Shadowsocks.Encryption.AEAD
// outbuf: ciphertext + tag
int ret;
ulong encClen = 0;
Logging.Dump("_encNonce before enc", _encNonce, nonceLen);
Logging.Dump("_sodiumEncSubkey", _sodiumEncSubkey, keyLen);
Logging.Dump("before cipherEncrypt: plain", plaintext, (int) plen);
logger.Dump("_encNonce before enc", _encNonce, nonceLen);
logger.Dump("_sodiumEncSubkey", _sodiumEncSubkey, keyLen);
logger.Dump("before cipherEncrypt: plain", plaintext, (int) plen);
switch (_cipher)
{
case CIPHER_CHACHA20IETFPOLY1305:
@@ -85,7 +88,7 @@ namespace Shadowsocks.Encryption.AEAD
throw new System.Exception("not implemented");
}
if (ret != 0) throw new CryptoErrorException(String.Format("ret is {0}", ret));
Logging.Dump("after cipherEncrypt: cipher", ciphertext, (int) encClen);
logger.Dump("after cipherEncrypt: cipher", ciphertext, (int) encClen);
clen = (uint) encClen;
}
@@ -96,9 +99,9 @@ namespace Shadowsocks.Encryption.AEAD
// outbuf: plaintext
int ret;
ulong decPlen = 0;
Logging.Dump("_decNonce before dec", _decNonce, nonceLen);
Logging.Dump("_sodiumDecSubkey", _sodiumDecSubkey, keyLen);
Logging.Dump("before cipherDecrypt: cipher", ciphertext, (int) clen);
logger.Dump("_decNonce before dec", _decNonce, nonceLen);
logger.Dump("_sodiumDecSubkey", _sodiumDecSubkey, keyLen);
logger.Dump("before cipherDecrypt: cipher", ciphertext, (int) clen);
switch (_cipher)
{
case CIPHER_CHACHA20IETFPOLY1305:
@@ -127,7 +130,7 @@ namespace Shadowsocks.Encryption.AEAD
}
if (ret != 0) throw new CryptoErrorException(String.Format("ret is {0}", ret));
Logging.Dump("after cipherDecrypt: plain", plaintext, (int) decPlen);
logger.Dump("after cipherDecrypt: plain", plaintext, (int) decPlen);
plen = (uint) decPlen;
}


+ 3
- 0
shadowsocks-csharp/Encryption/MbedTLS.cs View File

@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using NLog;
using Shadowsocks.Controller;
using Shadowsocks.Properties;
using Shadowsocks.Util;
@@ -9,6 +10,8 @@ namespace Shadowsocks.Encryption
{
public static class MbedTLS
{
private static Logger logger = LogManager.GetCurrentClassLogger();
private const string DLLNAME = "libsscrypto.dll";
public const int MBEDTLS_ENCRYPT = 1;


+ 3
- 0
shadowsocks-csharp/Encryption/OpenSSL.cs View File

@@ -3,6 +3,7 @@ using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using NLog;
using Shadowsocks.Controller;
using Shadowsocks.Encryption.Exception;
using Shadowsocks.Properties;
@@ -13,6 +14,8 @@ namespace Shadowsocks.Encryption
// XXX: only for OpenSSL 1.1.0 and higher
public static class OpenSSL
{
private static Logger logger = LogManager.GetCurrentClassLogger();
private const string DLLNAME = "libsscrypto.dll";
public const int OPENSSL_ENCRYPT = 1;


+ 4
- 1
shadowsocks-csharp/Encryption/Sodium.cs View File

@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using NLog;
using Shadowsocks.Controller;
using Shadowsocks.Properties;
using Shadowsocks.Util;
@@ -9,6 +10,8 @@ namespace Shadowsocks.Encryption
{
public static class Sodium
{
private static Logger logger = LogManager.GetCurrentClassLogger();
private const string DLLNAME = "libsscrypto.dll";
private static bool _initialized = false;
@@ -34,7 +37,7 @@ namespace Shadowsocks.Encryption
}
AES256GCMAvailable = crypto_aead_aes256gcm_is_available() == 1;
Logging.Debug($"sodium: AES256GCMAvailable is {AES256GCMAvailable}");
logger.Debug($"sodium: AES256GCMAvailable is {AES256GCMAvailable}");
}
}
}


+ 56
- 5
shadowsocks-csharp/Model/Configuration.cs View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using NLog;
using Shadowsocks.Controller;
namespace Shadowsocks.Model
@@ -9,6 +10,9 @@ namespace Shadowsocks.Model
[Serializable]
public class Configuration
{
[JsonIgnore]
private static Logger logger = LogManager.GetCurrentClassLogger();
public string version;
public List<Server> configs;
@@ -32,14 +36,23 @@ namespace Shadowsocks.Model
public bool autoCheckUpdate;
public bool checkPreRelease;
public bool isVerboseLogging;
//public NLogConfig.LogLevel logLevel;
public LogViewerConfig logViewer;
public ProxyConfig proxy;
public HotkeyConfig hotkey;
[JsonIgnore]
NLogConfig nLogConfig;
private static readonly string CONFIG_FILE = "gui-config.json";
[JsonIgnore]
public bool updated = false;
[JsonIgnore]
public string localHost => GetLocalHost();
private string GetLocalHost() {
private string GetLocalHost()
{
return isIPv6Enabled ? "[::1]" : "127.0.0.1";
}
public Server GetCurrentServer()
@@ -78,6 +91,10 @@ namespace Shadowsocks.Model
string configContent = File.ReadAllText(CONFIG_FILE);
Configuration config = JsonConvert.DeserializeObject<Configuration>(configContent);
config.isDefault = false;
if (UpdateChecker.Asset.CompareVersion(UpdateChecker.Version, config.version ?? "0") > 0)
{
config.updated = true;
}
if (config.configs == null)
config.configs = new List<Server>();
@@ -93,19 +110,43 @@ namespace Shadowsocks.Model
config.proxy = new ProxyConfig();
if (config.hotkey == null)
config.hotkey = new HotkeyConfig();
if (!System.Net.Sockets.Socket.OSSupportsIPv6) {
if (!System.Net.Sockets.Socket.OSSupportsIPv6)
{
config.isIPv6Enabled = false; // disable IPv6 if os not support
}
//TODO if remote host(server) do not support IPv6 (or DNS resolve AAAA TYPE record) disable IPv6?
config.proxy.CheckConfig();
try
{
config.nLogConfig = NLogConfig.LoadXML();
switch (config.nLogConfig.GetLogLevel())
{
case NLogConfig.LogLevel.Fatal:
case NLogConfig.LogLevel.Error:
case NLogConfig.LogLevel.Warn:
case NLogConfig.LogLevel.Info:
config.isVerboseLogging = false;
break;
case NLogConfig.LogLevel.Debug:
case NLogConfig.LogLevel.Trace:
config.isVerboseLogging = true;
break;
}
}
catch (Exception e)
{
// todo: route the error to UI since there is no log file in this scenario
logger.Error(e, "Cannot get the log level from NLog config file. Please check if the nlog config file exists with corresponding XML nodes.");
}
return config;
}
catch (Exception e)
{
if (!(e is FileNotFoundException))
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
return new Configuration
{
index = 0,
@@ -118,7 +159,7 @@ namespace Shadowsocks.Model
},
logViewer = new LogViewerConfig(),
proxy = new ProxyConfig(),
hotkey = new HotkeyConfig()
hotkey = new HotkeyConfig(),
};
}
}
@@ -141,10 +182,20 @@ namespace Shadowsocks.Model
sw.Write(jsonString);
sw.Flush();
}
try
{
// apply changs to NLog.config
config.nLogConfig.SetLogLevel(config.isVerboseLogging? NLogConfig.LogLevel.Trace: NLogConfig.LogLevel.Info);
NLogConfig.SaveXML(config.nLogConfig);
}
catch(Exception e)
{
logger.Error(e, "Cannot set the log level to NLog config file. Please check if the nlog config file exists with corresponding XML nodes.");
}
}
catch (IOException e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
}
}


+ 122
- 0
shadowsocks-csharp/Model/NlogConfig.cs View File

@@ -0,0 +1,122 @@
using NLog;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace Shadowsocks.Model
{
public class NLogConfig
{
public enum LogLevel
{
Fatal,
Error,
Warn,
Info,
Debug,
Trace,
}
const string NLOG_CONFIG_FILE_NAME = "nLog.config";
const string TARGET_MIN_LEVEL_ATTRIBUTE = "minlevel";
const string LOGGER_FILE_NAME_ATTRIBUTE = "fileName";
XmlDocument doc = new XmlDocument();
XmlElement logFileNameElement;
XmlElement logLevelElement;
/// <summary>
/// Load the NLog config xml file content
/// </summary>
public static NLogConfig LoadXML()
{
NLogConfig config = new NLogConfig();
config.doc.Load(NLOG_CONFIG_FILE_NAME);
config.logLevelElement = (XmlElement)SelectSingleNode(config.doc, "//nlog:logger[@name='*']");
config.logFileNameElement = (XmlElement)SelectSingleNode(config.doc, "//nlog:target[@name='file']");
return config;
}
/// <summary>
/// Save the content to NLog config xml file
/// </summary>
public static void SaveXML(NLogConfig nLogConfig)
{
nLogConfig.doc.Save(NLOG_CONFIG_FILE_NAME);
}
/// <summary>
/// Get the current minLogLevel from xml file
/// </summary>
/// <returns></returns>
public LogLevel GetLogLevel()
{
LogLevel level = LogLevel.Warn;
string levelStr = logLevelElement.GetAttribute(TARGET_MIN_LEVEL_ATTRIBUTE);
Enum.TryParse(levelStr, out level);
return level;
}
/// <summary>
/// Get the target fileName from xml file
/// </summary>
/// <returns></returns>
public string GetLogFileName()
{
return logFileNameElement.GetAttribute(LOGGER_FILE_NAME_ATTRIBUTE);
}
/// <summary>
/// Set the minLogLevel to xml file
/// </summary>
/// <param name="logLevel"></param>
public void SetLogLevel(LogLevel logLevel)
{
logLevelElement.SetAttribute(TARGET_MIN_LEVEL_ATTRIBUTE, logLevel.ToString("G"));
}
/// <summary>
/// Set the target fileName to xml file
/// </summary>
/// <param name="fileName"></param>
public void SetLogFileName(string fileName)
{
logFileNameElement.SetAttribute(LOGGER_FILE_NAME_ATTRIBUTE, fileName);
}
/// <summary>
/// Select a single XML node/elemant
/// </summary>
/// <param name="doc"></param>
/// <param name="xpath"></param>
/// <returns></returns>
private static XmlNode SelectSingleNode(XmlDocument doc, string xpath)
{
XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable);
manager.AddNamespace("nlog", "http://www.nlog-project.org/schemas/NLog.xsd");
//return doc.SelectSingleNode("//nlog:logger[(@shadowsocks='managed') and (@name='*')]", manager);
return doc.SelectSingleNode(xpath, manager);
}
/// <summary>
/// Extract the pre-defined NLog configuration file is does not exist. Then reload the Nlog configuration.
/// </summary>
public static void TouchAndApplyNLogConfig()
{
LogManager.LoadConfiguration(NLOG_CONFIG_FILE_NAME);
}
/// <summary>
/// NLog reload the config file and apply to current LogManager
/// </summary>
public static void LoadConfiguration()
{
LogManager.LoadConfiguration(NLOG_CONFIG_FILE_NAME);
}
}
}

+ 5
- 3
shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs View File

@@ -5,7 +5,7 @@ using System.Linq;
using System.Reflection;

using Newtonsoft.Json;
using NLog;
using Shadowsocks.Controller;

namespace Shadowsocks.Model
@@ -13,6 +13,8 @@ namespace Shadowsocks.Model
[Serializable]
public class StatisticsStrategyConfiguration
{
private static Logger logger = LogManager.GetCurrentClassLogger();

public static readonly string ID = "com.shadowsocks.strategy.statistics";
public bool StatisticsEnabled { get; set; } = false;
public bool ByHourOfDay { get; set; } = true;
@@ -39,7 +41,7 @@ namespace Shadowsocks.Model
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
return new StatisticsStrategyConfiguration();
}
}
@@ -53,7 +55,7 @@ namespace Shadowsocks.Model
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
}
}



+ 15
- 12
shadowsocks-csharp/Program.cs View File

@@ -3,6 +3,7 @@ using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using NLog;
using Microsoft.Win32;
using Shadowsocks.Controller;
@@ -14,6 +15,7 @@ namespace Shadowsocks
{
static class Program
{
private static Logger logger = LogManager.GetCurrentClassLogger();
public static ShadowsocksController MainController { get; private set; }
public static MenuViewController MenuController { get; private set; }
public static string[] Args { get; private set; }
@@ -24,8 +26,11 @@ namespace Shadowsocks
[STAThread]
static void Main(string[] args)
{
// todo: initialize the NLog configuartion
Model.NLogConfig.TouchAndApplyNLogConfig();
// .NET Framework 4.7.2 on Win7 compatibility
System.Net.ServicePointManager.SecurityProtocol |=
System.Net.ServicePointManager.SecurityProtocol |=
System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12;
// store args for further use
@@ -78,18 +83,16 @@ namespace Shadowsocks
return;
}
Directory.SetCurrentDirectory(Application.StartupPath);
#if DEBUG
Logging.OpenLogFile();
// truncate privoxy log file while debugging
string privoxyLogFilename = Utils.GetTempPath("privoxy.log");
if (File.Exists(privoxyLogFilename))
using (new FileStream(privoxyLogFilename, FileMode.Truncate)) { }
#else
Logging.OpenLogFile();
#endif
MainController = new ShadowsocksController();
MenuController = new MenuViewController(MainController);
HotKeys.Init(MainController);
MainController.Start();
Application.Run();
@@ -102,7 +105,7 @@ namespace Shadowsocks
if (Interlocked.Increment(ref exited) == 1)
{
string errMsg = e.ExceptionObject.ToString();
Logging.Error(errMsg);
logger.Error(errMsg);
MessageBox.Show(
$"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{errMsg}",
"Shadowsocks non-UI Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
@@ -115,7 +118,7 @@ namespace Shadowsocks
if (Interlocked.Increment(ref exited) == 1)
{
string errorMsg = $"Exception Detail: {Environment.NewLine}{e.Exception}";
Logging.Error(errorMsg);
logger.Error(errorMsg);
MessageBox.Show(
$"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{errorMsg}",
"Shadowsocks UI Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
@@ -128,7 +131,7 @@ namespace Shadowsocks
switch (e.Mode)
{
case PowerModes.Resume:
Logging.Info("os wake up");
logger.Info("os wake up");
if (MainController != null)
{
System.Threading.Tasks.Task.Factory.StartNew(() =>
@@ -137,11 +140,11 @@ namespace Shadowsocks
try
{
MainController.Start(false);
Logging.Info("controller started");
logger.Info("controller started");
}
catch (Exception ex)
{
Logging.LogUsefulException(ex);
logger.LogUsefulException(ex);
}
});
}
@@ -150,9 +153,9 @@ namespace Shadowsocks
if (MainController != null)
{
MainController.Stop();
Logging.Info("controller stopped");
logger.Info("controller stopped");
}
Logging.Info("os suspend");
logger.Info("os suspend");
break;
}
}


+ 4
- 1
shadowsocks-csharp/Proxy/HttpProxy.cs View File

@@ -4,6 +4,7 @@ using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using NLog;
using Shadowsocks.Controller;
using Shadowsocks.Util.Sockets;

@@ -11,6 +12,8 @@ namespace Shadowsocks.Proxy
{
public class HttpProxy : IProxy
{
private static Logger logger = LogManager.GetCurrentClassLogger();

private class FakeAsyncResult : IAsyncResult
{
public readonly HttpState innerState;
@@ -179,7 +182,7 @@ namespace Shadowsocks.Proxy

private bool OnLineRead(string line, object state)
{
Logging.Debug(line);
logger.Debug(line);

if (_respondLineCount == 0)
{


+ 4
- 1
shadowsocks-csharp/Util/ProcessManagement/Job.cs View File

@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using NLog;
using Shadowsocks.Controller;

namespace Shadowsocks.Util.ProcessManagement
@@ -11,6 +12,8 @@ namespace Shadowsocks.Util.ProcessManagement
*/
public class Job : IDisposable
{
private static Logger logger = LogManager.GetCurrentClassLogger();

private IntPtr handle = IntPtr.Zero;

public Job()
@@ -54,7 +57,7 @@ namespace Shadowsocks.Util.ProcessManagement

if (!succ)
{
Logging.Error("Failed to call AssignProcessToJobObject! GetLastError=" + Marshal.GetLastWin32Error());
logger.Error("Failed to call AssignProcessToJobObject! GetLastError=" + Marshal.GetLastWin32Error());
}

return succ;


+ 5
- 2
shadowsocks-csharp/Util/SystemProxy/Sysproxy.cs View File

@@ -1,4 +1,5 @@
using Newtonsoft.Json;
using NLog;
using Shadowsocks.Controller;
using Shadowsocks.Model;
using Shadowsocks.Properties;
@@ -14,6 +15,8 @@ namespace Shadowsocks.Util.SystemProxy
{
public static class Sysproxy
{
private static Logger logger = LogManager.GetCurrentClassLogger();
private const string _userWininetConfigFile = "user-wininet.json";
private readonly static string[] _lanIP = {
@@ -70,7 +73,7 @@ namespace Shadowsocks.Util.SystemProxy
}
catch (IOException e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
}
}
@@ -238,7 +241,7 @@ namespace Shadowsocks.Util.SystemProxy
}
catch (IOException e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
}
}


+ 11
- 9
shadowsocks-csharp/Util/Util.cs View File

@@ -1,4 +1,5 @@
using System;
using NLog;
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
@@ -26,6 +27,8 @@ namespace Shadowsocks.Util
public static class Utils
{
private static Logger logger = LogManager.GetCurrentClassLogger();
private static string _tempPath = null;
// return path to store temporary files
@@ -48,7 +51,7 @@ namespace Shadowsocks.Util
}
catch (Exception e)
{
Logging.Error(e);
logger.Error(e);
throw;
}
}
@@ -58,7 +61,7 @@ namespace Shadowsocks.Util
public enum WindowsThemeMode { Dark, Light }
// Support on Windows 10 1903+
public static WindowsThemeMode GetWindows10SystemThemeSetting(bool isVerbose)
public static WindowsThemeMode GetWindows10SystemThemeSetting()
{
WindowsThemeMode themeMode = WindowsThemeMode.Dark;
try
@@ -78,11 +81,10 @@ namespace Shadowsocks.Util
}
catch
{
if (isVerbose)
{
Logging.Info(
$"Cannot get Windows 10 system theme mode, return default value 0 (dark mode).");
}
logger.Debug(
$"Cannot get Windows 10 system theme mode, return default value 0 (dark mode).");
}
return themeMode;
}
@@ -232,7 +234,7 @@ namespace Shadowsocks.Util
}
catch (Exception e)
{
Logging.LogUsefulException(e);
logger.LogUsefulException(e);
return null;
}
}


+ 123
- 116
shadowsocks-csharp/View/ConfigForm.Designer.cs View File

@@ -106,10 +106,10 @@
this.tableLayoutPanel1.Controls.Add(this.PluginArgumentsLabel, 0, 8);
this.tableLayoutPanel1.Controls.Add(this.RemarksLabel, 0, 10);
this.tableLayoutPanel1.Controls.Add(this.NeedPluginArgCheckBox, 1, 7);
this.tableLayoutPanel1.Location = new System.Drawing.Point(8, 21);
this.tableLayoutPanel1.Location = new System.Drawing.Point(10, 26);
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(3);
this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(4);
this.tableLayoutPanel1.RowCount = 12;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
@@ -123,16 +123,17 @@
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.Size = new System.Drawing.Size(279, 292);
this.tableLayoutPanel1.Size = new System.Drawing.Size(394, 357);
this.tableLayoutPanel1.TabIndex = 0;
//
// PluginOptionsLabel
//
this.PluginOptionsLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.PluginOptionsLabel.AutoSize = true;
this.PluginOptionsLabel.Location = new System.Drawing.Point(18, 166);
this.PluginOptionsLabel.Location = new System.Drawing.Point(24, 203);
this.PluginOptionsLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.PluginOptionsLabel.Name = "PluginOptionsLabel";
this.PluginOptionsLabel.Size = new System.Drawing.Size(89, 12);
this.PluginOptionsLabel.Size = new System.Drawing.Size(119, 15);
this.PluginOptionsLabel.TabIndex = 6;
this.PluginOptionsLabel.Text = "Plugin Options";
this.toolTip1.SetToolTip(this.PluginOptionsLabel, "Environment variables for plugin program");
@@ -140,20 +141,22 @@
// PluginTextBox
//
this.PluginTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.PluginTextBox.Location = new System.Drawing.Point(113, 135);
this.PluginTextBox.Location = new System.Drawing.Point(151, 165);
this.PluginTextBox.Margin = new System.Windows.Forms.Padding(4);
this.PluginTextBox.MaxLength = 256;
this.PluginTextBox.Name = "PluginTextBox";
this.PluginTextBox.Size = new System.Drawing.Size(160, 21);
this.PluginTextBox.Size = new System.Drawing.Size(235, 25);
this.PluginTextBox.TabIndex = 5;
this.PluginTextBox.WordWrap = false;
//
// RemarksTextBox
//
this.RemarksTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.RemarksTextBox.Location = new System.Drawing.Point(113, 238);
this.RemarksTextBox.Location = new System.Drawing.Point(151, 291);
this.RemarksTextBox.Margin = new System.Windows.Forms.Padding(4);
this.RemarksTextBox.MaxLength = 32;
this.RemarksTextBox.Name = "RemarksTextBox";
this.RemarksTextBox.Size = new System.Drawing.Size(160, 21);
this.RemarksTextBox.Size = new System.Drawing.Size(235, 25);
this.RemarksTextBox.TabIndex = 8;
this.RemarksTextBox.WordWrap = false;
//
@@ -161,9 +164,10 @@
//
this.IPLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.IPLabel.AutoSize = true;
this.IPLabel.Location = new System.Drawing.Point(48, 10);
this.IPLabel.Location = new System.Drawing.Point(64, 13);
this.IPLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.IPLabel.Name = "IPLabel";
this.IPLabel.Size = new System.Drawing.Size(59, 12);
this.IPLabel.Size = new System.Drawing.Size(79, 15);
this.IPLabel.TabIndex = 0;
this.IPLabel.Text = "Server IP";
//
@@ -171,9 +175,10 @@
//
this.ServerPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.ServerPortLabel.AutoSize = true;
this.ServerPortLabel.Location = new System.Drawing.Point(36, 37);
this.ServerPortLabel.Location = new System.Drawing.Point(48, 46);
this.ServerPortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.ServerPortLabel.Name = "ServerPortLabel";
this.ServerPortLabel.Size = new System.Drawing.Size(71, 12);
this.ServerPortLabel.Size = new System.Drawing.Size(95, 15);
this.ServerPortLabel.TabIndex = 1;
this.ServerPortLabel.Text = "Server Port";
//
@@ -181,9 +186,10 @@
//
this.PasswordLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.PasswordLabel.AutoSize = true;
this.PasswordLabel.Location = new System.Drawing.Point(54, 64);
this.PasswordLabel.Location = new System.Drawing.Point(72, 79);
this.PasswordLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.PasswordLabel.Name = "PasswordLabel";
this.PasswordLabel.Size = new System.Drawing.Size(53, 12);
this.PasswordLabel.Size = new System.Drawing.Size(71, 15);
this.PasswordLabel.TabIndex = 2;
this.PasswordLabel.Text = "Password";
this.PasswordLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
@@ -191,30 +197,34 @@
// IPTextBox
//
this.IPTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.IPTextBox.Location = new System.Drawing.Point(113, 6);
this.IPTextBox.Location = new System.Drawing.Point(151, 8);
this.IPTextBox.Margin = new System.Windows.Forms.Padding(4);
this.IPTextBox.MaxLength = 512;
this.IPTextBox.Name = "IPTextBox";
this.IPTextBox.Size = new System.Drawing.Size(160, 21);
this.IPTextBox.Size = new System.Drawing.Size(235, 25);
this.IPTextBox.TabIndex = 0;
this.IPTextBox.WordWrap = false;
//
// ServerPortTextBox
//
this.ServerPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.ServerPortTextBox.Location = new System.Drawing.Point(113, 33);
this.ServerPortTextBox.Location = new System.Drawing.Point(151, 41);
this.ServerPortTextBox.Margin = new System.Windows.Forms.Padding(4);
this.ServerPortTextBox.MaxLength = 10;
this.ServerPortTextBox.Name = "ServerPortTextBox";
this.ServerPortTextBox.Size = new System.Drawing.Size(160, 21);
this.ServerPortTextBox.Size = new System.Drawing.Size(235, 25);
this.ServerPortTextBox.TabIndex = 1;
this.ServerPortTextBox.WordWrap = false;
//
// PasswordTextBox
//
this.PasswordTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.PasswordTextBox.Location = new System.Drawing.Point(113, 60);
this.PasswordTextBox.Font = new System.Drawing.Font("Consolas", 9F);
this.PasswordTextBox.Location = new System.Drawing.Point(151, 74);
this.PasswordTextBox.Margin = new System.Windows.Forms.Padding(4);
this.PasswordTextBox.MaxLength = 256;
this.PasswordTextBox.Name = "PasswordTextBox";
this.PasswordTextBox.Size = new System.Drawing.Size(160, 21);
this.PasswordTextBox.Size = new System.Drawing.Size(235, 25);
this.PasswordTextBox.TabIndex = 2;
this.PasswordTextBox.UseSystemPasswordChar = true;
this.PasswordTextBox.WordWrap = false;
@@ -223,9 +233,10 @@
//
this.EncryptionLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.EncryptionLabel.AutoSize = true;
this.EncryptionLabel.Location = new System.Drawing.Point(42, 113);
this.EncryptionLabel.Location = new System.Drawing.Point(56, 138);
this.EncryptionLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.EncryptionLabel.Name = "EncryptionLabel";
this.EncryptionLabel.Size = new System.Drawing.Size(65, 12);
this.EncryptionLabel.Size = new System.Drawing.Size(87, 15);
this.EncryptionLabel.TabIndex = 4;
this.EncryptionLabel.Text = "Encryption";
//
@@ -236,69 +247,54 @@
this.EncryptionSelect.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.EncryptionSelect.FormattingEnabled = true;
this.EncryptionSelect.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.EncryptionSelect.ItemHeight = 12;
this.EncryptionSelect.Items.AddRange(new object[] {
"rc4-md5",
"salsa20",
"chacha20",
"chacha20-ietf",
"aes-256-cfb",
"aes-192-cfb",
"aes-128-cfb",
"aes-256-ctr",
"aes-192-ctr",
"aes-128-ctr",
"bf-cfb",
"camellia-128-cfb",
"camellia-192-cfb",
"camellia-256-cfb",
"aes-128-gcm",
"aes-192-gcm",
"aes-256-gcm",
"chacha20-ietf-poly1305",
"xchacha20-ietf-poly1305"});
this.EncryptionSelect.Location = new System.Drawing.Point(113, 109);
this.EncryptionSelect.ItemHeight = 15;
this.EncryptionSelect.Location = new System.Drawing.Point(151, 134);
this.EncryptionSelect.Margin = new System.Windows.Forms.Padding(4);
this.EncryptionSelect.Name = "EncryptionSelect";
this.EncryptionSelect.Size = new System.Drawing.Size(160, 20);
this.EncryptionSelect.Size = new System.Drawing.Size(235, 23);
this.EncryptionSelect.TabIndex = 4;
//
// TimeoutLabel
//
this.TimeoutLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.TimeoutLabel.AutoSize = true;
this.TimeoutLabel.Location = new System.Drawing.Point(30, 269);
this.TimeoutLabel.Location = new System.Drawing.Point(40, 329);
this.TimeoutLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.TimeoutLabel.Name = "TimeoutLabel";
this.TimeoutLabel.RightToLeft = System.Windows.Forms.RightToLeft.No;
this.TimeoutLabel.Size = new System.Drawing.Size(77, 12);
this.TimeoutLabel.Size = new System.Drawing.Size(103, 15);
this.TimeoutLabel.TabIndex = 9;
this.TimeoutLabel.Text = "Timeout(Sec)";
//
// TimeoutTextBox
//
this.TimeoutTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.TimeoutTextBox.Location = new System.Drawing.Point(113, 265);
this.TimeoutTextBox.Location = new System.Drawing.Point(151, 324);
this.TimeoutTextBox.Margin = new System.Windows.Forms.Padding(4);
this.TimeoutTextBox.MaxLength = 5;
this.TimeoutTextBox.Name = "TimeoutTextBox";
this.TimeoutTextBox.Size = new System.Drawing.Size(160, 21);
this.TimeoutTextBox.Size = new System.Drawing.Size(235, 25);
this.TimeoutTextBox.TabIndex = 9;
//
// PluginLabel
//
this.PluginLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.PluginLabel.AutoSize = true;
this.PluginLabel.Location = new System.Drawing.Point(18, 139);
this.PluginLabel.Location = new System.Drawing.Point(24, 170);
this.PluginLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.PluginLabel.Name = "PluginLabel";
this.PluginLabel.Size = new System.Drawing.Size(89, 12);
this.PluginLabel.Size = new System.Drawing.Size(119, 15);
this.PluginLabel.TabIndex = 5;
this.PluginLabel.Text = "Plugin Program";
//
// PluginOptionsTextBox
//
this.PluginOptionsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.PluginOptionsTextBox.Location = new System.Drawing.Point(113, 162);
this.PluginOptionsTextBox.Location = new System.Drawing.Point(151, 198);
this.PluginOptionsTextBox.Margin = new System.Windows.Forms.Padding(4);
this.PluginOptionsTextBox.MaxLength = 256;
this.PluginOptionsTextBox.Name = "PluginOptionsTextBox";
this.PluginOptionsTextBox.Size = new System.Drawing.Size(160, 21);
this.PluginOptionsTextBox.Size = new System.Drawing.Size(235, 25);
this.PluginOptionsTextBox.TabIndex = 6;
this.PluginOptionsTextBox.WordWrap = false;
//
@@ -307,9 +303,10 @@
this.ShowPasswdCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.ShowPasswdCheckBox.AutoSize = true;
this.ShowPasswdCheckBox.Location = new System.Drawing.Point(113, 87);
this.ShowPasswdCheckBox.Location = new System.Drawing.Point(151, 107);
this.ShowPasswdCheckBox.Margin = new System.Windows.Forms.Padding(4);
this.ShowPasswdCheckBox.Name = "ShowPasswdCheckBox";
this.ShowPasswdCheckBox.Size = new System.Drawing.Size(102, 16);
this.ShowPasswdCheckBox.Size = new System.Drawing.Size(133, 19);
this.ShowPasswdCheckBox.TabIndex = 3;
this.ShowPasswdCheckBox.Text = "Show Password";
this.ShowPasswdCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
@@ -319,10 +316,11 @@
// PluginArgumentsTextBox
//
this.PluginArgumentsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.PluginArgumentsTextBox.Location = new System.Drawing.Point(113, 211);
this.PluginArgumentsTextBox.Location = new System.Drawing.Point(151, 258);
this.PluginArgumentsTextBox.Margin = new System.Windows.Forms.Padding(4);
this.PluginArgumentsTextBox.MaxLength = 512;
this.PluginArgumentsTextBox.Name = "PluginArgumentsTextBox";
this.PluginArgumentsTextBox.Size = new System.Drawing.Size(160, 21);
this.PluginArgumentsTextBox.Size = new System.Drawing.Size(235, 25);
this.PluginArgumentsTextBox.TabIndex = 7;
this.PluginArgumentsTextBox.WordWrap = false;
//
@@ -330,9 +328,10 @@
//
this.PluginArgumentsLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.PluginArgumentsLabel.AutoSize = true;
this.PluginArgumentsLabel.Location = new System.Drawing.Point(6, 215);
this.PluginArgumentsLabel.Location = new System.Drawing.Point(8, 263);
this.PluginArgumentsLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.PluginArgumentsLabel.Name = "PluginArgumentsLabel";
this.PluginArgumentsLabel.Size = new System.Drawing.Size(101, 12);
this.PluginArgumentsLabel.Size = new System.Drawing.Size(135, 15);
this.PluginArgumentsLabel.TabIndex = 7;
this.PluginArgumentsLabel.Text = "Plugin Arguments";
this.toolTip1.SetToolTip(this.PluginArgumentsLabel, "Not a SIP003 standard. Used as CLI arguments.\r\nMandatory:\r\n%SS_LOCAL_HOST%, %SS_L" +
@@ -342,18 +341,20 @@
//
this.RemarksLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.RemarksLabel.AutoSize = true;
this.RemarksLabel.Location = new System.Drawing.Point(60, 242);
this.RemarksLabel.Location = new System.Drawing.Point(80, 296);
this.RemarksLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.RemarksLabel.Name = "RemarksLabel";
this.RemarksLabel.Size = new System.Drawing.Size(47, 12);
this.RemarksLabel.Size = new System.Drawing.Size(63, 15);
this.RemarksLabel.TabIndex = 8;
this.RemarksLabel.Text = "Remarks";
//
// NeedPluginArgCheckBox
//
this.NeedPluginArgCheckBox.AutoSize = true;
this.NeedPluginArgCheckBox.Location = new System.Drawing.Point(113, 189);
this.NeedPluginArgCheckBox.Location = new System.Drawing.Point(151, 231);
this.NeedPluginArgCheckBox.Margin = new System.Windows.Forms.Padding(4);
this.NeedPluginArgCheckBox.Name = "NeedPluginArgCheckBox";
this.NeedPluginArgCheckBox.Size = new System.Drawing.Size(144, 16);
this.NeedPluginArgCheckBox.Size = new System.Drawing.Size(189, 19);
this.NeedPluginArgCheckBox.TabIndex = 10;
this.NeedPluginArgCheckBox.Text = "Need Plugin Argument";
this.NeedPluginArgCheckBox.UseVisualStyleBackColor = true;
@@ -364,7 +365,8 @@
this.panel2.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.panel2.AutoSize = true;
this.panel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.panel2.Location = new System.Drawing.Point(165, 187);
this.panel2.Location = new System.Drawing.Point(206, 234);
this.panel2.Margin = new System.Windows.Forms.Padding(4);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(0, 0);
this.panel2.TabIndex = 1;
@@ -373,10 +375,10 @@
//
this.OKButton.DialogResult = System.Windows.Forms.DialogResult.OK;
this.OKButton.Dock = System.Windows.Forms.DockStyle.Right;
this.OKButton.Location = new System.Drawing.Point(3, 3);
this.OKButton.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0);
this.OKButton.Location = new System.Drawing.Point(4, 4);
this.OKButton.Margin = new System.Windows.Forms.Padding(4, 4, 4, 0);
this.OKButton.Name = "OKButton";
this.OKButton.Size = new System.Drawing.Size(75, 23);
this.OKButton.Size = new System.Drawing.Size(94, 29);
this.OKButton.TabIndex = 17;
this.OKButton.Text = "OK";
this.OKButton.UseVisualStyleBackColor = true;
@@ -386,10 +388,10 @@
//
this.MyCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.MyCancelButton.Dock = System.Windows.Forms.DockStyle.Right;
this.MyCancelButton.Location = new System.Drawing.Point(84, 3);
this.MyCancelButton.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0);
this.MyCancelButton.Location = new System.Drawing.Point(106, 4);
this.MyCancelButton.Margin = new System.Windows.Forms.Padding(4, 4, 4, 0);
this.MyCancelButton.Name = "MyCancelButton";
this.MyCancelButton.Size = new System.Drawing.Size(75, 23);
this.MyCancelButton.Size = new System.Drawing.Size(94, 29);
this.MyCancelButton.TabIndex = 18;
this.MyCancelButton.Text = "Cancel";
this.MyCancelButton.UseVisualStyleBackColor = true;
@@ -399,10 +401,10 @@
//
this.ApplyButton.Dock = System.Windows.Forms.DockStyle.Right;
this.ApplyButton.Enabled = false;
this.ApplyButton.Location = new System.Drawing.Point(165, 3);
this.ApplyButton.Margin = new System.Windows.Forms.Padding(3, 3, 0, 0);
this.ApplyButton.Location = new System.Drawing.Point(208, 4);
this.ApplyButton.Margin = new System.Windows.Forms.Padding(4, 4, 0, 0);
this.ApplyButton.Name = "ApplyButton";
this.ApplyButton.Size = new System.Drawing.Size(75, 23);
this.ApplyButton.Size = new System.Drawing.Size(94, 29);
this.ApplyButton.TabIndex = 19;
this.ApplyButton.Text = "Apply";
this.ApplyButton.UseVisualStyleBackColor = true;
@@ -411,10 +413,10 @@
// DeleteButton
//
this.DeleteButton.Dock = System.Windows.Forms.DockStyle.Right;
this.DeleteButton.Location = new System.Drawing.Point(86, 6);
this.DeleteButton.Margin = new System.Windows.Forms.Padding(3, 6, 0, 3);
this.DeleteButton.Location = new System.Drawing.Point(108, 8);
this.DeleteButton.Margin = new System.Windows.Forms.Padding(4, 8, 0, 4);
this.DeleteButton.Name = "DeleteButton";
this.DeleteButton.Size = new System.Drawing.Size(80, 23);
this.DeleteButton.Size = new System.Drawing.Size(100, 29);
this.DeleteButton.TabIndex = 13;
this.DeleteButton.Text = "&Delete";
this.DeleteButton.UseVisualStyleBackColor = true;
@@ -423,10 +425,10 @@
// AddButton
//
this.AddButton.Dock = System.Windows.Forms.DockStyle.Left;
this.AddButton.Location = new System.Drawing.Point(0, 6);
this.AddButton.Margin = new System.Windows.Forms.Padding(0, 6, 3, 3);
this.AddButton.Location = new System.Drawing.Point(0, 8);
this.AddButton.Margin = new System.Windows.Forms.Padding(0, 8, 4, 4);
this.AddButton.Name = "AddButton";
this.AddButton.Size = new System.Drawing.Size(80, 23);
this.AddButton.Size = new System.Drawing.Size(100, 29);
this.AddButton.TabIndex = 12;
this.AddButton.Text = "&Add";
this.AddButton.UseVisualStyleBackColor = true;
@@ -437,10 +439,11 @@
this.ServerGroupBox.AutoSize = true;
this.ServerGroupBox.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.ServerGroupBox.Controls.Add(this.tableLayoutPanel1);
this.ServerGroupBox.Location = new System.Drawing.Point(178, 0);
this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(12, 0, 0, 0);
this.ServerGroupBox.Location = new System.Drawing.Point(223, 0);
this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(15, 0, 0, 0);
this.ServerGroupBox.Name = "ServerGroupBox";
this.ServerGroupBox.Size = new System.Drawing.Size(290, 330);
this.ServerGroupBox.Padding = new System.Windows.Forms.Padding(4);
this.ServerGroupBox.Size = new System.Drawing.Size(408, 405);
this.ServerGroupBox.TabIndex = 0;
this.ServerGroupBox.TabStop = false;
this.ServerGroupBox.Text = "Server";
@@ -449,11 +452,11 @@
//
this.ServersListBox.FormattingEnabled = true;
this.ServersListBox.IntegralHeight = false;
this.ServersListBox.ItemHeight = 12;
this.ServersListBox.ItemHeight = 15;
this.ServersListBox.Location = new System.Drawing.Point(0, 0);
this.ServersListBox.Margin = new System.Windows.Forms.Padding(0);
this.ServersListBox.Name = "ServersListBox";
this.ServersListBox.Size = new System.Drawing.Size(166, 148);
this.ServersListBox.Size = new System.Drawing.Size(206, 184);
this.ServersListBox.TabIndex = 11;
this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged);
//
@@ -470,14 +473,14 @@
this.tableLayoutPanel2.Controls.Add(this.ServersListBox, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.ServerGroupBox, 1, 0);
this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel4, 0, 1);
this.tableLayoutPanel2.Location = new System.Drawing.Point(12, 12);
this.tableLayoutPanel2.Location = new System.Drawing.Point(15, 15);
this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 3;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.Size = new System.Drawing.Size(468, 426);
this.tableLayoutPanel2.Size = new System.Drawing.Size(631, 528);
this.tableLayoutPanel2.TabIndex = 7;
//
// tableLayoutPanel6
@@ -490,21 +493,21 @@
this.tableLayoutPanel6.Controls.Add(this.MoveDownButton, 1, 0);
this.tableLayoutPanel6.Controls.Add(this.MoveUpButton, 0, 0);
this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Top;
this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 394);
this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 487);
this.tableLayoutPanel6.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel6.Name = "tableLayoutPanel6";
this.tableLayoutPanel6.RowCount = 1;
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel6.Size = new System.Drawing.Size(166, 32);
this.tableLayoutPanel6.Size = new System.Drawing.Size(208, 41);
this.tableLayoutPanel6.TabIndex = 10;
//
// MoveDownButton
//
this.MoveDownButton.Dock = System.Windows.Forms.DockStyle.Right;
this.MoveDownButton.Location = new System.Drawing.Point(86, 6);
this.MoveDownButton.Margin = new System.Windows.Forms.Padding(3, 6, 0, 3);
this.MoveDownButton.Location = new System.Drawing.Point(108, 8);
this.MoveDownButton.Margin = new System.Windows.Forms.Padding(4, 8, 0, 4);
this.MoveDownButton.Name = "MoveDownButton";
this.MoveDownButton.Size = new System.Drawing.Size(80, 23);
this.MoveDownButton.Size = new System.Drawing.Size(100, 29);
this.MoveDownButton.TabIndex = 16;
this.MoveDownButton.Text = "Move D&own";
this.MoveDownButton.UseVisualStyleBackColor = true;
@@ -513,10 +516,10 @@
// MoveUpButton
//
this.MoveUpButton.Dock = System.Windows.Forms.DockStyle.Left;
this.MoveUpButton.Location = new System.Drawing.Point(0, 6);
this.MoveUpButton.Margin = new System.Windows.Forms.Padding(0, 6, 3, 3);
this.MoveUpButton.Location = new System.Drawing.Point(0, 8);
this.MoveUpButton.Margin = new System.Windows.Forms.Padding(0, 8, 4, 4);
this.MoveUpButton.Name = "MoveUpButton";
this.MoveUpButton.Size = new System.Drawing.Size(80, 23);
this.MoveUpButton.Size = new System.Drawing.Size(100, 29);
this.MoveUpButton.TabIndex = 15;
this.MoveUpButton.Text = "Move &Up";
this.MoveUpButton.UseVisualStyleBackColor = true;
@@ -534,23 +537,24 @@
this.tableLayoutPanel5.Controls.Add(this.ProxyPortTextBox, 1, 0);
this.tableLayoutPanel5.Controls.Add(this.ProxyPortLabel, 0, 0);
this.tableLayoutPanel5.Controls.Add(this.PortableModeCheckBox, 0, 1);
this.tableLayoutPanel5.Location = new System.Drawing.Point(166, 330);
this.tableLayoutPanel5.Location = new System.Drawing.Point(208, 405);
this.tableLayoutPanel5.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel5.Name = "tableLayoutPanel5";
this.tableLayoutPanel5.Padding = new System.Windows.Forms.Padding(3);
this.tableLayoutPanel5.Padding = new System.Windows.Forms.Padding(4);
this.tableLayoutPanel5.RowCount = 2;
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel5.Size = new System.Drawing.Size(196, 64);
this.tableLayoutPanel5.Size = new System.Drawing.Size(251, 82);
this.tableLayoutPanel5.TabIndex = 9;
//
// ProxyPortTextBox
//
this.ProxyPortTextBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.ProxyPortTextBox.Location = new System.Drawing.Point(77, 6);
this.ProxyPortTextBox.Location = new System.Drawing.Point(103, 8);
this.ProxyPortTextBox.Margin = new System.Windows.Forms.Padding(4);
this.ProxyPortTextBox.MaxLength = 10;
this.ProxyPortTextBox.Name = "ProxyPortTextBox";
this.ProxyPortTextBox.Size = new System.Drawing.Size(113, 21);
this.ProxyPortTextBox.Size = new System.Drawing.Size(140, 25);
this.ProxyPortTextBox.TabIndex = 10;
this.ProxyPortTextBox.WordWrap = false;
//
@@ -558,9 +562,10 @@
//
this.ProxyPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.ProxyPortLabel.AutoSize = true;
this.ProxyPortLabel.Location = new System.Drawing.Point(6, 10);
this.ProxyPortLabel.Location = new System.Drawing.Point(8, 13);
this.ProxyPortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.ProxyPortLabel.Name = "ProxyPortLabel";
this.ProxyPortLabel.Size = new System.Drawing.Size(65, 12);
this.ProxyPortLabel.Size = new System.Drawing.Size(87, 15);
this.ProxyPortLabel.TabIndex = 10;
this.ProxyPortLabel.Text = "Proxy Port";
//
@@ -569,9 +574,10 @@
this.PortableModeCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.PortableModeCheckBox.AutoSize = true;
this.tableLayoutPanel5.SetColumnSpan(this.PortableModeCheckBox, 2);
this.PortableModeCheckBox.Location = new System.Drawing.Point(6, 37);
this.PortableModeCheckBox.Location = new System.Drawing.Point(8, 48);
this.PortableModeCheckBox.Margin = new System.Windows.Forms.Padding(4);
this.PortableModeCheckBox.Name = "PortableModeCheckBox";
this.PortableModeCheckBox.Size = new System.Drawing.Size(102, 16);
this.PortableModeCheckBox.Size = new System.Drawing.Size(133, 19);
this.PortableModeCheckBox.TabIndex = 11;
this.PortableModeCheckBox.Text = "Portable Mode";
this.toolTip1.SetToolTip(this.PortableModeCheckBox, "restart required");
@@ -585,17 +591,17 @@
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 25F));
this.tableLayoutPanel3.Controls.Add(this.MyCancelButton, 1, 0);
this.tableLayoutPanel3.Controls.Add(this.OKButton, 0, 0);
this.tableLayoutPanel3.Controls.Add(this.ApplyButton, 2, 0);
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Right;
this.tableLayoutPanel3.Location = new System.Drawing.Point(228, 397);
this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3);
this.tableLayoutPanel3.Location = new System.Drawing.Point(329, 491);
this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(4, 4, 0, 4);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 1;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.Size = new System.Drawing.Size(240, 26);
this.tableLayoutPanel3.Size = new System.Drawing.Size(302, 33);
this.tableLayoutPanel3.TabIndex = 8;
//
// tableLayoutPanel4
@@ -609,22 +615,22 @@
this.tableLayoutPanel4.Controls.Add(this.DeleteButton, 1, 0);
this.tableLayoutPanel4.Controls.Add(this.AddButton, 0, 0);
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Top;
this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 330);
this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 405);
this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
this.tableLayoutPanel4.RowCount = 2;
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.Size = new System.Drawing.Size(166, 64);
this.tableLayoutPanel4.Size = new System.Drawing.Size(208, 82);
this.tableLayoutPanel4.TabIndex = 8;
//
// DuplicateButton
//
this.DuplicateButton.Dock = System.Windows.Forms.DockStyle.Left;
this.DuplicateButton.Location = new System.Drawing.Point(0, 38);
this.DuplicateButton.Margin = new System.Windows.Forms.Padding(0, 6, 3, 3);
this.DuplicateButton.Location = new System.Drawing.Point(0, 49);
this.DuplicateButton.Margin = new System.Windows.Forms.Padding(0, 8, 4, 4);
this.DuplicateButton.Name = "DuplicateButton";
this.DuplicateButton.Size = new System.Drawing.Size(80, 23);
this.DuplicateButton.Size = new System.Drawing.Size(100, 29);
this.DuplicateButton.TabIndex = 14;
this.DuplicateButton.Text = "Dupli&cate";
this.DuplicateButton.UseVisualStyleBackColor = true;
@@ -633,19 +639,20 @@
// ConfigForm
//
this.AcceptButton = this.OKButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleDimensions = new System.Drawing.SizeF(120F, 120F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.AutoSize = true;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.CancelButton = this.MyCancelButton;
this.ClientSize = new System.Drawing.Size(491, 438);
this.ClientSize = new System.Drawing.Size(614, 548);
this.Controls.Add(this.tableLayoutPanel2);
this.Controls.Add(this.panel2);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Margin = new System.Windows.Forms.Padding(4);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "ConfigForm";
this.Padding = new System.Windows.Forms.Padding(12, 12, 12, 9);
this.Padding = new System.Windows.Forms.Padding(15, 15, 15, 11);
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Edit Servers";
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ConfigForm_FormClosed);


+ 80
- 2
shadowsocks-csharp/View/ConfigForm.cs View File

@@ -2,7 +2,9 @@ using Shadowsocks.Controller;
using Shadowsocks.Model;
using Shadowsocks.Properties;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
namespace Shadowsocks.View
@@ -17,10 +19,86 @@ namespace Shadowsocks.View
private bool isChange = false;
private class EncryptionMethod
{
public readonly string name;
public readonly bool deprecated;
// Edit here to add/delete encryption method displayed in UI
private static string[] deprecatedMethod = new string[]
{
"rc4-md5",
"salsa20",
"chacha20",
"bf-cfb",
"chacha20-ietf",
"aes-256-cfb",
"aes-192-cfb",
"aes-128-cfb",
"aes-256-ctr",
"aes-192-ctr",
"aes-128-ctr",
"camellia-256-cfb",
"camellia-192-cfb",
"camellia-128-cfb",
};
private static string[] inuseMethod = new string[]
{
"aes-256-gcm",
"aes-192-gcm",
"aes-128-gcm",
"chacha20-ietf-poly1305",
"xchacha20-ietf-poly1305",
};
public static EncryptionMethod[] AllMethods
{
get
{
if (!init) Init();
return allMethods;
}
}
private static bool init = false;
private static EncryptionMethod[] allMethods;
private static Dictionary<string, EncryptionMethod> methodByName = new Dictionary<string, EncryptionMethod>();
private static void Init()
{
var all = new List<EncryptionMethod>();
all.AddRange(inuseMethod.Select(i => new EncryptionMethod(i, false)));
all.AddRange(deprecatedMethod.Select(d => new EncryptionMethod(d, true)));
allMethods = all.ToArray();
foreach (var item in all)
{
methodByName[item.name] = item;
}
init = true;
}
public static EncryptionMethod GetMethod(string name)
{
if (!init) Init();
return methodByName[name];
}
private EncryptionMethod(string name, bool deprecated)
{
this.name = name;
this.deprecated = deprecated;
}
public override string ToString()
{
return deprecated ? $"{name} ({I18N.GetString("deprecated")})" : name;
}
}
public ConfigForm(ShadowsocksController controller)
{
Font = SystemFonts.MessageBoxFont;
InitializeComponent();
EncryptionSelect.Items.AddRange(EncryptionMethod.AllMethods);
// a dirty hack
ServersListBox.Dock = DockStyle.Fill;
@@ -115,7 +193,7 @@ namespace Shadowsocks.View
server = address,
server_port = addressPort.Value,
password = serverPassword,
method = EncryptionSelect.Text,
method = ((EncryptionMethod)EncryptionSelect.SelectedItem).name,
plugin = PluginTextBox.Text,
plugin_opts = PluginOptionsTextBox.Text,
plugin_args = PluginArgumentsTextBox.Text,
@@ -316,7 +394,7 @@ namespace Shadowsocks.View
IPTextBox.Text = server.server;
ServerPortTextBox.Text = server.server_port.ToString();
PasswordTextBox.Text = server.password;
EncryptionSelect.Text = server.method ?? Server.DefaultMethod;
EncryptionSelect.SelectedItem = EncryptionMethod.GetMethod(server.method ?? Server.DefaultMethod);
PluginTextBox.Text = server.plugin;
PluginOptionsTextBox.Text = server.plugin_opts;
PluginArgumentsTextBox.Text = server.plugin_args;


+ 35
- 10
shadowsocks-csharp/View/LogForm.cs View File

@@ -11,11 +11,14 @@ using Shadowsocks.Properties;
using Shadowsocks.Model;
using Shadowsocks.Util;
using System.Text;
using NLog;
namespace Shadowsocks.View
{
public partial class LogForm : Form
{
private static Logger logger = LogManager.GetCurrentClassLogger();
long lastOffset;
string filename;
Timer timer;
@@ -38,13 +41,27 @@ namespace Shadowsocks.View
TextAnnotation outboundAnnotation = new TextAnnotation();
#endregion
public LogForm(ShadowsocksController controller, string filename)
public LogForm(ShadowsocksController controller)
{
this.controller = controller;
this.filename = filename;
InitializeComponent();
Icon = Icon.FromHandle(Resources.ssw128.GetHicon());
var nLogConfig = NLogConfig.LoadXML();
try
{
this.filename = nLogConfig.GetLogFileName();
}
catch(Exception)
{
// failed to get the file name
}
if (string.IsNullOrEmpty(this.filename))
{
LogMessageTextBox.AppendText("Cannot get the log file name from NLog config file. Please check if the nlog config file exists with corresponding XML nodes.");
}
LogViewerConfig config = controller.GetConfigurationCopy().logViewer;
topMostTrigger = config.topMost;
@@ -158,6 +175,8 @@ namespace Shadowsocks.View
private void InitContent()
{
if (string.IsNullOrEmpty(filename) || !File.Exists(filename))
return;
using (StreamReader reader = new StreamReader(new FileStream(filename,
FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
{
@@ -170,7 +189,7 @@ namespace Shadowsocks.View
string line = "";
StringBuilder appendText = new StringBuilder(1024);
while ((line = reader.ReadLine()) != null)
appendText.Append(line + Environment.NewLine);
appendText.AppendLine(line);
LogMessageTextBox.AppendText(appendText.ToString());
LogMessageTextBox.ScrollToCaret();
@@ -181,6 +200,11 @@ namespace Shadowsocks.View
private void UpdateContent()
{
this.Text = I18N.GetString("Log Viewer") +
$" [in: {Utils.FormatBytes(controller.InboundCounter)}, out: {Utils.FormatBytes(controller.OutboundCounter)}]";
if (string.IsNullOrEmpty(filename) || !File.Exists(filename))
return;
try
{
using (StreamReader reader = new StreamReader(new FileStream(filename,
@@ -194,7 +218,7 @@ namespace Shadowsocks.View
while ((line = reader.ReadLine()) != null)
{
changed = true;
appendText.Append(line + Environment.NewLine);
appendText.AppendLine(line);
}
if (changed)
@@ -209,9 +233,6 @@ namespace Shadowsocks.View
catch (FileNotFoundException)
{
}
this.Text = I18N.GetString("Log Viewer") +
$" [in: {Utils.FormatBytes(controller.InboundCounter)}, out: {Utils.FormatBytes(controller.OutboundCounter)}]";
}
private void LogForm_Load(object sender, EventArgs e)
@@ -270,7 +291,7 @@ namespace Shadowsocks.View
private void OpenLocationMenuItem_Click(object sender, EventArgs e)
{
string argument = "/select, \"" + filename + "\"";
Logging.Debug(argument);
logger.Debug(argument);
System.Diagnostics.Process.Start("explorer.exe", argument);
}
@@ -287,7 +308,11 @@ namespace Shadowsocks.View
#region Clean up the content in LogMessageTextBox.
private void DoClearLogs()
{
Logging.Clear();
try
{
File.Delete(filename);
}
catch { }
lastOffset = 0;
LogMessageTextBox.Clear();
}
@@ -317,7 +342,7 @@ namespace Shadowsocks.View
}
catch (Exception ex)
{
Logging.LogUsefulException(ex);
logger.LogUsefulException(ex);
MessageBox.Show(ex.Message);
}
}


+ 23
- 24
shadowsocks-csharp/View/MenuViewController.cs View File

@@ -1,4 +1,5 @@
using Shadowsocks.Controller;
using NLog;
using Shadowsocks.Controller;
using Shadowsocks.Model;
using Shadowsocks.Properties;
using Shadowsocks.Util;
@@ -17,6 +18,7 @@ namespace Shadowsocks.View
{
public class MenuViewController
{
private static Logger logger = LogManager.GetCurrentClassLogger();
// yes this is just a menu view controller
// when config form is closed, it moves away from RAM
// and it should just do anything related to the config form
@@ -220,7 +222,7 @@ namespace Shadowsocks.View
{
Color colorMask = Color.White;
Utils.WindowsThemeMode currentWindowsThemeMode = Utils.GetWindows10SystemThemeSetting(controller.GetCurrentConfiguration().isVerboseLogging);
Utils.WindowsThemeMode currentWindowsThemeMode = Utils.GetWindows10SystemThemeSetting();
if (isProxyEnabled)
{
@@ -372,7 +374,7 @@ namespace Shadowsocks.View
{
string argument = @"/select, " + e.Path;
System.Diagnostics.Process.Start("explorer.exe", argument);
Process.Start("explorer.exe", argument);
}
void ShowBalloonTip(string title, string content, ToolTipIcon icon, int timeout)
@@ -386,7 +388,7 @@ namespace Shadowsocks.View
void controller_UpdatePACFromGFWListError(object sender, System.IO.ErrorEventArgs e)
{
ShowBalloonTip(I18N.GetString("Failed to update PAC file"), e.GetException().Message, ToolTipIcon.Error, 5000);
Logging.LogUsefulException(e.GetException());
logger.LogUsefulException(e.GetException());
}
void controller_UpdatePACFromGFWListCompleted(object sender, GFWListUpdater.ResultEventArgs e)
@@ -415,10 +417,10 @@ namespace Shadowsocks.View
if (updateChecker.NewVersionFound)
{
updateChecker.NewVersionFound = false; /* Reset the flag */
if (System.IO.File.Exists(updateChecker.LatestVersionLocalName))
if (File.Exists(updateChecker.LatestVersionLocalName))
{
string argument = "/select, \"" + updateChecker.LatestVersionLocalName + "\"";
System.Diagnostics.Process.Start("explorer.exe", argument);
Process.Start("explorer.exe", argument);
}
}
}
@@ -454,30 +456,30 @@ namespace Shadowsocks.View
{
items.RemoveAt(0);
}
int i = 0;
int strategyCount = 0;
foreach (var strategy in controller.GetStrategies())
{
MenuItem item = new MenuItem(strategy.Name);
item.Tag = strategy.ID;
item.Click += AStrategyItem_Click;
items.Add(i, item);
i++;
items.Add(strategyCount, item);
strategyCount++;
}
// user wants a seperator item between strategy and servers menugroup
items.Add(i++, new MenuItem("-"));
items.Add(strategyCount++, new MenuItem("-"));
int strategyCount = i;
int serverCount = 0;
Configuration configuration = controller.GetConfigurationCopy();
foreach (var server in configuration.configs)
{
if (Configuration.ChecksServer(server))
{
MenuItem item = new MenuItem(server.FriendlyName());
item.Tag = i - strategyCount;
item.Tag = configuration.configs.FindIndex(s => s == server);
item.Click += AServerItem_Click;
items.Add(i, item);
i++;
items.Add(strategyCount + serverCount, item);
serverCount++;
}
}
@@ -543,7 +545,7 @@ namespace Shadowsocks.View
}
else
{
logForm = new LogForm(controller, Logging.LogFilePath);
logForm = new LogForm(controller);
logForm.Show();
logForm.Activate();
logForm.FormClosed += logForm_FormClosed;
@@ -565,7 +567,12 @@ namespace Shadowsocks.View
if (_isFirstRun)
{
CheckUpdateForFirstRun();
ShowFirstTimeBalloon();
ShowBalloonTip(
I18N.GetString("Shadowsocks is here"),
I18N.GetString("You can turn on/off Shadowsocks in the context menu"),
ToolTipIcon.Info,
0
);
_isFirstRun = false;
}
}
@@ -604,14 +611,6 @@ namespace Shadowsocks.View
updateChecker.CheckUpdate(config, 3000);
}
private void ShowFirstTimeBalloon()
{
_notifyIcon.BalloonTipTitle = I18N.GetString("Shadowsocks is here");
_notifyIcon.BalloonTipText = I18N.GetString("You can turn on/off Shadowsocks in the context menu");
_notifyIcon.BalloonTipIcon = ToolTipIcon.Info;
_notifyIcon.ShowBalloonTip(0);
}
private void AboutItem_Click(object sender, EventArgs e)
{
Process.Start("https://github.com/shadowsocks/shadowsocks-windows");


+ 1
- 0
shadowsocks-csharp/View/StatisticsStrategyConfigurationForm.Designer.cs View File

@@ -481,6 +481,7 @@
this.MinimumSize = new System.Drawing.Size(1000, 800);
this.Name = "StatisticsStrategyConfigurationForm";
this.Text = "StatisticsStrategyConfigurationForm";
this.Text = "Statistics configuration";
((System.ComponentModel.ISupportInitialize)(this.StatisticsChart)).EndInit();
this.chartModeSelector.ResumeLayout(false);
this.chartModeSelector.PerformLayout();


+ 1
- 0
shadowsocks-csharp/packages.config View File

@@ -2,6 +2,7 @@
<packages>
<package id="GlobalHotKey" version="1.1.0" targetFramework="net472" />
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net472" />
<package id="NLog" version="4.6.8" targetFramework="net472" />
<package id="StringEx.CS" version="0.3.1" targetFramework="net472" developmentDependency="true" />
<package id="ZXing.Net" version="0.16.5" targetFramework="net472" />
</packages>

+ 15
- 1
shadowsocks-csharp/shadowsocks-csharp.csproj View File

@@ -74,12 +74,21 @@
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.6.8\lib\net45\NLog.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Management" />
<Reference Include="System.Net" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Transactions" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Windows.Forms.DataVisualization" />
@@ -94,6 +103,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Controller\HotkeyReg.cs" />
<Compile Include="Controller\LoggerExtension.cs" />
<Compile Include="Controller\Service\PACDaemon.cs" />
<Compile Include="Controller\System\Hotkeys\HotkeyCallbacks.cs" />
<Compile Include="Encryption\AEAD\AEADEncryptor.cs" />
@@ -114,6 +124,7 @@
<Compile Include="Encryption\Stream\StreamOpenSSLEncryptor.cs" />
<Compile Include="Encryption\Stream\StreamSodiumEncryptor.cs" />
<Compile Include="Model\HotKeyConfig.cs" />
<Compile Include="Model\NLogConfig.cs" />
<Compile Include="Model\ProxyConfig.cs" />
<Compile Include="Model\SysproxyConfig.cs" />
<Compile Include="Properties\Resources.Designer.cs">
@@ -137,7 +148,6 @@
<Compile Include="Controller\Service\GFWListUpdater.cs" />
<Compile Include="Controller\I18N.cs" />
<Compile Include="Controller\Service\Listener.cs" />
<Compile Include="Controller\Logging.cs" />
<Compile Include="Controller\Service\PortForwarder.cs" />
<Compile Include="Controller\Service\UDPRelay.cs" />
<Compile Include="Controller\Service\UpdateChecker.cs" />
@@ -292,6 +302,10 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>user-rule.txt</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="Data\nlog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>nlog.config</TargetPath>
</ContentWithTargetPath>
<Content Include="Resources\ss32Fill.png" />
<Content Include="Resources\ss32In.png" />
<Content Include="Resources\ss32Out.png" />


+ 11
- 2
shadowsocks-windows.sln View File

@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.10
# Visual Studio Version 16
VisualStudioVersion = 16.0.29709.97
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "shadowsocks-csharp", "shadowsocks-csharp\shadowsocks-csharp.csproj", "{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}"
EndProject
@@ -12,21 +12,30 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShadowsocksTest", "test\Sha
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|Any CPU.ActiveCfg = Debug|x86
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.ActiveCfg = Debug|x86
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Build.0 = Debug|x86
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Deploy.0 = Debug|x86
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|Any CPU.ActiveCfg = Release|x86
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.ActiveCfg = Release|x86
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.Build.0 = Release|x86
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|Any CPU.ActiveCfg = Debug|x86
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.ActiveCfg = Debug|x86
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.Build.0 = Debug|x86
{45913187-0685-4903-B250-DCEF0479CD86}.Release|Any CPU.ActiveCfg = Release|x86
{45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.ActiveCfg = Release|x86
{45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F7E7D35B-4FDA-4385-95CF-09DADED042EA}
EndGlobalSection
EndGlobal

Loading…
Cancel
Save