PHPDaemon\Clients\DNS\Connection::onUdpPacket PHP Метод

onUdpPacket() публичный Метод

Called when new UDP packet received.
public onUdpPacket ( string $pct ) : void
$pct string
Результат void
    public function onUdpPacket($pct)
    {
        if (mb_orig_strlen($pct) < 10) {
            return;
        }
        $orig = $pct;
        $this->response = [];
        Binary::getWord($pct);
        // ID
        $bitmap = Binary::getBitmap(Binary::getByte($pct)) . Binary::getBitmap(Binary::getByte($pct));
        //$qr = (int) $bitmap[0];
        $opcode = bindec(substr($bitmap, 1, 4));
        //$aa = (int) $bitmap[5];
        //$tc = (int) $bitmap[6];
        //$rd = (int) $bitmap[7];
        //$ra = (int) $bitmap[8];
        //$z = bindec(substr($bitmap, 9, 3));
        $rcode = bindec(mb_orig_substr($bitmap, 12));
        $this->response['status'] = ['rcode' => $rcode, 'msg' => $this->getMessageByRcode($rcode)];
        $qdcount = Binary::getWord($pct);
        $ancount = Binary::getWord($pct);
        $nscount = Binary::getWord($pct);
        $arcount = Binary::getWord($pct);
        for ($i = 0; $i < $qdcount; ++$i) {
            $name = Binary::parseLabels($pct, $orig);
            $typeInt = Binary::getWord($pct);
            $type = isset(Pool::$type[$typeInt]) ? Pool::$type[$typeInt] : 'UNK(' . $typeInt . ')';
            $classInt = Binary::getWord($pct);
            $class = isset(Pool::$class[$classInt]) ? Pool::$class[$classInt] : 'UNK(' . $classInt . ')';
            if (!isset($this->response[$type])) {
                $this->response[$type] = [];
            }
            $record = ['name' => $name, 'type' => $type, 'class' => $class];
            $this->response['query'][] = $record;
        }
        $getResRecord = function (&$pct) use($orig) {
            $name = Binary::parseLabels($pct, $orig);
            $typeInt = Binary::getWord($pct);
            $type = isset(Pool::$type[$typeInt]) ? Pool::$type[$typeInt] : 'UNK(' . $typeInt . ')';
            $classInt = Binary::getWord($pct);
            $class = isset(Pool::$class[$classInt]) ? Pool::$class[$classInt] : 'UNK(' . $classInt . ')';
            $ttl = Binary::getDWord($pct);
            $length = Binary::getWord($pct);
            $data = mb_orig_substr($pct, 0, $length);
            $pct = mb_orig_substr($pct, $length);
            $record = ['name' => $name, 'type' => $type, 'class' => $class, 'ttl' => $ttl];
            if ($type === 'A' || $type === 'AAAA') {
                if ($data === "") {
                    $record['ip'] = false;
                    $record['ttl'] = 5;
                } else {
                    $record['ip'] = inet_ntop($data);
                }
            } elseif ($type === 'NS') {
                $record['ns'] = Binary::parseLabels($data, $orig);
            } elseif ($type === 'CNAME') {
                $record['cname'] = Binary::parseLabels($data, $orig);
            } elseif ($type === 'SOA') {
                $record['mname'] = Binary::parseLabels($data, $orig);
                $record['rname'] = Binary::parseLabels($data, $orig);
                $record['serial'] = Binary::getDWord($data);
                $record['refresh'] = Binary::getDWord($data);
                $record['retry'] = Binary::getDWord($data);
                $record['expire'] = Binary::getDWord($data);
                $record['nx'] = Binary::getDWord($data);
            } elseif ($type === 'MX') {
                $record['preference'] = Binary::getWord($data);
                $record['exchange'] = Binary::parseLabels($data, $orig);
            } elseif ($type === 'TXT') {
                $record['text'] = '';
                $lastLength = -1;
                while (($length = mb_orig_strlen($data)) > 0 && $length !== $lastLength) {
                    $record['text'] .= Binary::parseLabels($data, $orig);
                    $lastLength = $length;
                }
            } elseif ($type === 'SRV') {
                $record['priority'] = Binary::getWord($data);
                $record['weight'] = Binary::getWord($data);
                $record['port'] = Binary::getWord($data);
                $record['target'] = Binary::parseLabels($data, $orig);
            }
            return $record;
        };
        for ($i = 0; $i < $ancount; ++$i) {
            $record = $getResRecord($pct);
            if (!isset($this->response[$record['type']])) {
                $this->response[$record['type']] = [];
            }
            $this->response[$record['type']][] = $record;
        }
        for ($i = 0; $i < $nscount; ++$i) {
            $record = $getResRecord($pct);
            if (!isset($this->response[$record['type']])) {
                $this->response[$record['type']] = [];
            }
            $this->response[$record['type']][] = $record;
        }
        for ($i = 0; $i < $arcount; ++$i) {
            $record = $getResRecord($pct);
            if (!isset($this->response[$record['type']])) {
                $this->response[$record['type']] = [];
            }
            $this->response[$record['type']][] = $record;
        }
        $this->onResponse->executeOne($this->response);
        if (!$this->keepalive) {
            $this->finish();
            return;
        } else {
            $this->checkFree();
        }
    }