def handle_bank_relay(self, msg): """Send a message to the bank on behalf of someone else, then send the reply onward @param msg: the message to relay @type msg: str""" version, msg = Basic.read_byte(msg) assert version == 1, "only accepts version 1 of PAR protocol" responseHop, msg = Basic.read_byte(msg) bankMsg, msg = Basic.read_lenstr(msg) responseMsg, msg = Basic.read_lenstr(msg) payment = UDPPayment.UDPPayment(self.bank, bankMsg) paymentDeferred = payment.get_deferred() def success(response, responseMsg=responseMsg, responseHop=responseHop): responseMsg += response if responseHop != 0: self.send_direct_tor_message(responseMsg, "payment", True, responseHop) else: self.handle_payment(responseMsg) paymentDeferred.addCallback(success) def failure(error): if error and hasattr(error, "value") and issubclass( type(error.value), TimeoutError): #TODO: this indicates that the bank is down, or something is wrong with their network? log_msg("Relayed payment timed out :(", 0, "par") else: log_ex(error, "Relaying payment message failed!") paymentDeferred.addErrback(failure)
def handle_bank_relay(self, msg): """Send a message to the bank on behalf of someone else, then send the reply onward @param msg: the message to relay @type msg: str""" version, msg = Basic.read_byte(msg) assert version == 1, "only accepts version 1 of PAR protocol" responseHop, msg = Basic.read_byte(msg) bankMsg, msg = Basic.read_lenstr(msg) responseMsg, msg = Basic.read_lenstr(msg) payment = UDPPayment.UDPPayment(self.bank, bankMsg) paymentDeferred = payment.get_deferred() def success(response, responseMsg=responseMsg, responseHop=responseHop): responseMsg += response if responseHop != 0: self.send_direct_tor_message(responseMsg, "payment", True, responseHop) else: self.handle_payment(responseMsg) paymentDeferred.addCallback(success) def failure(error): if error and hasattr(error, "value") and issubclass(type(error.value), TimeoutError): #TODO: this indicates that the bank is down, or something is wrong with their network? log_msg("Relayed payment timed out :(", 0, "par") else: log_ex(error, "Relaying payment message failed!") paymentDeferred.addErrback(failure)
def handle_dht_request(self, data): log_msg("Got remote DHT request", 4, "dht") #unpack and validate the message: version, data = Basic.read_byte(data) assert version == Node.VERSION #read the infohash: vals, data = Basic.read_message("20s", data) infohash = vals[0] #read each peer: peers = set() while len(data) > 0: #what type of peer? (ip or url) peerType, data = Basic.read_byte(data) #IP peer: if peerType == 0: vals, data = Basic.read_message("!4sH", data) host = socket.inet_ntoa(vals[0]) port = vals[1] #URL peer: elif peerType == 1: host, data = Basic.read_lenstr(data) port, data = Basic.read_short(data) #bad peer type: else: raise Exception("Unknown peer address type: %s" % (peerType)) peers.add((host, port)) #note that there is a new transaction: transactionId = self.currentTransactionId self.responses[transactionId] = "" self.currentTransactionId += 1 #now add each peer: for host, port in peers: #make sure it's not one of our defaults #TODO: in the future, make sure we don't already know about it anyway? Eh, maybe that will break DHT somehow? if (host, port) not in Node.BOOTSTRAP_NODES: log_msg("Neat, someone told us about a new DHT node", 2) self.dhtNode.add_contact(host, port) #and then send out the request: def response(data, transactionId=transactionId): #is this the last message? if len(data) <= 0: #then send the response for this transaction: self._send_peers(transactionId) #otherwise, just accumulate the data for later: else: self.responses[transactionId] += "".join(data[0]) self.dhtNode.get_peers(infohash, response)