diff --git a/akka-actor-tests/src/test/scala/akka/io/dns/internal/AsyncDnsManagerSpec.scala b/akka-actor-tests/src/test/scala/akka/io/dns/internal/AsyncDnsManagerSpec.scala index 030e2e0608..7ac54d74b0 100644 --- a/akka-actor-tests/src/test/scala/akka/io/dns/internal/AsyncDnsManagerSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/io/dns/internal/AsyncDnsManagerSpec.scala @@ -4,9 +4,12 @@ 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.{ AAAARecord, ResourceRecord } +import akka.io.dns.DnsProtocol.{ Resolve, Resolved } import akka.testkit.{ AkkaSpec, ImplicitSender } 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) 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) + } } } diff --git a/akka-actor-tests/src/test/scala/akka/io/dns/internal/AsyncDnsResolverSpec.scala b/akka-actor-tests/src/test/scala/akka/io/dns/internal/AsyncDnsResolverSpec.scala index e305f2ddcf..687e53f494 100644 --- a/akka-actor-tests/src/test/scala/akka/io/dns/internal/AsyncDnsResolverSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/io/dns/internal/AsyncDnsResolverSpec.scala @@ -114,9 +114,7 @@ class AsyncDnsResolverSpec extends AkkaSpec( r ! Resolve(name) dnsClient1.expectNoMessage(50.millis) val answer = expectMsgType[Resolved] - answer.records.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")) - ) + val Seq(AAAARecord("1:2:3:0:0:0:0:0", Int.MaxValue, _)) = answer.records.collect { case r: AAAARecord ⇒ r } } "return additional records for SRV requests" in { diff --git a/akka-actor/src/main/scala/akka/io/dns/internal/AsyncDnsManager.scala b/akka-actor/src/main/scala/akka/io/dns/internal/AsyncDnsManager.scala index 21b8fd64f1..f51168bf4b 100644 --- a/akka-actor/src/main/scala/akka/io/dns/internal/AsyncDnsManager.scala +++ b/akka-actor/src/main/scala/akka/io/dns/internal/AsyncDnsManager.scala @@ -10,7 +10,7 @@ import java.util.concurrent.TimeUnit import akka.actor.{ Actor, ActorLogging, ActorRefFactory, Deploy, Props, Timers } import akka.annotation.InternalApi 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, DnsExt, PeriodicCacheCleanup } import akka.routing.FromConfig @@ -74,7 +74,10 @@ private[io] final class AsyncDnsManager(val ext: DnsExt) extends Actor val adapted = DnsProtocol.Resolve(name) val reply = (resolver ? adapted).mapTo[DnsProtocol.Resolved] .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) } reply pipeTo sender diff --git a/akka-actor/src/main/scala/akka/io/dns/internal/AsyncDnsResolver.scala b/akka-actor/src/main/scala/akka/io/dns/internal/AsyncDnsResolver.scala index 8dd845a6b2..74266a6803 100644 --- a/akka-actor/src/main/scala/akka/io/dns/internal/AsyncDnsResolver.scala +++ b/akka-actor/src/main/scala/akka/io/dns/internal/AsyncDnsResolver.scala @@ -4,14 +4,14 @@ package akka.io.dns.internal -import java.net.{ InetAddress, InetSocketAddress } +import java.net.{ Inet4Address, Inet6Address, InetAddress, InetSocketAddress } import java.nio.charset.StandardCharsets import akka.actor.{ Actor, ActorLogging, ActorRef, ActorRefFactory, Props } import akka.annotation.InternalApi import akka.io.dns.DnsProtocol.{ Ip, RequestType, Srv } 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.util.{ Helpers, Timeout } @@ -59,7 +59,10 @@ private[io] final class AsyncDnsResolver( Future.fromTry { Try { 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) } }