From 8a4d976815fadfe85a233c28b405659fd882b5d1 Mon Sep 17 00:00:00 2001 From: Javier Puerto Date: Thu, 23 Feb 2017 14:33:10 +0100 Subject: [PATCH 1/2] Select right IP address based on Java preferences. (#22336) * Change priority of DNS resolved addresses based on java.net.preferIPv6Addresses property. #22330 * Include test specs for IPv6 resolver selection. #22330 * Use Java system properties to retrieve the IPv6 preference. #22330 (cherry picked from commit 6406c0ed95bf295b27bbb0e7e8e228f5979a1336) --- .../src/test/scala/akka/io/DnsSpec.scala | 38 +++++++++++++++++++ akka-actor/src/main/scala/akka/io/Dns.scala | 10 ++++- 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 akka-actor-tests/src/test/scala/akka/io/DnsSpec.scala diff --git a/akka-actor-tests/src/test/scala/akka/io/DnsSpec.scala b/akka-actor-tests/src/test/scala/akka/io/DnsSpec.scala new file mode 100644 index 0000000000..6796719506 --- /dev/null +++ b/akka-actor-tests/src/test/scala/akka/io/DnsSpec.scala @@ -0,0 +1,38 @@ +package akka.io + +import java.net.{ Inet4Address, Inet6Address, InetAddress } + +import scala.collection.immutable.Seq +import org.scalatest.{ BeforeAndAfterAll, Matchers, WordSpec } + +class DnsSpec extends WordSpec with BeforeAndAfterAll with Matchers { + + val ip4Address = InetAddress.getByAddress("localhost", Array[Byte](127, 0, 0, 1)) match { + case address: Inet4Address ⇒ address + } + val ipv6Address = InetAddress.getByAddress("localhost", Array[Byte](0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)) match { + case address: Inet6Address ⇒ address + } + + var temporaryValue: Option[String] = None + + override def beforeAll() = { + temporaryValue = sys.props.get("java.net.preferIPv6Addresses") + } + + override def afterAll() = temporaryValue match { + case Some(value) ⇒ sys.props.put("java.net.preferIPv6Addresses", value) + case _ ⇒ sys.props.remove("java.net.preferIPv6Addresses") + } + + "Dns" should { + "resolve to a IPv6 address if it is the preferred network stack" in { + sys.props.put("java.net.preferIPv6Addresses", true.toString) + Dns.Resolved("test", Seq(ip4Address), Seq(ipv6Address)).addr should ===(ipv6Address) + } + "resolve to a IPv4 address if IPv6 is not the preferred network stack" in { + sys.props.remove("java.net.preferIPv6Addresses") + Dns.Resolved("test", Seq(ip4Address), Seq(ipv6Address)).addr should ===(ip4Address) + } + } +} diff --git a/akka-actor/src/main/scala/akka/io/Dns.scala b/akka-actor/src/main/scala/akka/io/Dns.scala index fb621334e4..1c7d0c67f7 100644 --- a/akka-actor/src/main/scala/akka/io/Dns.scala +++ b/akka-actor/src/main/scala/akka/io/Dns.scala @@ -26,7 +26,7 @@ object Dns extends ExtensionId[DnsExt] with ExtensionIdProvider { } case class Resolved(name: String, ipv4: immutable.Seq[Inet4Address], ipv6: immutable.Seq[Inet6Address]) extends Command { - val addrOption: Option[InetAddress] = ipv4.headOption orElse ipv6.headOption + val addrOption: Option[InetAddress] = IpVersionSelector.getInetAddress(ipv4.headOption, ipv6.headOption) @throws[UnknownHostException] def addr: InetAddress = addrOption match { @@ -89,3 +89,11 @@ class DnsExt(system: ExtendedActorSystem) extends IO.Extension { def getResolver: ActorRef = manager } + +object IpVersionSelector { + def getInetAddress(ipv4: Option[Inet4Address], ipv6: Option[Inet6Address]): Option[InetAddress] = + System.getProperty("java.net.preferIPv6Addresses") match { + case "true" ⇒ ipv6 orElse ipv4 + case _ ⇒ ipv4 orElse ipv6 + } +} \ No newline at end of file From 35f951d0e498a03f7ccf22b800ae1cb680ac0354 Mon Sep 17 00:00:00 2001 From: Patrik Nordwall Date: Thu, 23 Feb 2017 14:49:04 +0100 Subject: [PATCH 2/2] Move DnsSpec to multi-jvm test, #22330 * run in separate jvm to avoid issues with parallel test execution when modifying global System.properties (cherry picked from commit 1586afe79be568e3815d62d2fb0179a8a017d568) --- .../src/test/scala/akka/io/DnsSpec.scala | 38 ------------- .../src/multi-jvm/scala/akka/io/DnsSpec.scala | 56 +++++++++++++++++++ 2 files changed, 56 insertions(+), 38 deletions(-) delete mode 100644 akka-actor-tests/src/test/scala/akka/io/DnsSpec.scala create mode 100644 akka-remote-tests/src/multi-jvm/scala/akka/io/DnsSpec.scala diff --git a/akka-actor-tests/src/test/scala/akka/io/DnsSpec.scala b/akka-actor-tests/src/test/scala/akka/io/DnsSpec.scala deleted file mode 100644 index 6796719506..0000000000 --- a/akka-actor-tests/src/test/scala/akka/io/DnsSpec.scala +++ /dev/null @@ -1,38 +0,0 @@ -package akka.io - -import java.net.{ Inet4Address, Inet6Address, InetAddress } - -import scala.collection.immutable.Seq -import org.scalatest.{ BeforeAndAfterAll, Matchers, WordSpec } - -class DnsSpec extends WordSpec with BeforeAndAfterAll with Matchers { - - val ip4Address = InetAddress.getByAddress("localhost", Array[Byte](127, 0, 0, 1)) match { - case address: Inet4Address ⇒ address - } - val ipv6Address = InetAddress.getByAddress("localhost", Array[Byte](0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)) match { - case address: Inet6Address ⇒ address - } - - var temporaryValue: Option[String] = None - - override def beforeAll() = { - temporaryValue = sys.props.get("java.net.preferIPv6Addresses") - } - - override def afterAll() = temporaryValue match { - case Some(value) ⇒ sys.props.put("java.net.preferIPv6Addresses", value) - case _ ⇒ sys.props.remove("java.net.preferIPv6Addresses") - } - - "Dns" should { - "resolve to a IPv6 address if it is the preferred network stack" in { - sys.props.put("java.net.preferIPv6Addresses", true.toString) - Dns.Resolved("test", Seq(ip4Address), Seq(ipv6Address)).addr should ===(ipv6Address) - } - "resolve to a IPv4 address if IPv6 is not the preferred network stack" in { - sys.props.remove("java.net.preferIPv6Addresses") - Dns.Resolved("test", Seq(ip4Address), Seq(ipv6Address)).addr should ===(ip4Address) - } - } -} diff --git a/akka-remote-tests/src/multi-jvm/scala/akka/io/DnsSpec.scala b/akka-remote-tests/src/multi-jvm/scala/akka/io/DnsSpec.scala new file mode 100644 index 0000000000..2ca5b64d14 --- /dev/null +++ b/akka-remote-tests/src/multi-jvm/scala/akka/io/DnsSpec.scala @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2017 Lightbend Inc. + */ +package akka.io + +import java.net.Inet4Address +import java.net.Inet6Address +import java.net.InetAddress +import akka.remote.RemotingMultiNodeSpec +import akka.remote.testkit.MultiNodeConfig + +object DnsSpec extends MultiNodeConfig { + val first = role("first") +} + +class DnsSpecMultiJvmNode1 extends DnsSpec + +// This is a multi-jvm tests because it is modifying global System.properties +class DnsSpec extends RemotingMultiNodeSpec(DnsSpec) { + + def initialParticipants = roles.size + + val ip4Address = InetAddress.getByAddress("localhost", Array[Byte](127, 0, 0, 1)) match { + case address: Inet4Address ⇒ address + } + val ipv6Address = InetAddress.getByAddress("localhost", Array[Byte](0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)) match { + case address: Inet6Address ⇒ address + } + + var temporaryValue: Option[String] = None + + override def atStartup(): Unit = { + temporaryValue = sys.props.get("java.net.preferIPv6Addresses") + } + + override def afterTermination(): Unit = { + temporaryValue match { + case Some(value) ⇒ sys.props.put("java.net.preferIPv6Addresses", value) + case _ ⇒ sys.props.remove("java.net.preferIPv6Addresses") + } + } + + "Dns" must { + + "resolve to a IPv6 address if it is the preferred network stack" in { + sys.props.put("java.net.preferIPv6Addresses", true.toString) + Dns.Resolved("test", List(ip4Address), List(ipv6Address)).addr should ===(ipv6Address) + } + "resolve to a IPv4 address if IPv6 is not the preferred network stack" in { + sys.props.remove("java.net.preferIPv6Addresses") + Dns.Resolved("test", List(ip4Address), List(ipv6Address)).addr should ===(ip4Address) + } + + } + +}