def onDataNotFound(self, prefix, interest, face, interestFilterId, filter): print "Data not found for interest: " + interest.getName().toUri() if interest.getName().get( -3).toEscapedString() == "bout" or interest.getName().get( -3).toEscapedString() == "genericfunctions": if interest.getName().toUri() in self.remainingTasks: # We are already trying to process this task, so we don't add it to the list of tasks pass else: self.remainingTasks[interest.getName().toUri()] = "in-progress" else: print "Got unexpected interest: " + interest.getName().toUri() # .../SAMPLE/<timestamp> timestamp = interest.getName().get(-1) catalogInterest = Interest(self.catalogPrefix) # Traverse catalogs in range from leftmost child catalogInterest.setChildSelector(0) catalogInterest.setMustBeFresh(True) catalogInterest.setInterestLifetimeMilliseconds(4000) exclude = Exclude() exclude.appendAny() exclude.appendComponent(timestamp) catalogInterest.setExclude(catalogInterest) self.face.expressInterest(catalogInterest, self.onCatalogData, self.onCatalogTimeout) print "Expressed catalog interest " + catalogInterest.getName().toUri() return
def reissueInterest(self): BACKOFF_THRESHOLD = 10 if self.backoffCounter > BACKOFF_THRESHOLD: self.TIMEOUT += 50 self.backoffCounter = 0 self.logger.debug('Backing off interval to ' + str(self.TIMEOUT)) if self.backoffCounter < -BACKOFF_THRESHOLD: self.TIMEOUT -= 50 self.backoffCounter = 0 self.logger.debug('Reducing backoff interval to ' + str(self.TIMEOUT)) if self.nextIssue is not None: now = time.clock() if self.nextIssue > now: pass # time.sleep(self.nextIssue-now) interest = Interest(Name(self.prefix)) interest.setInterestLifetimeMilliseconds(self.interestLifetime) interest.setMustBeFresh(False) if self.lastVersion is not None: e = Exclude() e.appendAny() e.appendComponent(self.lastVersion) interest.setExclude(e) interest.setChildSelector(1) #rightmost == freshest self.face.expressInterest(interest, self.onData, self.onTimeout) self.nextIssue = time.clock()+self.TIMEOUT/2000
def onCatalogData(self, interest, data): # Find the next catalog print "Received catalog data " + data.getName().toUri() catalogTimestamp = data.getName().get(-2) exclude = Exclude() exclude.appendAny() exclude.appendComponent(catalogTimestamp) nextCatalogInterest = Interest(interest.getName()) nextCatalogInterest.setExclude(exclude) nextCatalogInterest.setChildSelector(0) nextCatalogInterest.setMustBeFresh(True) nextCatalogInterest.setInterestLifetimeMilliseconds(2000) self.face.expressInterest(nextCatalogInterest, self.onCatalogData, self.onCatalogTimeout) print "Expressed catalog interest " + nextCatalogInterest.getName( ).toUri() # We ignore the version in the catalog if self.encrypted: self.consumer.consume(contentName, self.onCatalogConsumeComplete, self.onConsumeFailed) else: self.onCatalogConsumeComplete(data, data.getContent())
def consume(self, prefix, onVerified, onVerifyFailed, onTimeout): """ Consume data continuously under a given prefix, each time sending interest with the last timestamp excluded :param name: prefix to consume data under :type name: Name :param onData: onData(data) gets called after received data's onVerifyFailed :type onData: function object :param onVerifyFailed: onVerifyFailed(data) gets called if received data cannot be verified :type onVerifyFailed: function object :param onTimeout: onTimeout(interest) gets called if a consumer interest times out :type onTimeout: function object """ name = Name(prefix) interest = Interest(name) interest.setInterestLifetimeMilliseconds(self._defaultInterestLifetime) if self._currentTimestamp: exclude = Exclude() exclude.appendAny() exclude.appendComponent(Name.Component.fromVersion(self._currentTimestamp)) interest.setExclude(exclude) self._face.expressInterest(interest, lambda i, d : self.onData(i, d, onVerified, onVerifyFailed, onTimeout), lambda i: self.beforeReplyTimeout(i, onVerified, onVerifyFailed, onTimeout)) return
def onData(self, interest, data): self._keyChain.verifyData(data, self.onVerified, self.onVerifyFailed) dataName = data.getName() dataQueue = None if __debug__: print("Got data: " + dataName.toUri() + "; " + data.getContent().toRawStr()) for i in range(0, len(dataName)): if dataName.get(i).toEscapedString() == AGGREGATION_COMPONENT: dataType = dataName.get(i - 1).toEscapedString() aggregationType = dataName.get(i + 1).toEscapedString() startTime = int(dataName.get(i + 2).toEscapedString()) endTime = int(dataName.get(i + 3).toEscapedString()) childName = dataName.get(i - 3).toEscapedString() dataAndAggregationType = dataType + aggregationType dataDictKey = self.getDataDictKey(startTime, endTime, childName) dataQueue = self._dataQueue[dataAndAggregationType] dataQueue._dataDict[dataDictKey] = data break # TODO: check what if interval/starttime is misconfigured if dataQueue: self.calculateAggregation(dataType, aggregationType, dataQueue._childrenList, startTime, endTime - startTime, dataQueue._publishingPrefix) # Always ask for the next piece of data when we receive this one; assumes interval does not change; this also assumes there are no more components after endTime #newInterestName = dataName.getPrefix(i + 2).append(str(endTime)).append(str(endTime + (endTime - startTime))) # We don't expect aggregated data name to be continuous within our given time window, so we ask with exclusion instead newInterestName = dataName.getPrefix(i + 2) newInterest = Interest(interest) newInterest.setName(newInterestName) newInterest.setChildSelector(0) exclude = Exclude() exclude.appendAny() exclude.appendComponent(dataName.get(i + 2)) newInterest.setExclude(exclude) self._face.expressInterest(newInterest, self.onData, self.onTimeout) if __debug__: print(" issue interest: " + interest.getName().toUri()) return
def onSchemaVerified(self, data, onUpdateSuccess, onUpdateFailed): print "trust schema verified: " + data.getName().toUri() version = data.getName().get(-1) namespace = data.getName().getPrefix(-2).toUri() if not (namespace in self._trustSchemas): print "unexpected: received trust schema for application namespace that's not being followed; malformed data name?" return if version.toVersion() <= self._trustSchemas[namespace]["version"]: msg = "Got out-of-date trust schema" print msg if onUpdateFailed: onUpdateFailed(msg) return self._trustSchemas[namespace]["version"] = version.toVersion() if "pending-schema" in self._trustSchemas[namespace] and self._trustSchemas[namespace]["pending-schema"].getName().toUri() == data.getName().toUri(): # we verified a pending trust schema, don't need to keep that any more del self._trustSchemas[namespace]["pending-schema"] self._trustSchemas[namespace]["trust-schema"] = data.getContent().toRawStr() print self._trustSchemas[namespace]["trust-schema"] # TODO: what about trust schema for discovery, is discovery its own application? newInterest = Interest(Name(data.getName()).getPrefix(-1)) newInterest.setChildSelector(1) exclude = Exclude() exclude.appendAny() exclude.appendComponent(version) newInterest.setExclude(exclude) self._face.expressInterest(newInterest, lambda interest, data: self.onTrustSchemaData(interest, data, onUpdateSuccess, onUpdateFailed), lambda interest: self.onTrustSchemaTimeout(interest, onUpdateSuccess, onUpdateFailed)) # Note: this changes the verification rules for root cert, future trust schemas as well; ideally from the outside this doesn't have an impact, but do we want to avoid this? # Per reset function in ConfigPolicyManager; For now we don't call reset as we still want root cert in our certCache, instead of asking for it again (when we want to verify) each time we update the trust schema self._policyManager.config = BoostInfoParser() self._policyManager.config.read(self._trustSchemas[namespace]["trust-schema"], "updated-schema") if onUpdateSuccess: onUpdateSuccess(data.getContent().toRawStr(), self._trustSchemas[namespace]["is-initial"]) self._trustSchemas[namespace]["is-initial"] = False return
def expressInterestPirAndRepeat(self): self.log.debug("callbackCountUniqueData: " + str(self._callbackCountUniqueData) + ", callbackCountTimeout: " + str(self._callbackCountTimeout)) # Express interest for each pir we have discovered for pir in self.getPirs(): interest = Interest(Name(pir.id)) interest.setExclude(pir.status.getExclude()) interest.setInterestLifetimeMilliseconds(1000.0) interest.setChildSelector(1) self.face.expressInterest(interest, self.onDataPir, self.onTimeoutPir) self._countExpressedInterests += 1 debugStr = "Sent interest: " + interest.getName().toUri() debugStr += "\tExclude: " + interest.getExclude().toUri() debugStr += "\tLifetime: " + str(interest.getInterestLifetimeMilliseconds()) self.log.debug(debugStr) # Reschedule again in 0.5 sec self.loop.call_later(1.0, self.expressInterestPirAndRepeat)
def onSchemaVerificationFailed(self, data, reason, onUpdateSuccess, onUpdateFailed): print "trust schema verification failed: " + reason namespace = data.getName().getPrefix(-2).toUri() if not (namespace in self._trustSchemas): print "unexpected: received trust schema for application namespace that's not being followed; malformed data name?" return newInterest = Interest(Name(data.getName()).getPrefix(-1)) newInterest.setChildSelector(1) exclude = Exclude() exclude.appendAny() exclude.appendComponent(Name.Component.fromVersion(self._trustSchemas[namespace]["version"])) newInterest.setExclude(exclude) # Don't immediately ask for potentially the same content again if verification fails self._face.callLater(4000, lambda : self._face.expressInterest(newInterest, lambda interest, data: self.onTrustSchemaData(interest, data, onUpdateSuccess, onUpdateFailed), lambda interest: self.onTrustSchemaTimeout(interest, onUpdateSuccess, onUpdateFailed))) return