Completed
Push — master ( fe5fd9...28190b )
by Sam
07:00 queued 04:19
created

HIP   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 158
Duplicated Lines 0 %

Test Coverage

Coverage 90.91%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 18
eloc 54
c 1
b 0
f 0
dl 0
loc 158
ccs 60
cts 66
cp 0.9091
rs 10

13 Methods

Rating   Name   Duplication   Size   Complexity  
A getRendezvousServers() 0 3 1
A fromWire() 0 18 2
A getPublicKeyAlgorithm() 0 3 1
A getPublicKey() 0 3 1
A fromText() 0 15 3
A addRendezvousServer() 0 7 2
A toText() 0 7 1
A clearRendezvousServer() 0 3 1
A getHostIdentityTag() 0 3 1
A setPublicKeyAlgorithm() 0 3 1
A setPublicKey() 0 3 1
A toWire() 0 15 2
A setHostIdentityTag() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Badcow DNS Library.
7
 *
8
 * (c) Samuel Williams <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Badcow\DNS\Rdata;
15
16
use Badcow\DNS\Message;
17
use Badcow\DNS\Parser\ParseException;
18
use Badcow\DNS\Parser\Tokens;
19
use Badcow\DNS\Validator;
20
21
/**
22
 * {@link https://tools.ietf.org/html/rfc8005}.
23
 */
24
class HIP implements RdataInterface
25
{
26 1
    use RdataTrait;
27
28
    const TYPE = 'HIP';
29
    const TYPE_CODE = 55;
30
31
    /**
32
     * @var int
33
     */
34
    private $publicKeyAlgorithm;
35
36
    /**
37
     * @var string
38
     */
39
    private $hostIdentityTag;
40
41
    /**
42
     * @var string
43
     */
44
    private $publicKey;
45
46
    /**
47
     * @var string[]
48
     */
49
    private $rendezvousServers = [];
50
51 1
    public function getPublicKeyAlgorithm(): int
52
    {
53 1
        return $this->publicKeyAlgorithm;
54
    }
55
56 4
    public function setPublicKeyAlgorithm(int $publicKeyAlgorithm): void
57
    {
58 4
        $this->publicKeyAlgorithm = $publicKeyAlgorithm;
59 4
    }
60
61 1
    public function getHostIdentityTag(): string
62
    {
63 1
        return $this->hostIdentityTag;
64
    }
65
66 4
    public function setHostIdentityTag(string $hostIdentityTag): void
67
    {
68 4
        $this->hostIdentityTag = $hostIdentityTag;
69 4
    }
70
71 1
    public function getPublicKey(): string
72
    {
73 1
        return $this->publicKey;
74
    }
75
76 4
    public function setPublicKey(string $publicKey): void
77
    {
78 4
        $this->publicKey = $publicKey;
79 4
    }
80
81 4
    public function addRendezvousServer(string $server): void
82
    {
83 4
        if (!Validator::fullyQualifiedDomainName($server)) {
84
            throw new \InvalidArgumentException('Rendezvous Server must be a fully-qualified domain name.');
85
        }
86
87 4
        $this->rendezvousServers[] = $server;
88 4
    }
89
90
    /**
91
     * @return string[]
92
     */
93 1
    public function getRendezvousServers(): array
94
    {
95 1
        return $this->rendezvousServers;
96
    }
97
98
    /**
99
     * Clear all rendezvous servers from the record.
100
     */
101
    public function clearRendezvousServer(): void
102
    {
103
        $this->rendezvousServers = [];
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109 1
    public function toText(): string
110
    {
111 1
        return sprintf('%d %s %s %s',
112 1
            $this->publicKeyAlgorithm,
113 1
            bin2hex($this->hostIdentityTag),
114 1
            base64_encode($this->publicKey),
115 1
            implode(Tokens::SPACE, $this->rendezvousServers)
116
        );
117
    }
118
119
    /**
120
     * {@inheritdoc}
121
     */
122 1
    public function toWire(): string
123
    {
124 1
        $rdata = pack('CCn',
125 1
            strlen($this->hostIdentityTag),
126 1
            $this->publicKeyAlgorithm,
127 1
            strlen($this->publicKey)
128
        );
129
130 1
        $rdata .= $this->hostIdentityTag;
131 1
        $rdata .= $this->publicKey;
132 1
        foreach ($this->rendezvousServers as $server) {
133 1
            $rdata .= Message::encodeName($server);
134
        }
135
136 1
        return $rdata;
137
    }
138
139
    /**
140
     * {@inheritdoc}
141
     *
142
     * @throws ParseException
143
     */
144 1
    public function fromText(string $text): void
145
    {
146 1
        $rdata = explode(Tokens::SPACE, $text);
147 1
        $this->setPublicKeyAlgorithm((int) array_shift($rdata));
148
149 1
        if (false === $hostIdentityTag = @hex2bin((string) array_shift($rdata))) {
150
            throw new ParseException(sprintf('Unable to parse host identity tag of rdata string "%s".', $text));
151
        }
152 1
        $this->setHostIdentityTag($hostIdentityTag);
153
154 1
        if (false === $publicKey = base64_decode((string) array_shift($rdata), true)) {
155
            throw new ParseException(sprintf('Unable to parse public key of rdata string "%s".', $text));
156
        }
157 1
        $this->setPublicKey($publicKey);
158 1
        array_map([$this, 'addRendezvousServer'], $rdata);
159 1
    }
160
161
    /**
162
     * {@inheritdoc}
163
     */
164 1
    public function fromWire(string $rdata, int &$offset = 0, ?int $rdLength = null): void
165
    {
166 1
        $end = $offset + ($rdLength ?? strlen($rdata));
167 1
        $integers = unpack('C<hitLen>/C<algorithm>/n<pkLen>', $rdata, $offset);
168 1
        $offset += 4;
169 1
        $hitLen = (int) $integers['<hitLen>'];
170 1
        $pkLen = (int) $integers['<pkLen>'];
171
172 1
        $this->setPublicKeyAlgorithm((int) $integers['<algorithm>']);
173
174 1
        $this->setHostIdentityTag(substr($rdata, $offset, $hitLen));
175 1
        $offset += $hitLen;
176
177 1
        $this->setPublicKey(substr($rdata, $offset, $pkLen));
178 1
        $offset += $pkLen;
179
180 1
        while ($offset < $end) {
181 1
            $this->addRendezvousServer(Message::decodeName($rdata, $offset));
182
        }
183 1
    }
184
}
185