in actor/src/main/scala/org/apache/pekko/io/dns/internal/DnsClient.scala [94:195]
def ready(socket: ActorRef): Receive = {
case DropRequest(msg) =>
inflightRequests.get(msg.id).foreach {
case (_, orig) if Seq(msg.name) == orig.questions.map(_.name) =>
log.debug("Dropping request [{}]", msg.id)
inflightRequests -= msg.id
case (_, orig) =>
log.warning("Cannot drop inflight DNS request the question [{}] does not match [{}]",
msg.name,
orig.questions.map(_.name).mkString(","))
}
case Question4(id, name) =>
log.debug("Resolving [{}] (A)", name)
val msg = message(name, id, RecordType.A)
newInflightRequests(msg, sender()) {
log.debug("Message [{}] to [{}]: [{}]", id, ns, msg)
socket ! Udp.Send(msg.write(), ns)
}
case Question6(id, name) =>
log.debug("Resolving [{}] (AAAA)", name)
val msg = message(name, id, RecordType.AAAA)
newInflightRequests(msg, sender()) {
log.debug("Message [{}] to [{}]: [{}]", id, ns, msg)
socket ! Udp.Send(msg.write(), ns)
}
case SrvQuestion(id, name) =>
log.debug("Resolving [{}] (SRV)", name)
val msg = message(name, id, RecordType.SRV)
newInflightRequests(msg, sender()) {
log.debug("Message [{}] to [{}]: [{}]", id, ns, msg)
socket ! Udp.Send(msg.write(), ns)
}
case Udp.CommandFailed(cmd) =>
log.debug("Command failed [{}]", cmd)
cmd match {
case send: Udp.Send =>
// best effort, don't throw
Try {
val msg = Message.parse(send.payload)
inflightRequests.get(msg.id).foreach {
case (s, orig) if isSameQuestion(msg.questions, orig.questions) =>
s ! Failure(new RuntimeException("Send failed to nameserver"))
inflightRequests -= msg.id
case (_, orig) =>
log.warning("Cannot command failed question [{}] does not match [{}]",
msg.questions.mkString(","),
orig.questions.mkString(","))
}
}
case _ =>
log.warning("Dns client failed to send {}", cmd)
}
case Udp.Received(data, remote) =>
log.debug("Received message from [{}]: [{}]", remote, data)
val msg = Message.parse(data)
log.debug("Decoded UDP DNS response [{}]", msg)
if (msg.flags.isTruncated) {
log.debug("DNS response truncated, falling back to TCP")
inflightRequests.get(msg.id) match {
case Some((_, msg)) =>
tcpDnsClient ! msg
case _ =>
log.debug("Client for id {} not found. Discarding unsuccessful response.", msg.id)
}
} else {
inflightRequests.get(msg.id) match {
case Some((_, orig)) if !isSameQuestion(msg.questions, orig.questions) =>
log.warning(
"Unexpected DNS response id {} question [{}] does not match question asked [{}]",
msg.id,
msg.questions.mkString(","),
orig.questions.mkString(","))
case Some((_, _)) =>
if (log.isDebugEnabled) {
log.debug("DNS response id {} has response code {}: question [{}]",
msg.id,
msg.flags.responseCode,
msg.questions.mkString(","))
}
val (recs, additionalRecs) =
if (msg.flags.responseCode == ResponseCode.SUCCESS) (msg.answerRecs, msg.additionalRecs) else (Nil, Nil)
self ! Answer(msg.id, recs, additionalRecs)
case None =>
log.warning("Unexpected DNS response invalid id {}", msg.id)
}
}
case response: Answer =>
inflightRequests.get(response.id) match {
case Some((reply, _)) =>
reply ! response
inflightRequests -= response.id
case None =>
log.debug("Client for id {} not found. Discarding response.", response.id)
}
case Udp.Unbind => socket ! Udp.Unbind
case Udp.Unbound => context.stop(self)
}