Example #1
0
 /**
  * {@inheritdoc}
  */
 public function connect(string $domain, int $port = null, array $options = []) : \Generator
 {
     // Check if $domain is actually an IP address.
     if (preg_match(self::IP_REGEX, $domain)) {
         return yield from $this->connector->connect($domain, $port, $options);
     }
     $options = array_merge(['name' => $domain], $options);
     try {
         $ips = (yield from $this->resolver->resolve($domain, $options));
     } catch (DnsException $exception) {
         throw new FailureException(sprintf('Could not resolve host %s.', $domain), 0, $exception);
     }
     if (empty($ips)) {
         throw new FailureException(sprintf('Host for %s not found.', $domain));
     }
     foreach ($ips as $ip) {
         try {
             return yield from $this->connector->connect($ip, $port, $options);
         } catch (TimeoutException $exception) {
             // Connection timed out, try next IP address.
         } catch (FailureException $exception) {
             // Connection failed, try next IP address.
         }
     }
     throw new FailureException(sprintf('Could not connect to %s:%d.', $domain, $port), 0, $exception);
 }
Example #2
0
 /**
  * {@inheritdoc}
  */
 public function execute(string $name, $type, array $options = []) : \Generator
 {
     $timeout = isset($options['timeout']) ? (double) $options['timeout'] : self::DEFAULT_TIMEOUT;
     $retries = isset($options['retries']) ? (int) $options['retries'] : self::DEFAULT_RETRIES;
     if (0 > $retries) {
         $retries = 0;
     }
     $question = $this->createQuestion($name, $type);
     $request = $this->createRequest($question);
     $data = $this->encoder->encode($request);
     /** @var \Icicle\Socket\Socket $socket */
     $socket = (yield from $this->connector->connect($this->address, $this->port, ['protocol' => self::PROTOCOL]));
     try {
         $attempt = 0;
         do {
             try {
                 yield from $socket->write($data);
                 $response = (yield from $socket->read(self::MAX_PACKET_SIZE, null, $timeout));
                 try {
                     $response = $this->decoder->decode($response);
                 } catch (\Exception $exception) {
                     throw new FailureException($exception);
                     // Wrap in more specific exception.
                 }
                 if (0 !== $response->getResponseCode()) {
                     throw new ResponseCodeException($response);
                 }
                 if ($response->getId() !== $request->getId()) {
                     throw new ResponseIdException($response);
                 }
                 return $response;
             } catch (TimeoutException $exception) {
                 // Ignore timeout and try the request again.
             }
         } while (++$attempt <= $retries);
         throw new NoResponseException('No response from server.');
     } finally {
         $socket->close();
     }
 }