Example #1
0
	def post(self):
		"""
		Unserialise the data and accept the following calls:
		PING
		CHAT
		APPEND
		LEAVING
		FIND_NODE
		FIND_VALUE

		APPEND signifies the requesting host has data for the given hash.
		"""
		parser = restful.reqparse.RequestParser()
		parser.add_argument("data", type=str, help="The RPC body.", default=None)
		args = parser.parse_args()
		if not args.data:
			return {}, 400

		response = []
		data = json.loads(args.data)

		if not validate_signature(data):
			log("Received message from %s with an invalid signature." % request.remote_addr)
			return "Invalid message signature.", 400

		if not 'node' in data:
			log("%s didn't provide useable information about themselves." % request.remote_addr, "warning")
			return {}, 400

		# Validate the node field for internet hosts
		if not any([request.remote_addr.startswith(subnet) for subnet in local_subnets]):
			stated_addr = data['node'].split()[1]
			if stated_addr != request.remote_addr:
				log("Request made from %s stated it originated from %s" % (request.remote_addr, stated_addr), "warning")
				return "sicillian shrug", 418

		# Execute the corresponding RPC handler
		for field in data.keys():
			if field.startswith('rpc_'):
				rpc_name = 'handle_%s' % field.replace('rpc_', '')
#				data[rpc_name] = data[field]
#				del data[field]
				rpc_method = getattr(app.routes.protocol, rpc_name, None)
				if not rpc_method:
					log("%s tried to call unknown procedure %s." % (request.remote_addr, rpc_name), "warning")
					return {}, 400
				response = rpc_method(data)
				break

		return response
Example #2
0
		def store(responses):
			"""
			A closure for a dictionary of responses from ALPHA nodes containing
			peer information for neighbours close to a target key.

			These responses don't contain their own 'peers' field at the moment.
			"""
#			print pprint.pformat(responses)
			nodes = []
			for id, response in responses.items():
				valid_signature = utils.validate_signature(response)
				log("Received %s signature from %s." % \
					("valid" if valid_signature else "invalid", long(id.encode('hex'), 16)))
				if valid_signature:
					for data in response['nodes']:
						if not [data['node'][1],data['node'][2]] in [[n.ip, n.port] for n in nodes]:
							nodes.append(Node(*data['node'], pubkey=data['pubkey']))
			log("Telling %s we have %s." % (nodes, url))
			# Change self.storage_method when ready.
			threads = [gevent.spawn(self.storage_method, node, hexlify(hashed_url), content_hash) for node in nodes]
			gevent.joinall(threads)
			threads = [thread.value for thread in threads]
			log("%s: %s" % (self.storage_method.func_name, threads))