first commit
This commit is contained in:
parent
20c5f58f64
commit
6db140f57d
252
Dns.php
Normal file
252
Dns.php
Normal file
@ -0,0 +1,252 @@
|
||||
<?php
|
||||
/**
|
||||
* Workerman DNS Protocol
|
||||
* @author Enoch EchoNoch Enoch@laysense.com
|
||||
* @Repo http://git.laysense.com/enoch/workerman-dns
|
||||
* @Github http://github.com/ywnsya/workerman-dns
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
namespace Workerman\Protocols;
|
||||
class Dns
|
||||
{
|
||||
/**
|
||||
* 检查包的完整性
|
||||
* 如果能够得到包长,则返回包的在buffer中的长度,否则返回0继续等待数据
|
||||
* 如果协议有问题,则可以返回false,当前客户端连接会因此断开
|
||||
* @param string $buffer
|
||||
* @return int
|
||||
*/
|
||||
public static function input($buffer)
|
||||
{
|
||||
|
||||
return 200;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打包,当向客户端发送数据的时候会自动调用
|
||||
* @param string $buffer
|
||||
* @return string
|
||||
*/
|
||||
public static function encode($buffer)
|
||||
{
|
||||
$buffer=json_decode($buffer);
|
||||
$type=$buffer->type;
|
||||
switch($type){
|
||||
case 'A':
|
||||
$type='0001';
|
||||
#$lenth='0004';
|
||||
$ip=$buffer->detail;
|
||||
$n=0;
|
||||
foreach($ip as $i){
|
||||
$nss=explode('.',$i);
|
||||
$detail[$n]='';
|
||||
foreach($nss as $part){
|
||||
$tpart=str_pad(dechex($part),2,"0",STR_PAD_LEFT);
|
||||
$detail[$n]=$detail[$n].$tpart;
|
||||
};
|
||||
$lenth[$n]=str_pad(dechex((strlen($detail[$n])/2)),4,"0",STR_PAD_LEFT);
|
||||
$n=$n+1;
|
||||
};
|
||||
break;
|
||||
case 'NS':
|
||||
$type='0002';
|
||||
#$lenth='0004';
|
||||
$ns=$buffer->detail;
|
||||
$n=0;
|
||||
foreach($ns as $i){
|
||||
$nss=explode('.',$i);
|
||||
$detail[$n]='';
|
||||
foreach($nss as $part){
|
||||
#$len=strlen($part);
|
||||
$len=str_pad(dechex(strlen($part)),2,"0",STR_PAD_LEFT);
|
||||
$tpart=bin2hex($part);
|
||||
$detail[$n]=$detail[$n].$len.$tpart;
|
||||
};
|
||||
$detail[$n]=$detail[$n].'00';
|
||||
$lenth[$n]=str_pad(dechex((strlen($detail[$n])/2)),4,"0",STR_PAD_LEFT);
|
||||
$n=$n+1;
|
||||
};
|
||||
break;
|
||||
case 'PTR':
|
||||
$type='000C';
|
||||
$ns=$buffer->detail;
|
||||
$nss=explode('.',$ns);
|
||||
$detail[0]='';
|
||||
foreach($nss as $part){
|
||||
$len=str_pad(dechex(strlen($part)),2,"0",STR_PAD_LEFT);
|
||||
$tpart=bin2hex($part);
|
||||
$detail[0]=$detail[0].$len.$tpart;
|
||||
};
|
||||
$detail[0]=$detail[0].'00';
|
||||
$lenth[0]=str_pad(dechex((strlen($detail[0])/2)),4,"0",STR_PAD_LEFT);
|
||||
break;
|
||||
case 'CNAME':
|
||||
$type='0005';
|
||||
$ns=$buffer->detail;
|
||||
$n=0;
|
||||
foreach($ns as $i){
|
||||
$nss=explode('.',$i);
|
||||
$detail[$n]='';
|
||||
foreach($nss as $part){
|
||||
#$len=strlen($part);
|
||||
$len=str_pad(dechex(strlen($part)),2,"0",STR_PAD_LEFT);
|
||||
$tpart=bin2hex($part);
|
||||
$detail[$n]=$detail[$n].$len.$tpart;
|
||||
};
|
||||
$detail[$n]=$detail[$n].'00';
|
||||
$lenth[$n]=str_pad(dechex((strlen($detail[$n])/2)),4,"0",STR_PAD_LEFT);
|
||||
$n=$n+1;
|
||||
};
|
||||
break;
|
||||
case 'SOA':
|
||||
$type='0006';
|
||||
$ns=$buffer->detail;
|
||||
$ns=json_decode( json_encode( $ns),true);
|
||||
if($ns['type']=='none'){
|
||||
$Rns=dns_get_record($ns['name'],DNS_SOA);
|
||||
$Rns=$Rns[0];
|
||||
$ns=$Rns;
|
||||
$buffer->ttl=$Rns['ttl'];
|
||||
}
|
||||
|
||||
$nss=explode('.',$ns['mname']);
|
||||
$detail[0]='';
|
||||
foreach($nss as $part){
|
||||
$len=str_pad(dechex(strlen($part)),2,"0",STR_PAD_LEFT);
|
||||
$tpart=bin2hex($part);
|
||||
$detail[0]=$detail[0].$len.$tpart;
|
||||
};
|
||||
$detail[0]=$detail[0].'00';
|
||||
unset($nss,$len,$tpart);
|
||||
$nss=explode('.',$ns['rname']);
|
||||
foreach($nss as $part){
|
||||
$len=str_pad(dechex(strlen($part)),2,"0",STR_PAD_LEFT);
|
||||
$tpart=bin2hex($part);
|
||||
$detail[0]=$detail[0].$len.$tpart;
|
||||
};
|
||||
$detail[0]=$detail[0].'00'.str_pad(dechex($ns['serial']),8,"0",STR_PAD_LEFT).str_pad(dechex($ns['refresh']),8,"0",STR_PAD_LEFT).str_pad(dechex($ns['retry']),8,"0",STR_PAD_LEFT).str_pad(dechex($ns['expire']),8,"0",STR_PAD_LEFT).str_pad(dechex($ns['minimum-ttl']),8,"0",STR_PAD_LEFT);
|
||||
|
||||
|
||||
$lenth[0]=str_pad(dechex((strlen($detail[0])/2)),4,"0",STR_PAD_LEFT);
|
||||
break;
|
||||
case 'AAAA':
|
||||
$type='001C';
|
||||
$ip=$buffer->detail;
|
||||
$n=0;
|
||||
foreach($ip as $i){
|
||||
$detail[$n]="$i";
|
||||
$lenth[$n]="0010";
|
||||
$n=$n+1;
|
||||
};
|
||||
break;
|
||||
case 'TEXT':
|
||||
$type='0010';
|
||||
$ns=$buffer->detail;
|
||||
$n=0;
|
||||
foreach($ns as $i){
|
||||
$detail[$n]='';
|
||||
$text=bin2hex($i);
|
||||
$tlen=str_pad(dechex((strlen($text)/2)),2,"0",STR_PAD_LEFT);
|
||||
$detail[$n]=$tlen.$text;
|
||||
$lenth[$n]=str_pad(dechex((strlen($detail[$n])/2)),4,"0",STR_PAD_LEFT);
|
||||
$n=$n+1;
|
||||
};
|
||||
break;
|
||||
case 'MX':
|
||||
$type='000F';
|
||||
$ns=$buffer->detail;
|
||||
$n=0;
|
||||
|
||||
print_r($ns);
|
||||
|
||||
foreach($ns as $i){
|
||||
$nss=explode('.',$i->name);
|
||||
$detail[$n]='';
|
||||
foreach($nss as $part){
|
||||
#$len=strlen($part);
|
||||
$len=str_pad(dechex(strlen($part)),2,"0",STR_PAD_LEFT);
|
||||
$tpart=bin2hex($part);
|
||||
$detail[$n]=$detail[$n].$len.$tpart;
|
||||
};
|
||||
$detail[$n]=$detail[$n].'00';
|
||||
$lenth[$n]=str_pad(dechex((strlen($detail[$n])/2)+2),4,"0",STR_PAD_LEFT).str_pad(dechex($i->pre),4,"0",STR_PAD_LEFT);
|
||||
$n=$n+1;
|
||||
};
|
||||
break;
|
||||
}
|
||||
$ttl=str_pad(dechex($buffer->ttl),8,"0",STR_PAD_LEFT);
|
||||
$status='8180';
|
||||
$questions='0001';
|
||||
$AnswerRRs=str_pad(count((array)$buffer->detail),4,"0",STR_PAD_LEFT);
|
||||
#$AnswerRRs='0001';
|
||||
$AuthorityRRs='0000';
|
||||
$AdditionalRRs='0000';
|
||||
$answer='';
|
||||
$n=0;
|
||||
foreach($detail as $c){
|
||||
$rlenth='';
|
||||
$rlenth=$lenth[$n];
|
||||
$n=$n+1;
|
||||
$answer=$answer.'C00C'.$type.'0001'.$ttl.$rlenth.$c;
|
||||
}
|
||||
$response=$buffer->id.$status.$questions.$AnswerRRs.$AuthorityRRs.$AdditionalRRs.$buffer->query.$answer;
|
||||
return hex2bin($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解包,当接收到的数据字节数等于input返回的值(大于0的值)自动调用
|
||||
* 并传递给onMessage回调函数的$data参数
|
||||
* @param string $buffer
|
||||
* @return string
|
||||
*/
|
||||
public static function decode($buffer)
|
||||
{
|
||||
$data=bin2hex($buffer);
|
||||
$id=substr($data,0,4);
|
||||
$type=substr($data,-8,4);
|
||||
switch($type){
|
||||
case '0001':
|
||||
$type='A';
|
||||
break;
|
||||
case '0002':
|
||||
$type='NS';
|
||||
break;
|
||||
case '000c':
|
||||
$type='PTR';
|
||||
break;
|
||||
case '0006':
|
||||
$type='SOA';
|
||||
break;
|
||||
case '001c':
|
||||
$type='AAAA';
|
||||
break;
|
||||
case '0005':
|
||||
$type='CNAME';
|
||||
break;
|
||||
case '0010':
|
||||
$type='TEXT';
|
||||
break;
|
||||
case '000f':
|
||||
$type='MX';
|
||||
break;
|
||||
}
|
||||
$name=substr($data,24,-8);
|
||||
$namede=str_split($name,2);
|
||||
$realname='';
|
||||
foreach($namede as $cha){
|
||||
$chat=hex2bin($cha);
|
||||
if(!ctype_alnum($chat)){
|
||||
$chat='.';
|
||||
}
|
||||
$realname=$realname.$chat;
|
||||
}
|
||||
$realname=substr($realname,1,-1);
|
||||
$query=substr($data,24);
|
||||
|
||||
#$returndata="$type".'|||'."$realname";
|
||||
$returndata= json_encode(array('type' => $type, 'name' => "$realname", 'id'=>"$id", 'query'=>"$query"));
|
||||
|
||||
return $returndata;
|
||||
}
|
||||
}
|
228
php-ipv6.php
Normal file
228
php-ipv6.php
Normal file
@ -0,0 +1,228 @@
|
||||
|
||||
<?php
|
||||
/* PHP-IPv6 V1.0.
|
||||
* Copyright (c) 2010 Mr.Bin <bin_jly@163.com>
|
||||
*/
|
||||
class ipv6 {
|
||||
function addr($addr=null) {
|
||||
// 常规获取IPv6地址或格式化IP地址为IPv6格式
|
||||
!$addr && ($addr = $_SERVER['REMOTE_ADDR']);
|
||||
$type = self::type($addr);
|
||||
if ( $type === 6 && self::ipv6_check($addr) ) return $addr;
|
||||
elseif ( $type === 4 ) return self::ip426($addr);
|
||||
else return 'Unknown';
|
||||
}
|
||||
|
||||
function realip() {
|
||||
/* 穿过代理获取真实IP地址
|
||||
* 返回值为数组,array[0]为真实IP,array[1]为代理IP(可能为空)
|
||||
* 若array[0]和array[1]相等,则实际真实IP可能无法获取(高度匿名?)
|
||||
*/
|
||||
$is_proxy = false;
|
||||
if ( $_SERVER['HTTP_X_FORWARDED_FOR'] ) {
|
||||
$is_proxy = true;
|
||||
$ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
|
||||
foreach($ips as $ip){
|
||||
if ( !self::wan_ip($ip) ) $ip = false;
|
||||
else break;
|
||||
}
|
||||
}
|
||||
if ( !$ip && $_SERVER['HTTP_CLIENT_IP'] ) {
|
||||
$is_proxy = true;
|
||||
$ip = $_SERVER['HTTP_CLIENT_IP'];
|
||||
if ( !self::wan_ip($ip) ) $ip = false;
|
||||
}
|
||||
if ( $is_proxy ) {
|
||||
$proxy = $_SERVER['REMOTE_ADDR'];
|
||||
if (!$ip) $ip = $proxy;
|
||||
} else {
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
}
|
||||
return explode(',', $ip.','.$proxy);
|
||||
}
|
||||
|
||||
function cut($addr) {
|
||||
// 压缩IPv6地址
|
||||
if (!self::ipv6_check($addr)) return $addr;
|
||||
$addr = self::fill($addr);
|
||||
$arr = explode(':',$addr);
|
||||
foreach ($arr as $a) {
|
||||
$arr2[] = preg_replace('/^0{1,3}(\w+)/','\1',$a);
|
||||
}
|
||||
$addr = join(':',$arr2);
|
||||
$olen = strlen($addr);
|
||||
for($i=6;$i>0;$i--){
|
||||
// 初步压缩
|
||||
$addr = preg_replace('/:(0\:){'.$i.'}/','::',$addr,1);
|
||||
if (strlen($addr) < $olen ) break;
|
||||
}
|
||||
$addr = preg_replace('/^0\:\:/','::',$addr);
|
||||
$addr = preg_replace('/\:\:0$/','::',$addr);
|
||||
return $addr;
|
||||
}
|
||||
|
||||
function fill($addr) {
|
||||
// 标准IPv6格式
|
||||
if (!self::ipv6_check($addr)) return $addr;
|
||||
$addr = self::_fix_v4($addr);
|
||||
$arr = explode(':',$addr);
|
||||
foreach ($arr as $a) {
|
||||
$l = strlen($a);
|
||||
if ( $l > 0 && $l < 4 )
|
||||
$arr2[] = str_repeat('0', 4-$l).$a;
|
||||
else $arr2[] = $a;
|
||||
}
|
||||
$addr = join(':',$arr2);
|
||||
$fil = ':'.str_repeat('0000:', 9-count($arr));
|
||||
$addr = str_replace('::',$fil,$addr);
|
||||
$addr = preg_replace('/^\:/','0000:',$addr);
|
||||
$addr = preg_replace('/\:$/',':0000',$addr);
|
||||
return $addr;
|
||||
}
|
||||
|
||||
function ip2bin($addr) {
|
||||
$type = self::type($addr);
|
||||
if ( $type === 0 ) return false;
|
||||
elseif ( $type === 4 ) $addr = self::ip426($addr);
|
||||
else $addr = self::fill($addr);
|
||||
$hexstr = str_replace(':','',$addr);
|
||||
return pack('H*', $hexstr);
|
||||
}
|
||||
|
||||
function bin2ip($bin) {
|
||||
if ( strlen($bin) !== 16 ) return false;
|
||||
$arr = str_split(join('',unpack('H*', $bin)), 4);
|
||||
$addr = join(':',$arr);
|
||||
return $addr;
|
||||
}
|
||||
|
||||
function ip426($addr) {
|
||||
// IPv4 to IPv6
|
||||
if (!self::ipv4_check($addr)) return $addr;
|
||||
$hex = dechex(self::ip2long($addr));
|
||||
$hex = str_repeat('0', 8-strlen($hex)).$hex;
|
||||
$ipv6 = '0000:0000:0000:0000:0000:0000:';
|
||||
$ipv6 .= substr($hex,0,4) . ':' . substr($hex,4,4);
|
||||
return $ipv6;
|
||||
}
|
||||
|
||||
function type($addr) {
|
||||
if ( self::ipv6_check($addr) ) return 6;
|
||||
elseif ( self::ipv4_check($addr) ) return 4;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
function ipv4_check($addr) {
|
||||
$arr = explode('.', $addr);
|
||||
$l = count($arr);
|
||||
for ( $i=0;$i<$l;$i++ ) {
|
||||
if ( strlen($arr[$i]) > 3 ) return false;
|
||||
if ( !is_numeric($arr[$i]) ) return false;
|
||||
$a = intval($arr[$i], 10);
|
||||
if ($a > 255 || $a <0) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function ipv6_check($addr) {
|
||||
$addr = self::_fix_v4($addr);
|
||||
if ( strpos($addr, '.') ) return false;
|
||||
$l1 = count(explode('::',$addr));
|
||||
if ( $l1 > 2 ) return false;
|
||||
$l2 = count(explode(':',$addr));
|
||||
if ( $l2 < 3 || $l2 > 8 ) return false;
|
||||
if ( $l2 < 8 && $l1 !== 2 ) return false;
|
||||
preg_match('/^([0-9a-f]{0,4}\:)+[0-9a-f]{0,4}$/i',$addr,$arr);
|
||||
if ( !$arr[0] ) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function ip2long($addr) {
|
||||
$arr = explode('.', $addr);
|
||||
$l = count($arr);
|
||||
$long = 0;
|
||||
for ( $i=0;$i<$l;$i++ ) {
|
||||
if ( strlen($arr[$i]) > 3 ) return false;
|
||||
if ( !is_numeric($arr[$i]) ) return false;
|
||||
$a = intval($arr[$i], 10);
|
||||
if ($a > 255 || $a <0) return false;
|
||||
$long += $a * pow(2, 24-$i*8);
|
||||
}
|
||||
return $long;
|
||||
}
|
||||
|
||||
function wan_ip($addr) {
|
||||
// 检查外网可用地址
|
||||
if ( self::ipv6_check($addr) ) {
|
||||
$addr = self::fill($addr);
|
||||
// IPv4类地址处理
|
||||
$v4p = substr($addr,0,29);
|
||||
if ( $v4p == '0000:0000:0000:0000:0000:0000'
|
||||
|| strtolower($v4p) == 'ffff:0000:0000:0000:0000:0000' ) {
|
||||
$t = str_replace($v4p,'',$addr);
|
||||
$t = str_replace(':','',$t);
|
||||
$ipv4 = long2ip(hexdec($t));
|
||||
return self::_wan_ipv4($ipv4);
|
||||
}
|
||||
// 取前16位进行比较
|
||||
$v6p = substr($addr,0,4);
|
||||
$bin = decbin(hexdec($v6p));
|
||||
$p = str_repeat(0, 16-strlen($bin)).$bin;
|
||||
if ( (($p&'1110000000000000')=='0010000000000000') //2000::/3
|
||||
|| (($p&'1111111000000000')=='1111110000000000') //FC00::/7
|
||||
|| (($p&'1111111111000000')=='1111111010000000') //FE80::/10
|
||||
|| (($p&'1111111100000000')=='1111111100000000') //FF00::/8
|
||||
) return false;
|
||||
return true;
|
||||
} else {
|
||||
return self::_wan_ipv4($addr);
|
||||
}
|
||||
}
|
||||
|
||||
private function _wan_ipv4($addr){
|
||||
if ( !self::ipv4_check($addr) ) return false;
|
||||
$arr = explode('.',$addr);
|
||||
$bin = decbin($arr[0]*256+$arr[1]);
|
||||
$p = str_repeat(0, 16-strlen($bin)).$bin;
|
||||
$p8 = $p & '1111111100000000';
|
||||
$p16 = &$p;
|
||||
if ( ($p8 == '0000000000000000') // 0/8
|
||||
|| ($p8 == '0000010100000000') // 5/8
|
||||
|| ($p8 == '0000101000000000') // 10/8
|
||||
|| ($p8 == '0001011100000000') // 23/8
|
||||
|| ($p8 == '0010010000000000') // 36/8
|
||||
|| ($p8 == '0010010100000000') // 37/8
|
||||
|| ($p8 == '0010011100000000') // 39/8
|
||||
|| ($p8 == '0010101000000000') // 42/8
|
||||
|| ($p8 == '0110010000000000') // 100/8
|
||||
|| ($p8 == '0110011000000000') // 102/8
|
||||
|| ($p8 == '0110011100000000') // 103/8
|
||||
|| ($p8 == '0110100000000000') // 104/8
|
||||
|| ($p8 == '0110100100000000') // 105/8
|
||||
|| ($p8 == '0110101000000000') // 106/8
|
||||
|| ($p8 == '0111111100000000') // 127/8
|
||||
|| ($p16 == '1010100111111110') // 169.254/16
|
||||
|| (($p&'1111111111110000')=='1010110000010000') // 172.16/12
|
||||
|| ($p8 == '1011001100000000') // 179/8
|
||||
|| ($p8 == '1011100100000000') // 185/8
|
||||
|| ($p16 == '1100000010101000') // 192.168/16
|
||||
|| (($p&'1110000000000000')=='1110000000000000') // 224/8-255/8
|
||||
) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private function _fix_v4($addr) {
|
||||
// 修正IPv4位址类IPv6格式为标准IPv6格式,不验证合法性
|
||||
if ( !strpos($addr, '.') ) return $addr;
|
||||
preg_match('/(\d+\.){3}\d+$/',$addr,$arr);
|
||||
if ( !self::ipv4_check($arr[0]) ) return $addr;
|
||||
$hex = dechex(self::ip2long($arr[0]));
|
||||
$hex = str_repeat('0', 8-strlen($hex)).$hex;
|
||||
$v4p = substr($hex,0,4) . ':' . substr($hex,4,4);
|
||||
$p1 = str_replace($arr[0],'',$addr);
|
||||
strtolower($p1) === 'ffff:' && $p1 = '::'.$p1;
|
||||
$addr = $p1 . $v4p;
|
||||
return $addr;
|
||||
}
|
||||
}
|
||||
?>
|
106
readme.md
Normal file
106
readme.md
Normal file
@ -0,0 +1,106 @@
|
||||
# Workerman-DNS
|
||||
|
||||
Workerman的DNS协议,实现了简单的DNS协议解析和相应
|
||||
|
||||
目前支持以下DNS类型:
|
||||
|
||||
* A
|
||||
* AAAA
|
||||
* CNAME
|
||||
* SOA
|
||||
* PTR
|
||||
* MX
|
||||
* TXT
|
||||
|
||||
> 本仓库内vendor文件夹为[Workerman](https://www.workerman.net/)
|
||||
>
|
||||
> 您可以删除,直接将本仓库根目录下的 Dns.php 放置到您的Workerman项目中的 /vendor/workerman/workerman/Protocols 目录下
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 使用方式:
|
||||
|
||||
详见start.php 文件
|
||||
|
||||
> 注意:使用53端口需要root权限
|
||||
|
||||
#### 1.监听端口
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Workerman\Worker;
|
||||
use Workerman\Connection\TcpConnection;
|
||||
use Workerman\Protocols\Http\Request;
|
||||
require_once __DIR__ . '/php-ipv6.php'; #IPv6支持
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
$worker = new Worker('Dns://0.0.0.0:53');
|
||||
$worker->transport = 'udp';
|
||||
|
||||
|
||||
```
|
||||
|
||||
#### 2.获取查询内容
|
||||
|
||||
```php
|
||||
$worker->onMessage = function($connection, $data){
|
||||
$data=json_decode($data);
|
||||
$type=$data->type; #查询类型
|
||||
$name=$data->name; #查询内容(一般是域名,PTR时为倒序IP)
|
||||
$rip=$connection->getRemoteIp(); #客户端IP
|
||||
|
||||
#输出信息
|
||||
echo "\n Type:$type \n Domain: $name\n Client IP: $rip \n";
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.响应A记录
|
||||
|
||||
```php
|
||||
$worker->onMessage = function($connection, $data){
|
||||
|
||||
$send['type']='A';
|
||||
$send['detail'][1]='119.29.29.29'; #第一条记录
|
||||
$send['detail'][2]='8.8.8.8'; #第二条记录
|
||||
$send['ttl']=30;
|
||||
|
||||
|
||||
|
||||
#id和query一般情况下直接返回输出即可
|
||||
$send['id']=$data->id;
|
||||
$send['query']=$data->query;
|
||||
|
||||
|
||||
|
||||
$send=json_encode($send);
|
||||
$connection->send($send);
|
||||
|
||||
|
||||
};
|
||||
Worker::runAll();
|
||||
```
|
||||
|
||||
#### 4.响应其他记录
|
||||
|
||||
见start.php 内有所有记录类型的响应方式
|
||||
|
||||
#### 5.说明
|
||||
|
||||
您应当通过获取query的 `$name`通过查询数据库等方式返回数据,对于不存在的记录应当返回SOA记录
|
||||
|
||||
您需要的时候可以通过 `dns_get_record()`向上级DNS递归查找并缓存
|
||||
|
||||
这一系列操作,本协议不提供,您可以自行通过Redis等并利用workerman实现
|
||||
|
||||
不建议作为根域名的NS服务器使用
|
||||
|
||||
## 已知问题
|
||||
|
||||
本协议最早写于鄙人刚学习php的阶段,现在翻出来无疑是屎山一坨,代码写的和xxs一样,性能不敢测试,还请各位大佬包容
|
||||
|
||||
目前已知问题是:
|
||||
|
||||
域名不存在时可能出现BUG
|
166
start.php
166
start.php
@ -1,53 +1,135 @@
|
||||
<?php
|
||||
/**
|
||||
* Workerman DNS Protocol
|
||||
* @author Enoch EchoNoch Enoch@laysense.com
|
||||
* @Repo http://git.laysense.com/enoch/workerman-dns
|
||||
* @Github http://github.com/ywnsya/workerman-dns
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
use Workerman\Worker;
|
||||
use Workerman\Connection\TcpConnection;
|
||||
use Workerman\Protocols\Http\Request;
|
||||
require_once __DIR__ . '/php-ipv6.php'; #IPv6支持
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
$udp_worker = new Worker('udp://172.26.141.97:53');
|
||||
$udp_worker->onMessage = function($connection, $data){
|
||||
$data=bin2hex($data);
|
||||
echo($data);
|
||||
echo "\n";
|
||||
$type=substr($data,-8,4);
|
||||
switch($type){
|
||||
case '0001':
|
||||
$type='A';
|
||||
break;
|
||||
case '0002':
|
||||
$type='NS';
|
||||
break;
|
||||
case '000c':
|
||||
$type='PTR';
|
||||
break;
|
||||
case '001c':
|
||||
$type='AAAA';
|
||||
break;
|
||||
case '0005':
|
||||
$type='CNAME';
|
||||
break;
|
||||
case '0010':
|
||||
$type='TEXT';
|
||||
break;
|
||||
}
|
||||
echo($type);
|
||||
echo "\n";
|
||||
$name=$type=substr($data,24,-8);
|
||||
$namede=str_split($name,2);
|
||||
$realname='';
|
||||
foreach($namede as $cha){
|
||||
$chat=hex2bin($cha);
|
||||
if(!ctype_alnum($chat)){
|
||||
$chat='.';
|
||||
}
|
||||
$realname=$realname.$chat;
|
||||
}
|
||||
$realname=substr($realname,1,-1);
|
||||
$worker = new Worker('Dns://0.0.0.0:53');
|
||||
$worker->transport = 'udp';
|
||||
$worker->onMessage = function($connection, $data){
|
||||
$data=json_decode($data);
|
||||
$type=$data->type; #查询类型
|
||||
$name=$data->name; #查询内容(一般是域名,PTR时为倒序IP)
|
||||
$rip=$connection->getRemoteIp(); #客户端IP
|
||||
|
||||
echo "$realname";
|
||||
#输出信息
|
||||
echo "\n Type:$type \n Domain: $name\n Client IP: $rip \n";
|
||||
|
||||
|
||||
if($type=='A'){
|
||||
$send['type']='A';
|
||||
$send['detail'][1]='119.29.29.29';
|
||||
$send['detail'][2]='8.8.8.8';
|
||||
$send['ttl']=30;
|
||||
};
|
||||
|
||||
|
||||
if($type=='PTR'){
|
||||
/**
|
||||
* 请注意:Nslookup和一部分dns程序会在任何请求发出前先对DNS服务器的IP发送PTR请求
|
||||
* 如果不设置PTR请求,收到PTR请求后会报错
|
||||
* 此外,请注意PTR请求所请求的域名(其实是IP)格式为倒序IP.in.addr.arpa
|
||||
* 例如,PTR: 192.168.0.1 则 $name 收到的是: 1.0.168.192.in.addr.arpa
|
||||
*/
|
||||
$send['type']='PTR';
|
||||
$send['detail']='dns.laysense.com';
|
||||
$send['ttl']=30;
|
||||
};
|
||||
|
||||
if($type=='NS'){
|
||||
$send['type']='NS';
|
||||
$send['detail'][1]='coco.bunny.net';
|
||||
$send['detail'][2]='kiki.bunny.net';
|
||||
$send['ttl']=600;
|
||||
};
|
||||
|
||||
if($type=='CNAME'){
|
||||
$send['type']='CNAME';
|
||||
$send['detail'][1]='baidu.cn';
|
||||
$send['detail'][2]='baidu.com';
|
||||
$send['ttl']=600;
|
||||
}
|
||||
|
||||
if($type=='CNAME'){
|
||||
$send['type']='CNAME';
|
||||
$send['detail'][1]='baidu.cn';
|
||||
$send['detail'][2]='baidu.com';
|
||||
$send['ttl']=600;
|
||||
}
|
||||
|
||||
if($type=='AAAA'){
|
||||
$ipv6=new IPv6;
|
||||
$send['type']='AAAA';
|
||||
$send['detail'][1]=bin2hex($ipv6->ip2bin("fe80::2c5f")); #此操作可以还原被简化的IPv6地址 协议内不再对IPv6地址进行处理,请按照本方式传递16进制无":"的完整16位IPv6
|
||||
$send['detail'][2]=bin2hex($ipv6->ip2bin("2001:0:2851:b9d0:2c5f:f0d9:21be:4b96"));
|
||||
$send['ttl']=600;
|
||||
}
|
||||
|
||||
if($type=='TEXT'){
|
||||
$send['type']='TEXT';
|
||||
$send['detail'][1]='text1-test';
|
||||
$send['detail'][2]='text2-test';
|
||||
$send['ttl']=600;
|
||||
}
|
||||
|
||||
if($type=='MX'){
|
||||
$send['type']='MX';
|
||||
$send['detail'][1]['name']='mx.zoho.com';
|
||||
$send['detail'][1]['pre']='20'; #权重
|
||||
$send['detail'][2]['name']='mx2.zoho.com';
|
||||
$send['detail'][2]['pre']='30'; #权重
|
||||
$send['detail'][3]['name']='mx3.zoho.com';
|
||||
$send['detail'][3]['pre']='50'; #权重
|
||||
$send['ttl']=600;
|
||||
}
|
||||
|
||||
#无记录情况下返回SOA记录或域名不存在记录,防止报错
|
||||
if( (!isset($send['type'])) || (!isset($send['detail'])) || (!isset($send['ttl'])) || $type=='SOA'){
|
||||
|
||||
$send['type']='SOA';
|
||||
$send['detail']= array();
|
||||
|
||||
$send['detail']['type']='none';
|
||||
$send['detail']['name']=$name;
|
||||
|
||||
/**
|
||||
* SOA类型,如遇域名存在但无该查询类型的记录时返回
|
||||
* 请勿随意填写,本workermanDNS协议将自动向服务器配置的DNS获取SOA
|
||||
*
|
||||
* 自行返回SOA记录(不建议)[除非你真的准备直接把域名NS到这里]
|
||||
* $send['detail']['type']='self';
|
||||
* $send['detail']['mname']='dns31.hichina.com'; #主DNS服务器名
|
||||
* $send['detail']['rname']='hostmaster.hichina.com'; #DNS管理员邮箱
|
||||
* $send['detail']['serial']='2022052002'; #序列号 序列号必须递增 类似于dns记录的版本号 序列号变大时递归dns将更新记录
|
||||
* $send['detail']['refresh']='3600'; #区域应当被刷新前的时间间隔
|
||||
* $send['detail']['retry']='1200'; #刷新失败重试的时间间隔
|
||||
* $send['detail']['expire']='86400'; #规定在区域不再是权威的之前可以等待的时间间隔的上限
|
||||
* $send['detail']['minimum-ttl']='600'; #最小TTL
|
||||
*
|
||||
* $send['ttl']='180'; #当前TTL
|
||||
**/
|
||||
|
||||
|
||||
};
|
||||
|
||||
#id和query一般情况下直接返回输出即可
|
||||
$send['id']=$data->id;
|
||||
$send['query']=$data->query;
|
||||
|
||||
|
||||
|
||||
$send=json_encode($send);
|
||||
$connection->send($send);
|
||||
|
||||
echo "\n";
|
||||
|
||||
$connection->send('get');
|
||||
};
|
||||
Worker::runAll();
|
93
start2.php
93
start2.php
@ -1,93 +0,0 @@
|
||||
<?php
|
||||
use Workerman\Worker;
|
||||
use Workerman\Connection\TcpConnection;
|
||||
use Workerman\Protocols\Http\Request;
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
$worker = new Worker('Dns://172.26.141.97:53');
|
||||
$worker->transport = 'udp';
|
||||
$worker->onMessage = function($connection, $data){
|
||||
$data=json_decode($data);
|
||||
$type=$data->type; #查询类型
|
||||
$name=$data->name; #查询内容(一般是域名,PTR时为倒序IP)
|
||||
$rip=$connection->getRemoteIp(); #客户端IP
|
||||
|
||||
#输出信息
|
||||
echo "\n Type:$type \n Domain: $name\n Client IP: $rip \n";
|
||||
|
||||
|
||||
if($type=='A'){
|
||||
$send['type']='A';
|
||||
$send['detail'][1]='119.29.29.29';
|
||||
$send['detail'][2]='8.8.8.8';
|
||||
$send['ttl']=30;
|
||||
};
|
||||
|
||||
|
||||
if($type=='PTR'){
|
||||
/**
|
||||
* 请注意:Nslookup和一部分dns程序会在任何请求发出前先对DNS服务器的IP发送PTR请求
|
||||
* 如果不设置PTR请求,收到PTR请求后会报错
|
||||
* 此外,请注意PTR请求所请求的域名(其实是IP)格式为倒序IP.in.addr.arpa
|
||||
* 例如,PTR: 192.168.0.1 则 $name 收到的是: 1.0.168.192.in.addr.arpa
|
||||
*/
|
||||
$send['type']='PTR';
|
||||
$send['detail']='dns.laysense.com';
|
||||
$send['ttl']=30;
|
||||
};
|
||||
|
||||
if($type=='NS'){
|
||||
$send['type']='NS';
|
||||
$send['detail'][1]='coco.bunny.net';
|
||||
$send['detail'][2]='kiki.bunny.net';
|
||||
$send['ttl']=600;
|
||||
};
|
||||
|
||||
if($type=='CNAME'){
|
||||
$send['type']='CNAME';
|
||||
$send['detail'][1]='baidu.cn';
|
||||
$send['detail'][2]='baidu.com';
|
||||
$send['ttl']=600;
|
||||
}
|
||||
|
||||
if($type=='CNAME'){
|
||||
$send['type']='CNAME';
|
||||
$send['detail'][1]='baidu.cn';
|
||||
$send['detail'][2]='baidu.com';
|
||||
$send['ttl']=600;
|
||||
}
|
||||
|
||||
#无记录情况下返回SOA记录或域名不存在记录,防止报错
|
||||
if(unset($set['type'])||unset($set['detail'])||unset($set['ttl'])||$type=='SOA'){
|
||||
$send['type']='SOA';
|
||||
$send['detail']['type']='null';
|
||||
$send['detail']['name']=$name;
|
||||
/**
|
||||
* SOA类型,如遇域名存在但无该查询类型的记录时返回
|
||||
* 请勿随意填写,本workermanDNS协议将自动向服务器配置的DNS获取SOA
|
||||
*
|
||||
* 自行返回SOA记录(不建议)[除非你真的准备直接把域名NS到这里]
|
||||
* $send['detail']['type']='self';
|
||||
* $send['detail']['mname']='dns31.hichina.com'; #主DNS服务器名
|
||||
* $send['detail']['rname']='hostmaster.hichina.com' #DNS管理员邮箱
|
||||
* $send['detail']['serial']='2022052002' #序列号 序列号必须递增 类似于dns记录的版本号 序列号变大时递归dns将更新记录
|
||||
* $send['detail']['refresh']='3600' #区域应当被刷新前的时间间隔
|
||||
* $send['detail']['retry']='1200' #刷新失败重试的时间间隔
|
||||
* $send['detail']['expire']='86400' #规定在区域不再是权威的之前可以等待的时间间隔的上限
|
||||
* $send['detail']['minimum-ttl']='600' #最小TTL
|
||||
*
|
||||
**/
|
||||
|
||||
};
|
||||
|
||||
#id和query一般情况下直接返回输出即可
|
||||
$send['id']=$data->id;
|
||||
$send['query']=$data->query;
|
||||
|
||||
|
||||
|
||||
$send=json_encode($send);
|
||||
$connection->send($send);
|
||||
|
||||
|
||||
};
|
||||
Worker::runAll();
|
187
vendor/workerman/workerman.log
vendored
187
vendor/workerman/workerman.log
vendored
@ -407,3 +407,190 @@ Stack trace:
|
||||
2022-12-15 12:43:46 pid:4091 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-15 13:13:22 pid:4091 Workerman[start2.php] stopping ...
|
||||
2022-12-15 13:13:22 pid:4091 Workerman[start2.php] has been stopped
|
||||
2022-12-16 11:01:11 pid:566 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 11:01:22 pid:567 TypeError: Cannot access offset of type string on string in /home/enoch/phpdns/start2.php:62
|
||||
Stack trace:
|
||||
#0 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2569): {closure}()
|
||||
#1 [internal function]: Workerman\Worker->acceptUdpConnection()
|
||||
#2 /home/enoch/phpdns/vendor/workerman/workerman/Events/Event.php(193): EventBase->loop()
|
||||
#3 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2463): Workerman\Events\Event->loop()
|
||||
#4 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1574): Workerman\Worker->run()
|
||||
#5 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1416): Workerman\Worker::forkOneWorkerForLinux()
|
||||
#6 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1390): Workerman\Worker::forkWorkersForLinux()
|
||||
#7 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(557): Workerman\Worker::forkWorkers()
|
||||
#8 /home/enoch/phpdns/start2.php(95): Workerman\Worker::runAll()
|
||||
#9 {main}
|
||||
2022-12-16 11:01:22 pid:566 worker[none:567] exit with status 64000
|
||||
2022-12-16 11:02:54 pid:566 Workerman[start2.php] stopping ...
|
||||
2022-12-16 11:02:54 pid:566 Workerman[start2.php] has been stopped
|
||||
2022-12-16 11:02:55 pid:666 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 11:02:58 pid:667 TypeError: Cannot access offset of type string on string in /home/enoch/phpdns/start2.php:62
|
||||
Stack trace:
|
||||
#0 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2569): {closure}()
|
||||
#1 [internal function]: Workerman\Worker->acceptUdpConnection()
|
||||
#2 /home/enoch/phpdns/vendor/workerman/workerman/Events/Event.php(193): EventBase->loop()
|
||||
#3 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2463): Workerman\Events\Event->loop()
|
||||
#4 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1574): Workerman\Worker->run()
|
||||
#5 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1416): Workerman\Worker::forkOneWorkerForLinux()
|
||||
#6 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1390): Workerman\Worker::forkWorkersForLinux()
|
||||
#7 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(557): Workerman\Worker::forkWorkers()
|
||||
#8 /home/enoch/phpdns/start2.php(95): Workerman\Worker::runAll()
|
||||
#9 {main}
|
||||
2022-12-16 11:02:58 pid:666 worker[none:667] exit with status 64000
|
||||
2022-12-16 11:04:08 pid:666 Workerman[start2.php] stopping ...
|
||||
2022-12-16 11:04:08 pid:666 Workerman[start2.php] has been stopped
|
||||
2022-12-16 11:04:09 pid:719 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 11:04:11 pid:720 TypeError: Cannot access offset of type string on string in /home/enoch/phpdns/start2.php:63
|
||||
Stack trace:
|
||||
#0 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2569): {closure}()
|
||||
#1 [internal function]: Workerman\Worker->acceptUdpConnection()
|
||||
#2 /home/enoch/phpdns/vendor/workerman/workerman/Events/Event.php(193): EventBase->loop()
|
||||
#3 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2463): Workerman\Events\Event->loop()
|
||||
#4 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1574): Workerman\Worker->run()
|
||||
#5 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1416): Workerman\Worker::forkOneWorkerForLinux()
|
||||
#6 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1390): Workerman\Worker::forkWorkersForLinux()
|
||||
#7 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(557): Workerman\Worker::forkWorkers()
|
||||
#8 /home/enoch/phpdns/start2.php(95): Workerman\Worker::runAll()
|
||||
#9 {main}
|
||||
2022-12-16 11:04:11 pid:719 worker[none:720] exit with status 64000
|
||||
2022-12-16 11:04:44 pid:719 Workerman[start2.php] stopping ...
|
||||
2022-12-16 11:04:44 pid:719 Workerman[start2.php] has been stopped
|
||||
2022-12-16 11:04:46 pid:783 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 11:04:47 pid:784 Error: Cannot use object of type stdClass as array in /home/enoch/phpdns/vendor/workerman/workerman/Protocols/Dns.php:97
|
||||
Stack trace:
|
||||
#0 /home/enoch/phpdns/vendor/workerman/workerman/Connection/UdpConnection.php(73): Workerman\Protocols\Dns::encode()
|
||||
#1 /home/enoch/phpdns/start2.php(92): Workerman\Connection\UdpConnection->send()
|
||||
#2 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2569): {closure}()
|
||||
#3 [internal function]: Workerman\Worker->acceptUdpConnection()
|
||||
#4 /home/enoch/phpdns/vendor/workerman/workerman/Events/Event.php(193): EventBase->loop()
|
||||
#5 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2463): Workerman\Events\Event->loop()
|
||||
#6 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1574): Workerman\Worker->run()
|
||||
#7 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1416): Workerman\Worker::forkOneWorkerForLinux()
|
||||
#8 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1390): Workerman\Worker::forkWorkersForLinux()
|
||||
#9 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(557): Workerman\Worker::forkWorkers()
|
||||
#10 /home/enoch/phpdns/start2.php(96): Workerman\Worker::runAll()
|
||||
#11 {main}
|
||||
2022-12-16 11:04:47 pid:783 worker[none:784] exit with status 64000
|
||||
2022-12-16 11:05:35 pid:783 Workerman[start2.php] stopping ...
|
||||
2022-12-16 11:05:35 pid:783 Workerman[start2.php] has been stopped
|
||||
2022-12-16 11:05:36 pid:842 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 11:05:38 pid:843 Error: Cannot use object of type stdClass as array in /home/enoch/phpdns/vendor/workerman/workerman/Protocols/Dns.php:98
|
||||
Stack trace:
|
||||
#0 /home/enoch/phpdns/vendor/workerman/workerman/Connection/UdpConnection.php(73): Workerman\Protocols\Dns::encode()
|
||||
#1 /home/enoch/phpdns/start2.php(92): Workerman\Connection\UdpConnection->send()
|
||||
#2 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2569): {closure}()
|
||||
#3 [internal function]: Workerman\Worker->acceptUdpConnection()
|
||||
#4 /home/enoch/phpdns/vendor/workerman/workerman/Events/Event.php(193): EventBase->loop()
|
||||
#5 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2463): Workerman\Events\Event->loop()
|
||||
#6 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1574): Workerman\Worker->run()
|
||||
#7 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1416): Workerman\Worker::forkOneWorkerForLinux()
|
||||
#8 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1390): Workerman\Worker::forkWorkersForLinux()
|
||||
#9 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(557): Workerman\Worker::forkWorkers()
|
||||
#10 /home/enoch/phpdns/start2.php(96): Workerman\Worker::runAll()
|
||||
#11 {main}
|
||||
2022-12-16 11:05:38 pid:842 worker[none:843] exit with status 64000
|
||||
2022-12-16 11:06:00 pid:842 Workerman[start2.php] stopping ...
|
||||
2022-12-16 11:06:00 pid:842 Workerman[start2.php] has been stopped
|
||||
2022-12-16 11:06:02 pid:903 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 11:06:02 pid:903 Workerman[start2.php] stopping ...
|
||||
2022-12-16 11:06:02 pid:903 Workerman[start2.php] has been stopped
|
||||
2022-12-16 11:07:17 pid:950 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 11:07:19 pid:951 Error: Cannot use object of type stdClass as array in /home/enoch/phpdns/vendor/workerman/workerman/Protocols/Dns.php:98
|
||||
Stack trace:
|
||||
#0 /home/enoch/phpdns/vendor/workerman/workerman/Connection/UdpConnection.php(73): Workerman\Protocols\Dns::encode()
|
||||
#1 /home/enoch/phpdns/start2.php(92): Workerman\Connection\UdpConnection->send()
|
||||
#2 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2569): {closure}()
|
||||
#3 [internal function]: Workerman\Worker->acceptUdpConnection()
|
||||
#4 /home/enoch/phpdns/vendor/workerman/workerman/Events/Event.php(193): EventBase->loop()
|
||||
#5 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2463): Workerman\Events\Event->loop()
|
||||
#6 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1574): Workerman\Worker->run()
|
||||
#7 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1416): Workerman\Worker::forkOneWorkerForLinux()
|
||||
#8 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1390): Workerman\Worker::forkWorkersForLinux()
|
||||
#9 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(557): Workerman\Worker::forkWorkers()
|
||||
#10 /home/enoch/phpdns/start2.php(96): Workerman\Worker::runAll()
|
||||
#11 {main}
|
||||
2022-12-16 11:07:19 pid:950 worker[none:951] exit with status 64000
|
||||
2022-12-16 11:08:12 pid:950 Workerman[start2.php] stopping ...
|
||||
2022-12-16 11:08:12 pid:950 Workerman[start2.php] has been stopped
|
||||
2022-12-16 11:08:13 pid:1002 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 11:08:14 pid:1003 Error: Cannot use object of type stdClass as array in /home/enoch/phpdns/vendor/workerman/workerman/Protocols/Dns.php:99
|
||||
Stack trace:
|
||||
#0 /home/enoch/phpdns/vendor/workerman/workerman/Connection/UdpConnection.php(73): Workerman\Protocols\Dns::encode()
|
||||
#1 /home/enoch/phpdns/start2.php(92): Workerman\Connection\UdpConnection->send()
|
||||
#2 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2569): {closure}()
|
||||
#3 [internal function]: Workerman\Worker->acceptUdpConnection()
|
||||
#4 /home/enoch/phpdns/vendor/workerman/workerman/Events/Event.php(193): EventBase->loop()
|
||||
#5 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2463): Workerman\Events\Event->loop()
|
||||
#6 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1574): Workerman\Worker->run()
|
||||
#7 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1416): Workerman\Worker::forkOneWorkerForLinux()
|
||||
#8 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1390): Workerman\Worker::forkWorkersForLinux()
|
||||
#9 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(557): Workerman\Worker::forkWorkers()
|
||||
#10 /home/enoch/phpdns/start2.php(96): Workerman\Worker::runAll()
|
||||
#11 {main}
|
||||
2022-12-16 11:08:14 pid:1002 worker[none:1003] exit with status 64000
|
||||
2022-12-16 11:08:37 pid:1002 Workerman[start2.php] stopping ...
|
||||
2022-12-16 11:08:37 pid:1002 Workerman[start2.php] has been stopped
|
||||
2022-12-16 11:08:38 pid:1058 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 11:08:48 pid:1058 Workerman[start2.php] stopping ...
|
||||
2022-12-16 11:08:48 pid:1058 Workerman[start2.php] has been stopped
|
||||
2022-12-16 11:10:18 pid:1179 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 11:10:20 pid:1180 Error: Cannot use object of type stdClass as array in /home/enoch/phpdns/vendor/workerman/workerman/Protocols/Dns.php:106
|
||||
Stack trace:
|
||||
#0 /home/enoch/phpdns/vendor/workerman/workerman/Connection/UdpConnection.php(73): Workerman\Protocols\Dns::encode()
|
||||
#1 /home/enoch/phpdns/start2.php(104): Workerman\Connection\UdpConnection->send()
|
||||
#2 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2569): {closure}()
|
||||
#3 [internal function]: Workerman\Worker->acceptUdpConnection()
|
||||
#4 /home/enoch/phpdns/vendor/workerman/workerman/Events/Event.php(193): EventBase->loop()
|
||||
#5 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2463): Workerman\Events\Event->loop()
|
||||
#6 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1574): Workerman\Worker->run()
|
||||
#7 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1416): Workerman\Worker::forkOneWorkerForLinux()
|
||||
#8 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1390): Workerman\Worker::forkWorkersForLinux()
|
||||
#9 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(557): Workerman\Worker::forkWorkers()
|
||||
#10 /home/enoch/phpdns/start2.php(108): Workerman\Worker::runAll()
|
||||
#11 {main}
|
||||
2022-12-16 11:10:20 pid:1179 worker[none:1180] exit with status 64000
|
||||
2022-12-16 11:12:08 pid:1179 Workerman[start2.php] stopping ...
|
||||
2022-12-16 11:12:08 pid:1179 Workerman[start2.php] has been stopped
|
||||
2022-12-16 11:12:09 pid:1236 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 11:12:13 pid:1236 Workerman[start2.php] stopping ...
|
||||
2022-12-16 11:12:14 pid:1236 Workerman[start2.php] has been stopped
|
||||
2022-12-16 11:12:28 pid:1301 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 11:12:33 pid:1301 Workerman[start2.php] stopping ...
|
||||
2022-12-16 11:12:33 pid:1301 Workerman[start2.php] has been stopped
|
||||
2022-12-16 11:33:45 pid:1554 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 11:34:21 pid:1554 Workerman[start2.php] stopping ...
|
||||
2022-12-16 11:34:21 pid:1554 Workerman[start2.php] has been stopped
|
||||
2022-12-16 11:34:22 pid:1644 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 11:35:08 pid:1644 Workerman[start2.php] stopping ...
|
||||
2022-12-16 11:35:08 pid:1644 Workerman[start2.php] has been stopped
|
||||
2022-12-16 11:51:43 pid:1748 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 12:10:13 pid:1748 Workerman[start2.php] stopping ...
|
||||
2022-12-16 12:10:13 pid:1748 Workerman[start2.php] has been stopped
|
||||
2022-12-16 12:10:14 pid:1892 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 12:10:28 pid:1893 TypeError: explode(): Argument #2 ($string) must be of type string, stdClass given in /home/enoch/phpdns/vendor/workerman/workerman/Protocols/Dns.php:156
|
||||
Stack trace:
|
||||
#0 /home/enoch/phpdns/vendor/workerman/workerman/Protocols/Dns.php(156): explode()
|
||||
#1 /home/enoch/phpdns/vendor/workerman/workerman/Connection/UdpConnection.php(73): Workerman\Protocols\Dns::encode()
|
||||
#2 /home/enoch/phpdns/start2.php(123): Workerman\Connection\UdpConnection->send()
|
||||
#3 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2569): {closure}()
|
||||
#4 [internal function]: Workerman\Worker->acceptUdpConnection()
|
||||
#5 /home/enoch/phpdns/vendor/workerman/workerman/Events/Event.php(193): EventBase->loop()
|
||||
#6 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(2463): Workerman\Events\Event->loop()
|
||||
#7 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1574): Workerman\Worker->run()
|
||||
#8 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1416): Workerman\Worker::forkOneWorkerForLinux()
|
||||
#9 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(1390): Workerman\Worker::forkWorkersForLinux()
|
||||
#10 /home/enoch/phpdns/vendor/workerman/workerman/Worker.php(557): Workerman\Worker::forkWorkers()
|
||||
#11 /home/enoch/phpdns/start2.php(127): Workerman\Worker::runAll()
|
||||
#12 {main}
|
||||
2022-12-16 12:10:28 pid:1892 worker[none:1893] exit with status 64000
|
||||
2022-12-16 12:10:29 pid:1892 Workerman[start2.php] stopping ...
|
||||
2022-12-16 12:10:29 pid:1892 Workerman[start2.php] has been stopped
|
||||
2022-12-16 12:13:59 pid:1998 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 12:14:35 pid:1998 Workerman[start2.php] stopping ...
|
||||
2022-12-16 12:14:35 pid:1998 Workerman[start2.php] has been stopped
|
||||
2022-12-16 12:14:36 pid:2050 Workerman[start2.php] start in DEBUG mode
|
||||
2022-12-16 12:14:40 pid:2050 Workerman[start2.php] stopping ...
|
||||
2022-12-16 12:14:40 pid:2050 Workerman[start2.php] has been stopped
|
||||
2022-12-16 12:24:20 pid:2191 Workerman[start.php] start in DEBUG mode
|
||||
2022-12-16 12:24:22 pid:2191 Workerman[start.php] stopping ...
|
||||
2022-12-16 12:24:22 pid:2191 Workerman[start.php] has been stopped
|
||||
|
92
vendor/workerman/workerman/Protocols/Dns.php
vendored
92
vendor/workerman/workerman/Protocols/Dns.php
vendored
@ -1,4 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* Workerman DNS Protocol
|
||||
* @author Enoch EchoNoch Enoch@laysense.com
|
||||
* @Repo http://git.laysense.com/enoch/workerman-dns
|
||||
* @Github http://github.com/ywnsya/workerman-dns
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
namespace Workerman\Protocols;
|
||||
class Dns
|
||||
{
|
||||
@ -91,6 +99,81 @@ class Dns
|
||||
$n=$n+1;
|
||||
};
|
||||
break;
|
||||
case 'SOA':
|
||||
$type='0006';
|
||||
$ns=$buffer->detail;
|
||||
$ns=json_decode( json_encode( $ns),true);
|
||||
if($ns['type']=='none'){
|
||||
$Rns=dns_get_record($ns['name'],DNS_SOA);
|
||||
$Rns=$Rns[0];
|
||||
$ns=$Rns;
|
||||
$buffer->ttl=$Rns['ttl'];
|
||||
}
|
||||
|
||||
$nss=explode('.',$ns['mname']);
|
||||
$detail[0]='';
|
||||
foreach($nss as $part){
|
||||
$len=str_pad(dechex(strlen($part)),2,"0",STR_PAD_LEFT);
|
||||
$tpart=bin2hex($part);
|
||||
$detail[0]=$detail[0].$len.$tpart;
|
||||
};
|
||||
$detail[0]=$detail[0].'00';
|
||||
unset($nss,$len,$tpart);
|
||||
$nss=explode('.',$ns['rname']);
|
||||
foreach($nss as $part){
|
||||
$len=str_pad(dechex(strlen($part)),2,"0",STR_PAD_LEFT);
|
||||
$tpart=bin2hex($part);
|
||||
$detail[0]=$detail[0].$len.$tpart;
|
||||
};
|
||||
$detail[0]=$detail[0].'00'.str_pad(dechex($ns['serial']),8,"0",STR_PAD_LEFT).str_pad(dechex($ns['refresh']),8,"0",STR_PAD_LEFT).str_pad(dechex($ns['retry']),8,"0",STR_PAD_LEFT).str_pad(dechex($ns['expire']),8,"0",STR_PAD_LEFT).str_pad(dechex($ns['minimum-ttl']),8,"0",STR_PAD_LEFT);
|
||||
|
||||
|
||||
$lenth[0]=str_pad(dechex((strlen($detail[0])/2)),4,"0",STR_PAD_LEFT);
|
||||
break;
|
||||
case 'AAAA':
|
||||
$type='001C';
|
||||
$ip=$buffer->detail;
|
||||
$n=0;
|
||||
foreach($ip as $i){
|
||||
$detail[$n]="$i";
|
||||
$lenth[$n]="0010";
|
||||
$n=$n+1;
|
||||
};
|
||||
break;
|
||||
case 'TEXT':
|
||||
$type='0010';
|
||||
$ns=$buffer->detail;
|
||||
$n=0;
|
||||
foreach($ns as $i){
|
||||
$detail[$n]='';
|
||||
$text=bin2hex($i);
|
||||
$tlen=str_pad(dechex((strlen($text)/2)),2,"0",STR_PAD_LEFT);
|
||||
$detail[$n]=$tlen.$text;
|
||||
$lenth[$n]=str_pad(dechex((strlen($detail[$n])/2)),4,"0",STR_PAD_LEFT);
|
||||
$n=$n+1;
|
||||
};
|
||||
break;
|
||||
case 'MX':
|
||||
$type='000F';
|
||||
$ns=$buffer->detail;
|
||||
$n=0;
|
||||
|
||||
print_r($ns);
|
||||
|
||||
foreach($ns as $i){
|
||||
$nss=explode('.',$i->name);
|
||||
$detail[$n]='';
|
||||
foreach($nss as $part){
|
||||
#$len=strlen($part);
|
||||
$len=str_pad(dechex(strlen($part)),2,"0",STR_PAD_LEFT);
|
||||
$tpart=bin2hex($part);
|
||||
$detail[$n]=$detail[$n].$len.$tpart;
|
||||
};
|
||||
$detail[$n]=$detail[$n].'00';
|
||||
$lenth[$n]=str_pad(dechex((strlen($detail[$n])/2)+2),4,"0",STR_PAD_LEFT).str_pad(dechex($i->pre),4,"0",STR_PAD_LEFT);
|
||||
$n=$n+1;
|
||||
};
|
||||
break;
|
||||
}
|
||||
$ttl=str_pad(dechex($buffer->ttl),8,"0",STR_PAD_LEFT);
|
||||
$status='8180';
|
||||
@ -108,7 +191,6 @@ class Dns
|
||||
$answer=$answer.'C00C'.$type.'0001'.$ttl.$rlenth.$c;
|
||||
}
|
||||
$response=$buffer->id.$status.$questions.$AnswerRRs.$AuthorityRRs.$AdditionalRRs.$buffer->query.$answer;
|
||||
echo $response;
|
||||
return hex2bin($response);
|
||||
}
|
||||
|
||||
@ -133,6 +215,9 @@ class Dns
|
||||
case '000c':
|
||||
$type='PTR';
|
||||
break;
|
||||
case '0006':
|
||||
$type='SOA';
|
||||
break;
|
||||
case '001c':
|
||||
$type='AAAA';
|
||||
break;
|
||||
@ -141,7 +226,10 @@ class Dns
|
||||
break;
|
||||
case '0010':
|
||||
$type='TEXT';
|
||||
break;
|
||||
break;
|
||||
case '000f':
|
||||
$type='MX';
|
||||
break;
|
||||
}
|
||||
$name=substr($data,24,-8);
|
||||
$namede=str_split($name,2);
|
||||
|
Loading…
Reference in New Issue
Block a user