def func(node, *args): msgID = sha1(str(random.getrandbits(255))).digest() m = Message() m.messageID = msgID m.sender.MergeFrom(self.sourceNode.getProto()) m.command = Command.Value(name.upper()) m.protoVer = PROTOCOL_VERSION for arg in args: m.arguments.append(str(arg)) m.testnet = self.multiplexer.testnet data = m.SerializeToString() address = (node.ip, node.port) relay_addr = None if node.nat_type == SYMMETRIC or \ (node.nat_type == RESTRICTED and self.sourceNode.nat_type == SYMMETRIC): relay_addr = node.relay_node d = defer.Deferred() if m.command != HOLE_PUNCH: timeout = reactor.callLater(self._waitTimeout, self.timeout, node) self._outstanding[msgID] = [d, address, timeout] self.log.debug("calling remote function %s on %s (msgid %s)" % (name, address, b64encode(msgID))) self.multiplexer.send_message(data, address, relay_addr) if self.multiplexer[address].state != State.CONNECTED and \ node.nat_type == RESTRICTED and \ self.sourceNode.nat_type != SYMMETRIC: self.hole_punch(Node(digest("null"), node.relay_node[0], node.relay_node[1], nat_type=FULL_CONE), address[0], address[1], "True") self.log.debug("sending hole punch message to %s" % address[0] + ":" + str(address[1])) return d
def receive_message(self, datagram, connection): m = Message() try: m.ParseFromString(datagram) sender = node.Node(m.sender.guid, m.sender.ip, m.sender.port, m.sender.signedPublicKey, m.sender.vendor) except Exception: # If message isn't formatted property then ignore self.log.warning("Received unknown message from %s, ignoring" % str(connection.dest_addr)) return False # Check that the GUID is valid. If not, ignore if self.router.isNewNode(sender): try: pubkey = m.sender.signedPublicKey[len(m.sender.signedPublicKey) - 32:] verify_key = nacl.signing.VerifyKey(pubkey) verify_key.verify(m.sender.signedPublicKey) h = nacl.hash.sha512(m.sender.signedPublicKey) pow_hash = h[64:128] if int(pow_hash[:6], 16) >= 50 or hexlify(m.sender.guid) != h[:40]: raise Exception('Invalid GUID') except Exception: self.log.warning("Received message from sender with invalid GUID, ignoring") return False if m.sender.vendor: VendorStore().save_vendor(m.sender.guid, m.sender.ip, m.sender.port, m.sender.signedPublicKey) msgID = m.messageID data = tuple(m.arguments) if msgID in self._outstanding: self._acceptResponse(msgID, data, sender) else: self._acceptRequest(msgID, str(Command.Name(m.command)).lower(), data, sender, connection)
def func(address, *args): msgID = sha1(str(random.getrandbits(255))).digest() d = defer.Deferred() if name != "hole_punch": seed = SEED_NODE_TESTNET if self.multiplexer.testnet else SEED_NODE if address in self.multiplexer and self.multiplexer[address].state == State.CONNECTED: timeout = timeout = reactor.callLater(self._waitTimeout, self.timeout, address) else: timeout = reactor.callLater(self._waitTimeout, self.hole_punch, seed, address[0], address[1], "True", msgID) self._outstanding[msgID] = [d, address, timeout] self.log.debug("calling remote function %s on %s (msgid %s)" % (name, address, b64encode(msgID))) elif args[3] in self._outstanding: prev_msgID = args[3] args = args[:3] deferred, addr, hp = self._outstanding[prev_msgID] # pylint: disable=W0612 timeout = reactor.callLater(3, self.timeout, addr) self._outstanding[prev_msgID] = [deferred, addr, timeout] self.log.debug("sending hole punch message to %s" % args[0] + ":" + str(args[1])) m = Message() m.messageID = msgID m.sender.MergeFrom(self.sourceNode.getProto()) m.command = Command.Value(name.upper()) m.protoVer = PROTOCOL_VERSION for arg in args: m.arguments.append(str(arg)) m.testnet = self.multiplexer.testnet data = m.SerializeToString() self.multiplexer.send_message(data, address) return d
def receive_message(self, datagram): if len(datagram) < 166: self.log.warning( "received datagram too small from %s, ignoring" % self.addr) return False try: m = Message() m.ParseFromString(datagram) self.node = Node( m.sender.guid, m.sender.nodeAddress.ip, m.sender.nodeAddress.port, m.sender.publicKey, None if not m.sender.HasField("relayAddress") else (m.sender.relayAddress.ip, m.sender.relayAddress.port), m.sender.natType, m.sender.vendor) self.remote_node_version = m.protoVer if self.time_last_message == 0: h = nacl.hash.sha512(m.sender.publicKey) pow_hash = h[40:] if int(pow_hash[:6], 16) >= 50 or m.sender.guid.encode("hex") != h[:40]: raise Exception('Invalid GUID') for processor in self.processors: if m.command in processor or m.command == NOT_FOUND: processor.receive_message(m, self.node, self.connection, self.ban_score) if m.command != PING: self.time_last_message = time.time() except Exception: # If message isn't formatted property then ignore self.log.warning( "received an invalid message from %s, ignoring" % self.addr) return False
def receive_message(self, datagram): if len(datagram) < 166: self.log.warning("received datagram too small from %s, ignoring" % self.addr) return False m = Message() try: m.ParseFromString(datagram) self.node = Node(m.sender.guid, m.sender.nodeAddress.ip, m.sender.nodeAddress.port, m.sender.publicKey, None if not m.sender.HasField("relayAddress") else (m.sender.relayAddress.ip, m.sender.relayAddress.port), m.sender.natType, m.sender.vendor) pubkey = m.sender.publicKey verify_key = nacl.signing.VerifyKey(pubkey) signature = m.signature m.ClearField("signature") verify_key.verify(m.SerializeToString(), signature) h = nacl.hash.sha512(m.sender.publicKey) pow_hash = h[40:] if int(pow_hash[:6], 16) >= 50 or m.sender.guid.encode("hex") != h[:40]: raise Exception('Invalid GUID') except Exception: # If message isn't formatted property then ignore self.log.warning("received an invalid message from %s, ignoring" % self.addr) return False for processor in self.processors: if m.command in processor or m.command == NOT_FOUND: processor.receive_message(m, self.node, self.connection, self.ban_score)
def _sendResponse(self, response, funcname, msgID, sender, connection): if self.noisy: self.log.debug("Sending response for msg id %s to %s" % (b64encode(msgID), sender)) m = Message() m.messageID = msgID m.sender.MergeFrom(self.proto) m.command = Command.Value(funcname.upper()) for arg in response: m.arguments.append(str(arg)) data = m.SerializeToString() connection.send_message(data)
def func(address, *args): msgID = sha1(str(random.getrandbits(255))).digest() m = Message() m.messageID = msgID m.sender.MergeFrom(self.proto) m.command = Command.Value(name.upper()) for arg in args: m.arguments.append(arg) data = m.SerializeToString() if self.noisy: self.log.msg("calling remote function %s on %s (msgid %s)" % (name, address, b64encode(msgID))) self.multiplexer.send_message(data, address) d = defer.Deferred() timeout = reactor.callLater(self._waitTimeout, self._timeout, msgID) self._outstanding[msgID] = (d, timeout) return d
def func(address, *args): msgID = sha1(str(random.getrandbits(255))).digest() m = Message() m.messageID = msgID m.sender.MergeFrom(self.proto) m.command = Command.Value(name.upper()) m.protoVer = PROTOCOL_VERSION for arg in args: m.arguments.append(str(arg)) m.testnet = self.multiplexer.testnet data = m.SerializeToString() d = defer.Deferred() self._outstanding[msgID] = [d, address] self.multiplexer.send_message(data, address) self.log.debug("calling remote function %s on %s (msgid %s)" % (name, address, b64encode(msgID))) return d
def receive_message(self, datagram): if len(datagram) < 166: self.log.warning( "received datagram too small from %s, ignoring" % str(self.connection.dest_addr)) return False m = Message() try: m.ParseFromString(datagram) for processor in self.processors: if m.command in processor: processor.receive_message(datagram, self.connection) except Exception: # If message isn't formatted property then ignore self.log.warning("Received unknown message from %s, ignoring" % str(self.connection.dest_addr)) return False
def func(address, *args): msgID = sha1(str(random.getrandbits(255))).digest() m = Message() m.messageID = msgID m.sender.MergeFrom(self.proto) m.command = Command.Value(name.upper()) for arg in args: m.arguments.append(str(arg)) data = m.SerializeToString() if self.noisy: self.log.debug("calling remote function %s on %s (msgid %s)" % (name, address, b64encode(msgID))) self.multiplexer.send_message(data, address) if name is not "hole_punch": d = defer.Deferred() timeout = reactor.callLater(self._waitTimeout, self._timeout, msgID, address) self._outstanding[msgID] = [d, timeout] return d
def _sendResponse(self, response, funcname, msgID, sender, connection): self.log.debug("sending response for msg id %s to %s" % (b64encode(msgID), sender)) m = Message() m.messageID = msgID m.sender.MergeFrom(self.sourceNode.getProto()) m.protoVer = PROTOCOL_VERSION m.testnet = self.multiplexer.testnet if response is None: m.command = NOT_FOUND else: m.command = Command.Value(funcname.upper()) if not isinstance(response, list): response = [response] for arg in response: m.arguments.append(str(arg)) m.signature = self.signing_key.sign(m.SerializeToString())[:64] connection.send_message(m.SerializeToString())
def func(address, *args): msgID = sha1(str(random.getrandbits(255))).digest() m = Message() m.messageID = msgID m.sender.MergeFrom(self.sourceNode.getProto()) m.command = Command.Value(name.upper()) m.protoVer = PROTOCOL_VERSION for arg in args: m.arguments.append(str(arg)) m.testnet = self.multiplexer.testnet data = m.SerializeToString() d = defer.Deferred() if name != "hole_punch": seed = SEED_NODE_TESTNET if self.multiplexer.testnet else SEED_NODE hole_punch = reactor.callLater(3, self.hole_punch, seed, address[0], address[1], "True") if address in self.multiplexer: hole_punch.cancel() self._outstanding[msgID] = [d, address, hole_punch] self.log.debug("calling remote function %s on %s (msgid %s)" % (name, address, b64encode(msgID))) else: self.log.debug("sending hole punch message to %s" % args[0] + ":" + str(args[1])) self.multiplexer.send_message(data, address) return d
def receive_message(self, datagram): if len(datagram) < 166: self.log.warning( "received datagram too small from %s, ignoring" % self.addr) return False m = Message() try: m.ParseFromString(datagram) self.node = Node(m.sender.guid, m.sender.ip, m.sender.port, m.sender.signedPublicKey, m.sender.vendor) for processor in self.processors: if m.command in processor or m.command == NOT_FOUND: processor.receive_message(datagram, self.connection) except Exception: # If message isn't formatted property then ignore self.log.warning("received unknown message from %s, ignoring" % self.addr) return False
def _sendResponse(self, response, funcname, msgID, sender, connection): self.log.debug("sending response for msg id %s to %s" % (b64encode(msgID), sender)) m = Message() m.messageID = msgID m.sender.MergeFrom(self.proto) m.protoVer = PROTOCOL_VERSION m.testnet = self.multiplexer.testnet if response is None: m.command = NOT_FOUND else: m.command = Command.Value(funcname.upper()) for arg in response: m.arguments.append(str(arg)) data = m.SerializeToString() connection.send_message(data)
def receive_message(self, datagram, connection, ban_score): m = Message() try: m.ParseFromString(datagram) sender = node.Node(m.sender.guid, m.sender.ip, m.sender.port, m.sender.signedPublicKey, m.sender.vendor) except Exception: # If message isn't formatted property then ignore self.log.warning("received unknown message from %s, ignoring" % str(connection.dest_addr)) return False if m.testnet != self.multiplexer.testnet: self.log.warning( "received message from %s with incorrect network parameters." % str(connection.dest_addr)) connection.shutdown() return False if m.protoVer < PROTOCOL_VERSION: self.log.warning( "received message from %s with incompatible protocol version." % str(connection.dest_addr)) connection.shutdown() return False # Check that the GUID is valid. If not, ignore if self.router.isNewNode(sender): try: pubkey = m.sender.signedPublicKey[len(m.sender.signedPublicKey ) - 32:] verify_key = nacl.signing.VerifyKey(pubkey) verify_key.verify(m.sender.signedPublicKey) h = nacl.hash.sha512(m.sender.signedPublicKey) pow_hash = h[64:128] if int(pow_hash[:6], 16) >= 50 or hexlify( m.sender.guid) != h[:40]: raise Exception('Invalid GUID') except Exception: self.log.warning( "received message from sender with invalid GUID, ignoring") connection.shutdown() return False if m.sender.vendor: self.db.VendorStore().save_vendor(m.sender.guid.encode("hex"), m.sender.ip, m.sender.port, m.sender.signedPublicKey) msgID = m.messageID if m.command == NOT_FOUND: data = None else: data = tuple(m.arguments) if msgID in self._outstanding: self._acceptResponse(msgID, data, sender) elif m.command != NOT_FOUND: ban_score.process_message(m) self._acceptRequest(msgID, str(Command.Name(m.command)).lower(), data, sender, connection)