| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 | 
							- <?php
 
- namespace App\Utils;
 
- use Exception;
 
- use Http;
 
- use Illuminate\Http\Client\PendingRequest;
 
- use Log;
 
- class NetworkDetection
 
- {
 
-     private static PendingRequest $basicRequest;
 
-     public function ping(string $ip): ?string
 
-     { // 用外部API进行Ping检测. TODO: 无权威外部API,功能缺失
 
-         $testers = ['oiowebPing', 'xiaoapiPing', 'yum6Ping'];
 
-         self::$basicRequest = Http::timeout(20)->withOptions(['http_errors' => false])->withUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36');
 
-         foreach ($testers as $tester) {
 
-             try {
 
-                 $result = $this->callLatencyTester($tester, $ip);
 
-                 if ($result !== null) {
 
-                     return $result;
 
-                 }
 
-             } catch (Exception $e) {
 
-                 Log::error("[$tester] 网络延迟测试报错: ".$e->getMessage());
 
-                 continue;
 
-             }
 
-         }
 
-         return null;
 
-     }
 
-     private function callLatencyTester(string $tester, string $ip): ?array
 
-     {
 
-         return match ($tester) {
 
-             'oiowebPing' => $this->oiowebPing($ip),
 
-             'xiaoapiPing' => $this->xiaoapiPing($ip),
 
-             'yum6Ping' => $this->yum6Ping($ip),
 
-         };
 
-     }
 
-     private function oiowebPing(string $ip)
 
-     {
 
-         $msg = null;
 
-         foreach ([1, 6, 14] as $line) {
 
-             $response = self::$basicRequest->get("https://api.oioweb.cn/api/hostping.php?host=$ip&node=$line"); // https://api.iiwl.cc/api/ping.php?host=
 
-             // 发送成功
 
-             if ($response->ok()) {
 
-                 $message = $response->json();
 
-                 if ($message && $message['code']) {
 
-                     $msg .= "{$message['node']}:{$message['data']['Time']}<br>";
 
-                 }
 
-             } else {
 
-                 return false;
 
-             }
 
-         }
 
-         if ($msg) {
 
-             return $msg;
 
-         }
 
-         Log::warning('【PING】检测'.$ip.'时,api.oioweb.cn无结果');
 
-         // 发送错误
 
-         return false;
 
-     }
 
-     private function xiaoapiPing(string $ip)
 
-     { // 开发依据 https://xiaoapi.cn/?action=doc&id=3
 
-         $response = self::$basicRequest->get("https://xiaoapi.cn/API/sping.php?url=$ip");
 
-         // 发送成功
 
-         if ($response->ok()) {
 
-             return $response->body();
 
-         }
 
-         Log::warning("【PING】检测{$ip}时,xiaoapi.cn无结果");
 
-         // 发送错误
 
-         return false;
 
-     }
 
-     private function yum6Ping(string $ip)
 
-     { // 来源 https://api.yum6.cn/ping.php?host=api.yum6.cn
 
-         $response = self::$basicRequest->get("https://api.yum6.cn/ping.php?host=$ip");
 
-         // 发送成功
 
-         if ($response->ok()) {
 
-             $msg = $response->json();
 
-             if ($msg && $msg['state'] === '1000') {
 
-                 return "<h4>{$msg['ip']}</h4>线路【{$msg['node']}】<br> 最小值:{$msg['ping_time_min']}<br> 平均值:{$msg['ping_time_avg']}<br> 最大值:{$msg['ping_time_max']}";
 
-             }
 
-         }
 
-         Log::warning('【PING】检测'.$ip.'时,api.yum6.cn无结果');
 
-         return false; // 发送错误
 
-     }
 
-     public function networkStatus(string $ip, int $port): ?array
 
-     {
 
-         $status = $this->networkCheck($ip, $port);
 
-         if ($status) {
 
-             $ret = [];
 
-             foreach (['icmp', 'tcp'] as $protocol) {
 
-                 if ($status['in'][$protocol] && $status['out'][$protocol]) {
 
-                     $check = 1; // 正常
 
-                 }
 
-                 if ($status['in'][$protocol] && ! $status['out'][$protocol]) {
 
-                     $check = 2; // 国外访问异常
 
-                 }
 
-                 if (! $status['in'][$protocol] && $status['out'][$protocol]) {
 
-                     $check = 3; // 被墙
 
-                 }
 
-                 $ret[$protocol] = $check ?? 4; // 服务器宕机
 
-             }
 
-             return $ret;
 
-         }
 
-         return null;
 
-     }
 
-     private function networkCheck(string $ip, int $port): ?array
 
-     { // 通过众多API进行节点阻断检测.
 
-         $checkers = ['toolsdaquan', 'flyzy2005', 'idcoffer', 'ip112', 'upx8', 'vps234', 'rss', 'gd', 'vps1352'];
 
-         self::$basicRequest = Http::timeout(15)->retry(2)->withOptions(['http_errors' => false])->withoutVerifying()->withUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36');
 
-         foreach ($checkers as $checker) {
 
-             try {
 
-                 $result = $this->callChecker($checker, $ip, $port);
 
-                 if ($result !== null) {
 
-                     return $result;
 
-                 }
 
-             } catch (Exception $e) {
 
-                 Log::error("[$checker] 网络阻断测试报错: ".$e->getMessage());
 
-                 continue;
 
-             }
 
-         }
 
-         return null;
 
-     }
 
-     private function callChecker(string $checker, string $ip, int $port): ?array
 
-     {
 
-         return match ($checker) {
 
-             'toolsdaquan' => $this->toolsdaquan($ip, $port),
 
-             'gd' => $this->gd($ip, $port),
 
-             'vps234' => $this->vps234($ip),
 
-             'flyzy2005' => $this->flyzy2005($ip, $port),
 
-             'idcoffer' => $this->idcoffer($ip, $port),
 
-             'ip112' => $this->ip112($ip, $port),
 
-             'upx8' => $this->upx8($ip, $port),
 
-             'vps1352' => $this->vps1352($ip, $port),
 
-             'rss' => $this->rss($ip, $port),
 
-         };
 
-     }
 
-     private function toolsdaquan(string $ip, int $port): ?array
 
-     { // 开发依据: https://www.toolsdaquan.com/ipcheck/
 
-         $response_inner = self::$basicRequest->withHeaders(['Referer' => 'https://www.toolsdaquan.com/ipcheck/'])->get("https://www.toolsdaquan.com/toolapi/public/ipchecking/$ip/$port");
 
-         $response_outer = self::$basicRequest->withHeaders(['Referer' => 'https://www.toolsdaquan.com/ipcheck/'])->get("https://www.toolsdaquan.com/toolapi/public/ipchecking2/$ip/$port");
 
-         if ($response_inner->ok() && $response_outer->ok()) {
 
-             return $this->common_detection($response_inner->json(), $response_outer->json(), $ip);
 
-         }
 
-         return null;
 
-     }
 
-     private function common_detection(array $inner, array $outer, string $ip): ?array
 
-     {
 
-         if (empty($inner) || empty($outer)) {
 
-             Log::warning("【阻断检测】检测{$ip}时,接口返回异常");
 
-             return null;
 
-         }
 
-         return [
 
-             'in' => [
 
-                 'icmp' => $inner['icmp'] === 'success',
 
-                 'tcp' => $inner['tcp'] === 'success',
 
-             ],
 
-             'out' => [
 
-                 'icmp' => $outer['outside_icmp'] === 'success',
 
-                 'tcp' => $outer['outside_tcp'] === 'success',
 
-             ],
 
-         ];
 
-     }
 
-     private function gd(string $ip, int $port): ?array
 
-     { // 开发依据: https://ping.gd/
 
-         $response = self::$basicRequest->get("https://ping.gd/api/ip-test/$ip:$port");
 
-         if ($response->ok()) {
 
-             $data = $response->json();
 
-             if ($data) {
 
-                 return [
 
-                     'in' => [
 
-                         'icmp' => $data[0]['result']['ping_alive'],
 
-                         'tcp' => $data[0]['result']['telnet_alive'],
 
-                     ],
 
-                     'out' => [
 
-                         'icmp' => $data[1]['result']['ping_alive'],
 
-                         'tcp' => $data[1]['result']['telnet_alive'],
 
-                     ],
 
-                 ];
 
-             }
 
-         }
 
-         Log::warning("【阻断检测】检测{$ip}时,[ping.gd]接口返回异常");
 
-         return null;
 
-     }
 
-     private function vps234(string $ip): ?array
 
-     { // 开发依据: https://www.vps234.com/ipchecker/
 
-         $response = self::$basicRequest->asForm()->post('https://www.vps234.com/ipcheck/getdata/', ['ip' => $ip]);
 
-         if ($response->ok()) {
 
-             $data = $response->json();
 
-             if ($data) {
 
-                 if ($data['error'] === false && $data['data']['success']) {
 
-                     $result = $data['data']['data'];
 
-                     return [
 
-                         'in' => [
 
-                             'icmp' => $result['innerICMP'],
 
-                             'tcp' => $result['innerTCP'],
 
-                         ],
 
-                         'out' => [
 
-                             'icmp' => $result['outICMP'],
 
-                             'tcp' => $result['outTCP'],
 
-                         ],
 
-                     ];
 
-                 }
 
-                 Log::warning('【阻断检测】检测'.$ip.'时,[vps234]接口返回'.var_export($data, true));
 
-             }
 
-             Log::warning("【阻断检测】检测{$ip}时, [vps234]接口返回异常");
 
-         }
 
-         return null;
 
-     }
 
-     private function flyzy2005(string $ip, int $port): ?array
 
-     { // 开发依据: https://www.flyzy2005.cn/tech/ip-check/
 
-         $response_inner = self::$basicRequest->get("https://mini.flyzy2005.cn/ip_check.php?ip=$ip&port=$port");
 
-         $response_outer = self::$basicRequest->get("https://mini.flyzy2005.cn/ip_check_outside.php?ip=$ip&port=$port");
 
-         if ($response_inner->ok() && $response_outer->ok()) {
 
-             return $this->common_detection($response_inner->json(), $response_outer->json(), $ip);
 
-         }
 
-         return null;
 
-     }
 
-     private function idcoffer(string $ip, int $port): ?array
 
-     { // 开发依据: https://www.idcoffer.com/ipcheck
 
-         $response_inner = self::$basicRequest->get("https://api.24kplus.com/ipcheck?host=$ip&port=$port");
 
-         $response_outer = self::$basicRequest->get("https://api.idcoffer.com/ipcheck?host=$ip&port=$port");
 
-         if ($response_inner->ok() && $response_outer->ok()) {
 
-             $inner = $response_inner->json();
 
-             $outer = $response_outer->json();
 
-             if ($inner && $outer) {
 
-                 if ($inner['code'] && $outer['code']) {
 
-                     return [
 
-                         'in' => [
 
-                             'icmp' => $inner['data']['ping'],
 
-                             'tcp' => $inner['data']['tcp'],
 
-                         ],
 
-                         'out' => [
 
-                             'icmp' => $outer['data']['ping'],
 
-                             'tcp' => $outer['data']['tcp'],
 
-                         ],
 
-                     ];
 
-                 }
 
-                 Log::warning('【阻断检测】检测'.$ip.$port.'时,[idcoffer]接口返回'.var_export($inner, true).PHP_EOL.var_export($outer, true));
 
-             }
 
-             Log::warning("【阻断检测】检测{$ip}时,[idcoffer]接口返回异常");
 
-         }
 
-         return null;
 
-     }
 
-     private function ip112(string $ip, int $port = 443): ?array
 
-     { // 开发依据: https://ip112.cn/
 
-         $response_inner = self::$basicRequest->asForm()->post('https://api.ycwxgzs.com/ipcheck/index.php', ['ip' => $ip, 'port' => $port]);
 
-         $response_outer = self::$basicRequest->asForm()->post('https://api.52bwg.com/ipcheck/ipcheck.php', ['ip' => $ip, 'port' => $port]);
 
-         if ($response_inner->ok() && $response_outer->ok()) {
 
-             $inner = $response_inner->json();
 
-             $outer = $response_outer->json();
 
-             if ($inner && $outer) {
 
-                 return [
 
-                     'in' => [
 
-                         'icmp' => str_contains($inner['icmp'], 'green'),
 
-                         'tcp' => str_contains($inner['tcp'], 'green'),
 
-                     ],
 
-                     'out' => [
 
-                         'icmp' => str_contains($outer['icmp'], 'green'),
 
-                         'tcp' => str_contains($outer['tcp'], 'green'),
 
-                     ],
 
-                 ];
 
-             }
 
-         }
 
-         Log::warning("【阻断检测】检测{$ip}时,[ip112]接口返回异常");
 
-         return null;
 
-     }
 
-     private function upx8(string $ip, int $port = 443): ?array
 
-     { // 开发依据: https://blog.upx8.com/ipcha.html
 
-         $response_inner = self::$basicRequest->asForm()->post('https://ip.upx8.com/check.php', ['ip' => $ip, 'port' => $port]);
 
-         $response_outer = self::$basicRequest->asForm()->post('https://ip.7761.cf/check.php', ['ip' => $ip, 'port' => $port]);
 
-         if ($response_inner->ok() && $response_outer->ok()) {
 
-             $inner = $response_inner->json();
 
-             $outer = $response_outer->json();
 
-             if ($inner && $outer) {
 
-                 return [
 
-                     'in' => [
 
-                         'icmp' => $inner['icmp'] === '正常',
 
-                         'tcp' => $inner['tcp'] === '正常',
 
-                     ],
 
-                     'out' => [
 
-                         'icmp' => $outer['icmp'] === '正常',
 
-                         'tcp' => $outer['tcp'] === '正常',
 
-                     ],
 
-                 ];
 
-             }
 
-         }
 
-         Log::warning("【阻断检测】检测{$ip}时,[upx8]接口返回异常");
 
-         return null;
 
-     }
 
-     private function vps1352(string $ip, int $port): ?array
 
-     { // 开发依据: https://www.51vps.info/ipcheck.html https://www.vps1352.com/ipcheck.html 有缺陷api,查不了海外做判断 备用
 
-         $response = self::$basicRequest->asForm()->withHeaders(['Referer' => 'https://www.51vps.info'])->post('https://www.vps1352.com/check.php', ['ip' => $ip, 'port' => $port]);
 
-         if ($response->ok()) {
 
-             $data = $response->json();
 
-             if ($data) {
 
-                 return [
 
-                     'in' => [
 
-                         'icmp' => $data['icmp'] === '开放',
 
-                         'tcp' => $data['tcp'] === '开放',
 
-                     ],
 
-                     'out' => [
 
-                         'icmp' => true,
 
-                         'tcp' => true,
 
-                     ],
 
-                 ];
 
-             }
 
-         }
 
-         Log::warning("【阻断检测】检测{$ip}时, [vps1352.com]接口返回异常");
 
-         return null;
 
-     }
 
-     private function rss(string $ip, int $port): ?array
 
-     { // https://ip.rss.ink/index/check
 
-         $client = self::$basicRequest->withHeaders(['X-Token' => '5AXfB1xVfuq5hxv4']);
 
-         foreach (['in', 'out'] as $type) {
 
-             foreach (['icmp', 'tcp'] as $protocol) {
 
-                 $response = $client->get('https://ip.rss.ink/netcheck/'.($type === 'in' ? 'cn' : 'global')."/api/check/$protocol?ip=$ip".($protocol === 'tcp' ? "&port=$port" : ''));
 
-                 if ($response->ok()) {
 
-                     $data = $response->json();
 
-                     $ret[$type][$protocol] = $data['msg'] === 'success';
 
-                 }
 
-             }
 
-         }
 
-         if (! isset($ret)) {
 
-             Log::warning("【阻断检测】检测{$ip}时, [rss]接口返回异常");
 
-         }
 
-         return $ret ?? null;
 
-     }
 
- }
 
 
  |