Example #1
0
 def merge_node_table(self, src: RsaKey, table: bfcp_pb2.NodeTable):
     src_key = pubkey_to_deterministic_string(src)
     if src_key not in self._wait_update_nodes:
         # probably an error/malicious
         return
     self._wait_update_nodes.remove(src)
     for entry in table.entries:
         node_key = pubkey_to_deterministic_string(get_node_pub_key(entry))
         if node_key in self._nodes:
             update_trust_score(self._nodes[node_key],
                                self._nodes[src_key].trust_score,
                                entry.trust_score)
         else:
             self._nodes[node_key] = entry
             self._nodes[node_key].new_trust_score(
                 self._nodes[src].trust_score, entry.trust_score)
Example #2
0
 def _parse_initial_node_table(initial_node_table: bfcp_pb2.NodeTable)\
         -> Dict[bytes, bfcp_pb2.NodeTableEntry]:
     result = RandomDict()
     for entry in initial_node_table.entries:
         pub_key = proto_to_pubkey(entry.node.public_key)
         result[pubkey_to_deterministic_string(pub_key)] = entry
     return result
Example #3
0
 async def update_node_table(self):
     self._last_update_timestamp = time()
     # TODO config this
     for i in range(10):
         node = self.get_random_node()
         await self._bfc.traffic_manager.send(bfcp_pb2.DiscoveryRequest(),
                                              get_node_pub_key(node))
         self._wait_update_nodes.add(
             pubkey_to_deterministic_string(get_node_pub_key(node)))
Example #4
0
    def get_random_node(self) -> bfcp_pb2.NodeTableEntry:
        """
        Get a random node for sending stuffs.
        :raises ValueError if there is no node.
        :return: a random node.
        """
        own_pub_key_index = pubkey_to_deterministic_string(self._bfc.rsa_key)
        if own_pub_key_index in self._nodes:
            del self._nodes[own_pub_key_index]

        if len(self._nodes) == 0:
            raise ValueError("No node in the trust table.")
        return self._nodes.random_value()
Example #5
0
    async def send(self,
                   msg: BouncyMessage,
                   pub_key: Optional[RsaKey] = None) -> None:
        """
        Sends the provided BouncyMessage to the node in the network identified by the given public
        key. It's also possible to send a message to the node itself.
        """
        msg = self._wrap_into_bouncy_message(msg)

        if pub_key is None:
            pub_key = get_node_pub_key(
                self._bfc.trust_table_manager.get_random_node())

        pub_key_index = pubkey_to_deterministic_string(pub_key)
        send_to = None
        if pub_key_index in self._open_client_sockets:
            send_to = self._open_client_sockets[pub_key_index]
        elif pub_key_index in self._open_server_sockets:
            send_to = self._open_server_sockets[pub_key_index]
        else:
            # We need to form a new connection
            node = self._bfc.trust_table_manager.get_node_by_pubkey(pub_key)
            if node is None:
                raise NodeNotFoundError(
                    'A node with the provided public key does not exist in the '
                    'trust table')

            reader, writer = await asyncio.open_connection(
                node.node.last_known_address,
                node.node.last_port,
                loop=self._async_loop)

            _log.debug('New client connection on %s. Logged by %s',
                       writer.get_extra_info('peername'),
                       str(self._serving_host))

            send_to = await self._open_new_socket_handler(reader, writer)
            self._register_client_socket_handler(send_to)
            self._open_client_sockets[pub_key_index] = send_to

        _log.debug(
            'Sending message: %s\nTo: %s\nLogged by: %s\nThread: %d', str(msg),
            str(
                self._bfc.trust_table_manager.get_node_by_pubkey(
                    send_to.get_peer_key())),
            str(self._bfc._self_node.last_port), threading.get_ident())
        await send_to.send_bouncy_message(msg)
Example #6
0
 def get_node_by_pubkey(
         self, pub_key: RsaKey) -> Optional[bfcp_pb2.NodeTableEntry]:
     """
     Returns a NodeTableEntry with the pub key, else return None
     """
     return self._nodes.get(pubkey_to_deterministic_string(pub_key), None)
Example #7
0
 def _register_client_socket_handler(self,
                                     socket_handler: BfcpSocketHandler):
     pub_key_index = pubkey_to_deterministic_string(
         socket_handler.get_peer_key())
     self._open_client_sockets[pub_key_index] = socket_handler