Skip to content

Commit e13d5df

Browse files
committed
implemented address resolvers
1 parent 439a592 commit e13d5df

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed

src/Common/DNSAddressResolver.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Neo4j PHP Client and Driver package.
5+
*
6+
* (c) Nagels <https://nagels.tech>
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 Laudis\Neo4j\Common;
13+
14+
use function array_filter;
15+
use function array_map;
16+
use function array_unique;
17+
use function array_values;
18+
use const DNS_A;
19+
use const DNS_AAAA;
20+
use function dns_get_record;
21+
use Laudis\Neo4j\Contracts\AddressResolverInterface;
22+
23+
class DNSAddressResolver implements AddressResolverInterface
24+
{
25+
/**
26+
* @return iterable<string>
27+
*/
28+
public function getAddresses(string $host): iterable
29+
{
30+
// By using the generator pattern we make sure to call the heavy DNS IO operations
31+
// as late as possible
32+
yield $host;
33+
34+
$records = dns_get_record($host, DNS_A | DNS_AAAA);
35+
if (count($records) === 0) {
36+
yield from $this->tryReverseLookup($host);
37+
} else {
38+
$records = array_map(static fn (array $x): string => $x['ip'] ?? '', $records);
39+
$records = array_filter($records, static fn (string $x) => $x !== '');
40+
yield from array_values(array_unique($records));
41+
}
42+
}
43+
44+
/**
45+
* @return iterable<string>
46+
*/
47+
private function tryReverseLookup(string $host): iterable
48+
{
49+
$records = dns_get_record($host.'.in-addr.arpa');
50+
if (count($records) !== 0) {
51+
$records = array_map(static fn (array $x): string => $x['target'] ?? '', $records);
52+
$records = array_filter($records, static fn (string $x) => $x !== '');
53+
yield from array_values(array_unique($records));
54+
}
55+
}
56+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Neo4j PHP Client and Driver package.
5+
*
6+
* (c) Nagels <https://nagels.tech>
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 Laudis\Neo4j\Contracts;
13+
14+
interface AddressResolverInterface
15+
{
16+
/**
17+
* Returns the addresses.
18+
*
19+
* @return iterable<string>
20+
*/
21+
public function getAddresses(string $host): iterable;
22+
}

tests/Unit/DNSAddressResolverTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Neo4j PHP Client and Driver package.
5+
*
6+
* (c) Nagels <https://nagels.tech>
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 Laudis\Neo4j\Tests\Unit;
13+
14+
use Laudis\Neo4j\Common\DNSAddressResolver;
15+
use PHPUnit\Framework\TestCase;
16+
17+
class DNSAddressResolverTest extends TestCase
18+
{
19+
private DNSAddressResolver $resolver;
20+
21+
protected function setUp(): void
22+
{
23+
parent::setUp();
24+
$this->resolver = new DNSAddressResolver();
25+
}
26+
27+
public function testResolverGhlenDotCom(): void
28+
{
29+
$records = [...$this->resolver->getAddresses('test.ghlen.com')];
30+
31+
$this->assertEqualsCanonicalizing(['test.ghlen.com', '123.123.123.123', '123.123.123.124'], $records);
32+
$this->assertNotEmpty($records);
33+
$this->assertEquals('test.ghlen.com', $records[0]);
34+
}
35+
36+
public function testResolverGoogleDotComReverse(): void
37+
{
38+
$records = [...$this->resolver->getAddresses('8.8.8.8')];
39+
40+
$this->assertEqualsCanonicalizing(['8.8.8.8', 'dns.google'], $records);
41+
$this->assertNotEmpty($records);
42+
$this->assertEquals('8.8.8.8', $records[0]);
43+
}
44+
45+
public function testBogus(): void
46+
{
47+
$this->assertEquals(['bogus'], [...$this->resolver->getAddresses('bogus')]);
48+
}
49+
}

0 commit comments

Comments
 (0)