diff --git a/src/Config/Config.php b/src/Config/Config.php index 9677ee57..29d2c5b3 100644 --- a/src/Config/Config.php +++ b/src/Config/Config.php @@ -96,7 +96,13 @@ public static function loadResolvConfBlocking($path = null) $config->nameservers[] = $ip; } } - + $matches = array(); + preg_match_all('/^search.*\s*$/m', $contents, $matches); + if(isset($matches[0][0])){ + $searches = preg_split('/\s+/', trim($matches[0][0])); + unset($searches[0]); + $config->searches= array_values($searches); + } return $config; } @@ -134,4 +140,5 @@ public static function loadWmicBlocking($command = null) } public $nameservers = array(); + public $searches = array(); } diff --git a/src/Query/RetryExecutor.php b/src/Query/RetryExecutor.php index 880609b2..65cd5097 100644 --- a/src/Query/RetryExecutor.php +++ b/src/Query/RetryExecutor.php @@ -9,11 +9,13 @@ final class RetryExecutor implements ExecutorInterface { private $executor; private $retries; + private $config; public function __construct(ExecutorInterface $executor, $retries = 2) { $this->executor = $executor; $this->retries = $retries; + $this->config = \React\Dns\Config\Config::loadSystemConfigBlocking(); } public function query(Query $query) diff --git a/src/Query/TimeoutExecutor.php b/src/Query/TimeoutExecutor.php index 06c51b15..3c5c4954 100644 --- a/src/Query/TimeoutExecutor.php +++ b/src/Query/TimeoutExecutor.php @@ -2,6 +2,7 @@ namespace React\Dns\Query; +use React\Dns\Model\Message; use React\EventLoop\Loop; use React\EventLoop\LoopInterface; use React\Promise\Promise; @@ -11,12 +12,14 @@ final class TimeoutExecutor implements ExecutorInterface private $executor; private $loop; private $timeout; + private $config; public function __construct(ExecutorInterface $executor, $timeout, LoopInterface $loop = null) { $this->executor = $executor; $this->loop = $loop ?: Loop::get(); $this->timeout = $timeout; + $this->config = \React\Dns\Config\Config::loadSystemConfigBlocking(); } public function query(Query $query) diff --git a/src/Query/UdpTransportExecutor.php b/src/Query/UdpTransportExecutor.php index 30a3d705..2765d7c3 100644 --- a/src/Query/UdpTransportExecutor.php +++ b/src/Query/UdpTransportExecutor.php @@ -5,6 +5,7 @@ use React\Dns\Model\Message; use React\Dns\Protocol\BinaryDumper; use React\Dns\Protocol\Parser; +use React\Dns\RecordNotFoundException; use React\EventLoop\Loop; use React\EventLoop\LoopInterface; use React\Promise\Deferred; @@ -208,7 +209,13 @@ public function query(Query $query) )); return; } - + if($response->rcode == Message::RCODE_NAME_ERROR){ + $deferred->reject(new RecordNotFoundException( + 'DNS query for ' . $query->describe() . ' returned an error response (Non-Existent Domain / NXDOMAIN)', + $response->rcode + )); + return; + } $deferred->resolve($response); }); diff --git a/tests/FunctionalResolverTest.php b/tests/FunctionalResolverTest.php index 2e8690dd..53e587e5 100644 --- a/tests/FunctionalResolverTest.php +++ b/tests/FunctionalResolverTest.php @@ -38,9 +38,9 @@ public function testResolveAllLocalhostResolvesWithArray() /** * @group internet */ - public function testResolveGoogleResolves() + public function testResolveBingResolves() { - $promise = $this->resolver->resolve('google.com'); + $promise = $this->resolver->resolve('bing.com'); $promise->then($this->expectCallableOnce(), $this->expectCallableNever()); Loop::run(); @@ -49,12 +49,12 @@ public function testResolveGoogleResolves() /** * @group internet */ - public function testResolveGoogleOverUdpResolves() + public function testResolveBingleOverUdpResolves() { $factory = new Factory(); $this->resolver = $factory->create('udp://8.8.8.8'); - $promise = $this->resolver->resolve('google.com'); + $promise = $this->resolver->resolve('bing.com'); $promise->then($this->expectCallableOnce(), $this->expectCallableNever()); Loop::run(); @@ -63,12 +63,12 @@ public function testResolveGoogleOverUdpResolves() /** * @group internet */ - public function testResolveGoogleOverTcpResolves() + public function testResolveBingOverTcpResolves() { $factory = new Factory(); $this->resolver = $factory->create('tcp://8.8.8.8'); - $promise = $this->resolver->resolve('google.com'); + $promise = $this->resolver->resolve('bing.com'); $promise->then($this->expectCallableOnce(), $this->expectCallableNever()); Loop::run(); @@ -77,12 +77,12 @@ public function testResolveGoogleOverTcpResolves() /** * @group internet */ - public function testResolveAllGoogleMxResolvesWithCache() + public function testResolveAllBingMxResolvesWithCache() { $factory = new Factory(); $this->resolver = $factory->createCached('8.8.8.8'); - $promise = $this->resolver->resolveAll('google.com', Message::TYPE_MX); + $promise = $this->resolver->resolveAll('bing.com', Message::TYPE_MX); $promise->then($this->expectCallableOnceWith($this->isType('array')), $this->expectCallableNever()); Loop::run(); @@ -90,12 +90,12 @@ public function testResolveAllGoogleMxResolvesWithCache() /** * @group internet */ - public function testResolveAllGoogleCaaResolvesWithCache() + public function testResolveAllbingCaaResolvesWithCache() { $factory = new Factory(); $this->resolver = $factory->createCached('8.8.8.8'); - $promise = $this->resolver->resolveAll('google.com', Message::TYPE_CAA); + $promise = $this->resolver->resolveAll('bing.com', Message::TYPE_CAA); $promise->then($this->expectCallableOnceWith($this->isType('array')), $this->expectCallableNever()); Loop::run(); @@ -114,11 +114,13 @@ public function testResolveInvalidRejects() $promise->then(null, function ($reason) use (&$exception) { $exception = $reason; }); - - /** @var \React\Dns\RecordNotFoundException $exception */ - $this->assertInstanceOf('React\Dns\RecordNotFoundException', $exception); - $this->assertEquals('DNS query for example.invalid (A) returned an error response (Non-Existent Domain / NXDOMAIN)', $exception->getMessage()); - $this->assertEquals(Message::RCODE_NAME_ERROR, $exception->getCode()); + $config = \React\Dns\Config\Config::loadSystemConfigBlocking(); + if (!count($config->searches)) { + /** @var \React\Dns\RecordNotFoundException $exception */ + $this->assertInstanceOf('React\Dns\RecordNotFoundException', $exception); + $this->assertEquals('DNS query for example.invalid (A) returned an error response (Non-Existent Domain / NXDOMAIN)', $exception->getMessage()); + $this->assertEquals(Message::RCODE_NAME_ERROR, $exception->getCode()); + } } public function testResolveCancelledRejectsImmediately() @@ -126,7 +128,7 @@ public function testResolveCancelledRejectsImmediately() // max_nesting_level was set to 100 for PHP Versions < 5.4 which resulted in failing test for legacy PHP ini_set('xdebug.max_nesting_level', 256); - $promise = $this->resolver->resolve('google.com'); + $promise = $this->resolver->resolve('bing.com'); $promise->cancel(); $time = microtime(true); @@ -142,7 +144,7 @@ public function testResolveCancelledRejectsImmediately() /** @var \React\Dns\Query\CancellationException $exception */ $this->assertInstanceOf('React\Dns\Query\CancellationException', $exception); - $this->assertEquals('DNS query for google.com (A) has been cancelled', $exception->getMessage()); + $this->assertEquals('DNS query for bing.com (A) has been cancelled', $exception->getMessage()); } /** @@ -150,7 +152,7 @@ public function testResolveCancelledRejectsImmediately() */ public function testResolveAllInvalidTypeRejects() { - $promise = $this->resolver->resolveAll('google.com', Message::TYPE_PTR); + $promise = $this->resolver->resolveAll('bing.com', Message::TYPE_PTR); Loop::run(); @@ -161,17 +163,18 @@ public function testResolveAllInvalidTypeRejects() /** @var \React\Dns\RecordNotFoundException $exception */ $this->assertInstanceOf('React\Dns\RecordNotFoundException', $exception); - $this->assertEquals('DNS query for google.com (PTR) did not return a valid answer (NOERROR / NODATA)', $exception->getMessage()); + $this->assertEquals('DNS query for bing.com (PTR) did not return a valid answer (NOERROR / NODATA)', $exception->getMessage()); $this->assertEquals(0, $exception->getCode()); } - public function testInvalidResolverDoesNotResolveGoogle() + public function testInvalidResolverDoesNotResolvebing() { $factory = new Factory(); $this->resolver = $factory->create('255.255.255.255'); - $promise = $this->resolver->resolve('google.com'); + $promise = $this->resolver->resolve('bing.com'); $promise->then($this->expectCallableNever(), $this->expectCallableOnce()); + Loop::run(); } public function testResolveShouldNotCauseGarbageReferencesWhenUsingInvalidNameserver() @@ -231,7 +234,7 @@ public function testCancelResolveShouldNotCauseGarbageReferences() // collect all garbage cycles } - $promise = $this->resolver->resolve('google.com'); + $promise = $this->resolver->resolve('bing.com'); $promise->cancel(); $promise = null; @@ -251,7 +254,7 @@ public function testCancelResolveCachedShouldNotCauseGarbageReferences() // collect all garbage cycles } - $promise = $this->resolver->resolve('google.com'); + $promise = $this->resolver->resolve('bing.com'); $promise->cancel(); $promise = null; diff --git a/tests/Query/TcpTransportExecutorTest.php b/tests/Query/TcpTransportExecutorTest.php index 33dddacd..a370f334 100644 --- a/tests/Query/TcpTransportExecutorTest.php +++ b/tests/Query/TcpTransportExecutorTest.php @@ -535,7 +535,7 @@ public function testQueryRejectsWhenServerSendsInvalidMessage() $address = stream_socket_get_name($server, false); $executor = new TcpTransportExecutor($address); - $query = new Query('google.com', Message::TYPE_A, Message::CLASS_IN); + $query = new Query('bing.com', Message::TYPE_A, Message::CLASS_IN); $exception = null; $executor->query($query)->then( @@ -552,7 +552,7 @@ function ($e) use (&$exception) { /** @var \RuntimeException $exception */ $this->assertInstanceOf('RuntimeException', $exception); - $this->assertEquals('DNS query for google.com (A) failed: Invalid message received from DNS server tcp://' . $address, $exception->getMessage()); + $this->assertEquals('DNS query for bing.com (A) failed: Invalid message received from DNS server tcp://' . $address, $exception->getMessage()); } public function testQueryRejectsWhenServerSendsInvalidId() @@ -688,7 +688,7 @@ public function testQueryResolvesIfServerSendsValidResponse() $this->assertInstanceOf('React\Dns\Model\Message', $response); } - + public function testQueryRejectsIfSocketIsClosedAfterPreviousQueryThatWasStillPending() { $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();