commit 1be161bb80559d23203b2b522bf8bdf33dfaebc3 Author: Karsten Loesing karsten.loesing@gmx.net Date: Thu Nov 10 18:50:31 2011 +0100
Move the warning-generating code its own class. --- src/org/torproject/chc/Checker.java | 288 ++++++++++++++++++++++ src/org/torproject/chc/Main.java | 15 +- src/org/torproject/chc/MetricsWebsiteReport.java | 6 + src/org/torproject/chc/NagiosReport.java | 5 + src/org/torproject/chc/Report.java | 4 + src/org/torproject/chc/StdOutReport.java | 282 +++++----------------- src/org/torproject/chc/Warning.java | 46 ++++ 7 files changed, 421 insertions(+), 225 deletions(-)
diff --git a/src/org/torproject/chc/Checker.java b/src/org/torproject/chc/Checker.java new file mode 100644 index 0000000..d095da4 --- /dev/null +++ b/src/org/torproject/chc/Checker.java @@ -0,0 +1,288 @@ +/* Copyright 2011 The Tor Project + * See LICENSE for licensing information */ +package org.torproject.chc; + +import java.io.*; +import java.text.*; +import java.util.*; + +/* Check a given consensus and votes for irregularities and write results + * to a warnings map consisting of warning type and details. */ +public class Checker { + + /* Warning messages consisting of type and details. */ + private SortedMap<Warning, String> warnings = + new TreeMap<Warning, String>(); + + public SortedMap<Warning, String> getWarnings() { + return this.warnings; + } + + /* Date-time format to format timestamps. */ + private static SimpleDateFormat dateTimeFormat; + static { + dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateTimeFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + } + + /* Downloaded consensus and corresponding votes for later + * processing. */ + private SortedMap<String, Status> downloadedConsensuses; + private Status downloadedConsensus; + private SortedSet<Status> downloadedVotes; + public void processDownloadedConsensuses( + SortedMap<String, Status> downloadedConsensuses) { + this.downloadedConsensuses = downloadedConsensuses; + } + + /* Check consensuses and votes for irregularities. */ + public void checkConsensus() { + this.findMostRecentConsensus(); + this.checkMissingConsensuses(); + this.checkAllConsensusesFresh(); + if (this.downloadedConsensus != null) { + if (this.isConsensusFresh(this.downloadedConsensus)) { + this.checkConsensusMethods(); + this.checkRecommendedVersions(); + this.checkConsensusParameters(); + this.checkAuthorityKeys(); + this.checkMissingVotes(); + this.checkBandwidthScanners(); + } + } else { + this.warnings.put(Warning.NoConsensusKnown, ""); + } + } + + /* Find most recent consensus and corresponding votes. */ + private void findMostRecentConsensus() { + long mostRecentValidAfterMillis = -1L; + for (Status downloadedConsensus : downloadedConsensuses.values()) { + if (downloadedConsensus.getValidAfterMillis() > + mostRecentValidAfterMillis) { + this.downloadedConsensus = downloadedConsensus; + mostRecentValidAfterMillis = + downloadedConsensus.getValidAfterMillis(); + } + } + if (this.downloadedConsensus != null) { + this.downloadedVotes = this.downloadedConsensus.getVotes(); + } + } + + /* Check if any directory authority didn't tell us a consensus. */ + private void checkMissingConsensuses() { + SortedSet<String> missingConsensuses = new TreeSet<String>( + Arrays.asList(("gabelmoo,tor26,ides,maatuska,dannenberg,urras," + + "moria1,dizum").split(","))); + missingConsensuses.removeAll(this.downloadedConsensuses.keySet()); + if (!missingConsensuses.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (String nickname : missingConsensuses) { + sb.append(", " + nickname); + } + this.warnings.put(Warning.ConsensusDownloadTimeout, + sb.toString().substring(2)); + } + } + + /* Check if all consensuses are fresh. */ + private void checkAllConsensusesFresh() { + long fresh = System.currentTimeMillis() - 60L * 60L * 1000L; + SortedSet<String> nonFresh = new TreeSet<String>(); + for (Map.Entry<String, Status> e : downloadedConsensuses.entrySet()) { + String nickname = e.getKey(); + Status downloadedConsensus = e.getValue(); + if (downloadedConsensus.getValidAfterMillis() < fresh) { + nonFresh.add(nickname); + } + } + if (!nonFresh.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (String nickname : nonFresh) { + sb.append(", " + nickname); + } + this.warnings.put(Warning.ConsensusNotFresh, + sb.toString().substring(2)); + } + } + + /* Check if the most recent consensus is older than 1 hour. */ + private boolean isConsensusFresh(Status consensus) { + return (consensus.getValidAfterMillis() >= + System.currentTimeMillis() - 60L * 60L * 1000L); + } + + /* Check supported consensus methods of all votes. */ + private void checkConsensusMethods() { + SortedSet<String> dirs = new TreeSet<String>(); + for (Status vote : this.downloadedVotes) { + if (!vote.getConsensusMethods().contains( + this.downloadedConsensus.getConsensusMethods().last())) { + dirs.add(vote.getNickname()); + } + } + if (!dirs.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (String dir : dirs) { + sb.append(", " + dir); + } + this.warnings.put(Warning.ConsensusMethodNotSupported, + sb.toString().substring(2)); + } + } + + /* Check if the recommended versions in a vote are different from the + * recommended versions in the consensus. */ + private void checkRecommendedVersions() { + SortedSet<String> unrecommendedClientVersions = new TreeSet<String>(), + unrecommendedServerVersions = new TreeSet<String>(); + for (Status vote : this.downloadedVotes) { + if (vote.getRecommendedClientVersions() != null && + !downloadedConsensus.getRecommendedClientVersions().equals( + vote.getRecommendedClientVersions())) { + StringBuilder message = new StringBuilder(); + message.append(vote.getNickname()); + for (String version : vote.getRecommendedClientVersions()) { + message.append(" " + version); + } + unrecommendedClientVersions.add(message.toString()); + } + if (vote.getRecommendedServerVersions() != null && + !downloadedConsensus.getRecommendedServerVersions().equals( + vote.getRecommendedServerVersions())) { + StringBuilder message = new StringBuilder(); + message.append(vote.getNickname()); + for (String version : vote.getRecommendedServerVersions()) { + message.append(" " + version); + } + unrecommendedServerVersions.add(message.toString()); + } + } + if (!unrecommendedServerVersions.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (String dir : unrecommendedServerVersions) { + sb.append(", " + dir); + } + this.warnings.put(Warning.DifferentRecommendedServerVersions, + sb.toString().substring(2)); + } + if (!unrecommendedClientVersions.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (String dir : unrecommendedClientVersions) { + sb.append(", " + dir); + } + this.warnings.put(Warning.DifferentRecommendedClientVersions, + sb.toString().substring(2)); + } + } + + /* Check if a vote contains conflicting or invalid consensus + * parameters. */ + private void checkConsensusParameters() { + Set<String> validParameters = new HashSet<String>(Arrays.asList( + ("circwindow,CircuitPriorityHalflifeMsec,refuseunknownexits," + + "cbtdisabled,cbtnummodes,cbtrecentcount,cbtmaxtimeouts," + + "cbtmincircs,cbtquantile,cbtclosequantile,cbttestfreq," + + "cbtmintimeout,cbtinitialtimeout,bwauthpid").split(","))); + SortedSet<String> conflicts = new TreeSet<String>(); + for (Status vote : this.downloadedVotes) { + Map<String, String> voteConsensusParams = + vote.getConsensusParams(); + boolean conflictOrInvalid = false; + if (voteConsensusParams != null) { + for (Map.Entry<String, String> e : + voteConsensusParams.entrySet()) { + if (!downloadedConsensus.getConsensusParams().containsKey( + e.getKey()) || + !downloadedConsensus.getConsensusParams().get(e.getKey()). + equals(e.getValue()) || + !validParameters.contains(e.getKey())) { + StringBuilder message = new StringBuilder(); + message.append(vote.getNickname()); + for (Map.Entry<String, String> p : + voteConsensusParams.entrySet()) { + message.append(" " + p.getKey() + "=" + p.getValue()); + } + conflicts.add(message.toString()); + break; + } + } + } + } + if (!conflicts.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (String dir : conflicts) { + sb.append(", " + dir); + } + this.warnings.put(Warning.ConflictingOrInvalidConsensusParams, + sb.toString().substring(2)); + } + } + + /* Check whether any of the authority keys expire in the next 14 + * days. */ + private void checkAuthorityKeys() { + SortedMap<String, String> expiringCertificates = + new TreeMap<String, String>(); + long now = System.currentTimeMillis(); + for (Status vote : this.downloadedVotes) { + long voteDirKeyExpiresMillis = vote.getDirKeyExpiresMillis(); + if (voteDirKeyExpiresMillis - 14L * 24L * 60L * 60L * 1000L < now) { + expiringCertificates.put(vote.getNickname(), + dateTimeFormat.format(voteDirKeyExpiresMillis)); + } + } + if (!expiringCertificates.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (Map.Entry<String, String> e : + expiringCertificates.entrySet()) { + String dir = e.getKey(); + String timestamp = e.getValue(); + sb.append(", " + dir + " " + timestamp); + } + this.warnings.put(Warning.CertificateExpiresSoon, + sb.toString().substring(2)); + } + } + + /* Check if any votes are missing. */ + private void checkMissingVotes() { + SortedSet<String> knownAuthorities = new TreeSet<String>( + Arrays.asList(("dannenberg,dizum,gabelmoo,ides,maatuska,moria1," + + "tor26,urras").split(","))); + SortedSet<String> missingVotes = + new TreeSet<String>(knownAuthorities); + for (Status vote : this.downloadedVotes) { + missingVotes.remove(vote.getNickname()); + } + if (!missingVotes.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (String missingDir : missingVotes) { + sb.append(", " + missingDir); + } + this.warnings.put(Warning.VotesMissing, + sb.toString().substring(2)); + } + } + + /* Check if any bandwidth scanner results are missing. */ + private void checkBandwidthScanners() { + SortedSet<String> missingBandwidthScanners = new TreeSet<String>( + Arrays.asList("ides,urras,moria1,gabelmoo,maatuska".split(","))); + for (Status vote : this.downloadedVotes) { + if (vote.getBandwidthWeights() > 0) { + missingBandwidthScanners.remove(vote.getNickname()); + } + } + if (!missingBandwidthScanners.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (String dir : missingBandwidthScanners) { + sb.append(", " + dir); + } + this.warnings.put(Warning.BandwidthScannerResultsMissing, + sb.toString().substring(2)); + } + } +} + diff --git a/src/org/torproject/chc/Main.java b/src/org/torproject/chc/Main.java index aa25e57..cdc65c3 100644 --- a/src/org/torproject/chc/Main.java +++ b/src/org/torproject/chc/Main.java @@ -21,16 +21,21 @@ public class Main { Downloader downloader = new Downloader(); downloader.downloadFromAuthorities();
- /* Parse consensus and votes and pass them to the reports. */ + /* Parse consensus and votes. */ Parser parser = new Parser(); SortedMap<String, Status> parsedDownloadedConsensuses = parser.parse( downloader.getConsensusStrings(), downloader.getVoteStrings()); - for (Report report : reports) { - report.processDownloadedConsensuses(parsedDownloadedConsensuses); - }
- /* Finish writing reports. */ + /* Check consensus and votes for possible problems. */ + Checker checker = new Checker(); + checker.processDownloadedConsensuses(parsedDownloadedConsensuses); + SortedMap<Warning, String> warnings = checker.getWarnings(); + + /* Pass warnings, consensuses, and votes to the reports, and finish + * writing them. */ for (Report report : reports) { + report.processWarnings(warnings); + report.processDownloadedConsensuses(parsedDownloadedConsensuses); report.writeReport(); }
diff --git a/src/org/torproject/chc/MetricsWebsiteReport.java b/src/org/torproject/chc/MetricsWebsiteReport.java index e1adc57..8aa52b5 100644 --- a/src/org/torproject/chc/MetricsWebsiteReport.java +++ b/src/org/torproject/chc/MetricsWebsiteReport.java @@ -25,6 +25,12 @@ public class MetricsWebsiteReport implements Report { this.htmlOutputFile = new File(htmlOutputFilename); }
+ /* Process warnings. */ + public void processWarnings(SortedMap<Warning, String> warnings) { + /* We could use these warnings instead of running all checks + * ourselves. But we're not doing that yet. */ + } + /* Store the downloaded consensus and corresponding votes for later * processing. */ private Status downloadedConsensus; diff --git a/src/org/torproject/chc/NagiosReport.java b/src/org/torproject/chc/NagiosReport.java index e7f5d03..6394c98 100644 --- a/src/org/torproject/chc/NagiosReport.java +++ b/src/org/torproject/chc/NagiosReport.java @@ -28,6 +28,11 @@ public class NagiosReport implements Report { this.downloadedConsensuses = downloadedConsensuses; }
+ /* Process warnings. */ + public void processWarnings(SortedMap<Warning, String> warnings) { + /* Don't use these warnings. This class will go away soon anyway. */ + } + /* Lists of output messages sorted by warnings, criticals, and * unknowns (increasing severity). */ private List<String> nagiosWarnings = new ArrayList<String>(), diff --git a/src/org/torproject/chc/Report.java b/src/org/torproject/chc/Report.java index 0f1a306..48015eb 100644 --- a/src/org/torproject/chc/Report.java +++ b/src/org/torproject/chc/Report.java @@ -13,6 +13,10 @@ public interface Report { public abstract void processDownloadedConsensuses( SortedMap<String, Status> downloadedConsensuses);
+ /* Process warnings consisting of warning type and details. */ + public abstract void processWarnings( + SortedMap<Warning, String> warnings); + /* Finish writing report. */ public abstract void writeReport(); } diff --git a/src/org/torproject/chc/StdOutReport.java b/src/org/torproject/chc/StdOutReport.java index 3512480..afdaba3 100644 --- a/src/org/torproject/chc/StdOutReport.java +++ b/src/org/torproject/chc/StdOutReport.java @@ -10,10 +10,6 @@ import java.util.*; * to stdout while rate-limiting warnings based on severity. */ public class StdOutReport implements Report {
- /* Warning messages and the time in millis that should have passed - * since sending them out. */ - private Map<String, Long> warnings = new HashMap<String, Long>(); - /* Date-time format to format timestamps. */ private static SimpleDateFormat dateTimeFormat; static { @@ -31,25 +27,16 @@ public class StdOutReport implements Report { this.downloadedConsensuses = downloadedConsensuses; }
+ /* Warnings obtained from checking the current consensus and votes. */ + private SortedMap<Warning, String> warnings; + public void processWarnings(SortedMap<Warning, String> warnings) { + this.warnings = warnings; + } + /* Check consensuses and votes for irregularities and write output to * stdout. */ public void writeReport() { this.readLastWarned(); - this.findMostRecentConsensus(); - this.checkMissingConsensuses(); - this.checkAllConsensusesFresh(); - if (this.downloadedConsensus != null) { - if (this.isConsensusFresh(this.downloadedConsensus)) { - this.checkConsensusMethods(); - this.checkRecommendedVersions(); - this.checkConsensusParameters(); - this.checkAuthorityKeys(); - this.checkMissingVotes(); - this.checkBandwidthScanners(); - } - } else { - this.warnings.put("No consensus known", 0L); - } this.prepareReport(); this.writeReportToStdOut(); this.writeLastWarned(); @@ -91,211 +78,66 @@ public class StdOutReport implements Report { } }
- /* Find most recent consensus and corresponding votes. */ - private void findMostRecentConsensus() { - long mostRecentValidAfterMillis = -1L; - for (Status downloadedConsensus : downloadedConsensuses.values()) { - if (downloadedConsensus.getValidAfterMillis() > - mostRecentValidAfterMillis) { - this.downloadedConsensus = downloadedConsensus; - mostRecentValidAfterMillis = - downloadedConsensus.getValidAfterMillis(); - } - } - if (this.downloadedConsensus != null) { - this.downloadedVotes = this.downloadedConsensus.getVotes(); - } - } - - /* Check if any directory authority didn't tell us a consensus. */ - private void checkMissingConsensuses() { - SortedSet<String> missingConsensuses = new TreeSet<String>( - Arrays.asList(("gabelmoo,tor26,ides,maatuska,dannenberg,urras," - + "moria1,dizum").split(","))); - missingConsensuses.removeAll(this.downloadedConsensuses.keySet()); - if (!missingConsensuses.isEmpty()) { - StringBuilder sb = new StringBuilder(); - for (String nickname : missingConsensuses) { - sb.append(", " + nickname); - } - this.warnings.put("The following directory authorities did not " - + "return a consensus within a timeout of 60 seconds: " - + sb.toString().substring(2), 150L * 60L * 1000L); - } - } - - /* Check if all consensuses are fresh. */ - private void checkAllConsensusesFresh() { - long fresh = System.currentTimeMillis() - 60L * 60L * 1000L; - SortedSet<String> nonFresh = new TreeSet<String>(); - for (Map.Entry<String, Status> e : downloadedConsensuses.entrySet()) { - String nickname = e.getKey(); - Status downloadedConsensus = e.getValue(); - if (downloadedConsensus.getValidAfterMillis() < fresh) { - nonFresh.add(nickname); - } - } - if (!nonFresh.isEmpty()) { - StringBuilder sb = new StringBuilder(); - for (String nickname : nonFresh) { - sb.append(", " + nickname); - } - this.warnings.put("The consensuses published by the following " - + "directory authorities are more than 1 hour old and " - + "therefore not fresh anymore: " - + sb.toString().substring(2), 150L * 60L * 1000L); - } - } - - /* Check if the most recent consensus is older than 1 hour. */ - private boolean isConsensusFresh(Status consensus) { - if (consensus.getValidAfterMillis() < - System.currentTimeMillis() - 60L * 60L * 1000L) { - return false; - } else { - return true; - } - } - - /* Check supported consensus methods of all votes. */ - private void checkConsensusMethods() { - for (Status vote : this.downloadedVotes) { - if (!vote.getConsensusMethods().contains( - this.downloadedConsensus.getConsensusMethods().last())) { - this.warnings.put(vote.getNickname() + " does not " - + "support consensus method " - + this.downloadedConsensus.getConsensusMethods().last(), - 24L * 60L * 60L * 1000L); - } - } - } - - /* Check if the recommended versions in a vote are different from the - * recommended versions in the consensus. */ - private void checkRecommendedVersions() { - for (Status vote : this.downloadedVotes) { - if (vote.getRecommendedClientVersions() != null && - !downloadedConsensus.getRecommendedClientVersions().equals( - vote.getRecommendedClientVersions())) { - StringBuilder message = new StringBuilder(); - message.append(vote.getNickname() + " recommends other " - + "client versions than the consensus:"); - for (String version : vote.getRecommendedClientVersions()) { - message.append(" " + version); - } - this.warnings.put(message.toString(), 150L * 60L * 1000L); - } - if (vote.getRecommendedServerVersions() != null && - !downloadedConsensus.getRecommendedServerVersions().equals( - vote.getRecommendedServerVersions())) { - StringBuilder message = new StringBuilder(); - message.append(vote.getNickname() + " recommends other " - + "server versions than the consensus:"); - for (String version : vote.getRecommendedServerVersions()) { - message.append(" " + version); - } - this.warnings.put(message.toString(), 150L * 60L * 1000L); - } - } - } - - /* Check if a vote contains conflicting or invalid consensus - * parameters. */ - private void checkConsensusParameters() { - Set<String> validParameters = new HashSet<String>(Arrays.asList( - ("circwindow,CircuitPriorityHalflifeMsec,refuseunknownexits," - + "cbtdisabled,cbtnummodes,cbtrecentcount,cbtmaxtimeouts," - + "cbtmincircs,cbtquantile,cbtclosequantile,cbttestfreq," - + "cbtmintimeout,cbtinitialtimeout,bwauthpid").split(","))); - for (Status vote : this.downloadedVotes) { - Map<String, String> voteConsensusParams = - vote.getConsensusParams(); - boolean conflictOrInvalid = false; - if (voteConsensusParams != null) { - for (Map.Entry<String, String> e : - voteConsensusParams.entrySet()) { - if (!downloadedConsensus.getConsensusParams().containsKey( - e.getKey()) || - !downloadedConsensus.getConsensusParams().get(e.getKey()). - equals(e.getValue()) || - !validParameters.contains(e.getKey())) { - StringBuilder message = new StringBuilder(); - message.append(vote.getNickname() + " sets conflicting or " - + "invalid consensus parameters:"); - for (Map.Entry<String, String> p : - voteConsensusParams.entrySet()) { - message.append(" " + p.getKey() + "=" + p.getValue()); - } - this.warnings.put(message.toString(), 150L * 60L * 1000L); - break; - } - } - } - } - } - - /* Check whether any of the authority keys expire in the next 14 - * days. */ - private void checkAuthorityKeys() { - for (Status vote : this.downloadedVotes) { - long voteDirKeyExpiresMillis = vote.getDirKeyExpiresMillis(); - if (voteDirKeyExpiresMillis - 14L * 24L * 60L * 60L * 1000L < - System.currentTimeMillis()) { - this.warnings.put(vote.getNickname() + "'s certificate " - + "expires in the next 14 days: " - + dateTimeFormat.format(voteDirKeyExpiresMillis), - 24L * 60L * 60L * 1000L); - } - } - } - - /* Check if any votes are missing. */ - private void checkMissingVotes() { - SortedSet<String> knownAuthorities = new TreeSet<String>( - Arrays.asList(("dannenberg,dizum,gabelmoo,ides,maatuska,moria1," - + "tor26,urras").split(","))); - SortedSet<String> missingVotes = - new TreeSet<String>(knownAuthorities); - for (Status vote : this.downloadedVotes) { - missingVotes.remove(vote.getNickname()); - } - if (!missingVotes.isEmpty()) { - StringBuilder sb = new StringBuilder(); - for (String missingDir : missingVotes) { - sb.append(", " + missingDir); - } - this.warnings.put("We're missing votes from the following " - + "directory authorities: " + sb.toString().substring(2), - 150L * 60L * 1000L); - } - } - - /* Check if any bandwidth scanner results are missing. */ - private void checkBandwidthScanners() { - SortedSet<String> missingBandwidthScanners = new TreeSet<String>( - Arrays.asList("ides,urras,moria1,gabelmoo,maatuska".split(","))); - for (Status vote : this.downloadedVotes) { - if (vote.getBandwidthWeights() > 0) { - missingBandwidthScanners.remove(vote.getNickname()); - } - } - if (!missingBandwidthScanners.isEmpty()) { - StringBuilder sb = new StringBuilder(); - for (String dir : missingBandwidthScanners) { - sb.append(", " + dir); - } - this.warnings.put("The following directory authorities are not " - + "reporting bandwidth scanner results: " - + sb.toString().substring(2), 150L * 60L * 1000L); - } - } - /* Prepare a report to be written to stdout. */ private String preparedReport = null; private void prepareReport() { + SortedMap<String, Long> warningStrings = new TreeMap<String, Long>(); + for (Map.Entry<Warning, String> e : this.warnings.entrySet()) { + Warning type = e.getKey(); + String details = e.getValue(); + switch (type) { + case NoConsensusKnown: + break; + case ConsensusDownloadTimeout: + warningStrings.put("The following directory authorities did " + + "not return a consensus within a timeout of 60 seconds: " + + details, 150L * 60L * 1000L); + break; + case ConsensusNotFresh: + warningStrings.put("The consensuses published by the following " + + "directory authorities are more than 1 hour old and " + + "therefore not fresh anymore: " + details, + 150L * 60L * 1000L); + break; + case ConsensusMethodNotSupported: + warningStrings.put("The following directory authorities do not " + + "support the consensus method that the consensus uses: " + + details, 24L * 60L * 60L * 1000L); + break; + case DifferentRecommendedClientVersions: + warningStrings.put("The following directory authorities " + + "recommend other client versions than the consensus: " + + details, 150L * 60L * 1000L); + break; + case DifferentRecommendedServerVersions: + warningStrings.put("The following directory authorities " + + "recommend other server versions than the consensus: " + + details, 150L * 60L * 1000L); + break; + case ConflictingOrInvalidConsensusParams: + warningStrings.put("The following directory authorities set " + + "conflicting or invalid consensus parameters: " + details, + 150L * 60L * 1000L); + break; + case CertificateExpiresSoon: + warningStrings.put("The certificates of the following " + + "directory authorities expire within the next 14 days: " + + details, 24L * 60L * 60L * 1000L); + break; + case VotesMissing: + warningStrings.put("We're missing votes from the following " + + "directory authorities: " + details, 150L * 60L * 1000L); + break; + case BandwidthScannerResultsMissing: + warningStrings.put("The following directory authorities are " + + "not reporting bandwidth scanner results: " + details, + 150L * 60L * 1000L); + break; + } + } long now = System.currentTimeMillis(); boolean writeReport = false; - for (Map.Entry<String, Long> e : this.warnings.entrySet()) { + for (Map.Entry<String, Long> e : warningStrings.entrySet()) { String message = e.getKey(); long warnInterval = e.getValue(); if (!lastWarned.containsKey(message) || @@ -305,7 +147,7 @@ public class StdOutReport implements Report { } if (writeReport) { StringBuilder sb = new StringBuilder(); - for (String message : this.warnings.keySet()) { + for (String message : warningStrings.keySet()) { this.lastWarned.put(message, now); sb.append("\n\n" + message); } diff --git a/src/org/torproject/chc/Warning.java b/src/org/torproject/chc/Warning.java new file mode 100644 index 0000000..3425c6c --- /dev/null +++ b/src/org/torproject/chc/Warning.java @@ -0,0 +1,46 @@ +/* Copyright 2011 The Tor Project + * See LICENSE for licensing information */ +package org.torproject.chc; + +/* Warning about irregularities in parsed consensuses and votes. */ +public enum Warning { + + /* No consensus is known that can be checked. */ + NoConsensusKnown, + + /* One or more directory authorities did not return a consensus within a + * timeout of 60 seconds. */ + ConsensusDownloadTimeout, + + /* One or more directory authorities published a consensus that is more + * than 1 hour old and therefore not fresh anymore. */ + ConsensusNotFresh, + + /* One or more directory authorities does not support the consensus + * method that the consensus uses. */ + ConsensusMethodNotSupported, + + /* One or more directory authorities recommends different client + * versions than the ones in the consensus. */ + DifferentRecommendedClientVersions, + + /* One or more directory authorities recommends different server + * versions than the ones in the consensus. */ + DifferentRecommendedServerVersions, + + /* One or more directory authorities set conflicting or invalid + * consensus parameters. */ + ConflictingOrInvalidConsensusParams, + + /* The certificate(s) of one or more directory authorities expire within + * the next 14 days. */ + CertificateExpiresSoon, + + /* The vote(s) of one or more directory authorities are missing. */ + VotesMissing, + + /* One or more directory authorities are not reporting bandwidth scanner + * results. */ + BandwidthScannerResultsMissing +} +