/** * Read and parse a DNS response message. * * This method assumes that the given request has been sent beforehand using the same transport. * * @param Request $request The request that caused the incoming response message. * @return Response Parsed and validated DNS response message. * * @throws ProtocolException When a malformed or invalid message is received. */ public function parse(Request $request) : \Generator { $response = new Response(yield from $this->transport->readShort()); $response->setFlags(yield from $this->transport->readShort()); if ($response->getId() !== $request->getId()) { throw new ProtocolException(\sprintf('Expected DNS message ID is %u, server returned %u', $request->getId(), $response->getId())); } $questionCount = (yield from $this->transport->readShort()); $answersCount = (yield from $this->transport->readShort()); $response->setAuthorityCount(yield from $this->transport->readShort()); $response->setAdditionalCount(yield from $this->transport->readShort()); // Parse questions: for ($i = 0; $i < $questionCount; $i++) { yield from $this->parseQuestion($response); } if ($response->getQuestions() !== $request->getQuestions()) { throw new ProtocolException('DNS server did not return the question(s) in the response message'); } // Parse answers: for ($i = 0; $i < $answersCount; $i++) { yield from $this->parseAnswer($response); } return $response; }