def handle_add_friend(self, data): """ Match to UID and return a new Friend instance representing our side. """ assert "rpc_add_friend" in data dht.log(data, "debug") request = data['rpc_add_friend'] if not "from" in request or not "to" in request: return False node = self.read_envelope(data) user = User.query.filter(User.uid == request['to']).first() if not user: return None from_addr = "/".join([self.router.network, str(node.long_id), request['from']]) friend = Friend.query.filter( and_(Friend.address == from_addr, Friend.user == user) ).first() if friend: # This permits the remote side to see if they're added or blocked. return dht.envelope(self.router, {"response": friend.jsonify()}) node = dht.Node(*data['node']) network = Network.query.filter(Network.name == self.router.network).first() if network != None: network = Network(name = self.router.network) peer = Peer.query.filter( and_(Peer.network == network, Peer.ip == node.ip, Peer.port == node.port) ).first() if peer == None: peer = Peer() peer.load_node(node) peer.network = network friend = Friend(address=from_addr) friend.state = 1 friend.received = True # TODO: Make this correspond to the existing rpc_friend method. user.friends.append(friend) peer.friends.append(friend) db.session.add(user) db.session.add(peer) db.session.add(friend) db.session.add(network) db.session.commit() return dht.envelope(self.router, {"response": friend.jsonify()})
def handle_find_node(self, data): """ Used for finding existing nodes near to a target ID. """ source = self.read_envelope(data) if not 'key' in data: return "No target key specified.", 400 node = dht.Node(data['key']) dht.log("Finding neighbours of %s." % node.long_id) nodes = {'nodes': [p.jsonify() for p in \ self.router.find_neighbours(node, exclude=source)]} return dht.envelope(self.router, nodes)
def handle_find_value(self, data): source = self.read_envelope(data) if not source: return if not 'rpc_find_value' in data: return # usually comes in as unicode if not isinstance(data['rpc_find_value'], (unicode, str)): return key = data['rpc_find_value'] dht.log("Finding value for %s" % key) value = self.storage.get(key, None) if key is None: dht.log("No value found for %s" % key) return self.rpc_find_node(sender, nodeid, key) dht.log("Found %s" % value) return dht.envelope(self.router,{'value':value})
def mock_transmit(routes, addr, data): """ Put dht.RoutingTable instances through to one another without calling out to the network. """ # Test case setup method should set a peers attr on this function beforehand if not hasattr(mock_transmit, "peers"): dht.log("Can't find test peers.") dht.log("synchrony.test.utils.mock_transmit is missing a peers dictionary.") return if isinstance(addr, dht.Node): addr = (addr.ip, addr.port) # Filter for everyone who isn't the intended recipient peer_routes = filter( lambda r: r if r.node.port == addr[1] else None, [r for r in mock_transmit.peers.values()] ) if not peer_routes: dht.log("Unknown peer %s:%i" % addr) return peer_routes = peer_routes[0] data = dht.envelope(routes, data) for field in data.keys(): if field.startswith('rpc_'): rpc_name = 'handle_%s' % field.replace('rpc_', '') rpc_method = getattr(peer_routes.protocol, rpc_name, None) if not rpc_method: dht.log("%s tried to call unknown procedure %s." % \ (routes.node, rpc_name), "warning") return return rpc_method(data)
def handle_ping(self, data): node = self.read_envelope(data) dht.log("Received rpc_ping from %s." % node) return dht.envelope(self.router, {'ping':"pong"})
def rpc_find_node(self, node_to_ask, node_to_find): address = (node_to_ask.ip, node_to_ask.port) message = {'key': node_to_find.id} message = dht.envelope(self.router, message) return self.handle_find_node(message)