-
-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use default nameservers (support /etc/resolv.conf) #29
Comments
Hello, I've tried to do something to work around this not yet available functionality, in reactphp/dns. You're idea is to read the file directly in my case i've based my resolve on the native php function. Perhaps my code can help some others, i'm brand new to event programming, promise and other stuff so i'm sure you will see some improvement. If the LocalExecutor Fail we can fall back on the classic Executor. I've created a LocalResolversExecutor (Query/LocalResolverExecutor.php) : <?php
namespace React\Dns\Query;
use React\Dns\RecordNotFoundException;
use React\Dns\Model\Message;
use React\Dns\Model\Record;
use React\Dns\Query\ExecutorInterface;
use React\Dns\Query\Query;
use React\EventLoop\LoopInterface;
use React\Promise\Deferred;
class LocalResolverExecutor implements ExecutorInterface
{
private $loop;
private $executor;
public function __construct(LoopInterface $loop, ExecutorInterface $executor, $timeout = 5)
{
$this->loop = $loop;
$this->executor = $executor;
$this->timeout = $timeout;
}
public function query($nameserver, Query $query)
{
$executor = $this->executor;
return $this
->doQuery($query)
->then(null, function () use ($query, $nameserver, $executor) {
return $executor->query($nameserver, $query);
});
}
public function doQuery($query)
{
$that = $this;
$name = $query->name;
$deferred = new Deferred(function ($resolve, $reject) use (&$timer, $name) {
$reject(new CancellationException(sprintf('DNS query for %s has been cancelled', $name)));
$timer->cancel();
});
$timer = $this->loop->addTimer($this->timeout, function () use ($name, $deferred) {
$deferred->reject(new TimeoutException(sprintf("DNS query for %s timed out", $name)));
});
$this->loop->addTimer(0, function () use ($that, $query, $deferred, $timer) {
$record = gethostbyname($query->name);
$timer->cancel();
if ($record == $query->name) {
$deferred->reject(new RecordNotFoundException(sprintf('Unable to resolve %s', $query->name)));
}
$response = $that->buildResponse($query, [ new Record($query->name, $query->type, $query->class, 5, $record) ]);
$deferred->resolve($response);
});
return $deferred->promise();
}
public function buildResponse(Query $query, array $records)
{
$response = new Message();
$response->header->set('id', $this->generateId());
$response->header->set('qr', 1);
$response->header->set('opcode', Message::OPCODE_QUERY);
$response->header->set('rd', 1);
$response->header->set('rcode', Message::RCODE_OK);
$response->questions[] = new Record($query->name, $query->type, $query->class);
$response->answers = $records;
$response->prepare();
return $response;
}
protected function generateId()
{
return mt_rand(0, 0xffff);
}
} And update Resolver/Factory.php to use it : @@ -11,13 +11,14 @@ use React\Dns\Protocol\Parser;
use React\Dns\Protocol\BinaryDumper;
use React\EventLoop\LoopInterface;
use React\Dns\Query\RetryExecutor;
+use React\Dns\Query\LocalResolverExecutor;
class Factory
{
public function create($nameserver, LoopInterface $loop)
{
$nameserver = $this->addPortToServerIfMissing($nameserver);
- $executor = $this->createRetryExecutor($loop);
+ $executor = $this->createLocalResolverExecutor($loop);
return new Resolver($nameserver, $executor);
}
@@ -46,7 +47,12 @@ class Factory
protected function createCachedExecutor(LoopInterface $loop, CacheInterface $cache)
{
- return new CachedExecutor($this->createRetryExecutor($loop), new RecordCache($cache));
+ return new CachedExecutor($this->createLocalResolverExecutor($loop), new RecordCache($cache));
+ }
+
+ protected function createLocalResolverExecutor(LoopInterface $loop)
+ {
+ return new LocalResolverExecutor($loop, $this->createRetryExecutor($loop));
}
protected function addPortToServerIfMissing($nameserver) Regards, |
Thanks for posting this @marty-macfly, but unfortunately your code relies on This ticket likely requires us to do the following:
|
I just landed here while trying to research how you guys do it on Windows. Windows stores that information in the registry unfortunately. :-( |
we could use |
If you build an adapter you could just use that library instead of just recreating it. |
@kelunik good point, this is basically a use case for reactphp/promise#78 |
No, async interoperability doesn't matter for a specific case. A common event loop does. |
@kelunik I see both things as somewhat related ;) |
They are, but a common loop makes things work, a common promise API makes things just a little bit easier. |
Aye, a common promise API/interface/spec is a first step to make that happen |
Loading the I will create a follow-up PR to implement nameserver detection for Windows. I've looked into reading this from While this works reasonably well, I still think that consumers will have to supply their own fallback if this "autodection" fails. In my opinion, this is best left up to higher level implementation such as reactphp/socket#90. |
We should look into reading the system's nameserver configuration rather than asking our users to hardcode their DNS settings.
Not to be confused with #10.
The text was updated successfully, but these errors were encountered: