diff --git a/akka-remote/src/main/resources/reference.conf b/akka-remote/src/main/resources/reference.conf index 017b531faa..8ec036db0e 100644 --- a/akka-remote/src/main/resources/reference.conf +++ b/akka-remote/src/main/resources/reference.conf @@ -100,6 +100,10 @@ akka { # Default is 2552 (AKKA), use 0 if you want a random available port port = 2552 + # (O) The address of a local network interface (IP Address) to bind to when creating + # outbound connections. Set to "" or "auto" for automatic selection of local address. + outbound-local-address = "auto" + # (I&O) Increase this if you want to be able to send messages with large payloads message-frame-size = 1 MiB diff --git a/akka-remote/src/main/scala/akka/remote/netty/Client.scala b/akka-remote/src/main/scala/akka/remote/netty/Client.scala index eafd01d91a..a0e91398fc 100644 --- a/akka-remote/src/main/scala/akka/remote/netty/Client.scala +++ b/akka-remote/src/main/scala/akka/remote/netty/Client.scala @@ -157,12 +157,12 @@ class ActiveRemoteClient private[akka] ( openChannels = new DefaultDisposableChannelGroup(classOf[RemoteClient].getName) executionHandler = new ExecutionHandler(netty.executor) - val b = new ClientBootstrap(netty.clientChannelFactory) b.setPipelineFactory(new ActiveRemoteClientPipelineFactory(name, b, executionHandler, remoteAddress, localAddress, this)) b.setOption("tcpNoDelay", true) b.setOption("keepAlive", true) b.setOption("connectTimeoutMillis", settings.ConnectionTimeout.toMillis) + settings.OutboundLocalAddress.foreach(s ⇒ b.setOption("localAddress", new InetSocketAddress(s, 0))) bootstrap = b val remoteIP = InetAddress.getByName(remoteAddress.host.get) diff --git a/akka-remote/src/main/scala/akka/remote/netty/Settings.scala b/akka-remote/src/main/scala/akka/remote/netty/Settings.scala index daa91a3014..2bb441dc3c 100644 --- a/akka-remote/src/main/scala/akka/remote/netty/Settings.scala +++ b/akka-remote/src/main/scala/akka/remote/netty/Settings.scala @@ -40,6 +40,11 @@ class NettySettings(config: Config, val systemName: String) { case value ⇒ value } + val OutboundLocalAddress: Option[String] = getString("outbound-local-address") match { + case "auto" | "" | null ⇒ None + case some ⇒ Some(some) + } + @deprecated("WARNING: This should only be used by professionals.", "2.0") val PortSelector = getInt("port") diff --git a/akka-remote/src/test/scala/akka/remote/RemoteConfigSpec.scala b/akka-remote/src/test/scala/akka/remote/RemoteConfigSpec.scala index 3074e033d7..f1809d42a5 100644 --- a/akka-remote/src/test/scala/akka/remote/RemoteConfigSpec.scala +++ b/akka-remote/src/test/scala/akka/remote/RemoteConfigSpec.scala @@ -43,6 +43,7 @@ class RemoteConfigSpec extends AkkaSpec( UsePassiveConnections must be(true) Hostname must not be "" // will be set to the local IP PortSelector must be(0) + OutboundLocalAddress must be(None) MessageFrameSize must be(1048576) ConnectionTimeout must be(2 minutes) Backlog must be(4096)