def _drop_packets_between(self, src_node_id, dst_node_id, drop_rate_percentage=100):
        """ Drop all packets send between src_node_id and dst_node_id with probability drop_rate_percentage """
        if self.comm_type == bft_config.COMM_TYPE_TCP_TLS:
            # Get source and destination ports from already initialized self.connections
            (src_port, dst_port) = self.connections[(src_node_id, dst_node_id)]
        else:
            # Source and destination ports are well-known ports
            src_port = bft_config.bft_msg_port_from_node_id(src_node_id)
            dst_port = bft_config.bft_msg_port_from_node_id(dst_node_id)
            pass

        self._drop_packets_between_ports(src_port, dst_port, drop_rate_percentage)
示例#2
0
    def setUpClass(cls):
        cls.origdir = os.getcwd()
        cls.testdir = tempfile.mkdtemp()
        cls.builddir = os.path.abspath("../../build")
        cls.toolsdir = os.path.join(cls.builddir, "tools")
        cls.serverbin = os.path.join(cls.builddir,"tests/simpleTest/server")
        os.chdir(cls.testdir)
        cls.generateKeys()
        cls.config = bft_config.Config(4, 1, 0, 4096, 1000, 50, "")
        cls.replicas = [bft_config.Replica(id=i,
                                           ip="127.0.0.1",
                                           port=bft_config.bft_msg_port_from_node_id(i),
                                           metrics_port=bft_config.metrics_port_from_node_id(i))
                        for i in range(0,4)]

        print("Running tests in {}".format(cls.testdir))
        cls.startServers()
示例#3
0
 def __init__(self, config, replicas, background_nursery, ro_replicas=[]):
     super().__init__(config, replicas, ro_replicas)
     self.sock = trio.socket.socket(trio.socket.AF_INET,
                                    trio.socket.SOCK_DGRAM)
     self.port = bft_msg_port_from_node_id(self.client_id)
    def _build_port_connectivity_matrix(self, time_to_wait_sec=5.0, time_between_retries=0.25):
        """
        Used only in TCP communication.
        Build a connectivity matrix self.connections, a dictionary which maps a pair src_node_id, dest_node_id
        into a matching source_port and dest_port.
        Having this data structure allows to translate "block communication between node id X and node it Y" very easily
        onto the underlaying ports.
        Since module cannot know if all replicas started or no, it retries the discovery in a loop, with
        time_between_retries seconds between retries. It fails after time_to_wait_sec seconds (This should never happen)
        """
        assert isinstance(time_to_wait_sec, float) and isinstance(time_between_retries, float)
        wait_until_time = time.time() + time_to_wait_sec
        server_msg_ports = [bft_config.bft_msg_port_from_node_id(i) for i in self.bft_network.all_replicas()]
        all_connections_established = False
        num_replicas = self.bft_network.config.n
        # Rules to calculate num_expected_connections:
        # 1) Each client/replica connect to all other replicas with lower ID. Hence, replica 0 does not connect to
        # anyone.
        # 2) Each active client connects to all other replicas.
        # 3) Clients do not connect to each other.
        # 4) Each connection is bi-directional (hence 2 lines in output.
        # 5) Each connection is uni-directional for our purpose.
        # So between replicas we get 2 * (0 + 1 + 2... + N-1) = N * (N -1) connections, where N is the number of
        # replicas and for the clients <-> replicas we get 2 * N * num_clients connections
        num_expected_connections = num_replicas * (num_replicas - 1) + (len(self.all_client_ids) * num_replicas * 2)
        while time.time() < wait_until_time:
            try:
                # Use 'netstat -tpun' and grep on server known ports, to get all established TCP connection details
                netstat_output = subprocess.run(['netstat', '-tpun'],
                                                check=True, universal_newlines=True,
                                                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                # stringify the grep command regex
                grep_format = "127.0.0.1:%d .* ESTABLISHED "
                grep_str = ""
                grep_reg_or = "\\|"
                for i in range(len(server_msg_ports)):
                    grep_str += (grep_format % server_msg_ports[i]) + grep_reg_or
                grep_str = grep_str[:len(grep_str) - len(grep_reg_or)]
                grep_output = subprocess.run(['grep', grep_str],
                                             check=True, universal_newlines=True, input=netstat_output.stdout,
                                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                netstat_lines = grep_output.stdout.splitlines()
                if len(netstat_lines) == num_expected_connections:
                    # Success, all expected data is parsed, break.
                    all_connections_established = True
                    break
                else:
                    # Failure, connections are not yet fully established, need to retry
                    time.sleep(time_between_retries)
                    continue
            except subprocess.CalledProcessError:
                # Failure, connections are not yet fully established, need to retry
                time.sleep(time_between_retries)
                continue

        assert all_connections_established, "Failed to build port connectivity matrix using netstat!"

        # Here we pars the data we got from grep_output
        for line in netstat_lines:
            tokens = list(filter(None, split(' |:|/', line)))
            src_port = int(tokens[4])
            dst_port = int(tokens[6])
            src_proc_id = int(tokens[8])
            assert (src_port in server_msg_ports) ^ (dst_port in server_msg_ports)

            src_node_id = self._port_to_node_id(src_port, dst_port, src_proc_id)
            dst_node_id = self._port_to_node_id(dst_port, src_port)

            self.connections[(src_node_id, dst_node_id)] = (src_port, dst_port)
        assert len(self.connections) == num_expected_connections