Avoid an error in the fallback script when a fallback doesn't have any uptime

Sometimes, the fallback generation script doesn't add attributes to the
fallbacks in the list. If this happens, log an error, and avoid selecting
that fallback.

This is a rare issue: it should not change selection behaviour.

Fixes issue #20945.
This commit is contained in:
teor 2016-12-11 22:47:00 +11:00
parent 654367f026
commit 53ec087450
No known key found for this signature in database
GPG Key ID: 450CBA7F968F094B
2 changed files with 38 additions and 31 deletions

View File

@ -33,3 +33,5 @@
OnionOO. When a relay operator has multiple relays, this prioritises OnionOO. When a relay operator has multiple relays, this prioritises
relays that are up over relays that are down. relays that are up over relays that are down.
Closes ticket #20926; bugfix on 0.2.8.3-alpha. Closes ticket #20926; bugfix on 0.2.8.3-alpha.
- Stop failing when a relay has no uptime data in updateFallbackDirs.py.
Closes ticket 20945; bugfix on tor-0.2.8.1-alpha.

View File

@ -862,37 +862,42 @@ class Candidate(object):
self._badexit = self._avg_generic_history(badexit) / ONIONOO_SCALE_ONE self._badexit = self._avg_generic_history(badexit) / ONIONOO_SCALE_ONE
def is_candidate(self): def is_candidate(self):
if (MUST_BE_RUNNING_NOW and not self.is_running()): try:
logging.info('%s not a candidate: not running now, unable to check ' + if (MUST_BE_RUNNING_NOW and not self.is_running()):
'DirPort consensus download', self._fpr) logging.info('%s not a candidate: not running now, unable to check ' +
return False 'DirPort consensus download', self._fpr)
if (self._data['last_changed_address_or_port'] > return False
self.CUTOFF_ADDRESS_AND_PORT_STABLE): if (self._data['last_changed_address_or_port'] >
logging.info('%s not a candidate: changed address/port recently (%s)', self.CUTOFF_ADDRESS_AND_PORT_STABLE):
self._fpr, self._data['last_changed_address_or_port']) logging.info('%s not a candidate: changed address/port recently (%s)',
return False self._fpr, self._data['last_changed_address_or_port'])
if self._running < CUTOFF_RUNNING: return False
logging.info('%s not a candidate: running avg too low (%lf)', if self._running < CUTOFF_RUNNING:
self._fpr, self._running) logging.info('%s not a candidate: running avg too low (%lf)',
return False self._fpr, self._running)
if self._v2dir < CUTOFF_V2DIR: return False
logging.info('%s not a candidate: v2dir avg too low (%lf)', if self._v2dir < CUTOFF_V2DIR:
self._fpr, self._v2dir) logging.info('%s not a candidate: v2dir avg too low (%lf)',
return False self._fpr, self._v2dir)
if self._badexit is not None and self._badexit > PERMITTED_BADEXIT: return False
logging.info('%s not a candidate: badexit avg too high (%lf)', if self._badexit is not None and self._badexit > PERMITTED_BADEXIT:
self._fpr, self._badexit) logging.info('%s not a candidate: badexit avg too high (%lf)',
return False self._fpr, self._badexit)
# this function logs a message depending on which check fails return False
if not self.is_valid_version(): # this function logs a message depending on which check fails
return False if not self.is_valid_version():
if self._guard < CUTOFF_GUARD: return False
logging.info('%s not a candidate: guard avg too low (%lf)', if self._guard < CUTOFF_GUARD:
self._fpr, self._guard) logging.info('%s not a candidate: guard avg too low (%lf)',
return False self._fpr, self._guard)
if (not self._data.has_key('consensus_weight') return False
or self._data['consensus_weight'] < 1): if (not self._data.has_key('consensus_weight')
logging.info('%s not a candidate: consensus weight invalid', self._fpr) or self._data['consensus_weight'] < 1):
logging.info('%s not a candidate: consensus weight invalid', self._fpr)
return False
except BaseException as e:
logging.warning("Exception %s when checking if fallback is a candidate",
str(e))
return False return False
return True return True