commit 98b595e62dc63053360dc2a99504b36779e1f253 Author: Karsten Loesing karsten.loesing@gmx.net Date: Thu Dec 8 11:32:32 2011 +0100
Remember fetch times when requesting consensuses. --- src/org/torproject/doctor/Download.java | 38 +++++++++++++++ src/org/torproject/doctor/Downloader.java | 73 +++++++++++++++-------------- src/org/torproject/doctor/Main.java | 4 +- src/org/torproject/doctor/Parser.java | 23 ++++++---- src/org/torproject/doctor/Status.java | 9 ++++ 5 files changed, 101 insertions(+), 46 deletions(-)
diff --git a/src/org/torproject/doctor/Download.java b/src/org/torproject/doctor/Download.java new file mode 100644 index 0000000..35c24f9 --- /dev/null +++ b/src/org/torproject/doctor/Download.java @@ -0,0 +1,38 @@ +/* Copyright 2011 The Tor Project + * See LICENSE for licensing information */ +package org.torproject.doctor; + +public class Download { + + /* Nickname of the authority from which this download was made. */ + private String authority; + public String getAuthority() { + return this.authority; + } + + /* Request URL. */ + private String url; + public String getUrl() { + return this.url; + } + + /* Unparsed response string. */ + private String responseString; + public String getResponseString() { + return this.responseString; + } + + /* Fetch time in millis. */ + private long fetchTime; + public long getFetchTime() { + return this.fetchTime; + } + + public Download(String authority, String url, String responseString, + long fetchTime) { + this.authority = authority; + this.responseString = responseString; + this.fetchTime = fetchTime; + } +} + diff --git a/src/org/torproject/doctor/Downloader.java b/src/org/torproject/doctor/Downloader.java index 3125062..c929a96 100755 --- a/src/org/torproject/doctor/Downloader.java +++ b/src/org/torproject/doctor/Downloader.java @@ -37,8 +37,8 @@ public class Downloader { }
/* Download the most recent consensus from all authorities. */ - private SortedMap<String, String> downloadedConsensuses = - new TreeMap<String, String>(); + private List<Download> downloadedConsensuses = + new ArrayList<Download>(); private void downloadConsensus() { Map<String, String> urls = new HashMap<String, String>(); for (Map.Entry<String, String> e : this.authorities.entrySet()) { @@ -46,19 +46,10 @@ public class Downloader { String address = e.getValue(); String resource = "/tor/status-vote/current/consensus.z"; String fullUrl = "http://" + address + resource; - urls.put(nickname, fullUrl); - } - Map<String, String> responses = - this.downloadFromAuthority(new HashSet<String>(urls.values())); - for (Map.Entry<String, String> e : urls.entrySet()) { - String nickname = e.getKey(); - String url = e.getValue(); - if (responses.containsKey(url)) { - String response = responses.get(url); - this.downloadedConsensuses.put(nickname, response); - } + urls.put(fullUrl, nickname); } - if (responses.isEmpty()) { + this.downloadedConsensuses = this.downloadFromAuthority(urls); + if (this.downloadedConsensuses.isEmpty()) { System.err.println("Could not download consensus from any of the " + "directory authorities. Ignoring."); } @@ -68,14 +59,18 @@ public class Downloader { * interrupted after a timeout. */ private static class DownloadRunnable implements Runnable { Thread mainThread; + String nickname; String url; String response; boolean finished = false; - public DownloadRunnable(String url) { + long requestStart = 0L, requestEnd = 0L; + public DownloadRunnable(String nickname, String url) { this.mainThread = Thread.currentThread(); + this.nickname = nickname; this.url = url; } public void run() { + this.requestStart = System.currentTimeMillis(); try { URL u = new URL(this.url); HttpURLConnection huc = (HttpURLConnection) u.openConnection(); @@ -105,16 +100,28 @@ public class Downloader { /* Can't do much except leaving this.response at null. */ } this.finished = true; + this.requestEnd = System.currentTimeMillis(); + } + public Download getDownload() { + Download result = null; + if (this.response != null) { + result = new Download(this.nickname, this.url, this.response, + this.requestEnd - this.requestStart); + } + return result; } }
/* Download one or more consensuses or votes from one or more directory * authorities using a timeout of 60 seconds. */ - private Map<String, String> downloadFromAuthority(Set<String> urls) { + private List<Download> downloadFromAuthority(Map<String, String> urls) { Set<DownloadRunnable> downloadRunnables = new HashSet<DownloadRunnable>(); - for (String url : urls) { - DownloadRunnable downloadRunnable = new DownloadRunnable(url); + for (Map.Entry<String, String> e : urls.entrySet()) { + String url = e.getKey(); + String nickname = e.getValue(); + DownloadRunnable downloadRunnable = new DownloadRunnable(nickname, + url); downloadRunnables.add(downloadRunnable); new Thread(downloadRunnable).start(); } @@ -137,12 +144,11 @@ public class Downloader { break; } } - Map<String, String> responses = new HashMap<String, String>(); + List<Download> responses = new ArrayList<Download>(); for (DownloadRunnable downloadRunnable : downloadRunnables) { - String url = downloadRunnable.url; - String response = downloadRunnable.response; - if (response != null) { - responses.put(url, response); + Download download = downloadRunnable.getDownload(); + if (download != null) { + responses.add(download); } downloadRunnable.finished = true; } @@ -160,8 +166,8 @@ public class Downloader { * authorities publishing the corresponding votes. */ private SortedSet<String> fingerprints = new TreeSet<String>(); private void parseConsensusToFindReferencedVotes() { - for (String downloadedConsensus : - this.downloadedConsensuses.values()) { + for (Download download : this.downloadedConsensuses) { + String downloadedConsensus = download.getResponseString(); try { BufferedReader br = new BufferedReader(new StringReader( downloadedConsensus)); @@ -208,7 +214,7 @@ public class Downloader {
/* Download the votes published by directory authorities listed in the * consensus. */ - private List<String> downloadedVotes = new ArrayList<String>(); + private List<Download> downloadedVotes = new ArrayList<Download>(); private void downloadReferencedVotes() { for (String fingerprint : this.fingerprints) { String downloadedVote = null; @@ -222,26 +228,21 @@ public class Downloader { String resource = "/tor/status-vote/current/" + fingerprint + ".z"; String fullUrl = "http://" + authority + resource; - Set<String> urls = new HashSet<String>(); - urls.add(fullUrl); - Map<String, String> downloadedVotes = - this.downloadFromAuthority(urls); - if (downloadedVotes.containsKey(fullUrl)) { - downloadedVote = downloadedVotes.get(fullUrl); - this.downloadedVotes.add(downloadedVote); - } + Map<String, String> urls = new HashMap<String, String>(); + urls.put(fullUrl, authority); + this.downloadedVotes = this.downloadFromAuthority(urls); } } }
/* Return the previously downloaded (unparsed) consensus string by * authority nickname. */ - public SortedMap<String, String> getConsensusStrings() { + public List<Download> getConsensuses() { return this.downloadedConsensuses; }
/* Return the previously downloaded (unparsed) vote strings. */ - public List<String> getVoteStrings() { + public List<Download> getVotes() { return this.downloadedVotes; } } diff --git a/src/org/torproject/doctor/Main.java b/src/org/torproject/doctor/Main.java index 47f3f0b..ec160e9 100755 --- a/src/org/torproject/doctor/Main.java +++ b/src/org/torproject/doctor/Main.java @@ -19,11 +19,13 @@ public class Main { * authorities. */ Downloader downloader = new Downloader(); downloader.downloadFromAuthorities(); + List<Download> downloadedConsensuses = downloader.getConsensuses(); + List<Download> downloadedVotes = downloader.getVotes();
/* Parse consensus and votes. */ Parser parser = new Parser(); SortedMap<String, Status> parsedDownloadedConsensuses = parser.parse( - downloader.getConsensusStrings(), downloader.getVoteStrings()); + downloadedConsensuses, downloadedVotes);
/* Check consensus and votes for possible problems. */ Checker checker = new Checker(); diff --git a/src/org/torproject/doctor/Parser.java b/src/org/torproject/doctor/Parser.java index 36abd78..9a91033 100755 --- a/src/org/torproject/doctor/Parser.java +++ b/src/org/torproject/doctor/Parser.java @@ -13,22 +13,26 @@ public class Parser { /* Parse and return a consensus and corresponding votes, or null if * something goes wrong. */ public SortedMap<String, Status> parse( - SortedMap<String, String> consensusStrings, - List<String> voteStrings) { + List<Download> downloadedConsensuses, + List<Download> downloadedVotes) { SortedSet<Status> parsedVotes = new TreeSet<Status>(); - for (String voteString : voteStrings) { - Status parsedVote = this.parseConsensusOrVote(voteString, false); + for (Download downloadedVote : downloadedVotes) { + String voteString = downloadedVote.getResponseString(); + long fetchTime = downloadedVote.getFetchTime(); + Status parsedVote = this.parseConsensusOrVote(voteString, fetchTime, + false); if (parsedVote != null) { parsedVotes.add(parsedVote); } } SortedMap<String, Status> parsedConsensuses = new TreeMap<String, Status>(); - for (Map.Entry<String, String> e : consensusStrings.entrySet()) { - String nickname = e.getKey(); - String consensusString = e.getValue(); + for (Download downloadedConsensus : downloadedConsensuses) { + String nickname = downloadedConsensus.getAuthority(); + String consensusString = downloadedConsensus.getResponseString(); + long fetchTime = downloadedConsensus.getFetchTime(); Status parsedConsensus = this.parseConsensusOrVote(consensusString, - true); + fetchTime, true); if (parsedConsensus != null) { for (Status parsedVote : parsedVotes) { if (parsedConsensus.getValidAfterMillis() == @@ -50,13 +54,14 @@ public class Parser { }
/* Parse a consensus or vote string into a Status instance. */ - private Status parseConsensusOrVote(String statusString, + private Status parseConsensusOrVote(String statusString, long fetchTime, boolean isConsensus) { if (statusString == null) { return null; } Status status = new Status(); status.setUnparsedString(statusString); + status.setFetchTime(fetchTime); try { BufferedReader br = new BufferedReader(new StringReader( statusString)); diff --git a/src/org/torproject/doctor/Status.java b/src/org/torproject/doctor/Status.java index 40a7225..0573ae2 100755 --- a/src/org/torproject/doctor/Status.java +++ b/src/org/torproject/doctor/Status.java @@ -29,6 +29,15 @@ public class Status implements Comparable<Status> { return this.unparsedString; }
+ /* Fetch time in millis. */ + private long fetchTime; + public void setFetchTime(long fetchTime) { + this.fetchTime = fetchTime; + } + public long getFetchTime() { + return this.fetchTime; + } + /* Votes published at the same time as this consensus; votes don't * reference any statuses. */ private SortedSet<Status> votes = new TreeSet<Status>();
tor-commits@lists.torproject.org