Support IPv6 in async-dns (#25687)

* Support IPv6 in async-dns

* Expect AAAA records for IPv6
This commit is contained in:
Arnout Engelen 2018-09-28 07:41:07 +02:00 committed by Christopher Batey
parent 6464dea52b
commit 9a54ae92d5
4 changed files with 28 additions and 9 deletions

View file

@ -4,9 +4,12 @@
package akka.io.dns.internal package akka.io.dns.internal
import java.net.InetAddress import java.net.{ Inet6Address, InetAddress }
import scala.collection.immutable.Seq
import akka.io.Dns import akka.io.Dns
import akka.io.dns.{ AAAARecord, ResourceRecord }
import akka.io.dns.DnsProtocol.{ Resolve, Resolved }
import akka.testkit.{ AkkaSpec, ImplicitSender } import akka.testkit.{ AkkaSpec, ImplicitSender }
class AsyncDnsManagerSpec extends AkkaSpec( class AsyncDnsManagerSpec extends AkkaSpec(
@ -24,6 +27,18 @@ class AsyncDnsManagerSpec extends AkkaSpec(
val oldProtocolReply = akka.io.Dns.Resolved("127.0.0.1", InetAddress.getByName("127.0.0.1") :: Nil) val oldProtocolReply = akka.io.Dns.Resolved("127.0.0.1", InetAddress.getByName("127.0.0.1") :: Nil)
expectMsg(oldProtocolReply) expectMsg(oldProtocolReply)
} }
"support ipv6" in {
dns ! Resolve("::1") // ::1 will short circuit the resolution
val Resolved("::1", Seq(AAAARecord("::1", Int.MaxValue, _)), Nil) = expectMsgType[Resolved]
}
"support ipv6 also using the old protocol" in {
dns ! akka.io.Dns.Resolve("::1") // ::1 will short circuit the resolution
val resolved = expectMsgType[akka.io.Dns.Resolved]
resolved.ipv4 should be(Nil)
resolved.ipv6.length should be(1)
}
} }
} }

View file

@ -114,9 +114,7 @@ class AsyncDnsResolverSpec extends AkkaSpec(
r ! Resolve(name) r ! Resolve(name)
dnsClient1.expectNoMessage(50.millis) dnsClient1.expectNoMessage(50.millis)
val answer = expectMsgType[Resolved] val answer = expectMsgType[Resolved]
answer.records.collect { case r: ARecord r }.toSet shouldEqual Set( val Seq(AAAARecord("1:2:3:0:0:0:0:0", Int.MaxValue, _)) = answer.records.collect { case r: AAAARecord r }
ARecord("1:2:3:0:0:0:0:0", Int.MaxValue, InetAddress.getByName("1:2:3:0:0:0:0:0"))
)
} }
"return additional records for SRV requests" in { "return additional records for SRV requests" in {

View file

@ -10,7 +10,7 @@ import java.util.concurrent.TimeUnit
import akka.actor.{ Actor, ActorLogging, ActorRefFactory, Deploy, Props, Timers } import akka.actor.{ Actor, ActorLogging, ActorRefFactory, Deploy, Props, Timers }
import akka.annotation.InternalApi import akka.annotation.InternalApi
import akka.dispatch.{ RequiresMessageQueue, UnboundedMessageQueueSemantics } import akka.dispatch.{ RequiresMessageQueue, UnboundedMessageQueueSemantics }
import akka.io.dns.{ ARecord, DnsProtocol, DnsSettings } import akka.io.dns.{ AAAARecord, ARecord, DnsProtocol, DnsSettings }
import akka.io.dns.internal.AsyncDnsManager.CacheCleanup import akka.io.dns.internal.AsyncDnsManager.CacheCleanup
import akka.io.{ Dns, DnsExt, PeriodicCacheCleanup } import akka.io.{ Dns, DnsExt, PeriodicCacheCleanup }
import akka.routing.FromConfig import akka.routing.FromConfig
@ -74,7 +74,10 @@ private[io] final class AsyncDnsManager(val ext: DnsExt) extends Actor
val adapted = DnsProtocol.Resolve(name) val adapted = DnsProtocol.Resolve(name)
val reply = (resolver ? adapted).mapTo[DnsProtocol.Resolved] val reply = (resolver ? adapted).mapTo[DnsProtocol.Resolved]
.map { asyncResolved .map { asyncResolved
val ips = asyncResolved.records.collect { case a: ARecord a.ip } val ips = asyncResolved.records.collect {
case a: ARecord a.ip
case a: AAAARecord a.ip
}
Dns.Resolved(asyncResolved.name, ips) Dns.Resolved(asyncResolved.name, ips)
} }
reply pipeTo sender reply pipeTo sender

View file

@ -4,14 +4,14 @@
package akka.io.dns.internal package akka.io.dns.internal
import java.net.{ InetAddress, InetSocketAddress } import java.net.{ Inet4Address, Inet6Address, InetAddress, InetSocketAddress }
import java.nio.charset.StandardCharsets 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.{ ARecord, DnsProtocol, DnsSettings, ResourceRecord } import akka.io.dns.{ AAAARecord, ARecord, DnsProtocol, DnsSettings, ResourceRecord }
import akka.pattern.{ ask, pipe } import akka.pattern.{ ask, pipe }
import akka.util.{ Helpers, Timeout } import akka.util.{ Helpers, Timeout }
@ -59,7 +59,10 @@ private[io] final class AsyncDnsResolver(
Future.fromTry { Future.fromTry {
Try { Try {
val address = InetAddress.getByName(name) // only checks validity, since known to be IP address val address = InetAddress.getByName(name) // only checks validity, since known to be IP address
val record = ARecord(name, Int.MaxValue, address) val record = address match {
case _: Inet4Address ARecord(name, Int.MaxValue, address)
case ipv6address: Inet6Address AAAARecord(name, Int.MaxValue, ipv6address)
}
DnsProtocol.Resolved(name, record :: Nil) DnsProtocol.Resolved(name, record :: Nil)
} }
} }