package org.apache.solr.cloud;

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */


import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * To use, tests must be able to run iptables, eg sudo chmod u+s iptables
 */
public class IpTables {
  static final Logger log = LoggerFactory
      .getLogger(IpTables.class);
  
  private static boolean ENABLED = Boolean.getBoolean("solr.tests.use.iptables");
  
  private static Set<Integer> BLOCK_PORTS = Collections.synchronizedSet(new HashSet<Integer>());
  
  public static void blockPort(int port) throws IOException,
      InterruptedException {
    if (ENABLED) {
      log.info("Block port with iptables: " + port);
      BLOCK_PORTS.add(port);
      runCmd(("iptables -A INPUT -p tcp --dport " + port + " -j DROP")
          .split("\\s"));
      runCmd(("iptables -A OUTPUT -p tcp --dport " + port + " -j DROP")
          .split("\\s"));
    }
  }
  
  public static void unblockPort(int port) throws IOException,
      InterruptedException {
    if (ENABLED) {
      log.info("Unblock port with iptables: " + port);
      runCmd(("iptables -D INPUT -p tcp --dport " + port + " -j DROP")
          .split("\\s"));
      runCmd(("iptables -D OUTPUT -p tcp --dport " + port + " -j DROP")
          .split("\\s"));
    }
  }
  
  public static void unblockAllPorts() throws IOException, InterruptedException {
    if (ENABLED) {
      log.info("Unblocking any ports previously blocked with iptables...");
      for (Integer port : BLOCK_PORTS) {
        IpTables.unblockPort(port);
      }
    }
  }
  
  private static void runCmd(String... cmd) throws IOException, InterruptedException {
    final int exitCode = new ProcessBuilder(cmd).inheritIO().start().waitFor();
    if (exitCode != 0) {
      throw new IOException("iptables process did not exit successfully, exit code was: " + exitCode);
    }
  }
}

@@ -1141,23 +1141,16 @@
 rFactory
-%0A      
 .getLogg
@@ -1189,16 +1189,22 @@
  static 
+final 
 boolean 
@@ -1280,16 +1280,22 @@
  static 
+final 
 Set%3CInte
@@ -1421,38 +1421,32 @@
 ows IOException,
-%0A     
  InterruptedExce
@@ -1824,22 +1824,16 @@
 ception,
-%0A     
  Interru
@@ -1855,32 +1855,62 @@
 %0A    if (ENABLED
+ && BLOCK_PORTS.contains(port)
 ) %7B%0A      log.in
@@ -2139,32 +2139,64 @@
 .split(%22%5C%5Cs%22));%0A
+      BLOCK_PORTS.remove(port);%0A
     %7D%0A  %7D%0A  %0A  p
@@ -2380,26 +2380,30 @@
    f
-or (
+inal 
 Integer
+%5B%5D
  port
- :
+s =
  BLO
@@ -2410,16 +2410,90 @@
 CK_PORTS
+.toArray(new Integer%5BBLOCK_PORTS.size()%5D);%0A      for (Integer port : ports
 ) %7B%0A    

Fix iptables helper (was broken because of more strict error checking, sorry!). I tested it on my linux box, works fine!