Comments (11)
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,
Macfly
from dns.
Thanks for posting this @marty-macfly, but unfortunately your code relies on $record = gethostbyname($query->name);
which makes the whole thing blocking.
This ticket likely requires us to do the following:
- Find the path to the configuration (resolv.conf vs Windows?)
- Find a way to load this file without blocking (filesystem component?)
- Parse the contents and then instantiate as usual
- Work out a proper user-facing API so you usually don't have to care about any of this
from dns.
I just landed here while trying to research how you guys do it on Windows. Windows stores that information in the registry unfortunately. :-(
from dns.
we could use reactphp/child-process
to launch reg query
like amphp/windows-registry
does.
from dns.
If you build an adapter you could just use that library instead of just recreating it.
from dns.
@kelunik good point, this is basically a use case for reactphp/promise#78
from dns.
No, async interoperability doesn't matter for a specific case. A common event loop does.
from dns.
@kelunik I see both things as somewhat related ;)
from dns.
They are, but a common loop makes things work, a common promise API makes things just a little bit easier.
from dns.
Aye, a common promise API/interface/spec is a first step to make that happen
from dns.
Loading the resolv.conf
is implemented in #92. This file is present on most systems and will very likely cover the 90% use case (it is not present on Windows systems).
I will create a follow-up PR to implement nameserver detection for Windows. I've looked into reading this from nslookup
(works, but blocks when network is not available), ipconfig /all
(difficult to parse due to localization), registry (non-trivial implementation) and wmic
(which I ended up using).
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.
from dns.
Related Issues (20)
- Support extended DNS (EDNS0)
- PHP Fatal error: Maximum function nesting level of '256' reached, aborting! Protocol/Parser.php on line 293 HOT 14
- DNS Cache is not used when the type of the response record is CNAME HOT 3
- Gate way issue Discord HOT 1
- Roadmap to stable v1.0.0 HOT 4
- Ask host OS for DNS service address at startup, if none given by caller HOT 3
- getting ttl value HOT 1
- querying for SOA but got CNAME instead of empty answer or error HOT 2
- Connection to DNS server lost HOT 1
- Support DNS search domain list (resolve local hostname to FQDN) HOT 3
- Question: I like the pure PHP DNS client. Can I use it without the $loop in a non-PHP react project? HOT 1
- Exceptions constantly thrown in debugger HOT 12
- Test failure because f integer overflow on 32-bit system HOT 1
- Question using protocol classes directly HOT 4
- Mark current version as stable / memory limit exceeded HOT 1
- How to use reactdns in a waiting (sync) mode? HOT 3
- How to store data in array when doing resolveAll()? HOT 2
- Failure modes HOT 8
- Consider supporting "Special-Use Domain Names" (.localhost, .invalid etc.) HOT 1
- Consider supporting advanced DNS config (nsswitch,conf, hosts.conf, resolv.conf options and ENV variables etc.) HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dns.