=dns #25451 resolve raw IP addresses in async-dns
This commit is contained in:
parent
36224f924b
commit
fd59579790
2 changed files with 39 additions and 5 deletions
|
|
@ -90,7 +90,9 @@ class AsyncDnsResolverIntegrationSpec extends AkkaSpec(
|
||||||
implicit val timeout = Timeout(duration)
|
implicit val timeout = Timeout(duration)
|
||||||
|
|
||||||
"Resolver" must {
|
"Resolver" must {
|
||||||
pending
|
|
||||||
|
pending // PENDING since needs `bind` server to be running to test end-to-end
|
||||||
|
|
||||||
"resolve single A record" in {
|
"resolve single A record" in {
|
||||||
val name = "a-single.akka.test"
|
val name = "a-single.akka.test"
|
||||||
val answer = resolve(name, DnsProtocol.Ip(ipv6 = false))
|
val answer = resolve(name, DnsProtocol.Ip(ipv6 = false))
|
||||||
|
|
@ -181,6 +183,23 @@ class AsyncDnsResolverIntegrationSpec extends AkkaSpec(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"not hang when resolving raw IP address" in {
|
||||||
|
val name = "127.0.0.1"
|
||||||
|
val answer = resolve(name)
|
||||||
|
answer.name shouldEqual name
|
||||||
|
answer.results.collect { case r: ARecord ⇒ r }.toSet shouldEqual Set(
|
||||||
|
ARecord("127.0.0.1", Int.MaxValue, InetAddress.getByName("127.0.0.1"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
"not hang when resolving raw IPv6 address" in {
|
||||||
|
val name = "1:2:3:0:0:0:0:0"
|
||||||
|
val answer = resolve(name)
|
||||||
|
answer.name shouldEqual name
|
||||||
|
answer.results.collect { case r: ARecord ⇒ r }.toSet shouldEqual Set(
|
||||||
|
ARecord("1:2:3:0:0:0:0:0", Int.MaxValue, InetAddress.getByName("1:2:3:0:0:0:0:0"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
"resolve same address twice" in {
|
"resolve same address twice" in {
|
||||||
resolve("a-single.akka.test").results.map(_.asInstanceOf[ARecord].ip) shouldEqual Seq(InetAddress.getByName("192.168.1.20"))
|
resolve("a-single.akka.test").results.map(_.asInstanceOf[ARecord].ip) shouldEqual Seq(InetAddress.getByName("192.168.1.20"))
|
||||||
resolve("a-single.akka.test").results.map(_.asInstanceOf[ARecord].ip) shouldEqual Seq(InetAddress.getByName("192.168.1.20"))
|
resolve("a-single.akka.test").results.map(_.asInstanceOf[ARecord].ip) shouldEqual Seq(InetAddress.getByName("192.168.1.20"))
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,14 @@
|
||||||
|
|
||||||
package akka.io.dns.internal
|
package akka.io.dns.internal
|
||||||
|
|
||||||
import java.net.InetSocketAddress
|
import java.net.{ InetAddress, InetSocketAddress }
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
|
||||||
import akka.actor.{ Actor, ActorLogging, ActorRef, ActorRefFactory, Props }
|
import akka.actor.{ Actor, ActorLogging, ActorRef, ActorRefFactory, Props }
|
||||||
import akka.annotation.InternalApi
|
import akka.annotation.InternalApi
|
||||||
import akka.io.dns.DnsProtocol.{ Ip, RequestType, Srv }
|
import akka.io.dns.DnsProtocol.{ Ip, RequestType, Srv }
|
||||||
import akka.io.dns.internal.DnsClient._
|
import akka.io.dns.internal.DnsClient._
|
||||||
import akka.io.dns.{ DnsProtocol, DnsSettings, ResourceRecord }
|
import akka.io.dns.{ ARecord, DnsProtocol, DnsSettings, ResourceRecord }
|
||||||
import akka.pattern.{ ask, pipe }
|
import akka.pattern.{ ask, pipe }
|
||||||
import akka.util.{ Helpers, Timeout }
|
import akka.util.{ Helpers, Timeout }
|
||||||
|
|
||||||
|
|
@ -49,7 +50,8 @@ private[io] final class AsyncDnsResolver(
|
||||||
|
|
||||||
override def receive: Receive = {
|
override def receive: Receive = {
|
||||||
case DnsProtocol.Resolve(name, _) if isInetAddress(name) ⇒
|
case DnsProtocol.Resolve(name, _) if isInetAddress(name) ⇒
|
||||||
log.warning("Tried to resolve ip [{}]. Ignoring.", name)
|
log.warning("Tried to resolve ip [{}], assuming resolved.", name)
|
||||||
|
alreadyResolvedIp(name) pipeTo sender()
|
||||||
case DnsProtocol.Resolve(name, mode) ⇒
|
case DnsProtocol.Resolve(name, mode) ⇒
|
||||||
resolve(name, mode, resolvers) pipeTo sender()
|
resolve(name, mode, resolvers) pipeTo sender()
|
||||||
}
|
}
|
||||||
|
|
@ -66,6 +68,18 @@ private[io] final class AsyncDnsResolver(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def alreadyResolvedIp(knownToBeIp: String): Future[DnsProtocol.Resolved] = {
|
||||||
|
if (isInetAddress(knownToBeIp))
|
||||||
|
Future {
|
||||||
|
val address = InetAddress.getByName(knownToBeIp) // only checks validity, since known to be IP address
|
||||||
|
val record = ARecord(knownToBeIp, Int.MaxValue, address)
|
||||||
|
DnsProtocol.Resolved(knownToBeIp, record :: Nil)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Future.failed(new IllegalArgumentException("Attempted to emit Resolved for known-to-be IP address, " +
|
||||||
|
s"yet argument was not an IP address, was: ${knownToBeIp}"))
|
||||||
|
}
|
||||||
|
|
||||||
private def sendQuestion(resolver: ActorRef, message: DnsQuestion): Future[Seq[ResourceRecord]] = {
|
private def sendQuestion(resolver: ActorRef, message: DnsQuestion): Future[Seq[ResourceRecord]] = {
|
||||||
val result = (resolver ? message).mapTo[Answer].map(_.rrs)
|
val result = (resolver ? message).mapTo[Answer].map(_.rrs)
|
||||||
result.onFailure {
|
result.onFailure {
|
||||||
|
|
@ -142,7 +156,8 @@ private[io] object AsyncDnsResolver {
|
||||||
"""^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$""".r
|
"""^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$""".r
|
||||||
|
|
||||||
private def isInetAddress(name: String): Boolean =
|
private def isInetAddress(name: String): Boolean =
|
||||||
ipv4Address.findAllMatchIn(name).nonEmpty || ipv6Address.findAllMatchIn(name).nonEmpty
|
ipv4Address.findAllMatchIn(name).nonEmpty ||
|
||||||
|
ipv6Address.findAllMatchIn(name).nonEmpty
|
||||||
|
|
||||||
private val Empty = Future.successful(immutable.Seq.empty[ResourceRecord])
|
private val Empty = Future.successful(immutable.Seq.empty[ResourceRecord])
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue