Skip to content

Commit

Permalink
Merge pull request shadowsocks#413 from kimw/master
Browse files Browse the repository at this point in the history
a lot of commits
  • Loading branch information
GangZhuo committed Jan 5, 2016
2 parents e76582c + 6f38bbb commit d2833e6
Show file tree
Hide file tree
Showing 31 changed files with 729 additions and 2,330 deletions.
1,902 changes: 0 additions & 1,902 deletions shadowsocks-csharp/3rd/SimpleJson.cs

This file was deleted.

57 changes: 47 additions & 10 deletions shadowsocks-csharp/Controller/Logging.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using Shadowsocks.Util;
using System;
using System.Collections.Generic;
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Net;

using Shadowsocks.Util;

namespace Shadowsocks.Controller
{
Expand All @@ -15,8 +15,7 @@ public static bool OpenLogFile()
{
try
{
string temppath = Utils.GetTempPath();
LogFile = Path.Combine(temppath, "shadowsocks.log");
LogFile = Utils.GetTempPath("shadowsocks.log");
FileStream fs = new FileStream(LogFile, FileMode.Append);
StreamWriterWithTimestamp sw = new StreamWriterWithTimestamp(fs);
sw.AutoFlush = true;
Expand All @@ -32,11 +31,41 @@ public static bool OpenLogFile()
}
}

public static void Error(object o)
{
Console.WriteLine("[E] " + o);
}

public static void Info(object o)
{
Console.WriteLine(o);
}

public static void Debug(object o)
{
#if DEBUG
Console.WriteLine("[D] " + o);
#endif
}

public static void Debug(EndPoint local, EndPoint remote, int len, string header = null, string tailer = null)
{
#if DEBUG
Console.WriteLine(o);
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}");
#endif
}

public static void Debug(Socket sock, int len, string header = null, string tailer = null)
{
#if DEBUG
Debug(sock.LocalEndPoint, sock.RemoteEndPoint, len, header, tailer);
#endif
}

Expand All @@ -57,19 +86,27 @@ public static void LogUsefulException(Exception e)
}
else if (se.SocketErrorCode == SocketError.NotConnected)
{
// close when not connected
// 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
{
Console.WriteLine(e);
Info(e);
}
}
else if (e is ObjectDisposedException)
{
}
else
{
Console.WriteLine(e);
Info(e);
}
}
}
Expand Down
81 changes: 44 additions & 37 deletions shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

using Shadowsocks.Model;
using Shadowsocks.Util;

Expand All @@ -30,8 +34,8 @@ public class AvailabilityStatistics
public Statistics FilteredStatistics { get; private set; }
public static readonly DateTime UnknownDateTime = new DateTime(1970, 1, 1);
private int Repeat => _config.RepeatTimesNum;
private const int RetryInterval = 2*60*1000; //retry 2 minutes after failed
private int Interval => (int) TimeSpan.FromMinutes(_config.DataCollectionMinutes).TotalMilliseconds;
private const int RetryInterval = 2 * 60 * 1000; //retry 2 minutes after failed
private int Interval => (int)TimeSpan.FromMinutes(_config.DataCollectionMinutes).TotalMilliseconds;
private Timer _timer;
private State _state;
private List<Server> _servers;
Expand All @@ -42,8 +46,7 @@ public class AvailabilityStatistics
//static constructor to initialize every public static fields before refereced
static AvailabilityStatistics()
{
var temppath = Utils.GetTempPath();
AvailabilityStatisticsFile = Path.Combine(temppath, StatisticsFilesName);
AvailabilityStatisticsFile = Utils.GetTempPath(StatisticsFilesName);
}

public AvailabilityStatistics(Configuration config, StatisticsStrategyConfiguration statisticsConfig)
Expand Down Expand Up @@ -107,11 +110,18 @@ private static async Task<DataList> GetInfoFromAPI(string API)
Logging.LogUsefulException(e);
return null;
}
dynamic obj;
if (!SimpleJson.SimpleJson.TryDeserializeObject(jsonString, out obj)) return null;
string country = obj["country"];
string city = obj["city"];
string isp = obj["isp"];
JObject obj;
try
{
obj = JObject.Parse(jsonString);
}
catch (JsonReaderException)
{
return null;
}
string country = (string)obj["country"];
string city = (string)obj["city"];
string isp = (string)obj["isp"];
if (country == null || city == null || isp == null) return null;
return new DataList {
new DataUnit(State.Geolocation, $"\"{country} {city}\""),
Expand All @@ -126,8 +136,7 @@ private async Task<List<DataList>> ICMPTest(Server server)
var IP = Dns.GetHostAddresses(server.server).First(ip => (ip.AddressFamily == AddressFamily.InterNetwork || ip.AddressFamily == AddressFamily.InterNetworkV6));
var ping = new Ping();
var ret = new List<DataList>();
foreach (
var timestamp in Enumerable.Range(0, Repeat).Select(_ => DateTime.Now.ToString(DateTimePattern)))
foreach (var timestamp in Enumerable.Range(0, Repeat).Select(_ => DateTime.Now.ToString(DateTimePattern)))
{
//ICMP echo. we can also set options and special bytes
try
Expand All @@ -146,7 +155,7 @@ var timestamp in Enumerable.Range(0, Repeat).Select(_ => DateTime.Now.ToString(D
}
catch (Exception e)
{
Console.WriteLine($"An exception occured when eveluating {server.FriendlyName()}");
Logging.Error($"An exception occured while eveluating {server.FriendlyName()}");
Logging.LogUsefulException(e);
}
}
Expand Down Expand Up @@ -182,11 +191,11 @@ private static void Append(DataList dataList, IEnumerable<DataUnit> extra)
if (!File.Exists(AvailabilityStatisticsFile))
{
var headerLine = string.Join(Delimiter, data.Select(kv => kv.Key).ToArray());
lines = new[] {headerLine, dataLine};
lines = new[] { headerLine, dataLine };
}
else
{
lines = new[] {dataLine};
lines = new[] { dataLine };
}
try
{
Expand Down Expand Up @@ -249,30 +258,29 @@ private void LoadRawStatistics()
Logging.Debug($"loading statistics from {path}");
if (!File.Exists(path))
{
Console.WriteLine($"statistics file does not exist, try to reload {RetryInterval/60/1000} minutes later");
Console.WriteLine($"statistics file does not exist, try to reload {RetryInterval / 60 / 1000} minutes later");
_timer.Change(RetryInterval, Interval);
return;
}
RawStatistics = (from l in File.ReadAllLines(path)
.Skip(1)
let strings = l.Split(new[] {","}, StringSplitOptions.RemoveEmptyEntries)
let rawData = new RawStatisticsData
{
Timestamp = ParseExactOrUnknown(strings[0]),
ServerName = strings[1],
ICMPStatus = strings[2],
RoundtripTime = int.Parse(strings[3]),
Geolocation = 5 > strings.Length ?
null
: strings[4],
ISP = 6 > strings.Length ? null : strings[5]
}
group rawData by rawData.ServerName into server
select new
{
ServerName = server.Key,
data = server.ToList()
}).ToDictionary(server => server.ServerName, server=> server.data);
RawStatistics = (from l in File.ReadAllLines(path).Skip(1)
let strings = l.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
let rawData = new RawStatisticsData
{
Timestamp = ParseExactOrUnknown(strings[0]),
ServerName = strings[1],
ICMPStatus = strings[2],
RoundtripTime = int.Parse(strings[3]),
Geolocation = 5 > strings.Length ?
null
: strings[4],
ISP = 6 > strings.Length ? null : strings[5]
}
group rawData by rawData.ServerName into server
select new
{
ServerName = server.Key,
data = server.ToList()
}).ToDictionary(server => server.ServerName, server => server.data);
}
catch (Exception e)
{
Expand Down Expand Up @@ -301,7 +309,7 @@ public class RawStatisticsData
public string ICMPStatus;
public int RoundtripTime;
public string Geolocation;
public string ISP ;
public string ISP;
}

public class StatisticsData
Expand All @@ -311,6 +319,5 @@ public class StatisticsData
public int MinResponse;
public int MaxResponse;
}

}
}
37 changes: 17 additions & 20 deletions shadowsocks-csharp/Controller/Service/GfwListUpdater.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Net;
using System.Text;

using Newtonsoft.Json;

using Shadowsocks.Model;
using Shadowsocks.Properties;
using SimpleJson;
using Shadowsocks.Util;
using Shadowsocks.Model;

namespace Shadowsocks.Controller
{
public class GFWListUpdater
{
private const string GFWLIST_URL = "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt";

private static string PAC_FILE = PACServer.PAC_FILE;

private static string USER_RULE_FILE = PACServer.USER_RULE_FILE;

private static string USER_ABP_FILE = PACServer.USER_ABP_FILE;

public event EventHandler<ResultEventArgs> UpdateCompleted;

public event ErrorEventHandler Error;
Expand All @@ -38,38 +34,39 @@ private void http_DownloadStringCompleted(object sender, DownloadStringCompleted
{
try
{
File.WriteAllText(Utils.GetTempPath("gfwlist.txt"), e.Result, Encoding.UTF8);
List<string> lines = ParseResult(e.Result);
if (File.Exists(USER_RULE_FILE))
if (File.Exists(PACServer.USER_RULE_FILE))
{
string local = File.ReadAllText(USER_RULE_FILE, Encoding.UTF8);
string local = File.ReadAllText(PACServer.USER_RULE_FILE, Encoding.UTF8);
string[] rules = local.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach(string rule in rules)
foreach (string rule in rules)
{
if (rule.StartsWith("!") || rule.StartsWith("["))
continue;
lines.Add(rule);
}
}
string abpContent;
if (File.Exists(USER_ABP_FILE))
if (File.Exists(PACServer.USER_ABP_FILE))
{
abpContent = File.ReadAllText(USER_ABP_FILE, Encoding.UTF8);
abpContent = File.ReadAllText(PACServer.USER_ABP_FILE, Encoding.UTF8);
}
else
{
abpContent = Utils.UnGzip(Resources.abp_js);
}
abpContent = abpContent.Replace("__RULES__", SimpleJson.SimpleJson.SerializeObject(lines));
if (File.Exists(PAC_FILE))
abpContent = abpContent.Replace("__RULES__", JsonConvert.SerializeObject(lines, Formatting.Indented));
if (File.Exists(PACServer.PAC_FILE))
{
string original = File.ReadAllText(PAC_FILE, Encoding.UTF8);
string original = File.ReadAllText(PACServer.PAC_FILE, Encoding.UTF8);
if (original == abpContent)
{
UpdateCompleted(this, new ResultEventArgs(false));
return;
}
}
File.WriteAllText(PAC_FILE, abpContent, Encoding.UTF8);
File.WriteAllText(PACServer.PAC_FILE, abpContent, Encoding.UTF8);
if (UpdateCompleted != null)
{
UpdateCompleted(this, new ResultEventArgs(true));
Expand All @@ -92,7 +89,7 @@ public void UpdatePACFromGFWList(Configuration config)
http.DownloadStringAsync(new Uri(GFWLIST_URL));
}

public List<string> ParseResult(string response)
public static List<string> ParseResult(string response)
{
byte[] bytes = Convert.FromBase64String(response);
string content = Encoding.ASCII.GetString(bytes);
Expand Down
16 changes: 7 additions & 9 deletions shadowsocks-csharp/Controller/Service/Listener.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using Shadowsocks.Model;
using System;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;

using Shadowsocks.Model;

namespace Shadowsocks.Controller
{
Expand Down Expand Up @@ -78,10 +78,8 @@ public void Start(Configuration config)
_tcpSocket.Listen(1024);

// Start an asynchronous socket to listen for connections.
Console.WriteLine("Shadowsocks started");
_tcpSocket.BeginAccept(
new AsyncCallback(AcceptCallback),
_tcpSocket);
Logging.Info("Shadowsocks started");
_tcpSocket.BeginAccept(new AsyncCallback(AcceptCallback), _tcpSocket);
UDPState udpState = new UDPState();
_udpSocket.BeginReceiveFrom(udpState.buffer, 0, udpState.buffer.Length, 0, ref udpState.remoteEndPoint, new AsyncCallback(RecvFromCallback), udpState);
}
Expand Down Expand Up @@ -163,7 +161,7 @@ public void AcceptCallback(IAsyncResult ar)
}
catch (Exception e)
{
Console.WriteLine(e);
Logging.LogUsefulException(e);
}
finally
{
Expand Down Expand Up @@ -208,7 +206,7 @@ private void ReceiveCallback(IAsyncResult ar)
}
catch (Exception e)
{
Console.WriteLine(e);
Logging.LogUsefulException(e);
conn.Close();
}
}
Expand Down
Loading

0 comments on commit d2833e6

Please sign in to comment.