Skip to content

Commit 5d90c89

Browse files
authored
Merge pull request #347 from MortezaBashsiz/dev
Pause/Play & Diagnose & Bugfix
2 parents 9e9cdf1 + ea7a6ea commit 5d90c89

18 files changed

+1080
-272
lines changed

windows/Classes/CheckIPWorking.cs

+71-34
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,18 @@ internal class CheckIPWorking
2424
private readonly int downloadTimeout;
2525
public string downloadException = "";
2626
public string frontingException = "";
27+
private bool isDiagnosing = false;
28+
public bool isV2rayExecutionSuccess = false;
2729

28-
public CheckIPWorking(string ip, ScanSpeed targetSpeed, CustomConfigInfo scanConfig, int downloadTimeout)
30+
public CheckIPWorking(string ip, ScanSpeed targetSpeed, CustomConfigInfo scanConfig, int downloadTimeout, bool isDiagnosing = false)
2931
{
3032
this.ip = ip;
3133
this.port = getPortByIP();
3234
v2rayConfigPath = $"v2ray-config/generated/config.{ip}.json";
3335
this.targetSpeed = targetSpeed;
3436
this.scanConfig = scanConfig;
3537
this.downloadTimeout = downloadTimeout;
38+
this.isDiagnosing = isDiagnosing;
3639
}
3740

3841
public CheckIPWorking()
@@ -41,27 +44,36 @@ public CheckIPWorking()
4144

4245
public bool check()
4346
{
44-
bool success = false;
45-
Tools.logStep("\n ------- Start IP Check ------- ");
46-
47+
bool v2rayDLSuccess = false;
48+
Tools.logStep("\n------------ Start IP Check ------------", isDiagnosing);
49+
Tools.logStep("IP: " + this.ip, isDiagnosing);
50+
4751
// first of all quick test on fronting domain through cloudflare
48-
if(checkFronting())
52+
bool frontingSuccess = checkFronting();
53+
54+
if (frontingSuccess || isDiagnosing) // on diagnosing we will always test v2ray
4955
{
50-
// don't speed test is selected by user
51-
if (targetSpeed.isSpeedZero())
56+
// don't speed test if that mode is selected by user
57+
if (targetSpeed.isSpeedZero() && !isDiagnosing)
5258
{
53-
success = true;
59+
v2rayDLSuccess = true;
5460
}
5561
else
5662
{
5763
// then test quality of connection by downloading small file through v2ray vpn
58-
success = checkV2ray();
64+
v2rayDLSuccess = checkV2ray();
5965
}
6066

6167
}
6268

63-
Tools.logStep("\n------- End IP Check -------\n");
64-
return success;
69+
Tools.logStep(
70+
string.Format(Environment.NewLine + "Fronting Result: {0}", frontingSuccess ? "SUCCESS" : "FAILED") + Environment.NewLine +
71+
string.Format("v2ray.exe Execution: {0}", isV2rayExecutionSuccess ? "SUCCESS" : "FAILED") + Environment.NewLine +
72+
string.Format("Download Result: {0}", v2rayDLSuccess ? "SUCCESS" : "FAILED"), isDiagnosing
73+
);
74+
75+
Tools.logStep("\n------------ End IP Check ------------\n", isDiagnosing);
76+
return v2rayDLSuccess;
6577

6678
}
6779

@@ -102,28 +114,35 @@ public bool checkFronting(bool withCustumDNSResolver = true, int timeout = 1)
102114

103115
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
104116
client.Timeout = TimeSpan.FromSeconds(timeout);
117+
Tools.logStep(Environment.NewLine + "----- Fronting Test -----", isDiagnosing);
105118

106-
Tools.logStep($"Start fronting check, timeout: {timeout}, Resolver IP: {ip}, withCustumDNSResolver: {withCustumDNSResolver.ToString()}");
119+
Tools.logStep($"Start fronting check, timeout: {timeout}, Resolver IP: {ip}, withCustumDNSResolver: {withCustumDNSResolver.ToString()}", isDiagnosing);
107120
Stopwatch sw = new Stopwatch();
108121
try
109122
{
110123

111124
string frUrl = "https://" + ConfigManager.Instance.getAppConfig()?.frontDomain;
112-
Tools.logStep($"Starting fronting check with url: {frUrl}");
125+
Tools.logStep($"Fronting check with url: {frUrl}", isDiagnosing);
113126
sw.Start();
114127
var html = client.GetStringAsync(frUrl).Result;
115-
Tools.logStep($"Fronting check done in {sw.ElapsedMilliseconds:n0} ms, content: '{html.Substring(0, 50)}'");
128+
Tools.logStep($"Fronting check done in {sw.ElapsedMilliseconds:n0} ms, content: '{html.Substring(0, 50)}'", isDiagnosing);
116129
frontingDuration = sw.ElapsedMilliseconds;
117130
return true;
118131
}
119132
catch (Exception ex)
120133
{
121134
string message = ex.Message;
122-
Tools.logStep($"Fronting check had exception: {message}");
135+
if (isTimeoutException(ex))
136+
{
137+
Tools.logStep("Fronting timed out.", isDiagnosing);
138+
}
139+
else
140+
{
141+
Tools.logStep($"Fronting check had exception: {message}", isDiagnosing);
123142

124-
// monitor exceptions
125-
if (!message.Contains("A task was canceled."))
143+
// monitor exceptions
126144
frontingException = message;
145+
}
127146

128147
return false;
129148
}
@@ -147,46 +166,59 @@ private bool checkDownloadSpeed()
147166

148167
var client = new HttpClient(handler);
149168
client.Timeout = TimeSpan.FromSeconds(timeout); // 2 seconds
150-
Tools.logStep($"Start check dl speed, proxy port: {port}, timeout: {timeout} sec, target speed: {targetSpeed.getTargetSpeed():n0} b/s");
169+
Tools.logStep(Environment.NewLine + "----- Download Test -----", isDiagnosing);
170+
Tools.logStep($"Start check dl speed, proxy port: {port}, timeout: {timeout} sec, target speed: {targetSpeed.getTargetSpeed():n0} b/s", isDiagnosing);
151171
Stopwatch sw = new Stopwatch();
152172
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
153173

154174
try
155175
{
156176
sw.Start();
157177
string dlUrl = "https://" + ConfigManager.Instance.getAppConfig().scanDomain + targetSpeed.getTargetFileSize(timeout);
158-
Tools.logStep($"Starting dl url: {dlUrl}");
178+
Tools.logStep($"Starting dl url: {dlUrl}", isDiagnosing);
159179
var data = client.GetStringAsync(dlUrl).Result;
160-
Tools.logStep($"*** Download success in {sw.ElapsedMilliseconds:n0} ms, dl size: {data.Length:n0} bytes for IP {ip}");
180+
Tools.logStep($"*** Download success in {sw.ElapsedMilliseconds:n0} ms, dl size: {data.Length:n0} bytes for IP {ip}", isDiagnosing);
161181

162182
return data.Length == targetSpeed.getTargetSpeed() * timeout;
163183
}
164184
catch (Exception ex)
165185
{
166186
string message = ex.Message;
167-
Tools.logStep($"dl had exception: {message}");
168-
169-
// monitor exceptions
170-
if (!message.Contains("A task was canceled."))
171-
downloadException = message;
172-
173-
if (ex.InnerException != null && ex.InnerException?.Message != "" && ! ex.Message.Contains(ex.InnerException?.Message))
187+
if (isTimeoutException(ex))
174188
{
175-
Tools.logStep($"Inner exception: {ex.InnerException?.Message}");
189+
Tools.logStep("Download timed out.", isDiagnosing);
176190
}
191+
else
192+
{
193+
Tools.logStep($"Download had exception: {message}", isDiagnosing);
194+
// monitor exceptions
195+
downloadException = message;
196+
197+
if (ex.InnerException != null && ex.InnerException?.Message != "" && ! ex.Message.Contains(ex.InnerException?.Message))
198+
{
199+
Tools.logStep($"Inner exception: {ex.InnerException?.Message}", isDiagnosing);
200+
}
201+
}
202+
177203
return false;
178204
}
179205
finally
180206
{
181207
downloadDuration = sw.ElapsedMilliseconds;
182208
if(downloadDuration > (timeout * 1000) + 500)
183209
{
184-
Tools.logStep($"Download took too long! {downloadDuration:n0} ms for IP {ip}");
210+
Tools.logStep($"Download took too long! {downloadDuration:n0} ms for IP {ip}", isDiagnosing);
185211
}
186212
handler.Dispose();
187213
client.Dispose();
188214
}
189215
}
216+
private bool isTimeoutException(Exception ex)
217+
{
218+
string msg = ex.Message;
219+
return msg.Contains("The request was aborted") ||
220+
msg.Contains("A task was canceled.");
221+
}
190222

191223
private bool createV2rayConfigFile()
192224
{
@@ -222,7 +254,7 @@ private bool createV2rayConfigFile()
222254
}
223255
catch (Exception ex)
224256
{
225-
Tools.logStep($"createV2rayConfigFile has exception: {ex.Message}");
257+
Tools.logStep($"createV2rayConfigFile has exception: {ex.Message}", isDiagnosing);
226258
return false;
227259
}
228260

@@ -252,18 +284,19 @@ private bool runV2rayProcess()
252284
//}
253285
startInfo.UseShellExecute = false;
254286
startInfo.Arguments = $"run -config=\"{v2rayConfigPath}\"";
255-
Tools.logStep($"Starting v2ray.exe with arg: {startInfo.Arguments}");
287+
Tools.logStep(Environment.NewLine + "----- Running v2ray.exe -----", isDiagnosing);
288+
Tools.logStep($"Starting v2ray.exe with arg: {startInfo.Arguments}", isDiagnosing);
256289
bool wasSuccess = false;
257290
try
258291
{
259292
process = Process.Start(startInfo);
260293
Thread.Sleep(1500);
261294
wasSuccess = process.Responding && !process.HasExited;
262-
Tools.logStep($"v2ray.exe executed success: {wasSuccess}");
295+
Tools.logStep($"v2ray.exe executed success: {wasSuccess}", isDiagnosing);
263296
}
264297
catch (Exception ex)
265298
{
266-
Tools.logStep($"v2ray.exe execution had exception: {ex.Message}");
299+
Tools.logStep($"v2ray.exe execution had exception: {ex.Message}", isDiagnosing);
267300
}
268301

269302
// log error
@@ -272,11 +305,15 @@ private bool runV2rayProcess()
272305
try
273306
{
274307
string err = process.StandardError.ReadToEnd();
275-
Tools.logStep($"v2ray.exe Error: {err}");
308+
string message = $"v2ray.exe Error: {err}";
309+
Tools.logStep(message, isDiagnosing);
310+
downloadException = message;
276311
}
277312
catch (Exception) {}
278313
}
279314

315+
isV2rayExecutionSuccess = wasSuccess;
316+
280317
return wasSuccess;
281318
}
282319

windows/Classes/Config/ConfigManager.cs

+6
Original file line numberDiff line numberDiff line change
@@ -117,5 +117,11 @@ private void checkDebugEnable()
117117
{
118118
return this.clientConfig;
119119
}
120+
121+
// when client config is updated from remote then we need to update it here too
122+
public void reloadClientConfig()
123+
{
124+
clientConfig = (new ClientConfig(appConfig)).getLoadedInstance();
125+
}
120126
}
121127
}

windows/Classes/Config/CustomConfigs.cs

+21-7
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ internal class CustomConfigs
1212
{
1313
public List<CustomConfigInfo> customConfigInfos = new();
1414
private static string customConfigsDirectory = "v2ray-config/custom-configs";
15-
private static string customConfigHelpUrl = "...";
15+
private static string customConfigHelpUrl = "https://github.com/MortezaBashsiz/CFScanner/discussions/210";
1616

1717
public CustomConfigs() {
1818
loadCustomConfigs();
@@ -27,10 +27,15 @@ public void loadCustomConfigs()
2727
{
2828
var customConfigObj = new CustomConfigInfo(customConfig, File.ReadAllText(customConfig));
2929

30+
string msg;
3031
// validate
31-
if (customConfigObj.isValid()) {
32+
if (customConfigObj.isValid(out msg)) {
3233
customConfigInfos.Add(customConfigObj);
3334
}
35+
else
36+
{
37+
Tools.logStep($"Invalid custom config: {msg}, File: {customConfig}");
38+
}
3439

3540
}
3641
}
@@ -39,7 +44,7 @@ public static bool addNewConfigFile(string fileName, out string errorMessage)
3944
{
4045
errorMessage = "";
4146
var validator = new CustomConfigInfo(fileName, File.ReadAllText(fileName));
42-
if (validator.isValid())
47+
if (validator.isValid(out errorMessage))
4348
{
4449
try
4550
{
@@ -54,7 +59,7 @@ public static bool addNewConfigFile(string fileName, out string errorMessage)
5459
}
5560
else
5661
{
57-
errorMessage = "Provided config file is not valid v2ray config. See here for more information: " + customConfigHelpUrl;
62+
errorMessage = $"Provided config file is not valid v2ray config: {errorMessage + Environment.NewLine}See here for more information: " + customConfigHelpUrl;
5863
return false;
5964
}
6065
}
@@ -71,24 +76,33 @@ public CustomConfigInfo(string fileName, string content)
7176
this.content = content;
7277
}
7378

74-
public bool isValid()
79+
public bool isValid(out string message)
7580
{
81+
message = "";
7682
try
7783
{
7884
var tt = JsonSerializer.Deserialize<JsonDocument>(content)!;
7985
}
8086
catch (Exception)
8187
{
8288
// it is invalid json
89+
message = "File is not in valid json format.";
8390
return false;
8491
}
8592

86-
if (!content.Contains("\"port\": \"PORTPORT\""))
93+
if (!content.Contains("\"port\": \"PORTPORT\""))
94+
{
95+
message = "PORTPORT parameter is not found in the file.";
8796
return false;
97+
}
8898

89-
if (!content.Contains("\"address\": \"IP.IP.IP.IP\""))
99+
if (!content.Contains("\"address\": \"IP.IP.IP.IP\""))
100+
{
101+
message = "IP.IP.IP.IP parameter is not found in the file.";
90102
return false;
103+
}
91104

105+
92106
return true;
93107
}
94108

windows/Classes/ExceptionMonitor.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ public void setControlColorStyles(ToolStripSplitButton control)
120120
// yellow warning
121121
else if (errRate <= warningErrRate)
122122
{
123-
control.ForeColor = Color.Orange;
123+
control.ForeColor = Color.OrangeRed;
124124
}
125125
// red danger
126126
else

windows/Classes/IP/IPAddressExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public static void getIPRangeInfo(string ip, int network, out uint start, out u
5050
total = end - start;
5151
}
5252

53-
public static List<string> getIPRange(string ipAndNet)
53+
public static List<string> getAllIPInRange(string ipAndNet)
5454
{
5555
string[] splitted = ipAndNet.Split('/');
5656
return getIPRange(splitted[0], Int32.Parse(splitted[1]));

0 commit comments

Comments
 (0)