public function resolve($hostname, $cb, $noncache = false, $nameServers = [])
{
if (!$this->preloading->hasCompleted()) {
$pool = $this;
$this->preloading->addListener(function ($job) use($hostname, $cb, $noncache, $pool, $nameServers) {
$pool->resolve($hostname, $cb, $noncache, $nameServers);
});
return;
}
$hostname = rtrim($hostname, '.') . '.';
if (isset($this->hosts[$hostname])) {
$cb($this->hosts[$hostname]);
return;
}
if (!$noncache && ($item = $this->resolveCache->get($hostname))) {
// cache hit
$ip = $item->getValue();
if ($ip === null) {
// operation in progress
$item->addListener($cb);
} else {
// hit
$cb($ip);
}
return;
} elseif (!$noncache) {
$item = $this->resolveCache->put($hostname, null);
$item->addListener($cb);
}
$pool = $this;
$this->get($hostname, function ($response) use($cb, $noncache, $hostname, $pool) {
if (!isset($response['A'])) {
if ($noncache) {
$cb(false);
} else {
$pool->resolveCache->put($hostname, false, 5);
// 5 - TTL of unsuccessful request
}
return;
}
if (!isset($response['A']) && !isset($response['AAAA'])) {
$cb(false);
return;
}
$addrs = [];
$ttl = 0;
if (isset($response['A'])) {
foreach ($response['A'] as $r) {
$addrs[] = $r['ip'];
$ttl = $r['ttl'];
}
}
if (isset($response['AAAA'])) {
foreach ($response['AAAA'] as $r) {
$addrs[] = $r['ip'];
$ttl = $r['ttl'];
}
}
if (sizeof($addrs) === 1) {
$addrs = $addrs[0];
}
if ($noncache) {
$cb($addrs);
} else {
$pool->resolveCache->put($hostname, $addrs, $ttl);
}
}, $noncache, $nameServers);
}