def _create_next_tree(self): last_ttl_window = 0 while self.run_flag.is_set(): start = time.time() cur_ttl_window = ConnectedHashTree.get_ttl_window() time_to_sleep = (ConnectedHashTree.get_time_till_next_ttl() - HASHTREE_UPDATE_WINDOW) if cur_ttl_window == last_ttl_window: time_to_sleep += HASHTREE_TTL if time_to_sleep > 0: sleep_interval(start, time_to_sleep, "BS._create_next_tree", self._quiet_startup()) # at this point, there should be <= HASHTREE_UPDATE_WINDOW # seconds left in current ttl logging.info("Started computing hashtree for next TTL window (%d)", cur_ttl_window + 2) last_ttl_window = ConnectedHashTree.get_ttl_window() ht_start = time.time() ifs = list(self.ifid2br.keys()) tree = ConnectedHashTree.get_next_tree(self.addr.isd_as, ifs, self.hashtree_gen_key, HashType.SHA256) ht_end = time.time() with self._hash_tree_lock: self._next_tree = tree logging.info( "Finished computing hashtree for TTL window %d in %.3fs" % (cur_ttl_window + 2, ht_end - ht_start))
def _create_next_tree(self): last_ttl_window = 0 ttl = self.config.revocation_tree_ttl update_window = ttl // 3 while self.run_flag.is_set(): start = time.time() cur_ttl_window = ConnectedHashTree.get_ttl_window(ttl) time_to_sleep = ConnectedHashTree.time_until_next_window( ttl) - update_window if cur_ttl_window == last_ttl_window: time_to_sleep += ttl if time_to_sleep > 0: sleep_interval(start, time_to_sleep, "BS._create_next_tree", self._quiet_startup()) # at this point, there should be <= update_window # seconds left in current ttl logging.info("Started computing hashtree for next TTL window (%d)", cur_ttl_window + 2) last_ttl_window = ConnectedHashTree.get_ttl_window(ttl) ht_start = time.time() ifs = list(self.ifid2br.keys()) tree = ConnectedHashTree.get_next_tree(self.addr.isd_as, ifs, self.hashtree_gen_key, ttl, HashType.SHA256) ht_end = time.time() with self._hash_tree_lock: self._next_tree = tree logging.info( "Finished computing hashtree for TTL window %d in %.3fs" % (cur_ttl_window + 2, ht_end - ht_start))
def worker(self): """ Worker thread that takes care of reading shared PCBs from ZK, and propagating PCBS/registering paths when master. """ last_propagation = last_registration = 0 last_ttl_window = ConnectedHashTree.get_ttl_window( self.config.revocation_tree_ttl) worker_cycle = 1.0 start = time.time() while self.run_flag.is_set(): sleep_interval(start, worker_cycle, "BS.worker cycle", self._quiet_startup()) start = time.time() # Update IS_MASTER metric. if self._labels: IS_MASTER.labels(**self._labels).set(int(self.zk.have_lock())) try: self.zk.wait_connected() self.pcb_cache.process() self.revobjs_cache.process() self.handle_rev_objs() cur_ttl_window = ConnectedHashTree.get_ttl_window( self.config.revocation_tree_ttl) if cur_ttl_window != last_ttl_window: self._maintain_hash_tree() last_ttl_window = cur_ttl_window ret = self.zk.get_lock(lock_timeout=0, conn_timeout=0) if not ret: # Failed to get the lock continue elif ret == ZK_LOCK_SUCCESS: logging.info("Became master") self._became_master() self.pcb_cache.expire(self.config.propagation_time * 10) self.revobjs_cache.expire(self.ZK_REV_OBJ_MAX_AGE) except ZkNoConnection: continue now = time.time() if now - last_propagation >= self.config.propagation_time: self.handle_pcbs_propagation() last_propagation = now if (self.config.registers_paths and now - last_registration >= self.config.registration_time): try: self.register_segments() except SCIONKeyError as e: logging.error("Error while registering segments: %s", e) pass last_registration = now
def worker(self): """ Worker thread that takes care of reading shared PCBs from ZK, and propagating PCBS/registering paths when master. """ last_propagation = last_registration = 0 last_ttl_window = ConnectedHashTree.get_ttl_window() worker_cycle = 1.0 was_master = False start = time.time() while self.run_flag.is_set(): sleep_interval(start, worker_cycle, "BS.worker cycle", self._quiet_startup()) start = time.time() try: self.process_pcb_queue() self.handle_unverified_beacons() self.zk.wait_connected() self.pcb_cache.process() self.revobjs_cache.process() self.handle_rev_objs() cur_ttl_window = ConnectedHashTree.get_ttl_window() if cur_ttl_window != last_ttl_window: self._maintain_hash_tree() last_ttl_window = cur_ttl_window if not self.zk.get_lock(lock_timeout=0, conn_timeout=0): was_master = False continue if not was_master: self._became_master() was_master = True self.pcb_cache.expire(self.config.propagation_time * 10) self.revobjs_cache.expire(self.ZK_REV_OBJ_MAX_AGE) except ZkNoConnection: continue now = time.time() if now - last_propagation >= self.config.propagation_time: self.handle_pcbs_propagation() last_propagation = now if (self.config.registers_paths and now - last_registration >= self.config.registration_time): try: self.register_segments() except SCIONKeyError as e: logging.error("Register_segments: %s", e) pass last_registration = now
def _maintain_hash_tree(self): """ Maintain the hashtree. Update the the windows in the connected tree """ with self._hash_tree_lock: if self._next_tree is not None: self._hash_tree.update(self._next_tree) self._next_tree = None else: logging.critical("Did not create hashtree in time; dying") kill_self() logging.info("New Hash Tree TTL window beginning: %s", ConnectedHashTree.get_ttl_window())