From 8da689fbc8580a09fe0d10b6cc3407b479dbca4e Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sat, 21 Aug 2021 03:23:19 +0800 Subject: [PATCH] refactor: new NTP check model --- functions/Curl.php | 27 +++++- functions/DNS.php | 4 +- functions/Domain.php | 11 +++ models/ntpCheck.php | 206 ++++++++++++++++++++++++++----------------- 4 files changed, 162 insertions(+), 86 deletions(-) diff --git a/functions/Curl.php b/functions/Curl.php index c6411f8..8793280 100644 --- a/functions/Curl.php +++ b/functions/Curl.php @@ -4,11 +4,30 @@ class Curl { public $ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.67'; public function get($url, $timeOut = 30) { // curl模拟Get 默认30s超时 + return $this->run(array( + [CURLOPT_URL, $url], + [CURLOPT_RETURNTRANSFER, 1], + [CURLOPT_CONNECTTIMEOUT, $timeOut], + [CURLOPT_USERAGENT, $this->ua] + )); + } + + public function post($url, $data, $timeOut = 30) { // curl模拟Post 默认30s超时 + return $this->run(array( + [CURLOPT_URL, $url], + [CURLOPT_RETURNTRANSFER, 1], + [CURLOPT_CONNECTTIMEOUT, $timeOut], + [CURLOPT_USERAGENT, $this->ua], + [CURLOPT_POST, 1], + [CURLOPT_POSTFIELDS, $data] + )); + } + + private function run($configs) { // 发起curl请求 $curl = curl_init(); - curl_setopt($curl, CURLOPT_URL, $url); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeOut); - curl_setopt($curl, CURLOPT_USERAGENT, $this->ua); + foreach ($configs as $config) { + curl_setopt($curl, $config[0], $config[1]); + } $content = curl_exec($curl); curl_close($curl); return $content; diff --git a/functions/DNS.php b/functions/DNS.php index 7aa71f7..1e49bf0 100644 --- a/functions/DNS.php +++ b/functions/DNS.php @@ -40,7 +40,7 @@ class DNS { return $ipAddr; } - private function ip2long6($ipv6) { // 压缩IPv6地址为long + public function ip2long6($ipv6) { // 压缩IPv6地址为long $ip_n = inet_pton($ipv6); $bits = 15; while ($bits >= 0) { @@ -51,7 +51,7 @@ class DNS { return gmp_strval(gmp_init($ipv6long, 2), 10); } - private function long2ip6($ipv6long) { // 解压long为IPv6地址 + public function long2ip6($ipv6long) { // 解压long为IPv6地址 $bin = gmp_strval(gmp_init($ipv6long, 10), 2); if (strlen($bin) < 128) { $pad = 128 - strlen($bin); diff --git a/functions/Domain.php b/functions/Domain.php index be4398e..d688142 100644 --- a/functions/Domain.php +++ b/functions/Domain.php @@ -5,6 +5,17 @@ class Domain { // 域名相关功能 preg_match('/^(?=^.{3,255}$)[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$/', $domain, $match); return (count($match) != 0); } + + public function isHost($host) { // 判断host是否合法 + preg_match('/^(?=^.{3,255}$)[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$/', $host, $match); + if (count($match) !== 0) { // 域名 + if (!is_numeric(substr($host, -1))) { return true; } // 域名最后一位不为数字 + } + if (filter_var($host, FILTER_VALIDATE_IP)) { // IP地址 + return true; + } + return false; + } } class extractDomain { diff --git a/models/ntpCheck.php b/models/ntpCheck.php index 306f2c4..1359e81 100644 --- a/models/ntpCheck.php +++ b/models/ntpCheck.php @@ -1,28 +1,28 @@ ntpDB); - $res = $db->query('SELECT * FROM `ntp_list` WHERE id=' . $list_id . ';'); + $res = $db->query('SELECT * FROM `ntp_list` WHERE id=' . $listId . ';'); return $res->fetchArray(SQLITE3_ASSOC)['name']; } - public function getNtpList() { // 获取所有NTP服务器地址 + public function getList() { // 获取所有NTP服务器地址 $db = new SqliteDB($this->ntpDB); $res = $db->query('SELECT * FROM `ntp_host`;'); while ($row = $res->fetchArray(SQLITE3_ASSOC)) { $index = $row['list_id']; unset($row['list_id']); - $data[$this->getListName($index)][] = $row; + $list[$this->getListName($index)][] = $row; } - return $data; + return $list; } } -class ntpCheck { - private function formatOffset($str) { // 格式化Offset +class ntpCheck { // NTP服务器检查 + private function formatOffset($str) { // 格式化偏移时间 $num = number_format($str, 6) * 1000; // s -> ms $str = sprintf("%1\$.3f", $num); // 补零到小数点后3位 if ($num > 0) { @@ -31,23 +31,61 @@ class ntpCheck { return $str . 'ms'; } - private function curlPost($url, $data) { // curl模拟post操作 40s超时 - $curl = curl_init(); - curl_setopt($curl, CURLOPT_URL, $url); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 40); - curl_setopt($curl, CURLOPT_POST, 1); - curl_setopt($curl, CURLOPT_POSTFIELDS, $data); - $content = curl_exec($curl); - curl_close($curl); - return $content; + private function sortByIp($servers) { // 排序算法 + $temp = array(); + foreach ($servers as $val){ + $temp[] = $val['Server']; + } + sort($temp); + $temp = array_flip($temp); + $sort = array(); + foreach ($servers as $val) { + $temp_1 = $val['Server']; + $temp_2 = $temp[$temp_1]; + $sort[$temp_2] = $val; + } + asort($sort); + return $sort; + } + + private function sortServer($servers) { // 按顺序排列服务器 + foreach ($servers as $server) { + if(filter_var($server['Server'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + $ipv4[] = $server; // 提取IPv4服务器 + } + if(filter_var($server['Server'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { + $ipv6[] = $server; // 提取IPv6服务器 + } + } + if (isset($ipv4)) { // 存在IPv4服务器 + foreach ($ipv4 as $index => $ip) { + $ipv4[$index]['Server'] = ip2long($ip['Server']); // IPv4预处理 + } + $ipv4 = $this->sortByIp($ipv4); // 排序IPv4服务器 + foreach ($ipv4 as $index => $ip) { + $ip['Server'] = long2ip($ip['Server']); // IPv4恢复 + $result[] = $ip; + } + } + if (isset($ipv6)) { // 存在IPv6服务器 + foreach ($ipv6 as $index => $ip) { + $ipv6[$index]['Server'] = (new DNS)->ip2long6($ip['Server']); // IPv6预处理 + } + $ipv6 = $this->sortByIp($ipv6); // 排序IPv6服务器 + foreach ($ipv6 as $index => $ip) { + $ip['Server'] = (new DNS)->long2ip6($ip['Server']); // IPv6恢复 + $result[] = $ip; + } + } + return (!isset($result)) ? array() : $result; // 无结果 返回空数组 } private function getNtpStatus($host) { // 获取NTP服务器状态 - $html = $this->curlPost('https://servertest.online/ntp', array( + $html = (new Curl)->post('https://servertest.online/ntp', array( 'a' => $host, 'c' => 'Query+both' )); + if ($html == '') { return null; } // 服务错误 preg_match('/<\/form>[\s\S]+