1010using WinCFScan . Classes . Config ;
1111using WinCFScan . Classes . HTTPRequest ;
1212
13- namespace WinCFScan . Classes
13+ namespace WinCFScan . Classes . Checker
1414{
1515 internal class CheckIPWorking
1616 {
1717 private readonly string ip ;
18- private Process ? process ;
18+ private Process ? process ;
1919 private string port ;
2020 private string v2rayConfigPath ;
2121 public long downloadDuration { get ; private set ; }
22+ public long uploadDuration { get ; private set ; }
2223 public long frontingDuration { get ; private set ; }
23- private ScanSpeed targetSpeed ;
24+ private ScanSpeed dlTargetSpeed ;
25+ private ScanSpeed upTargetSpeed ;
2426 private readonly CustomConfigInfo scanConfig ;
25- private readonly int downloadTimeout ;
27+ private readonly int checkTimeout ;
2628 public string downloadException = "" ;
29+ public string uploadException = "" ;
2730 public string frontingException = "" ;
2831 private bool isDiagnosing = false ;
2932 public bool isV2rayExecutionSuccess = false ;
33+ public CheckType checkType { get ; private set ; }
34+ private CheckResultStatus checkResultStatus ;
3035
31-
32-
33- public CheckIPWorking ( string ip , ScanSpeed targetSpeed , CustomConfigInfo scanConfig , int downloadTimeout , bool isDiagnosing = false )
36+ public CheckIPWorking ( string ip , ScanSpeed dlTargetSpeed , ScanSpeed upTargetSpeed , CustomConfigInfo scanConfig , CheckType checkType , int checkTimeout , bool isDiagnosing = false )
3437 {
3538 this . ip = ip ;
36- this . port = getPortByIP ( ) ;
39+ port = getPortByIP ( ) ;
3740 v2rayConfigPath = $ "v2ray-config/generated/config.{ ip } .json";
38- this . targetSpeed = targetSpeed ;
41+ this . dlTargetSpeed = dlTargetSpeed ;
42+ this . upTargetSpeed = upTargetSpeed ;
3943 this . scanConfig = scanConfig ;
40- this . downloadTimeout = downloadTimeout ;
44+ this . checkTimeout = checkTimeout ;
4145 this . isDiagnosing = isDiagnosing ;
46+ this . checkType = checkType ;
47+ checkResultStatus = new CheckResultStatus ( checkType ) ;
4248 }
4349
4450 public CheckIPWorking ( )
4551 {
4652 }
4753
48- public bool check ( )
54+ public bool check ( )
4955 {
5056 bool v2rayDLSuccess = false ;
5157 Tools . logStep ( "\n ------------ Start IP Check ------------" , isDiagnosing ) ;
52- Tools . logStep ( "IP: " + this . ip , isDiagnosing ) ;
58+ Tools . logStep ( "IP: " + ip , isDiagnosing ) ;
5359
5460 // first of all quick test on fronting domain through cloudflare
5561 bool frontingSuccess = checkFronting ( ) ;
5662
5763 if ( frontingSuccess || isDiagnosing ) // on diagnosing we will always test v2ray
5864 {
5965 // don't speed test if that mode is selected by user
60- if ( targetSpeed . isSpeedZero ( ) && ! isDiagnosing )
66+ if ( dlTargetSpeed . isSpeedZero ( ) && ! isDiagnosing )
6167 {
6268 v2rayDLSuccess = true ;
6369 }
@@ -70,26 +76,29 @@ public bool check()
7076 }
7177
7278 Tools . logStep (
73- string . Format ( Environment . NewLine + "Fronting Result: {0}" , frontingSuccess ? "SUCCESS" : "FAILED" ) + Environment . NewLine +
79+ string . Format ( Environment . NewLine + "Fronting Result: {0}" , frontingSuccess ? "SUCCESS" : "FAILED" ) + Environment . NewLine +
7480 string . Format ( "v2ray.exe Execution: {0}" , isV2rayExecutionSuccess ? "SUCCESS" : "FAILED" ) + Environment . NewLine +
75- string . Format ( "Download Result: {0}" , v2rayDLSuccess ? "SUCCESS" : "FAILED" ) , isDiagnosing
81+ string . Format ( "Download Result: {0}" , checkResultStatus . isDownSuccess ( ) ? "SUCCESS" : "FAILED" ) + Environment . NewLine +
82+ string . Format ( "Upload Result: {0}" , checkResultStatus . isUpSuccess ( ) ? "SUCCESS" : "FAILED" ) , isDiagnosing
7683 ) ;
7784
7885 Tools . logStep ( "\n ------------ End IP Check ------------\n " , isDiagnosing ) ;
7986 return v2rayDLSuccess ;
8087
8188 }
8289
83- public bool checkV2ray ( ) {
90+ public bool checkV2ray ( )
91+ {
8492 bool success = false ;
93+
8594 // create config
8695 if ( createV2rayConfigFile ( ) )
8796 {
8897 // start v2ray.exe process
8998 if ( runV2rayProcess ( ) )
9099 {
91- // send download request
92- if ( checkDownloadSpeed ( ) )
100+ // send download/upload request
101+ if ( checkV2raySpeed ( ) )
93102 {
94103 // speed was enough
95104 success = true ;
@@ -123,14 +132,14 @@ public bool checkFronting(bool withCustumDNSResolver = true, int timeout = 1)
123132 Stopwatch sw = new Stopwatch ( ) ;
124133 try
125134 {
126-
135+
127136 string frUrl = "https://" + ConfigManager . Instance . getAppConfig ( ) ? . frontDomain ;
128137 Tools . logStep ( $ "Fronting check with url: { frUrl } ", isDiagnosing ) ;
129138 sw . Start ( ) ;
130139 var html = client . GetStringAsync ( frUrl ) . Result ;
131140 Tools . logStep ( $ "Fronting check done in { sw . ElapsedMilliseconds : n0} ms, content: '{ html . Substring ( 0 , 50 ) } '", isDiagnosing ) ;
132141 frontingDuration = sw . ElapsedMilliseconds ;
133- return true ;
142+ return html . StartsWith ( "0000000000" ) ;
134143 }
135144 catch ( Exception ex )
136145 {
@@ -156,66 +165,45 @@ public bool checkFronting(bool withCustumDNSResolver = true, int timeout = 1)
156165
157166 }
158167
159- private bool checkDownloadSpeed ( )
168+ private bool checkV2raySpeed ( )
160169 {
161- var proxy = new WebProxy ( ) ;
162- proxy . Address = new Uri ( $ "socks5://127.0.0.1:{ port } ") ;
163- var handler = new HttpClientHandler
170+ // check download
171+ if ( checkType is CheckType . DOWNLOAD or CheckType . BOTH || isDiagnosing )
164172 {
165- Proxy = proxy
166- } ;
167-
168- int timeout = this . downloadTimeout ;
169-
170- var client = new HttpClient ( handler ) ;
171- client . Timeout = TimeSpan . FromSeconds ( timeout ) ; // 2 seconds
172- Tools . logStep ( Environment . NewLine + "----- Download Test -----" , isDiagnosing ) ;
173- Tools . logStep ( $ "Start check dl speed, proxy port: { port } , timeout: { timeout } sec, target speed: { targetSpeed . getTargetSpeed ( ) : n0} b/s", isDiagnosing ) ;
174- Stopwatch sw = new Stopwatch ( ) ;
175- //ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
176-
177- try
178- {
179- sw . Start ( ) ;
180- string dlUrl = "https://" + ConfigManager . Instance . getAppConfig ( ) . scanDomain + targetSpeed . getTargetFileSize ( timeout ) ;
181- Tools . logStep ( $ "Starting dl url: { dlUrl } ", isDiagnosing ) ;
182- var data = client . GetStringAsync ( dlUrl ) . Result ;
183- Tools . logStep ( $ "*** Download success in { sw . ElapsedMilliseconds : n0} ms, dl size: { data . Length : n0} bytes for IP { ip } ", isDiagnosing ) ;
184-
185- return data . Length == targetSpeed . getTargetSpeed ( ) * timeout ;
186- }
187- catch ( Exception ex )
188- {
189- string message = ex . Message ;
190- if ( isTimeoutException ( ex ) )
173+ string dlUrl = "https://" + ConfigManager . Instance . getAppConfig ( ) . downloadDomain + dlTargetSpeed . getTargetFileSize ( checkTimeout ) ;
174+ var cs = new CheckSettings ( ip , port , checkTimeout , dlUrl , isDiagnosing , checkType , dlTargetSpeed ) ;
175+ var dlChecker = new DownloadChecker ( cs ) ;
176+ if ( dlChecker . check ( ) )
191177 {
192- Tools . logStep ( "Download timed out." , isDiagnosing ) ;
178+ checkResultStatus . setDownloadSuccess ( ) ;
179+ downloadDuration = dlChecker . checkDuration ;
193180 }
194181 else
195182 {
196- Tools . logStep ( $ "Download had exception: { message } ", isDiagnosing ) ;
197- // monitor exceptions
198- downloadException = message ;
199-
200- if ( ex . InnerException != null && ex . InnerException ? . Message != "" && ! ex . Message . Contains ( ex . InnerException ? . Message ) )
201- {
202- Tools . logStep ( $ "Inner exception: { ex . InnerException ? . Message } ", isDiagnosing ) ;
203- }
183+ this . downloadException = dlChecker . exceptionMessage ;
204184 }
205185
206- return false ;
207186 }
208- finally
209- {
210- downloadDuration = sw . ElapsedMilliseconds ;
211- if ( downloadDuration > ( timeout * 1000 ) + 500 )
187+
188+ // check upload
189+ if ( checkType is CheckType . UPLOAD or CheckType . BOTH || isDiagnosing ) {
190+ string upUrl = "https://" + ConfigManager . Instance . getAppConfig ( ) . uploadDomain ;
191+ var cs = new CheckSettings ( ip , port , checkTimeout , upUrl , isDiagnosing , checkType , upTargetSpeed ) ;
192+ var upChecker = new UploadChecker ( cs ) ;
193+ if ( upChecker . check ( ) )
212194 {
213- Tools . logStep ( $ "Download took too long! { downloadDuration : n0} ms for IP { ip } ", isDiagnosing ) ;
195+ checkResultStatus . setUploadSuccess ( ) ;
196+ uploadDuration = upChecker . checkDuration ;
197+ }
198+ else
199+ {
200+ this . uploadException = upChecker . exceptionMessage ;
214201 }
215- handler . Dispose ( ) ;
216- client . Dispose ( ) ;
217202 }
203+
204+ return checkResultStatus . isSuccess ( ) ;
218205 }
206+
219207 private bool isTimeoutException ( Exception ex )
220208 {
221209 string msg = ex . Message ;
@@ -240,15 +228,15 @@ private bool createV2rayConfigFile()
240228 . Replace ( "HOSTHOST" , clientConfig . host )
241229 . Replace ( "CFPORTCFPORT" , clientConfig . port )
242230 . Replace ( "RANDOMHOST" , getRandomSNI ( clientConfig . host ) )
243- . Replace ( "IP.IP.IP.IP" , this . ip )
231+ . Replace ( "IP.IP.IP.IP" , ip )
244232 . Replace ( "ENDPOINTENDPOINT" , clientConfig . path ) ;
245233 }
246234 else
247235 { // just replace port and ip for custom v2ray configs
248236 configTemplate = scanConfig . content ;
249237 configTemplate = configTemplate
250238 . Replace ( "PORTPORT" , port )
251- . Replace ( "IP.IP.IP.IP" , this . ip ) ;
239+ . Replace ( "IP.IP.IP.IP" , ip ) ;
252240 }
253241
254242 File . WriteAllText ( v2rayConfigPath , configTemplate ) ;
@@ -267,15 +255,15 @@ private string getRandomSNI(string host)
267255 {
268256 var urlParts = host . Split ( "." ) ;
269257 urlParts [ 0 ] = Guid . NewGuid ( ) . ToString ( ) ;
270- return string . Join ( "." , urlParts ) ;
258+ return string . Join ( "." , urlParts ) ;
271259 }
272260
273261 // sum of ip segments plus 3000
274262 private string getPortByIP ( )
275- {
276- int sum = Int32 . Parse (
277- this . ip . Split ( "." ) . Aggregate ( ( current , next ) =>
278- ( Int32 . Parse ( current ) + Int32 . Parse ( next ) ) . ToString ( ) )
263+ {
264+ int sum = int . Parse (
265+ ip . Split ( "." ) . Aggregate ( ( current , next ) =>
266+ ( int . Parse ( current ) + int . Parse ( next ) ) . ToString ( ) )
279267 ) ;
280268
281269 return ( 3000 + sum ) . ToString ( ) ;
@@ -287,10 +275,10 @@ private bool runV2rayProcess()
287275 startInfo . FileName = "v2ray.exe" ;
288276 //if (!ConfigManager.Instance.enableDebug)
289277 //{
290- startInfo . WindowStyle = ProcessWindowStyle . Hidden ;
291- startInfo . RedirectStandardOutput = true ;
292- startInfo . RedirectStandardError = true ;
293- startInfo . CreateNoWindow = true ;
278+ startInfo . WindowStyle = ProcessWindowStyle . Hidden ;
279+ startInfo . RedirectStandardOutput = true ;
280+ startInfo . RedirectStandardError = true ;
281+ startInfo . CreateNoWindow = true ;
294282 //}
295283 startInfo . UseShellExecute = false ;
296284 startInfo . Arguments = $ "run -config=\" { v2rayConfigPath } \" ";
@@ -309,7 +297,7 @@ private bool runV2rayProcess()
309297 {
310298 Tools . logStep ( $ "v2ray.exe execution had exception: { ex . Message } ", isDiagnosing ) ;
311299 }
312-
300+
313301 // log error
314302 if ( ! wasSuccess )
315303 {
@@ -320,14 +308,14 @@ private bool runV2rayProcess()
320308 Tools . logStep ( message , isDiagnosing ) ;
321309 downloadException = message ;
322310 }
323- catch ( Exception ) { }
311+ catch ( Exception ) { }
324312 }
325313
326314 isV2rayExecutionSuccess = wasSuccess ;
327315
328316 return wasSuccess ;
329317 }
330318
331-
319+
332320 }
333321}
0 commit comments