This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | namespace PHPDaemon\Clients\DNS; |
||
3 | |||
4 | use PHPDaemon\Cache\CappedStorageHits; |
||
5 | use PHPDaemon\Core\ComplexJob; |
||
6 | use PHPDaemon\FS\FileSystem; |
||
7 | use PHPDaemon\Network\Client; |
||
8 | |||
9 | /** |
||
10 | * @package NetworkClients |
||
11 | * @subpackage DNSClient |
||
12 | * @author Vasily Zorin <[email protected]> |
||
13 | */ |
||
14 | class Pool extends Client |
||
15 | { |
||
16 | |||
17 | /** |
||
18 | * @var array Record Types [code => "name", ...] |
||
19 | */ |
||
20 | public static $type = [ |
||
21 | 1 => 'A', |
||
22 | 2 => 'NS', |
||
23 | 3 => 'MD', |
||
24 | 4 => 'MF', |
||
25 | 5 => 'CNAME', |
||
26 | 6 => 'SOA', |
||
27 | 7 => 'MB', |
||
28 | 8 => 'MG', |
||
29 | 9 => 'MR', |
||
30 | 10 => 'RR', |
||
31 | 11 => 'WKS', |
||
32 | 12 => 'PTR', |
||
33 | 13 => 'HINFO', |
||
34 | 14 => 'MINFO', |
||
35 | 15 => 'MX', |
||
36 | 16 => 'TXT', |
||
37 | 17 => 'RP', |
||
38 | 18 => 'AFSDB', |
||
39 | 19 => 'X25', |
||
40 | 20 => 'ISDN', |
||
41 | 21 => 'RT', |
||
42 | 22 => 'NSAP', |
||
43 | 23 => 'NSAP-PTR', |
||
44 | 24 => 'SIG', |
||
45 | 25 => 'KEY', |
||
46 | 26 => 'PX', |
||
47 | 27 => 'GPOS', |
||
48 | 28 => 'AAAA', |
||
49 | 29 => 'LOC', |
||
50 | 30 => 'NXT', |
||
51 | 31 => 'EID', |
||
52 | 32 => 'NIMLOC', |
||
53 | 33 => 'SRV', |
||
54 | 34 => 'ATMA', |
||
55 | 35 => 'NAPTR', |
||
56 | 36 => 'KX', |
||
57 | 37 => 'CERT', |
||
58 | 38 => 'A6', |
||
59 | 39 => 'DNAME', |
||
60 | 40 => 'SINK', |
||
61 | 41 => 'OPT', |
||
62 | 42 => 'APL', |
||
63 | 43 => 'DS', |
||
64 | 44 => 'SSHFP', |
||
65 | 45 => 'IPSECKEY', |
||
66 | 46 => 'RRSIG', |
||
67 | 47 => 'NSEC', |
||
68 | 48 => 'DNSKEY', |
||
69 | 49 => 'DHCID', |
||
70 | 50 => 'NSEC3', |
||
71 | 51 => 'NSEC3PARAM', |
||
72 | 55 => 'HIP', |
||
73 | 99 => 'SPF', |
||
74 | 100 => 'UINFO', |
||
75 | 101 => 'UID', |
||
76 | 102 => 'GID', |
||
77 | 103 => 'UNSPEC', |
||
78 | 249 => 'TKEY', |
||
79 | 250 => 'TSIG', |
||
80 | 251 => 'IXFR', |
||
81 | 252 => 'AXFR', |
||
82 | 253 => 'MAILB', |
||
83 | 254 => 'MAILA', |
||
84 | 255 => 'ALL', |
||
85 | 32768 => 'TA', |
||
86 | 32769 => 'DLV', |
||
87 | ]; |
||
88 | |||
89 | /** |
||
90 | * @var array Hosts file parsed [hostname => [addr, ...], ...] |
||
91 | */ |
||
92 | public $hosts = []; |
||
93 | |||
94 | /** |
||
95 | * @var \PHPDaemon\Core\ComplexJob Preloading ComplexJob |
||
96 | */ |
||
97 | public $preloading; |
||
98 | |||
99 | /** |
||
100 | * @var CappedStorageHits Resolve cache |
||
101 | */ |
||
102 | public $resolveCache; |
||
103 | |||
104 | /** |
||
105 | * @var array Classes [code => "class"] |
||
106 | */ |
||
107 | public static $class = [ |
||
108 | 1 => 'IN', |
||
109 | 3 => 'CH', |
||
110 | 255 => 'ANY', |
||
111 | ]; |
||
112 | |||
113 | /** |
||
114 | * @var array resolve.conf file parsed |
||
115 | */ |
||
116 | public $nameServers = []; |
||
117 | |||
118 | /** |
||
119 | * Constructor |
||
120 | */ |
||
121 | protected function init() |
||
122 | { |
||
123 | $this->resolveCache = new CappedStorageHits($this->config->resolvecachesize->value); |
||
0 ignored issues
–
show
|
|||
124 | } |
||
125 | |||
126 | /** |
||
127 | * Setting default config options |
||
128 | * Overriden from NetworkClient::getConfigDefaults |
||
129 | * @return array |
||
130 | */ |
||
131 | protected function getConfigDefaults() |
||
132 | { |
||
133 | return [ |
||
134 | /* [integer] port */ |
||
135 | 'port' => 53, |
||
136 | |||
137 | /* [integer] resolvecachesize */ |
||
138 | 'resolvecachesize' => 128, |
||
139 | |||
140 | /* [string] Servers */ |
||
141 | 'servers' => '', |
||
142 | |||
143 | /* [string] hostsfile */ |
||
144 | 'hostsfile' => '/etc/hosts', |
||
145 | |||
146 | /* [string] resolvfile */ |
||
147 | 'resolvfile' => '/etc/resolv.conf', |
||
148 | |||
149 | /* [boolean] Expose? */ |
||
150 | 'expose' => 1, |
||
151 | ]; |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * Applies config |
||
156 | * @return void |
||
157 | */ |
||
158 | public function applyConfig() |
||
159 | { |
||
160 | parent::applyConfig(); |
||
161 | $pool = $this; |
||
162 | if (!isset($this->preloading)) { |
||
163 | $this->preloading = new ComplexJob(); |
||
164 | } |
||
165 | $job = $this->preloading; |
||
166 | $job->addJob('resolvfile', function ($jobname, $job) use ($pool) { |
||
167 | FileSystem::readfile($pool->config->resolvfile->value, function ($file, $data) use ($pool, $job, $jobname) { |
||
0 ignored issues
–
show
The property
resolvfile does not seem to exist in PHPDaemon\Config\Section .
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
168 | if ($file) { |
||
169 | foreach (explode("\n", $data) as $line) { |
||
170 | $line = trim($line); |
||
171 | if ($line !== '' && $line[0] !== '#' && preg_match('~nameserver ([^\r\n;]+)~i', $line, $m)) { |
||
172 | $pool->nameServers[] = $m[1]; |
||
173 | } |
||
174 | } |
||
175 | } |
||
176 | $job->setResult($jobname); |
||
177 | }); |
||
178 | }); |
||
179 | $job->addJob('hostsfile', function ($jobname, $job) use ($pool) { |
||
180 | FileSystem::readfile($pool->config->hostsfile->value, function ($file, $data) use ($pool, $job, $jobname) { |
||
0 ignored issues
–
show
The property
hostsfile does not seem to exist in PHPDaemon\Config\Section .
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
181 | if ($file) { |
||
182 | preg_match_all('~^([^#]\S+)\s+([^\r\n]+)\s*~m', $data, $m, PREG_SET_ORDER); |
||
183 | $pool->hosts = []; |
||
184 | foreach ($m as $h) { |
||
0 ignored issues
–
show
The expression
$m of type null|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
185 | $hosts = preg_split('~\s+~', $h[2]); |
||
186 | $ip = $h[1]; |
||
187 | /* skip commentened ips */ |
||
188 | if (preg_match('~^[\s]*?#~m', $ip)) { |
||
189 | continue; |
||
190 | } |
||
191 | foreach ($hosts as $host) { |
||
192 | $host = rtrim($host, '.') . '.'; |
||
193 | $pool->hosts[$host][] = $ip; |
||
194 | } |
||
195 | } |
||
196 | } |
||
197 | $job->setResult($jobname); |
||
198 | }); |
||
199 | }); |
||
200 | $job(); |
||
201 | } |
||
202 | |||
203 | /** |
||
204 | * Resolves the host |
||
205 | * @param string $hostname Hostname |
||
206 | * @param callable $cb Callback |
||
207 | * @param boolean $noncache Noncache? |
||
208 | * @param array $nameServers |
||
209 | * @callback $cb ( array|string $addrs ) |
||
210 | * @return void |
||
211 | */ |
||
212 | public function resolve($hostname, $cb, $noncache = false, $nameServers = []) |
||
213 | { |
||
214 | View Code Duplication | if (!$this->preloading->hasCompleted()) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
215 | $pool = $this; |
||
216 | $this->preloading->addListener(function ($job) use ($hostname, $cb, $noncache, $pool, $nameServers) { |
||
0 ignored issues
–
show
|
|||
217 | $pool->resolve($hostname, $cb, $noncache, $nameServers); |
||
218 | }); |
||
219 | return; |
||
220 | } |
||
221 | $hostname = rtrim($hostname, '.') . '.'; |
||
222 | if (isset($this->hosts[$hostname])) { |
||
223 | $cb($this->hosts[$hostname]); |
||
224 | return; |
||
225 | } |
||
226 | if (!$noncache && ($item = $this->resolveCache->get($hostname))) { // cache hit |
||
227 | $ip = $item->getValue(); |
||
228 | if ($ip === null) { // operation in progress |
||
229 | $item->addListener($cb); |
||
230 | } else { // hit |
||
231 | $cb($ip); |
||
232 | } |
||
233 | return; |
||
234 | } elseif (!$noncache) { |
||
235 | $item = $this->resolveCache->put($hostname, null); |
||
236 | $item->addListener($cb); |
||
237 | } |
||
238 | $pool = $this; |
||
239 | $this->get($hostname, function ($response) use ($cb, $noncache, $hostname, $pool) { |
||
240 | if (!isset($response['A'])) { |
||
241 | if ($noncache) { |
||
242 | $cb(false); |
||
243 | } else { |
||
244 | $pool->resolveCache->put($hostname, false, 5); // 5 - TTL of unsuccessful request |
||
245 | } |
||
246 | return; |
||
247 | } |
||
248 | if (!isset($response['A']) && !isset($response['AAAA'])) { |
||
249 | $cb(false); |
||
250 | return; |
||
251 | } |
||
252 | $addrs = []; |
||
253 | $ttl = 0; |
||
254 | View Code Duplication | if (isset($response['A'])) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
255 | foreach ($response['A'] as $r) { |
||
256 | $addrs[] = $r['ip']; |
||
257 | $ttl = $r['ttl']; |
||
258 | } |
||
259 | } |
||
260 | View Code Duplication | if (isset($response['AAAA'])) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
261 | foreach ($response['AAAA'] as $r) { |
||
262 | $addrs[] = $r['ip']; |
||
263 | $ttl = $r['ttl']; |
||
264 | } |
||
265 | } |
||
266 | if (sizeof($addrs) === 1) { |
||
267 | $addrs = $addrs[0]; |
||
268 | } |
||
269 | if ($noncache) { |
||
270 | $cb($addrs); |
||
271 | } else { |
||
272 | $pool->resolveCache->put($hostname, $addrs, $ttl); |
||
273 | } |
||
274 | }, $noncache, $nameServers); |
||
275 | } |
||
276 | |||
277 | /** |
||
278 | * Gets the host information |
||
279 | * @param string $hostname Hostname |
||
280 | * @param callable $cb Callback |
||
281 | * @param boolean $noncache Noncache? |
||
282 | * @param array $nameServers |
||
283 | * @param string $proto |
||
284 | * @callback $cb ( ) |
||
285 | * @return void |
||
286 | */ |
||
287 | public function get($hostname, $cb, $noncache = false, $nameServers = [], $proto = 'udp') |
||
288 | { |
||
289 | $pool = $this; |
||
290 | if (!$nameServers) { |
||
0 ignored issues
–
show
The expression
$nameServers of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
291 | $nameServers = $this->nameServers; |
||
292 | } |
||
293 | View Code Duplication | if (!$this->preloading->hasCompleted()) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
294 | $this->preloading->addListener(function ($job) use ( |
||
0 ignored issues
–
show
|
|||
295 | $hostname, |
||
296 | $cb, |
||
297 | $noncache, |
||
298 | $pool, |
||
299 | $nameServers, |
||
300 | $proto |
||
301 | ) { |
||
302 | $pool->get($hostname, $cb, $noncache, $nameServers, $proto); |
||
303 | }); |
||
304 | return; |
||
305 | } |
||
306 | $nameServer = reset($nameServers); |
||
307 | $isIpv6 = filter_var($nameServer, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6); |
||
308 | if ($isIpv6) { |
||
309 | $nameServer = '[' . $nameServer . ']'; |
||
310 | } |
||
311 | $onGetConnection = function ($conn) use ($cb, $hostname, $nameServers, $noncache, $pool, $proto) { |
||
312 | if (!$conn || !$conn->isConnected()) { |
||
313 | if ($proto === 'udp') { |
||
314 | //Fail to connect via udp, trying by tcp |
||
315 | $pool->get($hostname, $cb, $noncache, $nameServers, 'tcp'); |
||
316 | return; |
||
317 | } |
||
318 | array_shift($nameServers); |
||
319 | if (!$nameServers) { |
||
0 ignored issues
–
show
The expression
$nameServers of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
320 | //Totally fail to resolve name |
||
321 | $cb(false); |
||
322 | } else { |
||
323 | //Fail connect to curr Ns, but we can try another ns |
||
324 | $pool->get($hostname, $cb, $noncache, $nameServers, 'udp'); |
||
325 | } |
||
326 | } else { |
||
327 | $conn->get( |
||
328 | $hostname, |
||
329 | function ($response) use ($hostname, $cb, $proto, $noncache, $nameServers, $pool) { |
||
330 | if ($response === false && $proto === 'udp') { |
||
331 | //Fail to connect via udp, trying by tcp |
||
332 | $pool->get($hostname, $cb, $noncache, $nameServers, 'tcp'); |
||
333 | } else { |
||
334 | call_user_func($cb, $response); |
||
335 | } |
||
336 | } |
||
337 | ); |
||
338 | } |
||
339 | }; |
||
340 | list($host, $type, $class) = explode(':', $hostname . '::', 3); |
||
0 ignored issues
–
show
The assignment to
$host is unused. Consider omitting it like so list($first,,$third) .
This checks looks for assignemnts to variables using the Consider the following code example. <?php
function returnThreeValues() {
return array('a', 'b', 'c');
}
list($a, $b, $c) = returnThreeValues();
print $a . " - " . $c;
Only the variables Instead, the list call could have been. list($a,, $c) = returnThreeValues();
![]() The assignment to
$class is unused. Consider omitting it like so list($first,,$third) .
This checks looks for assignemnts to variables using the Consider the following code example. <?php
function returnThreeValues() {
return array('a', 'b', 'c');
}
list($a, $b, $c) = returnThreeValues();
print $a . " - " . $c;
Only the variables Instead, the list call could have been. list($a,, $c) = returnThreeValues();
![]() |
|||
341 | if ($type === 'AXFR') { |
||
342 | $proto = 'tcp'; |
||
343 | } |
||
344 | $this->getConnection($proto . '://' . $nameServer, $onGetConnection); |
||
345 | return; |
||
346 | } |
||
347 | } |
||
348 |
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.
If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.