Skip to content

Commit 2030163

Browse files
authored
Merge pull request #2910 from database64128/master
🔙 Backport 2c15276 from v5/master to master
2 parents 82b58d8 + 893ff06 commit 2030163

File tree

5 files changed

+133
-24
lines changed

5 files changed

+133
-24
lines changed

shadowsocks-csharp/Controller/Service/GeositeUpdater.cs

Lines changed: 88 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
using Newtonsoft.Json;
1010
using Shadowsocks.Model;
1111
using System.Net;
12+
using System.Net.Http;
13+
using System.Threading.Tasks;
14+
using System.Security.Cryptography;
1215

1316
namespace Shadowsocks.Controller
1417
{
@@ -32,23 +35,37 @@ public static class GeositeUpdater
3235

3336
private static readonly string DATABASE_PATH = Utils.GetTempPath("dlc.dat");
3437

38+
private static HttpClientHandler httpClientHandler;
39+
private static HttpClient httpClient;
3540
private static readonly string GEOSITE_URL = "https://github.com/v2ray/domain-list-community/raw/release/dlc.dat";
41+
private static readonly string GEOSITE_SHA256SUM_URL = "https://github.com/v2ray/domain-list-community/raw/release/dlc.dat.sha256sum";
42+
private static byte[] geositeDB;
3643

3744
public static readonly Dictionary<string, IList<DomainObject>> Geosites = new Dictionary<string, IList<DomainObject>>();
3845

3946
static GeositeUpdater()
4047
{
41-
if (!File.Exists(DATABASE_PATH))
48+
//socketsHttpHandler = new SocketsHttpHandler();
49+
//httpClient = new HttpClient(socketsHttpHandler);
50+
51+
if (File.Exists(DATABASE_PATH) && new FileInfo(DATABASE_PATH).Length > 0)
4252
{
53+
geositeDB = File.ReadAllBytes(DATABASE_PATH);
54+
}
55+
else
56+
{
57+
geositeDB = Resources.dlc_dat;
4358
File.WriteAllBytes(DATABASE_PATH, Resources.dlc_dat);
4459
}
4560
LoadGeositeList();
4661
}
4762

48-
static void LoadGeositeList(byte[] data = null)
63+
/// <summary>
64+
/// load new GeoSite data from geositeDB
65+
/// </summary>
66+
static void LoadGeositeList()
4967
{
50-
data = data ?? File.ReadAllBytes(DATABASE_PATH);
51-
var list = GeositeList.Parser.ParseFrom(data);
68+
var list = GeositeList.Parser.ParseFrom(geositeDB);
5269
foreach (var item in list.Entries)
5370
{
5471
Geosites[item.GroupName.ToLower()] = item.Domains;
@@ -61,9 +78,12 @@ public static void ResetEvent()
6178
Error = null;
6279
}
6380

64-
public static void UpdatePACFromGeosite(Configuration config)
81+
public static async Task UpdatePACFromGeosite()
6582
{
6683
string geositeUrl = GEOSITE_URL;
84+
string geositeSha256sumUrl = GEOSITE_SHA256SUM_URL;
85+
SHA256 mySHA256 = SHA256.Create();
86+
var config = Program.MainController.GetCurrentConfiguration();
6787
string group = config.geositeGroup;
6888
bool blacklist = config.geositeBlacklistMode;
6989

@@ -73,31 +93,82 @@ public static void UpdatePACFromGeosite(Configuration config)
7393
geositeUrl = config.geositeUrl;
7494
}
7595
logger.Info($"Checking Geosite from {geositeUrl}");
76-
WebClient http = new WebClient();
96+
97+
// use System.Net.Http.HttpClient to download GeoSite db.
98+
// NASTY workaround: new HttpClient every update
99+
// because we can't change proxy on existing socketsHttpHandler instance
100+
httpClientHandler = new HttpClientHandler();
101+
httpClient = new HttpClient(httpClientHandler);
77102
if (config.enabled)
78103
{
79-
http.Proxy = new WebProxy(
104+
httpClientHandler.Proxy = new WebProxy(
80105
config.isIPv6Enabled
81106
? $"[{IPAddress.IPv6Loopback}]"
82107
: IPAddress.Loopback.ToString(),
83108
config.localPort);
84109
}
85-
http.DownloadDataCompleted += (o, e) =>
110+
111+
try
86112
{
87-
try
113+
// download checksum first
114+
var geositeSha256sum = await httpClient.GetStringAsync(geositeSha256sumUrl);
115+
geositeSha256sum = geositeSha256sum.Substring(0, 64).ToUpper();
116+
logger.Info($"Got Sha256sum: {geositeSha256sum}");
117+
// compare downloaded checksum with local geositeDB
118+
byte[] localDBHashBytes = mySHA256.ComputeHash(geositeDB);
119+
string localDBHash = BitConverter.ToString(localDBHashBytes).Replace("-", String.Empty);
120+
logger.Info($"Local Sha256sum: {localDBHash}");
121+
// if already latest
122+
if (geositeSha256sum == localDBHash)
123+
{
124+
logger.Info("Local GeoSite DB is up to date.");
125+
return;
126+
}
127+
128+
// not latest. download new DB
129+
var downloadedBytes = await httpClient.GetByteArrayAsync(geositeUrl);
130+
131+
// verify sha256sum
132+
byte[] downloadedDBHashBytes = mySHA256.ComputeHash(downloadedBytes);
133+
string downloadedDBHash = BitConverter.ToString(downloadedDBHashBytes).Replace("-", String.Empty);
134+
logger.Info($"Actual Sha256sum: {downloadedDBHash}");
135+
if (geositeSha256sum != downloadedDBHash)
88136
{
89-
File.WriteAllBytes(DATABASE_PATH, e.Result);
90-
LoadGeositeList();
137+
logger.Info("Sha256sum Verification: FAILED. Downloaded GeoSite DB is corrupted. Aborting the update.");
138+
throw new Exception("Sha256sum mismatch");
139+
}
140+
else
141+
{
142+
logger.Info("Sha256sum Verification: PASSED. Applying to local GeoSite DB.");
143+
}
91144

92-
bool pacFileChanged = MergeAndWritePACFile(group, blacklist);
93-
UpdateCompleted?.Invoke(null, new GeositeResultEventArgs(pacFileChanged));
145+
// write to geosite file
146+
using (FileStream geositeFileStream = File.Create(DATABASE_PATH))
147+
await geositeFileStream.WriteAsync(downloadedBytes, 0, downloadedBytes.Length);
148+
149+
// update stuff
150+
geositeDB = downloadedBytes;
151+
LoadGeositeList();
152+
bool pacFileChanged = MergeAndWritePACFile(group, blacklist);
153+
UpdateCompleted?.Invoke(null, new GeositeResultEventArgs(pacFileChanged));
154+
}
155+
catch (Exception ex)
156+
{
157+
Error?.Invoke(null, new ErrorEventArgs(ex));
158+
}
159+
finally
160+
{
161+
if (httpClientHandler != null)
162+
{
163+
httpClientHandler.Dispose();
164+
httpClientHandler = null;
94165
}
95-
catch (Exception ex)
166+
if (httpClient != null)
96167
{
97-
Error?.Invoke(null, new ErrorEventArgs(ex));
168+
httpClient.Dispose();
169+
httpClient = null;
98170
}
99-
};
100-
http.DownloadDataAsync(new Uri(geositeUrl));
171+
}
101172
}
102173

103174
public static bool MergeAndWritePACFile(string group, bool blacklist)

shadowsocks-csharp/Controller/ShadowsocksController.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -415,11 +415,6 @@ public static string GetServerURL(Server server)
415415
return $"ss://{url}{tag}";
416416
}
417417

418-
public void UpdatePACFromGeosite()
419-
{
420-
GeositeUpdater.UpdatePACFromGeosite(_config);
421-
}
422-
423418
public void UpdateStatisticsConfiguration(bool enabled)
424419
{
425420
if (availabilityStatistics != null)

shadowsocks-csharp/View/MenuViewController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -685,9 +685,9 @@ private void EditPACFileItem_Click(object sender, EventArgs e)
685685
controller.TouchPACFile();
686686
}
687687

688-
private void UpdatePACFromGeositeItem_Click(object sender, EventArgs e)
688+
private async void UpdatePACFromGeositeItem_Click(object sender, EventArgs e)
689689
{
690-
controller.UpdatePACFromGeosite();
690+
await GeositeUpdater.UpdatePACFromGeosite();
691691
}
692692

693693
private void EditUserRuleFileForGeositeItem_Click(object sender, EventArgs e)

shadowsocks-csharp/packages.config

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@
99
<package id="NLog" version="4.6.8" targetFramework="net472" />
1010
<package id="StringEx.CS" version="0.3.1" targetFramework="net472" developmentDependency="true" />
1111
<package id="System.Buffers" version="4.4.0" targetFramework="net472" />
12+
<package id="System.IO" version="4.3.0" targetFramework="net472" />
1213
<package id="System.Memory" version="4.5.2" targetFramework="net472" />
14+
<package id="System.Net.Http" version="4.3.4" targetFramework="net472" />
1315
<package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net472" />
16+
<package id="System.Runtime" version="4.3.0" targetFramework="net472" />
1417
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net472" />
18+
<package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net472" />
19+
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net472" />
20+
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net472" />
21+
<package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net472" />
1522
<package id="ZXing.Net" version="0.16.5" targetFramework="net472" />
1623
</packages>

shadowsocks-csharp/shadowsocks-csharp.csproj

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,24 +93,60 @@
9393
<Reference Include="System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
9494
<HintPath>..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
9595
</Reference>
96+
<Reference Include="System.ComponentModel.Composition" />
9697
<Reference Include="System.Configuration" />
9798
<Reference Include="System.Data" />
9899
<Reference Include="System.Data.DataSetExtensions" />
99100
<Reference Include="System.Drawing" />
101+
<Reference Include="System.IO, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
102+
<HintPath>..\packages\System.IO.4.3.0\lib\net462\System.IO.dll</HintPath>
103+
<Private>True</Private>
104+
<Private>True</Private>
105+
</Reference>
100106
<Reference Include="System.IO.Compression" />
101107
<Reference Include="System.Management" />
102108
<Reference Include="System.Memory, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
103109
<HintPath>..\packages\System.Memory.4.5.2\lib\netstandard2.0\System.Memory.dll</HintPath>
104110
</Reference>
105111
<Reference Include="System.Net" />
112+
<Reference Include="System.Net.Http, Version=4.1.1.3, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
113+
<HintPath>..\packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll</HintPath>
114+
<Private>True</Private>
115+
<Private>True</Private>
116+
</Reference>
106117
<Reference Include="System.Numerics" />
107118
<Reference Include="System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
108119
<HintPath>..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
109120
</Reference>
121+
<Reference Include="System.Runtime, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
122+
<HintPath>..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll</HintPath>
123+
<Private>True</Private>
124+
<Private>True</Private>
125+
</Reference>
110126
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
111127
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
112128
</Reference>
113129
<Reference Include="System.Runtime.Serialization" />
130+
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
131+
<HintPath>..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll</HintPath>
132+
<Private>True</Private>
133+
<Private>True</Private>
134+
</Reference>
135+
<Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
136+
<HintPath>..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
137+
<Private>True</Private>
138+
<Private>True</Private>
139+
</Reference>
140+
<Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
141+
<HintPath>..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
142+
<Private>True</Private>
143+
<Private>True</Private>
144+
</Reference>
145+
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
146+
<HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
147+
<Private>True</Private>
148+
<Private>True</Private>
149+
</Reference>
114150
<Reference Include="System.ServiceModel" />
115151
<Reference Include="System.Transactions" />
116152
<Reference Include="System.Web" />

0 commit comments

Comments
 (0)