Example #1
0
    def rpc_edit(self, node, data):
        """
        Implements inter-instance EDIT.

        Message data should be of the form
        { 
           'stream': 'stream_id',
           'from': ['uid', 'username'],
           'edit': '<span>Some DOM nodes to match and replace</span>'
        }   
        """
        data = base64.b64encode(json.dumps(data))
        key  = RSA.importKey(node.pubkey)
        data = key.encrypt(data, 32)
        dht.transmit(self.router, addr, {'rpc_edit': data})
Example #2
0
    def rpc_chat(self, nodeple, data):
        """
        Implements CHAT where we encrypt a message destined for the user with
        UID on the receiving node.

        Message data should be of the form
        { 
           'to': 'uid',
           'from': ['uid', 'username'],
           'type': Can be any of "message", "init", "close"
           'body': {'m':'content'}
        }
        """
        # Worth retaining this ping call for the routing information we get.
        node     = self.rpc_ping(nodeple)
        
        if node == None:
            return

        data     = base64.b64encode(json.dumps(data))
        key      = RSA.importKey(node.pubkey)
        data     = key.encrypt(data, 32)
        data     = base64.b64encode(data[0])
        response = dht.transmit(self.router, node, {'rpc_chat': data})
        dht.log(response, "debug")
        return response
Example #3
0
    def rpc_republish(self, node, data):
        """
        Please refer to SynchronyProtocol.republish_keys to see what's really going
        on here.
        
        The data argument here is a list that looks like this:
        [{'node': [[nodeple], 'pubkey'],'keys': {signature: key_data}}, ...]
        Where "key_data" is a b64encoded JSON dump of the return value for
        self.storage.get_entries_for(self.source_node).

        Peers save this message, as we remember when they send rpc_republish
        messages to us. We forward previous rpc_republish messages for peers
        we still have as a contact.
        """
        addr = self.get_address(node)
        data = {'rpc_republish': data}
        return dht.transmit(self.router, addr, data)
Example #4
0
    def rpc_add_friend(self, local_uid, addr):
        """
        addr is of the form "network_name/node_id/remote_user_id"
        Implements ADD_FRIEND where we find the node in addr and
        tell them a local user wants to add the remote UID as a friend.
        """
        if addr.count("/") != 2:
            return False, None
        network, node_id, remote_uid = addr.split("/")
        
        if network != self.router.network:
            return False, None

        node = dht.Node(long(node_id))
        nearest = self.router.find_neighbours(node)
        if len(nearest) == 0:
            dht.log("There are no neighbours to help us add users on %s as friends." % node_id)
            return False, None
        spider  = NodeSpider(self, node, nearest, self.ksize, self.router.alpha)
        nodes   = spider.find()

        if len(nodes) != 1:
            return False, None

        node    = nodes[0]

        # Sometimes spidering doesn't get us all the way there.
        # Check who we already know:
        if node.long_id != long(node_id):
            nodes = [n for n in self.router if n.long_id == long(node_id)]
            if len(nodes) != 1:
                return False, None
            node = nodes[0]

        dht.log(node_id, "debug")
        dht.log(node.long_id, "debug")

        dht.log("Found remote instance %s." % node)
        message = {"rpc_add_friend": {"from": local_uid, "to": remote_uid}}

        response = dht.transmit(self.router, node, message)
        if not isinstance(response, dict) or not "response" in response:
            return False, None

        return response['response'], node
Example #5
0
    def rpc_append(self, node, url_hash, content_hash):
        """
        Allows senders to tell peers they have the data for the hash of a path.
        Hash here is the hash made from the content the peer has stored.
        They're letting you know they have data that corresponds to the hash.
        {
         peers:       [],
         pubkey:      "",
         signature:   "",
         time:        1440064069.0,
         rpc_append:  {url_hash: content_hash},
        }
        """
        # Append this peer to the list of nodes storing data for this path
        # urls[data['url']].append(sender)
        addr = self.get_address(node)
        data = {"rpc_append": {url_hash: content_hash}}
#        if addr.threeple == self.source_node.threeple:
#            self.storage[url_hash] = (content_hash, addr)
        return dht.transmit(self.router, addr, data)
Example #6
0
    def rpc_ping(self, addr):
        # "addr" may be an (addr, port) tuple
        data = dht.transmit(self.router, addr, {"rpc_ping":True})
        # Remove peer
        if not data:
            if isinstance(addr, Node):
                self.router.remove_node(addr)
            return
        node = dht.Node(*data['node'], pubkey=data['pubkey'], router=self.router)
        self.router.add_contact(node)
        # FIXME: Ping nodes in the 'peers' part of the response.
        #        Don't let malicious nodes fill the routing table with
        #        information for peers who won't respond.
        if 'peers' in data:
            for peer in data['peers']:
                if peer['node'][0] == self.source_node.long_id:
                    continue
                peer = dht.Node(*peer['node'],
                            pubkey=peer['pubkey'],
                            router=self.router)
                self.router.add_contact(peer)
#                self.rpc_ping(node)
        return node
Example #7
0
 def rpc_find_value(self, node_to_ask, node_to_find):
     address = (node_to_ask.ip, node_to_ask.port)
     message = {'rpc_find_value': binascii.hexlify(node_to_find.id)}
     return dht.transmit(self.router, address, message)
Example #8
0
 def rpc_leaving(self, node):
     addr = self.get_address(node)
     return dht.transmit(self.router, addr, {"rpc_leaving":True})