commit ae9220cb41083c876af3a7492cf0d5218eaf1d60 Author: Karsten Loesing karsten.loesing@gmx.net Date: Thu Mar 10 09:17:06 2011 +0100
Warn if a bridge network status is possibly stale.
In February 2011, Tonga's tor process died, but it's tar cronjob continued to suppy us with "fresh" bridge descriptor tarballs (containing stale descriptors). We didn't detect this for two weeks, because we derive the bridge network status publication time from the tarball filename, and it looked recent all the time.
Adding a check whether the most recent descriptor that is contained in a bridge network status was published more than 1 hour before the status itself. This is a sign for the status being stale, even though it's not 100% reliable. We still should investigate these cases when they occur.
A test with the January and February 2011 tarballs shows that we'd have learned about Tonga's tor process dying 60-90 minutes after the fact. --- .../ernie/db/SanitizedBridgesWriter.java | 25 ++++++++++++++++++++ 1 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/src/org/torproject/ernie/db/SanitizedBridgesWriter.java b/src/org/torproject/ernie/db/SanitizedBridgesWriter.java index aa1bcec..7376e5a 100644 --- a/src/org/torproject/ernie/db/SanitizedBridgesWriter.java +++ b/src/org/torproject/ernie/db/SanitizedBridgesWriter.java @@ -403,6 +403,7 @@ public class SanitizedBridgesWriter { BufferedReader br = new BufferedReader(new StringReader(new String( data, "US-ASCII"))); String line = null; + String mostRecentDescPublished = null; while ((line = br.readLine()) != null) {
/* r lines contain sensitive information that needs to be removed @@ -433,6 +434,13 @@ public class SanitizedBridgesWriter { this.bridgeDescriptorMappings.put(mappingKey, mapping); }
+ /* Determine most recent descriptor publication time. */ + if (descPublicationTime.compareTo(publicationTime) <= 0 && + (mostRecentDescPublished == null || + descPublicationTime.compareTo(mostRecentDescPublished) > 0)) { + mostRecentDescPublished = descPublicationTime; + } + /* Write scrubbed r line to buffer. */ String hashedBridgeIdentityBase64 = Base64.encodeBase64String( DigestUtils.sha(Base64.decodeBase64(bridgeIdentity @@ -480,6 +488,23 @@ public class SanitizedBridgesWriter { scrubbed = new StringBuilder(); }
+ /* Check if we can tell from the descriptor publication times + * whether this status is possibly stale. */ + SimpleDateFormat formatter = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss"); + formatter.setTimeZone(TimeZone.getTimeZone("UTC")); + if (formatter.parse(publicationTime).getTime() - + formatter.parse(mostRecentDescPublished).getTime() > + 60L * 60L * 1000L) { + this.logger.warning("The most recent descriptor in the bridge " + + "network status published at " + publicationTime + " was " + + "published at " + mostRecentDescPublished + " which is " + + "more than 1 hour before the status. This is a sign for " + + "the status being stale. Please check!"); + } + } catch (ParseException e) { + this.logger.log(Level.WARNING, "Could not parse timestamp in " + + "bridge network status.", e); } catch (IOException e) { this.logger.log(Level.WARNING, "Could not parse bridge network " + "status.", e);