Esempio n. 1
0
    def bm_command_object(self):
        """Incoming object, process it"""
        objectOffset = self.payloadOffset
        nonce, expiresTime, objectType, version, streamNumber = \
            self.decode_payload_content("QQIvv")
        self.object = BMObject(nonce, expiresTime, objectType, version,
                               streamNumber, self.payload, self.payloadOffset)

        if len(self.payload) - self.payloadOffset > MAX_OBJECT_PAYLOAD_SIZE:
            logger.info(
                'The payload length of this object is too large (%d bytes).'
                ' Ignoring it.',
                len(self.payload) - self.payloadOffset)
            raise BMProtoExcessiveDataError()

        try:
            self.object.checkProofOfWorkSufficient()
            self.object.checkEOLSanity()
            self.object.checkAlreadyHave()
        except (BMObjectExpiredError, BMObjectAlreadyHaveError,
                BMObjectInsufficientPOWError):
            BMProto.stopDownloadingObject(self.object.inventoryHash)
            raise
        try:
            self.object.checkStream()
        except BMObjectUnwantedStreamError:
            acceptmismatch = BMConfigParser().get("inventory",
                                                  "acceptmismatch")
            BMProto.stopDownloadingObject(self.object.inventoryHash,
                                          acceptmismatch)
            if not acceptmismatch:
                raise

        try:
            self.object.checkObjectByType()
            objectProcessorQueue.put(
                (self.object.objectType, buffer(self.object.data)))
        except BMObjectInvalidError:
            BMProto.stopDownloadingObject(self.object.inventoryHash, True)
        else:
            try:
                del missingObjects[self.object.inventoryHash]
            except KeyError:
                pass

        if self.object.inventoryHash in Inventory() and Dandelion().hasHash(
                self.object.inventoryHash):
            Dandelion().removeHash(self.object.inventoryHash,
                                   "cycle detection")

        Inventory()[self.object.inventoryHash] = (
            self.object.objectType, self.object.streamNumber,
            buffer(self.payload[objectOffset:]), self.object.expiresTime,
            buffer(self.object.tag))
        self.handleReceivedObject(self.object.streamNumber,
                                  self.object.inventoryHash)
        invQueue.put((self.object.streamNumber, self.object.inventoryHash,
                      self.destination))
        return True
Esempio n. 2
0
 def expire(self):
     with self.lock:
         deadline = time()
         # only expire those that have a child node, i.e. those without a child not will stick around
         toDelete = [[v.stream, k, v.child] for k, v in self.hashMap.iteritems() if v.timeout < deadline and v.child]
         for row in toDelete:
             self.removeHash(row[1], 'expiration')
             invQueue.put((row[0], row[1], row[2]))
Esempio n. 3
0
    def expire(self):
        """Switch expired objects from stem to fluff mode"""
        with self.lock:
            deadline = time()
            toDelete = [
                [v.stream, k, v.child] for k, v in self.hashMap.iteritems()
                if v.timeout < deadline
            ]

            for row in toDelete:
                self.removeHash(row[1], 'expiration')
                invQueue.put(row)
        return toDelete
Esempio n. 4
0
 def maybeAddStem(self, connection):
     # fewer than MAX_STEMS outbound connections at last reshuffle?
     with self.lock:
         if len(self.stem) < MAX_STEMS:
             self.stem.append(connection)
             for k in (k for k, v in self.nodeMap.iteritems() if v is None):
                 self.nodeMap[k] = connection
             for k, v in {
                     k: v
                     for k, v in self.hashMap.iteritems() if v.child is None
             }.iteritems():
                 self.hashMap[k] = Stem(connection, v.stream,
                                        self.poissonTimeout())
                 invQueue.put((v.stream, k, v.child))
Esempio n. 5
0
    def bm_command_object(self):
        objectOffset = self.payloadOffset
        nonce, expiresTime, objectType, version, streamNumber = self.decode_payload_content(
            "QQIvv")
        self.object = BMObject(nonce, expiresTime, objectType, version,
                               streamNumber, self.payload, self.payloadOffset)

        if len(self.payload
               ) - self.payloadOffset > BMProto.maxObjectPayloadSize:
            logger.info(
                'The payload length of this object is too large (%s bytes). Ignoring it.'
                % len(self.payload) - self.payloadOffset)
            raise BMProtoExcessiveDataError()

        try:
            self.object.checkProofOfWorkSufficient()
            self.object.checkEOLSanity()
            self.object.checkAlreadyHave()
        except (BMObjectExpiredError, BMObjectAlreadyHaveError,
                BMObjectInsufficientPOWError) as e:
            BMProto.stopDownloadingObject(self.object.inventoryHash)
            raise e
        try:
            self.object.checkStream()
        except (BMObjectUnwantedStreamError, ) as e:
            BMProto.stopDownloadingObject(
                self.object.inventoryHash,
                BMConfigParser().get("inventory", "acceptmismatch"))
            if not BMConfigParser().get("inventory", "acceptmismatch"):
                raise e

        try:
            self.object.checkObjectByType()
            objectProcessorQueue.put(
                (self.object.objectType, buffer(self.object.data)))
        except BMObjectInvalidError as e:
            BMProto.stopDownloadingObject(self.object.inventoryHash, True)
        else:
            try:
                del state.missingObjects[self.object.inventoryHash]
            except KeyError:
                pass

        Inventory()[self.object.inventoryHash] = (
            self.object.objectType, self.object.streamNumber,
            buffer(self.payload[objectOffset:]), self.object.expiresTime,
            buffer(self.object.tag))
        invQueue.put((self.object.streamNumber, self.object.inventoryHash,
                      self.destination))
        return True
Esempio n. 6
0
 def maybeAddStem(self, connection):
     """
     If we had too few outbound connections, add the current one to the
     current stem list. Dandelion as designed by the authors should
     always have two active stem child connections.
     """
     # fewer than MAX_STEMS outbound connections at last reshuffle?
     with self.lock:
         if len(self.stem) < MAX_STEMS:
             self.stem.append(connection)
             for k in (k for k, v in self.nodeMap.iteritems() if v is None):
                 self.nodeMap[k] = connection
             for k, v in {
                     k: v for k, v in self.hashMap.iteritems()
                     if v.child is None
             }.iteritems():
                 self.hashMap[k] = Stem(
                     connection, v.stream, self.poissonTimeout())
                 invQueue.put((v.stream, k, v.child))
Esempio n. 7
0
    def bm_command_object(self):
        objectOffset = self.payloadOffset
        nonce, expiresTime, objectType, version, streamNumber = self.decode_payload_content("QQIvv")
        self.object = BMObject(nonce, expiresTime, objectType, version, streamNumber, self.payload, self.payloadOffset)

        if len(self.payload) - self.payloadOffset > BMProto.maxObjectPayloadSize:
            logger.info('The payload length of this object is too large (%s bytes). Ignoring it.' % len(self.payload) - self.payloadOffset)
            raise BMProtoExcessiveDataError()

        try:
            self.object.checkProofOfWorkSufficient()
            self.object.checkEOLSanity()
            self.object.checkAlreadyHave()
        except (BMObjectExpiredError, BMObjectAlreadyHaveError, BMObjectInsufficientPOWError) as e:
            BMProto.stopDownloadingObject(self.object.inventoryHash)
            raise e
        try:
            self.object.checkStream()
        except (BMObjectUnwantedStreamError,) as e:
            BMProto.stopDownloadingObject(self.object.inventoryHash, BMConfigParser().get("inventory", "acceptmismatch"))
            if not BMConfigParser().get("inventory", "acceptmismatch"):
                raise e

        try:
            self.object.checkObjectByType()
            objectProcessorQueue.put((self.object.objectType, buffer(self.object.data)))
        except BMObjectInvalidError as e:
            BMProto.stopDownloadingObject(self.object.inventoryHash, True)
        else:
            try:
                del state.missingObjects[self.object.inventoryHash]
            except KeyError:
                pass

        Inventory()[self.object.inventoryHash] = (
                self.object.objectType, self.object.streamNumber, buffer(self.payload[objectOffset:]), self.object.expiresTime, buffer(self.object.tag))
        invQueue.put((self.object.streamNumber, self.object.inventoryHash, self.destination))
        return True