diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2015-10-12 21:59:34 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2015-10-13 23:04:48 +0200 |
commit | b69d37dd79c204256d793896d08871d0a9966057 (patch) | |
tree | 9f51104f9fb9cde699551ad648c4e124d1cf3258 /server/sonar-process/src/main/java/org/sonar/process | |
parent | 472b20d3f8742bea0fddf4d28cc6fbdaeae2d11f (diff) | |
download | sonarqube-b69d37dd79c204256d793896d08871d0a9966057.tar.gz sonarqube-b69d37dd79c204256d793896d08871d0a9966057.zip |
Fix reliability of NetworkUtils#freePort()
Diffstat (limited to 'server/sonar-process/src/main/java/org/sonar/process')
-rw-r--r-- | server/sonar-process/src/main/java/org/sonar/process/NetworkUtils.java | 63 |
1 files changed, 44 insertions, 19 deletions
diff --git a/server/sonar-process/src/main/java/org/sonar/process/NetworkUtils.java b/server/sonar-process/src/main/java/org/sonar/process/NetworkUtils.java index 5dd5813917f..6e5e567ec9d 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/NetworkUtils.java +++ b/server/sonar-process/src/main/java/org/sonar/process/NetworkUtils.java @@ -19,34 +19,59 @@ */ package org.sonar.process; -import org.apache.commons.io.IOUtils; - import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.ArrayUtils; -public class NetworkUtils { +public final class NetworkUtils { + + private static final RandomPortFinder RANDOM_PORT_FINDER = new RandomPortFinder(); private NetworkUtils() { - // only static stuff + // only statics } - /** - * Get an unused port - */ public static int freePort() { - ServerSocket socket = null; - try { - socket = new ServerSocket(); - socket.setReuseAddress(true); - socket.bind(new InetSocketAddress("localhost", 0)); - return socket.getLocalPort(); - - } catch (IOException e) { - throw new IllegalStateException("Can not find a free network port", e); - - } finally { - IOUtils.closeQuietly(socket); + return RANDOM_PORT_FINDER.getNextAvailablePort(); + } + + static class RandomPortFinder { + private static final int MAX_TRY = 10; + // Firefox blocks some reserved ports : http://www-archive.mozilla.org/projects/netlib/PortBanning.html + private static final int[] BLOCKED_PORTS = {2049, 4045, 6000}; + + public int getNextAvailablePort() { + for (int i = 0; i < MAX_TRY; i++) { + try { + int port = getRandomUnusedPort(); + if (isValidPort(port)) { + return port; + } + } catch (Exception e) { + throw new IllegalStateException("Can't find an open network port", e); + } + } + + throw new IllegalStateException("Can't find an open network port"); + } + + public int getRandomUnusedPort() throws IOException { + ServerSocket socket = null; + try { + socket = new ServerSocket(); + socket.bind(new InetSocketAddress("localhost", 0)); + return socket.getLocalPort(); + } catch (IOException e) { + throw new IllegalStateException("Can not find a free network port", e); + } finally { + IOUtils.closeQuietly(socket); + } + } + + public static boolean isValidPort(int port) { + return port > 1023 && !ArrayUtils.contains(BLOCKED_PORTS, port); } } } |