Completed
Push — master ( 0cd2cd...e2ec22 )
by Sam
02:48
created

RdataDecoder   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Test Coverage

Coverage 89.29%

Importance

Changes 0
Metric Value
eloc 34
dl 0
loc 123
ccs 25
cts 28
cp 0.8929
rs 10
c 0
b 0
f 0
wmc 9

7 Methods

Rating   Name   Duplication   Size   Complexity  
A txt() 0 8 2
A mx() 0 5 1
A srv() 0 7 1
A soa() 0 10 1
A a() 0 3 1
A cname() 0 3 1
A decodeRdata() 0 9 2
1
<?php
2
3
/*
4
 * This file is part of PHP DNS Server.
5
 *
6
 * (c) Yif Swery <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace yswery\DNS;
13
14
class RdataDecoder
15
{
16
    /**
17
     * Maps an RData type to its decoder method.
18
     *
19
     * @var array
20
     */
21
    private static $methodMap = [
22
        RecordTypeEnum::TYPE_A => 'a',
23
        RecordTypeEnum::TYPE_AAAA => 'a',
24
        RecordTypeEnum::TYPE_CNAME => 'cname',
25
        RecordTypeEnum::TYPE_DNAME => 'cname',
26
        RecordTypeEnum::TYPE_NS => 'cname',
27
        RecordTypeEnum::TYPE_PTR => 'cname',
28
        RecordTypeEnum::TYPE_SOA => 'soa',
29
        RecordTypeEnum::TYPE_MX => 'mx',
30
        RecordTypeEnum::TYPE_TXT => 'txt',
31
        RecordTypeEnum::TYPE_SRV => 'srv',
32
    ];
33
    
34
    /**
35
     * @param int    $type
36
     * @param string $rdata
37
     *
38
     * @return array|string
39
     *
40
     * @throws UnsupportedTypeException
41
     */
42 6
    public static function decodeRdata(int $type, string $rdata)
43
    {
44 6
        if (!array_key_exists($type, self::$methodMap)) {
45
            throw new UnsupportedTypeException(
46
                sprintf('Record type "%s" is not a supported type.', RecordTypeEnum::getName($type))
47
            );
48
        }
49
50 6
        return call_user_func(['self', self::$methodMap[$type]], $rdata);
51
    }
52
53
    /**
54
     * Used for A and AAAA records.
55
     *
56
     * @param string $rdata
57
     * @return string
58
     */
59 5
    public static function a(string $rdata): string
60
    {
61 5
        return inet_ntop($rdata);
62
    }
63
64
    /**
65
     * Used for CNAME, DNAME, NS, and PTR records.
66
     *
67
     * @param string $rdata
68
     * @return string
69
     */
70 2
    public static function cname(string $rdata): string
71
    {
72 2
        return Decoder::decodeDomainName($rdata);
73
    }
74
75
    /**
76
     * Exclusively for SOA records.
77
     *
78
     * @param string $rdata
79
     * @return array
80
     */
81 1
    public static function soa(string $rdata): array
82
    {
83 1
        $offset = 0;
84
85 1
        return array_merge(
86
            [
87 1
                'mname' => Decoder::decodeDomainName($rdata, $offset),
88 1
                'rname' => Decoder::decodeDomainName($rdata, $offset),
89
            ],
90 1
            unpack('Nserial/Nrefresh/Nretry/Nexpire/Nminimum', substr($rdata, $offset))
91
        );
92
    }
93
94
    /**
95
     * Exclusively for MX records.
96
     *
97
     * @param string $rdata
98
     * @return array
99
     */
100 3
    public static function mx(string $rdata): array
101
    {
102
        return [
103 3
            'preference' => unpack('npreference', $rdata)['preference'],
104 3
            'exchange' => Decoder::decodeDomainName(substr($rdata, 2)),
105
        ];
106
    }
107
108
    /**
109
     * Exclusively for TXT records.
110
     *
111
     * @param string $rdata
112
     * @return string
113
     */
114 1
    public static function txt(string $rdata): string
115
    {
116 1
        $len = ord($rdata[0]);
117 1
        if ((strlen($rdata) + 1) < $len) {
118
            return null;
0 ignored issues
show
Bug Best Practice introduced by
The expression return null returns the type null which is incompatible with the type-hinted return string.
Loading history...
119
        }
120
121 1
        return substr($rdata, 1, $len);
122
    }
123
124
    /**
125
     * Exclusively for SRV records.
126
     *
127
     * @param string $rdata
128
     * @return array
129
     */
130 2
    public static function srv(string $rdata): array
131
    {
132 2
        $offset = 6;
133 2
        $values = unpack('npriority/nweight/nport', $rdata);
134 2
        $values['target'] = Decoder::decodeDomainName($rdata, $offset);
135
136 2
        return $values;
137
    }
138
}