From d448602cb2a81e2eb7e24dcca5c490c77a7877d2 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Sun, 6 Sep 2015 23:06:05 +0200 Subject: [PATCH] Making daemon to listen only loopback interface and to work without active ip interface --- .../rmi/kotlinr/KotlinCompilerClient.kt | 3 +- .../kotlinr/RemoteIncrementalCacheServer.kt | 6 ++- .../rmi/kotlinr/RemoteOutputStreamServer.kt | 6 ++- .../kotlin/rmi/LoopbackSocketFactory.kt | 53 +++++++++++++++++++ .../kotlin/rmi/service/CompileDaemon.kt | 6 ++- .../kotlin/rmi/service/CompileServiceImpl.kt | 5 +- 6 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/LoopbackSocketFactory.kt diff --git a/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/KotlinCompilerClient.kt b/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/KotlinCompilerClient.kt index 8ab5998f3f9..0fc7f4f5282 100644 --- a/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/KotlinCompilerClient.kt +++ b/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/KotlinCompilerClient.kt @@ -44,6 +44,7 @@ public data class DaemonReportMessage(public val category: DaemonReportCategory, public class DaemonReportingTargets(public val out: PrintStream? = null, public val messages: MutableCollection? = null) + public class KotlinCompilerClient { companion object { @@ -85,7 +86,7 @@ public class KotlinCompilerClient { private fun tryConnectToDaemon(port: Int, reportingTargets: DaemonReportingTargets): CompileService? { try { - val daemon = LocateRegistry.getRegistry("localhost", port) + val daemon = LocateRegistry.getRegistry(loopbackAddrName, port) ?.lookup(COMPILER_SERVICE_RMI_NAME) if (daemon != null) return daemon as? CompileService ?: diff --git a/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteIncrementalCacheServer.kt b/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteIncrementalCacheServer.kt index eea9346850a..53fa674b419 100644 --- a/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteIncrementalCacheServer.kt +++ b/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteIncrementalCacheServer.kt @@ -18,13 +18,15 @@ package org.jetbrains.kotlin.rmi.kotlinr import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache import org.jetbrains.kotlin.rmi.CompileService +import org.jetbrains.kotlin.rmi.clientLoopbackSocketFactory +import org.jetbrains.kotlin.rmi.serverLoopbackSocketFactory import java.rmi.server.UnicastRemoteObject -public class RemoteIncrementalCacheServer(val cache: IncrementalCache) : CompileService.RemoteIncrementalCache { +public class RemoteIncrementalCacheServer(val cache: IncrementalCache, port: Int = 0) : CompileService.RemoteIncrementalCache { init { - UnicastRemoteObject.exportObject(this, 0) + UnicastRemoteObject.exportObject(this, port, clientLoopbackSocketFactory, serverLoopbackSocketFactory) } override fun getObsoletePackageParts(): Collection = cache.getObsoletePackageParts() diff --git a/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteOutputStreamServer.kt b/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteOutputStreamServer.kt index 4b67c389486..19dd8c136ee 100644 --- a/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteOutputStreamServer.kt +++ b/compiler/rmi/kotlinr/src/org/jetbrains/kotlin/rmi/kotlinr/RemoteOutputStreamServer.kt @@ -17,14 +17,16 @@ package org.jetbrains.kotlin.rmi.kotlinr import org.jetbrains.kotlin.rmi.RemoteOutputStream +import org.jetbrains.kotlin.rmi.clientLoopbackSocketFactory +import org.jetbrains.kotlin.rmi.serverLoopbackSocketFactory import java.io.OutputStream import java.rmi.server.UnicastRemoteObject -class RemoteOutputStreamServer(val out: OutputStream) : RemoteOutputStream { +class RemoteOutputStreamServer(val out: OutputStream, port: Int = 0) : RemoteOutputStream { init { - UnicastRemoteObject.exportObject(this, 0) + UnicastRemoteObject.exportObject(this, port, clientLoopbackSocketFactory, serverLoopbackSocketFactory) } public fun disconnect() { diff --git a/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/LoopbackSocketFactory.kt b/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/LoopbackSocketFactory.kt new file mode 100644 index 00000000000..791826b38be --- /dev/null +++ b/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/LoopbackSocketFactory.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.rmi + +import java.io.IOException +import java.io.Serializable +import java.net.InetAddress +import java.net.ServerSocket +import java.net.Socket +import java.rmi.server.RMIClientSocketFactory +import java.rmi.server.RMIServerSocketFactory + + +// TODO switch to InetAddress.getLoopbackAddress on java 7+ +val loopbackAddrName = if (java.net.InetAddress.getLocalHost() is java.net.Inet6Address) "::1" else "127.0.0.1" +val loopbackAddr by lazy { InetAddress.getByName(loopbackAddrName) } +val serverLoopbackSocketFactory by lazy { ServerLoopbackSocketFactory() } +val clientLoopbackSocketFactory by lazy { ClientLoopbackSocketFactory() } + +data class ServerLoopbackSocketFactory : RMIServerSocketFactory, Serializable { + + throws(IOException::class) + override fun createServerSocket(port: Int): ServerSocket { + return ServerSocket(port, 5, loopbackAddr) + } +} + + +data class ClientLoopbackSocketFactory : RMIClientSocketFactory, Serializable { + + throws(IOException::class) + override fun createSocket(host: String, port: Int): Socket { + return Socket(loopbackAddr, port) + // just call the default client socket factory +// return RMISocketFactory.getDefaultSocketFactory().createSocket(host, port) + } +} + + diff --git a/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileDaemon.kt b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileDaemon.kt index 15ccf7a8491..cc4484de19a 100644 --- a/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileDaemon.kt +++ b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileDaemon.kt @@ -114,6 +114,7 @@ public class CompileDaemon { log.info("starting daemon") // TODO: find minimal set of permissions and restore security management + // note: may be not needed anymore since (hopefully) server is now loopback-only // if (System.getSecurityManager() == null) // System.setSecurityManager (RMISecurityManager()) // @@ -132,7 +133,7 @@ public class CompileDaemon { runFile.deleteOnExit() val compiler = K2JVMCompiler() - val compilerService = CompileServiceImpl(registry, compiler, compilerId, daemonOptions) + val compilerService = CompileServiceImpl(registry, compiler, compilerId, daemonOptions, port) if (daemonOptions.runFilesPath.isNotEmpty()) println(daemonOptions.runFilesPath) @@ -189,10 +190,11 @@ public class CompileDaemon { private fun createRegistry(attempts: Int) : Pair { var i = 0 var lastException: RemoteException? = null + while (i++ < attempts) { val port = random.nextInt(COMPILE_DAEMON_PORTS_RANGE_END - COMPILE_DAEMON_PORTS_RANGE_START) + COMPILE_DAEMON_PORTS_RANGE_START try { - return Pair(LocateRegistry.createRegistry(port), port) + return Pair(LocateRegistry.createRegistry(port, clientLoopbackSocketFactory, serverLoopbackSocketFactory), port) } catch (e: RemoteException) { // assuming that the port is already taken diff --git a/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileServiceImpl.kt b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileServiceImpl.kt index a97bfb9af22..71854ea71f3 100644 --- a/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileServiceImpl.kt +++ b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileServiceImpl.kt @@ -47,7 +47,8 @@ class CompileServiceImpl>( val registry: Registry, val compiler: Compiler, val selfCompilerId: CompilerId, - val daemonOptions: DaemonOptions + val daemonOptions: DaemonOptions, + port: Int ) : CompileService, UnicastRemoteObject() { // RMI-exposed API @@ -123,7 +124,7 @@ class CompileServiceImpl>( // ignoring if object already exported } - val stub = UnicastRemoteObject.exportObject(this, 0) as CompileService + val stub = UnicastRemoteObject.exportObject(this, port, clientLoopbackSocketFactory, serverLoopbackSocketFactory) as CompileService registry.rebind (COMPILER_SERVICE_RMI_NAME, stub); alive = true }