tor-commits
Threads by month
- ----- 2026 -----
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 214893 discussions
14 Dec '11
commit 960f62bd82c249b456a0aa2e1ae62f68c754aacb
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Wed Dec 14 16:03:58 2011 -0500
Start a section for the 0.2.3.10-alpha changelog
---
ChangeLog | 24 ++++++++++++++++++++++++
changes/bug4655 | 10 ----------
changes/bug4691 | 4 ----
changes/bug4702 | 6 ------
changes/geoip-december2011 | 3 ---
5 files changed, 24 insertions(+), 23 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index e0182af..2fe0711 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+Changes in version 0.2.3.10-alpha - 201?-??-??
+
+
+ o Minor bugfixes:
+ - If we can't attach streams to a rendezvous circuit when we
+ finish connecting to a hidden service, clear the rendezvous
+ circuit's stream-isolation state and try to attach streams
+ again. Previously, we cleared rendezvous circuits' isolation
+ state either too early (if they were freshly built) or not at
+ all (if they had been built earlier and were cannibalized).
+ Bugfix on 0.2.3.3-alpha; fixes bug 4655.
+ - Fix compilation of the libnatpmp helper on non-Windows. Bugfix on
+ 0.2.3.9-alpha; fixes bug 4691. Reported by Anthony G. Basile.
+
+ o Minor bugfixes:
+ - Fix an assertion failure when a relay with accounting enabled
+ starts up while dormant. Fixes bug 4702; bugfix on
+ 0.2.3.9-alpha.
+
+ o Minor features:
+ - Update to the December 6 2011 Maxmind GeoLite Country database.
+
+
+
Changes in version 0.2.3.9-alpha - 2011-12-08
Tor 0.2.3.9-alpha introduces initial IPv6 support for bridges, adds
a "DisableNetwork" security feature that bundles can use to avoid
diff --git a/changes/bug4655 b/changes/bug4655
deleted file mode 100644
index b91d871..0000000
--- a/changes/bug4655
+++ /dev/null
@@ -1,10 +0,0 @@
- o Minor bugfixes:
-
- - If we can't attach streams to a rendezvous circuit when we
- finish connecting to a hidden service, clear the rendezvous
- circuit's stream-isolation state and try to attach streams
- again. Previously, we cleared rendezvous circuits' isolation
- state either too early (if they were freshly built) or not at
- all (if they had been built earlier and were cannibalized).
- Bugfix on 0.2.3.3-alpha; fixes bug 4655.
-
diff --git a/changes/bug4691 b/changes/bug4691
deleted file mode 100644
index 124b8f8..0000000
--- a/changes/bug4691
+++ /dev/null
@@ -1,4 +0,0 @@
- o Major bugfixes:
- - Fix compilation of the libnatpmp helper on non-Windows. Bugfix on
- 0.2.3.9-alpha; fixes bug 4691. Reported by Anthony G. Basile.
-
diff --git a/changes/bug4702 b/changes/bug4702
deleted file mode 100644
index dcd3bfc..0000000
--- a/changes/bug4702
+++ /dev/null
@@ -1,6 +0,0 @@
- o Minor bugfixes:
-
- - Fix an assertion failure when a relay with accounting enabled
- starts up while dormant. Fixes bug 4702; bugfix on
- 0.2.3.9-alpha.
-
diff --git a/changes/geoip-december2011 b/changes/geoip-december2011
deleted file mode 100644
index 82a708d..0000000
--- a/changes/geoip-december2011
+++ /dev/null
@@ -1,3 +0,0 @@
- o Minor features:
- - Update to the December 6 2011 Maxmind GeoLite Country database.
-
1
0
[tor/release-0.2.2] Merge changes files for 0.2.2.35; start work on a blurb
by nickm@torproject.org 14 Dec '11
by nickm@torproject.org 14 Dec '11
14 Dec '11
commit ed4653905022ee8544dbe576fa29a85e230bfa93
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Wed Dec 14 16:01:33 2011 -0500
Merge changes files for 0.2.2.35; start work on a blurb
---
ChangeLog | 26 +++++++++++++++++++++++---
changes/bug4529 | 5 -----
changes/bug4530 | 6 ------
changes/bug4531 | 4 ----
changes/bug4535 | 3 ---
changes/geoip-december2011 | 3 ---
6 files changed, 23 insertions(+), 24 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 08fda38..a8f677b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,15 @@
-Changes in version 0.2.2.35 - 2011-11-??
+Changes in version 0.2.2.35 - 2011-12-1?
- Formalize end-of-life for 0.2.0.
+ Tor 0.2.2.35 fixes several bugs in previous versions, including
+ crash bugs for unusual configurations, and a long-term bug that
+ would that would prevent Tor from starting on Windows machines with
+ draconian AV software.
+
+ With this release, we remind everyone that 0.2.0.x has reached its
+ formal end-of-life. Those Tor versions have many known flaws, and
+ nobody should be using them. You should upgrade--ideally to the
+ 0.2.2.x series. If you're using a Linux or BSD and its packages are
+ obsolete, stop using those packages and upgrade anyway.
o Major bugfixes:
- Initialize Libevent with the EVENT_BASE_FLAG_NOLOCK flag enabled, so
@@ -55,6 +64,17 @@ Changes in version 0.2.2.35 - 2011-11-??
in ExcludeNodes. Fixes bug 4383; bugfix on 0.2.2.25-alpha.
- Backport fixes for a pair of compilation warnings on Windows.
Fixes bug 4521; bugfix on 0.2.2.28-beta and on 0.2.2.29-beta.
+ - If we had ever tried to call tor_addr_to_str on an address of
+ unknown type, we would have done a strdup on an uninitialized
+ buffer. Now we won't. Fixes bug 4529; bugfix on 0.2.1.3-alpha.
+ Reported by "troll_un".
+ - Correctly detect and handle transient lookup failures from
+ tor_addr_lookup. Fixes bug 4530; bugfix on 0.2.1.5-alpha.
+ Reported by "troll_un".
+ - Fix null-pointer access that could occur if TLS allocation failed.
+ Fixes bug 4531; bugfix on 0.2.0.20-rc. Found by "troll_un".
+ - Use tor_socket_t type for listener argument to accept(). Fixes bug
+ 4535; bugfix on 0.2.2.28-beta. Found by "troll_un".
o Minor features:
- Add two new config options for directory authorities:
@@ -67,7 +87,7 @@ Changes in version 0.2.2.35 - 2011-11-??
include the hidden service's directory in the warning message.
Previously, we would only tell the user that some hidden service
was ignored. Bugfix on 0.0.6; fixes bug 4426.
- - Update to the November 1 2011 Maxmind GeoLite Country database.
+ - Update to the December 6 2011 Maxmind GeoLite Country database.
o Packaging changes:
- Make it easier to automate expert package builds on Windows,
diff --git a/changes/bug4529 b/changes/bug4529
deleted file mode 100644
index 89d10b2..0000000
--- a/changes/bug4529
+++ /dev/null
@@ -1,5 +0,0 @@
- o Minor bufixes:
- - If we had ever tried to call tor_addr_to_str on an address of
- unknown type, we would have done a strdup on an uninitialized
- buffer. Now we won't. Fixes bug 4529; bugfix on 0.2.1.3-alpha.
- Reported by "troll_un".
diff --git a/changes/bug4530 b/changes/bug4530
deleted file mode 100644
index 7cd4726..0000000
--- a/changes/bug4530
+++ /dev/null
@@ -1,6 +0,0 @@
- o Minor bugfixes:
-
- - Correctly detect and handle transient lookup failures from
- tor_addr_lookup. Fixes bug 4530; bugfix on 0.2.1.5-alpha.
- Reported by "troll_un".
-
diff --git a/changes/bug4531 b/changes/bug4531
deleted file mode 100644
index 6209f9a..0000000
--- a/changes/bug4531
+++ /dev/null
@@ -1,4 +0,0 @@
- o Major bugfixes:
- - Fix null-pointer access that could occur if TLS allocation failed.
- Fixes bug 4531; bugfix on 0.2.0.20-rc. Found by "troll_un".
-
diff --git a/changes/bug4535 b/changes/bug4535
deleted file mode 100644
index 57ced29..0000000
--- a/changes/bug4535
+++ /dev/null
@@ -1,3 +0,0 @@
- o Minor bugfixes:
- - Use tor_socket_t type for listener argument to accept(). Fixes bug
- 4535; bugfix on 0.2.2.28-beta. Found by "troll_un".
diff --git a/changes/geoip-december2011 b/changes/geoip-december2011
deleted file mode 100644
index 82a708d..0000000
--- a/changes/geoip-december2011
+++ /dev/null
@@ -1,3 +0,0 @@
- o Minor features:
- - Update to the December 6 2011 Maxmind GeoLite Country database.
-
1
0
14 Dec '11
commit 228d6564f8e7b6bec635216d64282423f407025a
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Wed Dec 14 19:17:26 2011 +0100
Make consensus parsing a lot more robust.
---
src/org/torproject/descriptor/DirSourceEntry.java | 3 +
.../torproject/descriptor/NetworkStatusEntry.java | 25 +-
.../descriptor/RelayNetworkStatusConsensus.java | 17 +-
.../descriptor/impl/DescriptorParseException.java | 10 +
.../descriptor/impl/DirSourceEntryImpl.java | 115 +++-
.../descriptor/impl/NetworkStatusEntryImpl.java | 217 ++++--
.../torproject/descriptor/impl/ParseHelper.java | 147 +++
.../impl/RelayNetworkStatusConsensusImpl.java | 430 ++++++---
.../impl/RelayNetworkStatusVoteImpl.java | 15 +-
.../impl/RelayNetworkStatusConsensusImplTest.java | 932 ++++++++++++--------
10 files changed, 1307 insertions(+), 604 deletions(-)
diff --git a/src/org/torproject/descriptor/DirSourceEntry.java b/src/org/torproject/descriptor/DirSourceEntry.java
index 57ce684..190b1df 100644
--- a/src/org/torproject/descriptor/DirSourceEntry.java
+++ b/src/org/torproject/descriptor/DirSourceEntry.java
@@ -22,6 +22,9 @@ public interface DirSourceEntry {
/* Return the ORPort. */
public int getOrPort();
+ /* Return whether the dir-source was created using a legacy key. */
+ public boolean isLegacy();
+
/* Return the contact line. */
public String getContactLine();
diff --git a/src/org/torproject/descriptor/NetworkStatusEntry.java b/src/org/torproject/descriptor/NetworkStatusEntry.java
index 156d07b..5d48818 100644
--- a/src/org/torproject/descriptor/NetworkStatusEntry.java
+++ b/src/org/torproject/descriptor/NetworkStatusEntry.java
@@ -30,16 +30,29 @@ public interface NetworkStatusEntry {
/* Return the DirPort. */
public int getDirPort();
- /* Return the relay flags. */
+ /* Return the relay flags or null if the status entry didn't contain any
+ * relay flags. */
public SortedSet<String> getFlags();
- /* Return the Tor software version. */
+ /* Return the Tor software version or null if the status entry didn't
+ * contain a version line. */
public String getVersion();
- /* Return the bandwidth weight line. */
- public String getBandwidth();
+ /* Return the bandwidth weight or -1L if the status entry didn't
+ * contain a bandwidth line. */
+ public long getBandwidth();
- /* Return the port summary line. */
- public String getPorts();
+ /* Return the measured bandwidth or -1L if the status entry didn't
+ * contain a bandwidth line or didn't contain a Measured= keyword in its
+ * bandwidth line. */
+ public long getMeasured();
+
+ /* Return the default policy of the port summary or null if the status
+ * entry didn't contain a port summary line. */
+ public String getDefaultPolicy();
+
+ /* Return the port list of the port summary or null if the status entry
+ * didn't contain a port summary line. */
+ public String getPortList();
}
diff --git a/src/org/torproject/descriptor/RelayNetworkStatusConsensus.java b/src/org/torproject/descriptor/RelayNetworkStatusConsensus.java
index 17beeb5..42757ce 100644
--- a/src/org/torproject/descriptor/RelayNetworkStatusConsensus.java
+++ b/src/org/torproject/descriptor/RelayNetworkStatusConsensus.java
@@ -24,8 +24,11 @@ public interface RelayNetworkStatusConsensus extends Descriptor {
/* Return the valid-until time in milliseconds. */
public long getValidUntilMillis();
- /* Return a list of the voting-delay times in seconds. */
- public List<Long> getVotingDelay();
+ /* Return the VoteSeconds time in seconds. */
+ public long getVoteSeconds();
+
+ /* Return the DistSeconds time in seconds. */
+ public long getDistSeconds();
/* Return recommended server versions or null if the consensus doesn't
* contain recommended server versions. */
@@ -38,8 +41,9 @@ public interface RelayNetworkStatusConsensus extends Descriptor {
/* Return known relay flags. */
public SortedSet<String> getKnownFlags();
- /* Return consensus parameters. */
- public SortedMap<String, String> getConsensusParams();
+ /* Return consensus parameters or null if the consensus doesn't contain
+ * consensus parameters. */
+ public SortedMap<String, Integer> getConsensusParams();
/* Return dir-source entries representing the directories of which
* votes are contained in this consensus. */
@@ -58,7 +62,8 @@ public interface RelayNetworkStatusConsensus extends Descriptor {
/* Return directory signatures. */
public SortedMap<String, String> getDirectorySignatures();
- /* Return bandwidth weights. */
- public SortedMap<String, String> getBandwidthWeights();
+ /* Return bandwidth weights or null if the consensus doesn't contain
+ * bandwidth weights. */
+ public SortedMap<String, Integer> getBandwidthWeights();
}
diff --git a/src/org/torproject/descriptor/impl/DescriptorParseException.java b/src/org/torproject/descriptor/impl/DescriptorParseException.java
new file mode 100644
index 0000000..8670a3b
--- /dev/null
+++ b/src/org/torproject/descriptor/impl/DescriptorParseException.java
@@ -0,0 +1,10 @@
+/* Copyright 2011 The Tor Project
+ * See LICENSE for licensing information */
+package org.torproject.descriptor.impl;
+
+public class DescriptorParseException extends Exception {
+ protected DescriptorParseException(String message) {
+ super(message);
+ }
+}
+
diff --git a/src/org/torproject/descriptor/impl/DirSourceEntryImpl.java b/src/org/torproject/descriptor/impl/DirSourceEntryImpl.java
index a2d0b34..a38da87 100644
--- a/src/org/torproject/descriptor/impl/DirSourceEntryImpl.java
+++ b/src/org/torproject/descriptor/impl/DirSourceEntryImpl.java
@@ -6,6 +6,8 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.text.ParseException;
+import java.util.SortedSet;
+import java.util.TreeSet;
import org.torproject.descriptor.DirSourceEntry;
public class DirSourceEntryImpl implements DirSourceEntry {
@@ -16,30 +18,110 @@ public class DirSourceEntryImpl implements DirSourceEntry {
}
protected DirSourceEntryImpl(byte[] dirSourceEntryBytes)
- throws ParseException {
+ throws DescriptorParseException {
this.dirSourceEntryBytes = dirSourceEntryBytes;
+ this.initializeKeywords();
+ this.parseDirSourceEntryBytes();
+ this.checkKeywords();
+ }
+
+ private SortedSet<String> exactlyOnceKeywords, atMostOnceKeywords;
+ private void initializeKeywords() {
+ this.exactlyOnceKeywords = new TreeSet<String>();
+ this.exactlyOnceKeywords.add("dir-source");
+ this.exactlyOnceKeywords.add("vote-digest");
+ this.atMostOnceKeywords = new TreeSet<String>();
+ this.atMostOnceKeywords.add("contact");
+ }
+
+ private void parsedExactlyOnceKeyword(String keyword)
+ throws DescriptorParseException {
+ if (!this.exactlyOnceKeywords.contains(keyword)) {
+ throw new DescriptorParseException("Duplicate '" + keyword
+ + "' line in dir-source.");
+ }
+ this.exactlyOnceKeywords.remove(keyword);
+ }
+
+ private void parsedAtMostOnceKeyword(String keyword)
+ throws DescriptorParseException {
+ if (!this.atMostOnceKeywords.contains(keyword)) {
+ throw new DescriptorParseException("Duplicate " + keyword + "line "
+ + "in dir-source.");
+ }
+ this.atMostOnceKeywords.remove(keyword);
+ }
+
+ private void checkKeywords() throws DescriptorParseException {
+ if (!this.exactlyOnceKeywords.isEmpty()) {
+ throw new DescriptorParseException("dir-source does not contain a '"
+ + this.exactlyOnceKeywords.first() + "' line.");
+ }
+ }
+
+ private void parseDirSourceEntryBytes()
+ throws DescriptorParseException {
try {
BufferedReader br = new BufferedReader(new StringReader(
new String(this.dirSourceEntryBytes)));
String line;
while ((line = br.readLine()) != null) {
- if (line.startsWith("dir-source ")) {
- String[] parts = line.split(" ");
- this.nickname = parts[1];
- this.identity = parts[2];
- this.ip = parts[4];
- this.dirPort = Integer.parseInt(parts[5]);
- this.orPort = Integer.parseInt(parts[6]);
- } else if (line.startsWith("contact ")) {
- this.contactLine = line.substring("contact ".length());
- } else if (line.startsWith("vote-digest ")) {
- this.voteDigest = line.split(" ")[1];
+ if (line.startsWith("dir-source")) {
+ this.parseDirSourceLine(line);
+ } else if (line.startsWith("contact")) {
+ this.parseContactLine(line);
+ } else if (line.startsWith("vote-digest")) {
+ this.parseVoteDigestLine(line);
+ } else {
+ /* TODO Should we really throw an exception here? */
+ throw new DescriptorParseException("Unknown line '" + line
+ + "' in dir-source entry.");
}
}
} catch (IOException e) {
- /* TODO This cannot happen, right? */
+ throw new RuntimeException("Internal error: Ran into an "
+ + "IOException while parsing a String in memory. Something's "
+ + "really wrong.", e);
+ }
+ }
+
+ private void parseDirSourceLine(String line)
+ throws DescriptorParseException {
+ this.parsedExactlyOnceKeyword("dir-source");
+ String[] parts = line.split(" ");
+ String nickname = parts[1];
+ if (nickname.endsWith("-legacy")) {
+ nickname = nickname.substring(0, nickname.length()
+ - "-legacy".length());
+ this.isLegacy = true;
+ this.parsedExactlyOnceKeyword("vote-digest");
+ }
+ this.nickname = ParseHelper.parseNickname(line, nickname);
+ this.identity = ParseHelper.parseTwentyByteHexString(line, parts[2]);
+ this.ip = ParseHelper.parseIpv4Address(line, parts[4]);
+ this.dirPort = ParseHelper.parsePort(line, parts[5]);
+ this.orPort = ParseHelper.parsePort(line, parts[6]);
+ }
+
+ private void parseContactLine(String line)
+ throws DescriptorParseException {
+ this.parsedAtMostOnceKeyword("contact");
+ if (line.length() > "contact ".length()) {
+ this.contactLine = line.substring("contact ".length());
+ } else {
+ this.contactLine = "";
+ }
+ }
+
+ private void parseVoteDigestLine(String line)
+ throws DescriptorParseException {
+ this.parsedExactlyOnceKeyword("vote-digest");
+ String[] parts = line.split(" ");
+ if (parts.length != 2) {
+ throw new DescriptorParseException("Invalid line '" + line + "'.");
}
- /* TODO Implement some plausibility tests. */
+ this.voteDigest = ParseHelper.parseTwentyByteHexString(line,
+ parts[1]);
}
private String nickname;
@@ -52,6 +134,11 @@ public class DirSourceEntryImpl implements DirSourceEntry {
return this.identity;
}
+ private boolean isLegacy;
+ public boolean isLegacy() {
+ return this.isLegacy;
+ }
+
private String ip;
public String getIp() {
return this.ip;
diff --git a/src/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java b/src/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java
index 610fb1a..6612272 100644
--- a/src/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java
+++ b/src/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java
@@ -5,14 +5,10 @@ package org.torproject.descriptor.impl;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
import java.util.Arrays;
+import java.util.SortedMap;
import java.util.SortedSet;
-import java.util.TimeZone;
import java.util.TreeSet;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.codec.binary.Hex;
import org.torproject.descriptor.NetworkStatusEntry;
public class NetworkStatusEntryImpl implements NetworkStatusEntry {
@@ -22,60 +18,163 @@ public class NetworkStatusEntryImpl implements NetworkStatusEntry {
return this.statusEntryBytes;
}
- private static SimpleDateFormat dateTimeFormat;
- static {
- dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- dateTimeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
- }
-
protected NetworkStatusEntryImpl(byte[] statusEntryBytes)
- throws ParseException {
+ throws DescriptorParseException {
this.statusEntryBytes = statusEntryBytes;
+ this.initializeKeywords();
+ this.parseStatusEntryBytes();
+ }
+
+ private SortedSet<String> atMostOnceKeywords;
+ private void initializeKeywords() {
+ this.atMostOnceKeywords = new TreeSet<String>();
+ this.atMostOnceKeywords.add("s");
+ this.atMostOnceKeywords.add("v");
+ this.atMostOnceKeywords.add("w");
+ this.atMostOnceKeywords.add("p");
+ this.atMostOnceKeywords.add("m");
+ }
+
+ private void parsedAtMostOnceKeyword(String keyword)
+ throws DescriptorParseException {
+ if (!this.atMostOnceKeywords.contains(keyword)) {
+ throw new DescriptorParseException("Duplicate '" + keyword
+ + "' line in status entry.");
+ }
+ this.atMostOnceKeywords.remove(keyword);
+ }
+
+ private void parseStatusEntryBytes() throws DescriptorParseException {
try {
BufferedReader br = new BufferedReader(new StringReader(
new String(this.statusEntryBytes)));
- String line;
+ String line = br.readLine();
+ if (line == null || !line.startsWith("r ")) {
+ throw new DescriptorParseException("Status entry must start with "
+ + "an r line.");
+ }
+ String[] rLineParts = line.split(" ");
+ this.parseRLine(line, rLineParts);
while ((line = br.readLine()) != null) {
- if (line.startsWith("r ")) {
- String[] parts = line.split(" ");
- if (parts.length < 9) {
- throw new RuntimeException("r line '" + line + "' has fewer "
- + "space-separated elements than expected.");
- }
- this.nickname = parts[1];
- this.fingerprint = Hex.encodeHexString(Base64.decodeBase64(
- parts[2] + "=")).toLowerCase();
- this.descriptor = Hex.encodeHexString(Base64.decodeBase64(
- parts[3] + "=")).toLowerCase();
- this.publishedMillis = dateTimeFormat.parse(parts[4] + " "
- + parts[5]).getTime();
- this.address = parts[6];
- this.orPort = Integer.parseInt(parts[7]);
- this.dirPort = Integer.parseInt(parts[8]);
- } else if (line.equals("s")) {
- /* No flags to add. */
- } else if (line.startsWith("s ")) {
- this.flags.addAll(Arrays.asList(line.substring("s ".length()).
- split(" ")));
- } else if (line.startsWith("v ") || line.startsWith("opt v")) {
- this.version = line.substring(
- line.startsWith("v ") ? "v ".length() : "opt v".length());
- } else if (line.startsWith("w ")) {
- this.bandwidth = line.substring("w ".length());
- } else if (line.startsWith("p ")) {
- this.ports = line.substring(2);
- } else if (line.startsWith("m ")) {
- /* TODO Parse m lines in votes. */
+ String[] parts = !line.startsWith("opt ") ? line.split(" ") :
+ line.substring("opt ".length()).split(" ");
+ String keyword = parts[0];
+ if (keyword.equals("s")) {
+ this.parseSLine(line, parts);
+ } else if (keyword.equals("v")) {
+ this.parseVLine(line, parts);
+ } else if (keyword.equals("w")) {
+ this.parseWLine(line, parts);
+ } else if (keyword.equals("p")) {
+ this.parsePLine(line, parts);
+ } else if (keyword.equals("m")) {
+ this.parseMLine(line, parts);
} else {
- throw new RuntimeException("Unknown line '" + line + "' in "
- + "status entry.");
+ /* TODO Is throwing an exception the right thing to do here?
+ * This is probably fine for development, but once the library
+ * is in production use, this seems annoying. */
+ throw new DescriptorParseException("Unknown line '" + line
+ + "' in status entry.");
}
}
} catch (IOException e) {
- /* TODO Do something. */
+ throw new RuntimeException("Internal error: Ran into an "
+ + "IOException while parsing a String in memory. Something's "
+ + "really wrong.", e);
+ }
+ }
+
+ private void parseRLine(String line, String[] parts)
+ throws DescriptorParseException {
+ if (parts.length < 9) {
+ throw new RuntimeException("r line '" + line + "' has fewer "
+ + "space-separated elements than expected.");
+ }
+ this.nickname = ParseHelper.parseNickname(line, parts[1]);
+ this.fingerprint = ParseHelper.parseTwentyByteBase64String(line,
+ parts[2]);
+ this.descriptor = ParseHelper.parseTwentyByteBase64String(line,
+ parts[3]);
+ this.publishedMillis = ParseHelper.parseTimestampAtIndex(line, parts,
+ 4, 5);
+ this.address = ParseHelper.parseIpv4Address(line, parts[6]);
+ this.orPort = ParseHelper.parsePort(line, parts[7]);
+ this.dirPort = ParseHelper.parsePort(line, parts[8]);
+ }
+
+ private void parseSLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedAtMostOnceKeyword("s");
+ this.flags = new TreeSet<String>();
+ for (int i = 1; i < parts.length; i++) {
+ this.flags.add(parts[i]);
+ }
+ }
+
+ private void parseVLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedAtMostOnceKeyword("v");
+ String noOptLine = line;
+ if (noOptLine.startsWith("opt ")) {
+ noOptLine = noOptLine.substring(4);
+ }
+ if (noOptLine.length() < 3) {
+ throw new DescriptorParseException("Invalid line '" + line + "' in "
+ + "status entry.");
+ } else {
+ this.version = noOptLine.substring(2);
+ }
+ }
+
+ private void parseWLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedAtMostOnceKeyword("w");
+ SortedMap<String, Integer> pairs = ParseHelper.parseKeyValuePairs(
+ line, parts, 1);
+ if (pairs.isEmpty()) {
+ throw new DescriptorParseException("Illegal line '" + line + "'.");
+ }
+ if (pairs.containsKey("Bandwidth")) {
+ this.bandwidth = pairs.remove("Bandwidth");
+ }
+ if (pairs.containsKey("Measured")) {
+ this.measured = pairs.remove("Measured");
+ }
+ if (!pairs.isEmpty()) {
+ throw new DescriptorParseException("Unknown key-value pair in "
+ + "line '" + line + "'.");
}
- /* TODO Add some plausibility checks, like if we have a nickname
- * etc. */
+ }
+
+ private void parsePLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedAtMostOnceKeyword("p");
+ boolean isValid = true;
+ if (parts.length != 3) {
+ isValid = false;
+ } else if (!parts[1].equals("accept") && !parts[1].equals("reject")) {
+ isValid = false;
+ } else {
+ this.defaultPolicy = parts[1];
+ this.portList = parts[2];
+ String[] ports = parts[2].split(",", -1);
+ for (int i = 0; i < ports.length; i++) {
+ if (ports[i].length() < 1) {
+ isValid = false;
+ break;
+ }
+ }
+ }
+ if (!isValid) {
+ throw new DescriptorParseException("Illegal line '" + line + "'.");
+ }
+ }
+
+ private void parseMLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedAtMostOnceKeyword("m");
+ /* TODO Implement parsing of m lines in votes. Try to find where m
+ * lines are specified first. */
}
private String nickname;
@@ -113,7 +212,7 @@ public class NetworkStatusEntryImpl implements NetworkStatusEntry {
return this.dirPort;
}
- private SortedSet<String> flags = new TreeSet<String>();
+ private SortedSet<String> flags;
public SortedSet<String> getFlags() {
return new TreeSet<String>(this.flags);
}
@@ -123,14 +222,24 @@ public class NetworkStatusEntryImpl implements NetworkStatusEntry {
return this.version;
}
- private String bandwidth;
- public String getBandwidth() {
+ private long bandwidth = -1L;
+ public long getBandwidth() {
return this.bandwidth;
}
- private String ports;
- public String getPorts() {
- return this.ports;
+ private long measured = -1L;
+ public long getMeasured() {
+ return this.measured;
+ }
+
+ private String defaultPolicy;
+ public String getDefaultPolicy() {
+ return this.defaultPolicy;
+ }
+
+ private String portList;
+ public String getPortList() {
+ return this.portList;
}
}
diff --git a/src/org/torproject/descriptor/impl/ParseHelper.java b/src/org/torproject/descriptor/impl/ParseHelper.java
new file mode 100644
index 0000000..5f4a1bd
--- /dev/null
+++ b/src/org/torproject/descriptor/impl/ParseHelper.java
@@ -0,0 +1,147 @@
+/* Copyright 2011 The Tor Project
+ * See LICENSE for licensing information */
+package org.torproject.descriptor.impl;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.SortedMap;
+import java.util.TimeZone;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.binary.Hex;
+
+public class ParseHelper {
+
+ private static Pattern ipv4Pattern =
+ Pattern.compile("^[0-9\\.]{7,15}$");
+ public static String parseIpv4Address(String line, String address)
+ throws DescriptorParseException {
+ boolean isValid = true;
+ if (!ipv4Pattern.matcher(address).matches()) {
+ isValid = false;
+ } else {
+ String[] parts = address.split("\\.", -1);
+ if (parts.length != 4) {
+ isValid = false;
+ } else {
+ for (int i = 0; i < 4; i++) {
+ try {
+ int octetValue = Integer.parseInt(parts[i]);
+ if (octetValue < 0 || octetValue > 255) {
+ isValid = false;
+ }
+ } catch (NumberFormatException e) {
+ isValid = false;
+ }
+ }
+ }
+ }
+ if (!isValid) {
+ throw new DescriptorParseException("'" + address + "' in line '"
+ + line + "' is not a valid IPv4 address.");
+ }
+ return address;
+ }
+
+ public static int parsePort(String line, String portString)
+ throws DescriptorParseException {
+ int port = -1;
+ try {
+ port = Integer.parseInt(portString);
+ } catch (NumberFormatException e) {
+ throw new DescriptorParseException("'" + portString + "' in line '"
+ + line + "' is not a valid port number.");
+ }
+ if (port < 0 || port > 65535) {
+ throw new DescriptorParseException("'" + portString + "' in line '"
+ + line + "' is not a valid port number.");
+ }
+ return port;
+ }
+
+ private static SimpleDateFormat dateTimeFormat = new SimpleDateFormat(
+ "yyyy-MM-dd HH:mm:ss");
+ static {
+ dateTimeFormat.setLenient(false);
+ dateTimeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ }
+ public static long parseTimestampAtIndex(String line, String[] parts,
+ int dateIndex, int timeIndex) throws DescriptorParseException {
+ if (dateIndex >= parts.length || timeIndex >= parts.length) {
+ throw new DescriptorParseException("Line '" + line + "' does not "
+ + "contain a timestamp at the expected position.");
+ }
+ long result = -1L;
+ try {
+ result = dateTimeFormat.parse(
+ parts[dateIndex] + " " + parts[timeIndex]).getTime();
+ } catch (ParseException e) {
+ /* Leave result at -1L. */
+ }
+ if (result < 0L || result > 2000000000000L) {
+ throw new DescriptorParseException("Illegal timestamp format in "
+ + "line '" + line + "'.");
+ }
+ return result;
+ }
+
+ private static Pattern twentyByteHexPattern =
+ Pattern.compile("^[0-9A-F]{40}$");
+ public static String parseTwentyByteHexString(String line,
+ String hexString) throws DescriptorParseException {
+ if (!twentyByteHexPattern.matcher(hexString).matches()) {
+ throw new DescriptorParseException("Illegal hex string in line '"
+ + line + "'.");
+ }
+ return hexString;
+ }
+
+ public static SortedMap<String, Integer> parseKeyValuePairs(String line,
+ String[] parts, int startIndex) throws DescriptorParseException {
+ SortedMap<String, Integer> result = new TreeMap<String, Integer>();
+ for (int i = startIndex; i < parts.length; i++) {
+ String pair = parts[i];
+ String[] pairParts = pair.split("=");
+ if (pairParts.length != 2) {
+ throw new DescriptorParseException("Illegal key-value pair in "
+ + "line '" + line + "'.");
+ }
+ String pairName = pairParts[0];
+ try {
+ int pairValue = Integer.parseInt(pairParts[1]);
+ result.put(pairName, pairValue);
+ } catch (NumberFormatException e) {
+ throw new DescriptorParseException("Illegal value in line '"
+ + line + "'.");
+ }
+ }
+ return result;
+ }
+
+ private static Pattern nicknamePattern =
+ Pattern.compile("^[0-9a-zA-Z]{1,19}$");
+ public static String parseNickname(String line, String nickname)
+ throws DescriptorParseException {
+ if (!nicknamePattern.matcher(nickname).matches()) {
+ throw new DescriptorParseException("Illegal nickname in line '"
+ + line + "'.");
+ }
+ return nickname;
+ }
+
+ private static Pattern base64Pattern =
+ Pattern.compile("^[0-9a-zA-Z+/]{27}$");
+ public static String parseTwentyByteBase64String(String line,
+ String base64String) throws DescriptorParseException {
+ if (!base64Pattern.matcher(base64String).matches()) {
+ throw new DescriptorParseException("'" + base64String
+ + "' in line '" + line + "' is not a valid base64-encoded "
+ + "20-byte value.");
+ }
+ return Hex.encodeHexString(Base64.decodeBase64(base64String + "=")).
+ toUpperCase();
+ }
+}
+
diff --git a/src/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java b/src/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
index 7cbe94c..0771382 100644
--- a/src/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
+++ b/src/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
@@ -13,8 +13,6 @@ import java.util.SortedSet;
import java.util.TimeZone;
import java.util.TreeMap;
import java.util.TreeSet;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
import org.torproject.descriptor.Descriptor;
import org.torproject.descriptor.DirSourceEntry;
import org.torproject.descriptor.NetworkStatusEntry;
@@ -41,187 +39,324 @@ public class RelayNetworkStatusConsensusImpl
}
byte[] descBytes = new byte[end - start];
System.arraycopy(consensusBytes, start, descBytes, 0, end - start);
- RelayNetworkStatusConsensus parsedConsensus =
- new RelayNetworkStatusConsensusImpl(descBytes);
- parsedConsensuses.add(parsedConsensus);
start = end;
+ try {
+ RelayNetworkStatusConsensus parsedConsensus =
+ new RelayNetworkStatusConsensusImpl(descBytes);
+ parsedConsensuses.add(parsedConsensus);
+ } catch (DescriptorParseException e) {
+ /* TODO Handle this error somehow. */
+ System.err.println("Failed to parse consensus. Skipping.");
+ e.printStackTrace();
+ }
}
return parsedConsensuses;
}
- protected RelayNetworkStatusConsensusImpl(byte[] consensusBytes) {
+ protected RelayNetworkStatusConsensusImpl(byte[] consensusBytes)
+ throws DescriptorParseException {
this.consensusBytes = consensusBytes;
+ this.initializeKeywords();
this.parseConsensusBytes();
- this.checkConsistency();
- /* TODO Find a way to handle parse and consistency-check problems. */
+ this.checkKeywords();
+ }
+
+ private SortedSet<String> exactlyOnceKeywords, atMostOnceKeywords;
+ private void initializeKeywords() {
+ this.exactlyOnceKeywords = new TreeSet<String>();
+ this.exactlyOnceKeywords.add("vote-status");
+ this.exactlyOnceKeywords.add("consensus-method");
+ this.exactlyOnceKeywords.add("valid-after");
+ this.exactlyOnceKeywords.add("fresh-until");
+ this.exactlyOnceKeywords.add("valid-until");
+ this.exactlyOnceKeywords.add("voting-delay");
+ this.exactlyOnceKeywords.add("known-flags");
+ this.exactlyOnceKeywords.add("directory-footer");
+ this.atMostOnceKeywords = new TreeSet<String>();
+ this.atMostOnceKeywords.add("client-versions");
+ this.atMostOnceKeywords.add("server-versions");
+ this.atMostOnceKeywords.add("params");
+ this.atMostOnceKeywords.add("bandwidth-weights");
+ }
+
+ private void parsedExactlyOnceKeyword(String keyword)
+ throws DescriptorParseException {
+ if (!this.exactlyOnceKeywords.contains(keyword)) {
+ throw new DescriptorParseException("Duplicate '" + keyword
+ + "' line in consensus.");
+ }
+ this.exactlyOnceKeywords.remove(keyword);
+ }
+
+ private void parsedAtMostOnceKeyword(String keyword)
+ throws DescriptorParseException {
+ if (!this.atMostOnceKeywords.contains(keyword)) {
+ throw new DescriptorParseException("Duplicate " + keyword + "line "
+ + "in consensus.");
+ }
+ this.atMostOnceKeywords.remove(keyword);
+ }
+
+ private void checkKeywords() throws DescriptorParseException {
+ if (!this.exactlyOnceKeywords.isEmpty()) {
+ throw new DescriptorParseException("Consensus does not contain a '"
+ + this.exactlyOnceKeywords.first() + "' line.");
+ }
}
- private void parseConsensusBytes() {
+ private void parseConsensusBytes() throws DescriptorParseException {
try {
BufferedReader br = new BufferedReader(new StringReader(
new String(this.consensusBytes)));
- String line;
- SimpleDateFormat dateTimeFormat = new SimpleDateFormat(
- "yyyy-MM-dd HH:mm:ss");
- dateTimeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ String line = br.readLine();
+ if (line == null || !line.equals("network-status-version 3")) {
+ throw new DescriptorParseException("Consensus must start with "
+ + "line 'network-status-version 3'.");
+ }
+ this.networkStatusVersion = 3;
StringBuilder dirSourceEntryLines = null, statusEntryLines = null;
boolean skipSignature = false;
while ((line = br.readLine()) != null) {
- if (line.startsWith("network-status-version ")) {
- this.networkStatusVersion = Integer.parseInt(line.substring(
- "network-status-version ".length()));
- } else if (line.startsWith("vote-status ")) {
- if (!line.equals("vote-status consensus")) {
- throw new RuntimeException("Line '" + line + "' indicates "
- + "that this string is not a consensus. Aborting "
- + "parsing.");
- }
- } else if (line.startsWith("consensus-method ")) {
- this.consensusMethod = Integer.parseInt(line.substring(
- "consensus-method ".length()));
- } else if (line.startsWith("valid-after ")) {
- this.validAfterMillis = dateTimeFormat.parse(
- line.substring("valid-after ".length())).getTime();
- } else if (line.startsWith("fresh-until ")) {
- this.freshUntilMillis = dateTimeFormat.parse(
- line.substring("fresh-until ".length())).getTime();
- } else if (line.startsWith("valid-until ")) {
- this.validUntilMillis = dateTimeFormat.parse(
- line.substring("valid-until ".length())).getTime();
- } else if (line.startsWith("voting-delay ")) {
- for (String votingDelayString : line.substring(
- "voting-delay ".length()).split(" ")) {
- this.votingDelay.add(Long.parseLong(votingDelayString));
- }
- } else if (line.startsWith("client-versions ")) {
- this.recommendedClientVersions = new TreeSet<String>(
- Arrays.asList(line.split(" ")[1].split(",")));
- } else if (line.startsWith("server-versions ")) {
- this.recommendedServerVersions = new TreeSet<String>(
- Arrays.asList(line.split(" ")[1].split(",")));
- } else if (line.startsWith("known-flags ")) {
- for (String flag : line.substring("known-flags ".length()).
- split(" ")) {
- this.knownFlags.add(flag);
- }
- } else if (line.startsWith("params ")) {
- if (line.length() > "params ".length()) {
- for (String param :
- line.substring("params ".length()).split(" ")) {
- String paramName = param.split("=")[0];
- String paramValue = param.split("=")[1];
- this.consensusParams.put(paramName, paramValue);
- }
- }
- } else if (line.startsWith("dir-source ") ||
- line.startsWith("r ") || line.equals("directory-footer")) {
- /* TODO Add code for parsing legacy dir sources. */
+ if (line.length() < 1) {
+ throw new DescriptorParseException("Empty lines are not "
+ + "allowed in a consensus.");
+ }
+ String[] parts = line.split(" ");
+ if (parts.length < 1) {
+ throw new DescriptorParseException("No keyword found in line '"
+ + line + "'.");
+ }
+ String keyword = parts[0];
+ if (keyword.length() < 1) {
+ throw new DescriptorParseException("Empty keyword in line '"
+ + line + "'.");
+ }
+ if (keyword.equals("vote-status")) {
+ this.parseVoteStatusLine(line, parts);
+ } else if (keyword.equals("consensus-method")) {
+ this.parseConsensusMethodLine(line, parts);
+ } else if (keyword.equals("valid-after")) {
+ this.parseValidAfterLine(line, parts);
+ } else if (keyword.equals("fresh-until")) {
+ this.parseFreshUntilLine(line, parts);
+ } else if (keyword.equals("valid-until")) {
+ this.parseValidUntilLine(line, parts);
+ } else if (keyword.equals("voting-delay")) {
+ this.parseVotingDelayLine(line, parts);
+ } else if (keyword.equals("client-versions")) {
+ this.parseClientVersionsLine(line, parts);
+ } else if (keyword.equals("server-versions")) {
+ this.parseServerVersionsLine(line, parts);
+ } else if (keyword.equals("known-flags")) {
+ this.parseKnownFlagsLine(line, parts);
+ } else if (keyword.equals("params")) {
+ this.parseParamsLine(line, parts);
+ } else if (keyword.equals("dir-source") || keyword.equals("r") ||
+ keyword.equals("directory-footer")) {
if (dirSourceEntryLines != null) {
- DirSourceEntry dirSourceEntry = new DirSourceEntryImpl(
- dirSourceEntryLines.toString().getBytes());
- this.dirSourceEntries.put(dirSourceEntry.getIdentity(),
- dirSourceEntry);
+ this.parseDirSourceEntryLines(dirSourceEntryLines.toString());
dirSourceEntryLines = null;
}
if (statusEntryLines != null) {
- NetworkStatusEntryImpl statusEntry =
- new NetworkStatusEntryImpl(
- statusEntryLines.toString().getBytes());
- this.statusEntries.put(statusEntry.getFingerprint(),
- statusEntry);
+ this.parseStatusEntryLines(statusEntryLines.toString());
statusEntryLines = null;
}
- if (line.startsWith("dir-source ")) {
- dirSourceEntryLines = new StringBuilder();
- dirSourceEntryLines.append(line + "\n");
- } else if (line.startsWith("r ")) {
- statusEntryLines = new StringBuilder();
- statusEntryLines.append(line + "\n");
+ if (keyword.equals("dir-source")) {
+ dirSourceEntryLines = new StringBuilder(line + "\n");
+ } else if (keyword.equals("r")) {
+ statusEntryLines = new StringBuilder(line + "\n");
+ } else if (keyword.equals("directory-footer")) {
+ this.parsedExactlyOnceKeyword("directory-footer");
+ }
+ } else if (keyword.equals("contact") ||
+ keyword.equals("vote-digest")) {
+ if (dirSourceEntryLines == null) {
+ throw new DescriptorParseException(keyword + " line with no "
+ + "preceding dir-source line.");
}
- } else if (line.startsWith("contact ") ||
- line.startsWith("vote-digest ")) {
dirSourceEntryLines.append(line + "\n");
- } else if (line.startsWith("s ") || line.equals("s") ||
- line.startsWith("v ") || line.startsWith("w ") ||
- line.startsWith("p ")) {
- statusEntryLines.append(line + "\n");
- } else if (line.startsWith("bandwidth-weights ")) {
- if (line.length() > "bandwidth-weights ".length()) {
- for (String weight : line.substring("bandwidth-weights ".
- length()).split(" ")) {
- String weightName = weight.split("=")[0];
- String weightValue = weight.split("=")[1];
- this.bandwidthWeights.put(weightName, weightValue);
- }
+ } else if (keyword.equals("s") || keyword.equals("v") ||
+ keyword.equals("w") || keyword.equals("p")) {
+ if (statusEntryLines == null) {
+ throw new DescriptorParseException(keyword + " line with no "
+ + "preceding r line.");
}
-
- } else if (line.startsWith("directory-signature ")) {
- String[] parts = line.split(" ");
- String identity = parts[1];
- String signingKeyDigest = parts[2];
- this.directorySignatures.put(identity, signingKeyDigest);
+ statusEntryLines.append(line + "\n");
+ } else if (keyword.equals("bandwidth-weights")) {
+ this.parseBandwidthWeightsLine(line, parts);
+ } else if (keyword.equals("directory-signature")) {
+ this.parseDirectorySignatureLine(line, parts);
} else if (line.equals("-----BEGIN SIGNATURE-----")) {
skipSignature = true;
} else if (line.equals("-----END SIGNATURE-----")) {
skipSignature = false;
} else if (!skipSignature) {
- throw new RuntimeException("Unrecognized line '" + line + "'.");
+ /* TODO Is throwing an exception the right thing to do here?
+ * This is probably fine for development, but once the library
+ * is in production use, this seems annoying. */
+ throw new DescriptorParseException("Unrecognized line '" + line
+ + "'.");
}
}
} catch (IOException e) {
throw new RuntimeException("Internal error: Ran into an "
+ "IOException while parsing a String in memory. Something's "
+ "really wrong.", e);
- } catch (ParseException e) {
- /* TODO Handle me. */
- } catch (NumberFormatException e) {
- /* TODO Handle me. In theory, we shouldn't catch runtime
- * exceptions, but in this case it keeps the parsing code small. */
- } catch (ArrayIndexOutOfBoundsException e) {
- /* TODO Handle me. In theory, we shouldn't catch runtime
- * exceptions, but in this case it keeps the parsing code small. */
}
}
- private void checkConsistency() {
- if (this.networkStatusVersion == 0) {
- throw new RuntimeException("Consensus doesn't contain a "
- + "'network-status-version' line.");
+ private void parseVoteStatusLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedExactlyOnceKeyword("vote-status");
+ if (parts.length != 2 || !parts[1].equals("consensus")) {
+ throw new DescriptorParseException("Line '" + line + "' indicates "
+ + "that this is not a consensus.");
}
- if (this.consensusMethod == 0) {
- throw new RuntimeException("Consensus doesn't contain a "
- + "'consensus-method' line.");
+ }
+
+ private void parseConsensusMethodLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedExactlyOnceKeyword("consensus-method");
+ if (parts.length != 2) {
+ throw new DescriptorParseException("Illegal line '" + line
+ + "' in consensus.");
}
- if (this.validAfterMillis == 0L) {
- throw new RuntimeException("Consensus doesn't contain a "
- + "'valid-after' line.");
+ try {
+ this.consensusMethod = Integer.parseInt(parts[1]);
+ } catch (NumberFormatException e) {
+ throw new DescriptorParseException("Illegal consensus method "
+ + "number in line '" + line + "'.");
}
- if (this.freshUntilMillis == 0L) {
- throw new RuntimeException("Consensus doesn't contain a "
- + "'fresh-until' line.");
+ if (this.consensusMethod < 1) {
+ throw new DescriptorParseException("Illegal consensus method "
+ + "number in line '" + line + "'.");
}
- if (this.validUntilMillis == 0L) {
- throw new RuntimeException("Consensus doesn't contain a "
- + "'valid-until' line.");
+ }
+
+ private void parseValidAfterLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedExactlyOnceKeyword("valid-after");
+ this.validAfterMillis = ParseHelper.parseTimestampAtIndex(line, parts,
+ 1, 2);
+ }
+
+ private void parseFreshUntilLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedExactlyOnceKeyword("fresh-until");
+ this.freshUntilMillis = ParseHelper.parseTimestampAtIndex(line, parts,
+ 1, 2);
+ }
+
+ private void parseValidUntilLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedExactlyOnceKeyword("valid-until");
+ this.validUntilMillis = ParseHelper.parseTimestampAtIndex(line, parts,
+ 1, 2);
+ }
+
+ private void parseVotingDelayLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedExactlyOnceKeyword("voting-delay");
+ if (parts.length != 3) {
+ throw new DescriptorParseException("Wrong number of values in line "
+ + "'" + line + "'.");
}
- if (this.votingDelay.isEmpty()) {
- throw new RuntimeException("Consensus doesn't contain a "
- + "'voting-delay' line.");
+ try {
+ this.voteSeconds = Long.parseLong(parts[1]);
+ this.distSeconds = Long.parseLong(parts[2]);
+ } catch (NumberFormatException e) {
+ throw new DescriptorParseException("Illegal values in line '" + line
+ + "'.");
+ }
+ }
+
+ private void parseClientVersionsLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedAtMostOnceKeyword("client-versions");
+ this.recommendedClientVersions = this.parseClientOrServerVersions(
+ line, parts);
+ }
+
+ private void parseServerVersionsLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedAtMostOnceKeyword("server-versions");
+ this.recommendedServerVersions = this.parseClientOrServerVersions(
+ line, parts);
+ }
+
+ private SortedSet<String> parseClientOrServerVersions(String line,
+ String[] parts) throws DescriptorParseException {
+ SortedSet<String> result = new TreeSet<String>();
+ if (parts.length == 1) {
+ return result;
+ } else if (parts.length > 2) {
+ throw new DescriptorParseException("Illegal versions line '" + line
+ + "'.");
}
- if (this.knownFlags.isEmpty()) {
- throw new RuntimeException("Consensus doesn't contain a "
- + "'known-flags' line.");
+ String[] versions = parts[1].split(",", -1);
+ for (int i = 0; i < versions.length; i++) {
+ String version = versions[i];
+ if (version.length() < 1) {
+ throw new DescriptorParseException("Illegal versions line '"
+ + line + "'.");
+ }
+ result.add(version);
}
- if (this.dirSourceEntries.isEmpty()) {
- throw new RuntimeException("Consensus doesn't contain any "
- + "'dir-source' lines.");
+ return result;
+ }
+
+ private void parseKnownFlagsLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedExactlyOnceKeyword("known-flags");
+ if (parts.length < 2) {
+ throw new DescriptorParseException("No known flags in line '" + line
+ + "'.");
}
- if (this.statusEntries.isEmpty()) {
- throw new RuntimeException("Consensus doesn't contain any 'r' "
- + "lines.");
+ for (int i = 1; i < parts.length; i++) {
+ this.knownFlags.add(parts[i]);
}
}
+ private void parseParamsLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedAtMostOnceKeyword("params");
+ this.consensusParams = ParseHelper.parseKeyValuePairs(line, parts, 1);
+ }
+
+ private void parseDirSourceEntryLines(String string)
+ throws DescriptorParseException {
+ DirSourceEntry dirSourceEntry = new DirSourceEntryImpl(
+ string.getBytes());
+ this.dirSourceEntries.put(dirSourceEntry.getIdentity(),
+ dirSourceEntry);
+ }
+
+ private void parseStatusEntryLines(String string)
+ throws DescriptorParseException {
+ NetworkStatusEntryImpl statusEntry = new NetworkStatusEntryImpl(
+ string.getBytes());
+ this.statusEntries.put(statusEntry.getFingerprint(), statusEntry);
+ }
+
+ private void parseBandwidthWeightsLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedAtMostOnceKeyword("bandwidth-weights");
+ this.bandwidthWeights = ParseHelper.parseKeyValuePairs(line, parts,
+ 1);
+ }
+
+ private void parseDirectorySignatureLine(String line, String[] parts)
+ throws DescriptorParseException {
+ if (parts.length != 3) {
+ throw new DescriptorParseException("Illegal line '" + line + "'.");
+ }
+ String identity = ParseHelper.parseTwentyByteHexString(line,
+ parts[1]);
+ String signingKeyDigest = ParseHelper.parseTwentyByteHexString(line,
+ parts[2]);
+ this.directorySignatures.put(identity, signingKeyDigest);
+ }
+
private byte[] consensusBytes;
public byte[] getRawDescriptorBytes() {
return this.consensusBytes;
@@ -252,9 +387,14 @@ public class RelayNetworkStatusConsensusImpl
return this.validUntilMillis;
}
- private List<Long> votingDelay = new ArrayList<Long>();
- public List<Long> getVotingDelay() {
- return new ArrayList<Long>(this.votingDelay);
+ private long voteSeconds;
+ public long getVoteSeconds() {
+ return this.voteSeconds;
+ }
+
+ private long distSeconds;
+ public long getDistSeconds() {
+ return this.distSeconds;
}
private SortedSet<String> recommendedClientVersions;
@@ -274,10 +414,10 @@ public class RelayNetworkStatusConsensusImpl
return new TreeSet<String>(this.knownFlags);
}
- private SortedMap<String, String> consensusParams =
- new TreeMap<String, String>();
- public SortedMap<String, String> getConsensusParams() {
- return new TreeMap<String, String>(this.consensusParams);
+ private SortedMap<String, Integer> consensusParams;
+ public SortedMap<String, Integer> getConsensusParams() {
+ return this.consensusParams == null ? null:
+ new TreeMap<String, Integer>(this.consensusParams);
}
private SortedMap<String, DirSourceEntry> dirSourceEntries =
@@ -304,10 +444,10 @@ public class RelayNetworkStatusConsensusImpl
return new TreeMap<String, String>(this.directorySignatures);
}
- private SortedMap<String, String> bandwidthWeights =
- new TreeMap<String, String>();
- public SortedMap<String, String> getBandwidthWeights() {
- return new TreeMap<String, String>(this.bandwidthWeights);
+ private SortedMap<String, Integer> bandwidthWeights;
+ public SortedMap<String, Integer> getBandwidthWeights() {
+ return this.bandwidthWeights == null ? null :
+ new TreeMap<String, Integer>(this.bandwidthWeights);
}
}
diff --git a/src/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java b/src/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
index bf2668b..238a512 100644
--- a/src/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
+++ b/src/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
@@ -149,11 +149,16 @@ public class RelayNetworkStatusVoteImpl
} else if (line.startsWith("r ") ||
line.equals("directory-footer")) {
if (statusEntryLines != null) {
- NetworkStatusEntryImpl statusEntry =
- new NetworkStatusEntryImpl(
- statusEntryLines.toString().getBytes());
- this.statusEntries.put(statusEntry.getFingerprint(),
- statusEntry);
+ try {
+ NetworkStatusEntryImpl statusEntry =
+ new NetworkStatusEntryImpl(
+ statusEntryLines.toString().getBytes());
+ this.statusEntries.put(statusEntry.getFingerprint(),
+ statusEntry);
+ } catch (DescriptorParseException e) {
+ System.err.println("Could not parse status entry in vote. "
+ + "Skipping.");
+ }
statusEntryLines = null;
}
if (line.startsWith("r ")) {
diff --git a/test/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java b/test/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java
index 4a7a7be..520473d 100644
--- a/test/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java
+++ b/test/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java
@@ -21,94 +21,120 @@ public class RelayNetworkStatusConsensusImplTest {
* modifications requested by test methods. */
private static class ConsensusBuilder {
private String networkStatusVersionLine = "network-status-version 3";
- private static void createWithNetworkStatusVersionLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithNetworkStatusVersionLine(String line)
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.networkStatusVersionLine = line;
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
private String voteStatusLine = "vote-status consensus";
- private static void createWithVoteStatusLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithVoteStatusLine(String line)
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.voteStatusLine = line;
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
private String consensusMethodLine = "consensus-method 11";
- private static void createWithConsensusMethodLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithConsensusMethodLine(String line)
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.consensusMethodLine = line;
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
private String validAfterLine = "valid-after 2011-11-30 09:00:00";
- private static void createWithValidAfterLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithValidAfterLine(String line)
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.validAfterLine = line;
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
private String freshUntilLine = "fresh-until 2011-11-30 10:00:00";
- private static void createWithFreshUntilLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithFreshUntilLine(String line)
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.freshUntilLine = line;
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
private String validUntilLine = "valid-until 2011-11-30 12:00:00";
- private static void createWithValidUntilLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithValidUntilLine(String line)
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.validUntilLine = line;
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
private String votingDelayLine = "voting-delay 300 300";
- private static void createWithVotingDelayLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithVotingDelayLine(String line)
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.votingDelayLine = line;
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
private String clientVersionsLine = "client-versions 0.2.1.31,"
+ "0.2.2.34,0.2.3.6-alpha,0.2.3.7-alpha,0.2.3.8-alpha";
- private static void createWithClientVersionsLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithClientVersionsLine(String line)
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.clientVersionsLine = line;
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
private String serverVersionsLine = "server-versions 0.2.1.31,"
+ "0.2.2.34,0.2.3.6-alpha,0.2.3.7-alpha,0.2.3.8-alpha";
- private static void createWithServerVersionsLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithServerVersionsLine(String line)
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.serverVersionsLine = line;
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
private String knownFlagsLine = "known-flags Authority BadExit Exit "
+ "Fast Guard HSDir Named Running Stable Unnamed V2Dir Valid";
- private static void createWithKnownFlagsLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithKnownFlagsLine(String line)
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.knownFlagsLine = line;
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
private String paramsLine = "params "
+ "CircuitPriorityHalflifeMsec=30000 bwauthbestratio=1 "
+ "bwauthcircs=1 bwauthdescbw=0 bwauthkp=10000 bwauthpid=1 "
+ "bwauthtd=5000 bwauthti=50000 bwauthtidecay=5000 cbtnummodes=3 "
+ "cbtquantile=80 circwindow=1000 refuseunknownexits=1";
- private static void createWithParamsLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithParamsLine(String line)
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.paramsLine = line;
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
private List<String> dirSources = new ArrayList<String>();
private List<String> statusEntries = new ArrayList<String>();
private String directoryFooterLine = "directory-footer";
- private static void createWithDirectoryFooterLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithDirectoryFooterLine(String line)
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.directoryFooterLine = line;
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
private String bandwidthWeightsLine = "bandwidth-weights Wbd=285 "
+ "Wbe=0 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=1021 Wee=10000 "
+ "Weg=1021 Wem=10000 Wgb=10000 Wgd=8694 Wgg=10000 Wgm=10000 "
+ "Wmb=10000 Wmd=285 Wme=0 Wmg=0 Wmm=10000";
- private static void createWithBandwidthWeightsLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithBandwidthWeightsLine(String line)
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.bandwidthWeightsLine = line;
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
private List<String> directorySignatures = new ArrayList<String>();
private ConsensusBuilder() {
@@ -217,60 +243,78 @@ public class RelayNetworkStatusConsensusImplTest {
/* Helper class to build a directory source based on default data and
* modifications requested by test methods. */
private static class DirSourceBuilder {
- private static void createWithDirSource(String dirSourceString) {
+ private static RelayNetworkStatusConsensus
+ createWithDirSource(String dirSourceString)
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.dirSources.add(dirSourceString);
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
private String nickname = "gabelmoo";
- private static void createWithNickname(String string) {
+ private static RelayNetworkStatusConsensus
+ createWithNickname(String string)
+ throws DescriptorParseException {
DirSourceBuilder dsb = new DirSourceBuilder();
dsb.nickname = string;
- createWithDirSource(dsb.buildDirSource());
+ return createWithDirSource(dsb.buildDirSource());
}
private String identity = "ED03BB616EB2F60BEC80151114BB25CEF515B226";
- private static void createWithIdentity(String string) {
+ private static RelayNetworkStatusConsensus
+ createWithIdentity(String string)
+ throws DescriptorParseException {
DirSourceBuilder dsb = new DirSourceBuilder();
dsb.identity = string;
- createWithDirSource(dsb.buildDirSource());
+ return createWithDirSource(dsb.buildDirSource());
}
private String hostName = "212.112.245.170";
- private static void createWithHostName(String string) {
+ private static RelayNetworkStatusConsensus
+ createWithHostName(String string)
+ throws DescriptorParseException {
DirSourceBuilder dsb = new DirSourceBuilder();
dsb.hostName = string;
- createWithDirSource(dsb.buildDirSource());
+ return createWithDirSource(dsb.buildDirSource());
}
private String address = "212.112.245.170";
- private static void createWithAddress(String string) {
+ private static RelayNetworkStatusConsensus
+ createWithAddress(String string)
+ throws DescriptorParseException {
DirSourceBuilder dsb = new DirSourceBuilder();
dsb.address = string;
- createWithDirSource(dsb.buildDirSource());
+ return createWithDirSource(dsb.buildDirSource());
}
private String dirPort = "80";
- private static void createWithDirPort(String string) {
+ private static RelayNetworkStatusConsensus
+ createWithDirPort(String string)
+ throws DescriptorParseException {
DirSourceBuilder dsb = new DirSourceBuilder();
dsb.dirPort = string;
- createWithDirSource(dsb.buildDirSource());
+ return createWithDirSource(dsb.buildDirSource());
}
private String orPort = "443";
- private static void createWithOrPort(String string) {
+ private static RelayNetworkStatusConsensus
+ createWithOrPort(String string)
+ throws DescriptorParseException {
DirSourceBuilder dsb = new DirSourceBuilder();
dsb.orPort = string;
- createWithDirSource(dsb.buildDirSource());
+ return createWithDirSource(dsb.buildDirSource());
}
private String contactLine = "contact 4096R/C5AA446D Sebastian Hahn "
+ "<tor(a)sebastianhahn.net>";
- private static void createWithContactLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithContactLine(String line)
+ throws DescriptorParseException {
DirSourceBuilder dsb = new DirSourceBuilder();
dsb.contactLine = line;
- createWithDirSource(dsb.buildDirSource());
+ return createWithDirSource(dsb.buildDirSource());
}
private String voteDigestLine =
"vote-digest 0F398A5834D2C139E1D92310B09F814F243354D1";
- private static void createWithVoteDigestLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithVoteDigestLine(String line)
+ throws DescriptorParseException {
DirSourceBuilder dsb = new DirSourceBuilder();
dsb.voteDigestLine = line;
- createWithDirSource(dsb.buildDirSource());
+ return createWithDirSource(dsb.buildDirSource());
}
private String buildDirSource() {
StringBuilder sb = new StringBuilder();
@@ -294,76 +338,93 @@ public class RelayNetworkStatusConsensusImplTest {
/* Helper class to build a status entry based on default data and
* modifications requested by test methods. */
private static class StatusEntryBuilder {
- private static void createWithStatusEntry(String statusEntryString) {
+ private static RelayNetworkStatusConsensus
+ createWithStatusEntry(String statusEntryString)
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.statusEntries.add(statusEntryString);
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
private String nickname = "right2privassy3";
- private static void createWithNickname(String string) {
+ private static RelayNetworkStatusConsensus
+ createWithNickname(String string)
+ throws DescriptorParseException {
StatusEntryBuilder seb = new StatusEntryBuilder();
seb.nickname = string;
- createWithStatusEntry(seb.buildStatusEntry());
+ return createWithStatusEntry(seb.buildStatusEntry());
}
private String fingerprintBase64 = "ADQ6gCT3DiFHKPDFr3rODBUI8HM";
- private static void createWithFingerprintBase64(String string) {
+ private static RelayNetworkStatusConsensus
+ createWithFingerprintBase64(String string)
+ throws DescriptorParseException {
StatusEntryBuilder seb = new StatusEntryBuilder();
seb.fingerprintBase64 = string;
- createWithStatusEntry(seb.buildStatusEntry());
+ return createWithStatusEntry(seb.buildStatusEntry());
}
private String descriptorBase64 = "Yiti+nayuT2Efe2X1+M4nslwVuU";
- private static void createWithDescriptorBase64(String string) {
+ private static RelayNetworkStatusConsensus
+ createWithDescriptorBase64(String string)
+ throws DescriptorParseException {
StatusEntryBuilder seb = new StatusEntryBuilder();
seb.descriptorBase64 = string;
- createWithStatusEntry(seb.buildStatusEntry());
+ return createWithStatusEntry(seb.buildStatusEntry());
}
private String publishedString = "2011-11-29 21:34:27";
- private static void createWithPublishedString(String string) {
+ private static RelayNetworkStatusConsensus
+ createWithPublishedString(String string)
+ throws DescriptorParseException {
StatusEntryBuilder seb = new StatusEntryBuilder();
seb.publishedString = string;
- createWithStatusEntry(seb.buildStatusEntry());
+ return createWithStatusEntry(seb.buildStatusEntry());
}
private String address = "50.63.8.215";
- private static void createWithAddress(String string) {
+ private static RelayNetworkStatusConsensus
+ createWithAddress(String string) throws DescriptorParseException {
StatusEntryBuilder seb = new StatusEntryBuilder();
seb.address = string;
- createWithStatusEntry(seb.buildStatusEntry());
+ return createWithStatusEntry(seb.buildStatusEntry());
}
private String orPort = "9023";
- private static void createWithOrPort(String string) {
+ private static RelayNetworkStatusConsensus
+ createWithOrPort(String string) throws DescriptorParseException {
StatusEntryBuilder seb = new StatusEntryBuilder();
seb.orPort = string;
- createWithStatusEntry(seb.buildStatusEntry());
+ return createWithStatusEntry(seb.buildStatusEntry());
}
private String dirPort = "0";
- private static void createWithDirPort(String string) {
+ private static RelayNetworkStatusConsensus
+ createWithDirPort(String string) throws DescriptorParseException {
StatusEntryBuilder seb = new StatusEntryBuilder();
seb.dirPort = string;
- createWithStatusEntry(seb.buildStatusEntry());
+ return createWithStatusEntry(seb.buildStatusEntry());
}
private String sLine = "s Exit Fast Named Running Stable Valid";
- private static void createWithSLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithSLine(String line) throws DescriptorParseException {
StatusEntryBuilder seb = new StatusEntryBuilder();
seb.sLine = line;
- createWithStatusEntry(seb.buildStatusEntry());
+ return createWithStatusEntry(seb.buildStatusEntry());
}
private String vLine = "v Tor 0.2.1.29 (r8e9b25e6c7a2e70c)";
- private static void createWithVLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithVLine(String line) throws DescriptorParseException {
StatusEntryBuilder seb = new StatusEntryBuilder();
seb.vLine = line;
- createWithStatusEntry(seb.buildStatusEntry());
+ return createWithStatusEntry(seb.buildStatusEntry());
}
private String wLine = "w Bandwidth=1";
- private static void createWithWLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithWLine(String line) throws DescriptorParseException {
StatusEntryBuilder seb = new StatusEntryBuilder();
seb.wLine = line;
- createWithStatusEntry(seb.buildStatusEntry());
+ return createWithStatusEntry(seb.buildStatusEntry());
}
private String pLine = "p accept 80,1194,1220,1293";
- private static void createWithPLine(String line) {
+ private static RelayNetworkStatusConsensus
+ createWithPLine(String line) throws DescriptorParseException {
StatusEntryBuilder seb = new StatusEntryBuilder();
seb.pLine = line;
- createWithStatusEntry(seb.buildStatusEntry());
+ return createWithStatusEntry(seb.buildStatusEntry());
}
private String buildStatusEntry() {
StringBuilder sb = new StringBuilder();
@@ -393,24 +454,29 @@ public class RelayNetworkStatusConsensusImplTest {
/* Helper class to build a directory signature based on default data and
* modifications requested by test methods. */
private static class DirectorySignatureBuilder {
- private static void createWithDirectorySignature(
- String directorySignatureString) {
+ private static RelayNetworkStatusConsensus
+ createWithDirectorySignature(String directorySignatureString)
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.directorySignatures.add(directorySignatureString);
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
private String identity = "ED03BB616EB2F60BEC80151114BB25CEF515B226";
- private static void createWithIdentity(String string) {
+ private static RelayNetworkStatusConsensus
+ createWithIdentity(String string)
+ throws DescriptorParseException {
DirectorySignatureBuilder dsb = new DirectorySignatureBuilder();
dsb.identity = string;
- createWithDirectorySignature(dsb.buildDirectorySignature());
+ return createWithDirectorySignature(dsb.buildDirectorySignature());
}
private String signingKey =
"845CF1D0B370CA443A8579D18E7987E7E532F639";
- private static void createWithSigningKey(String string) {
+ private static RelayNetworkStatusConsensus
+ createWithSigningKey(String string)
+ throws DescriptorParseException {
DirectorySignatureBuilder dsb = new DirectorySignatureBuilder();
dsb.signingKey = string;
- createWithDirectorySignature(dsb.buildDirectorySignature());
+ return createWithDirectorySignature(dsb.buildDirectorySignature());
}
private String buildDirectorySignature() {
String directorySignature = "directory-signature " + identity + " "
@@ -426,505 +492,622 @@ public class RelayNetworkStatusConsensusImplTest {
}
}
- /* TODO We should check this. */
@Test()
- public void testSampleConsensus() {
+ public void testSampleConsensus() throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ RelayNetworkStatusConsensus consensus =
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ assertEquals(3, consensus.getNetworkStatusVersion());
+ assertEquals(11, consensus.getConsensusMethod());
+ assertEquals(1322643600000L, consensus.getValidAfterMillis());
+ assertEquals(1322647200000L, consensus.getFreshUntilMillis());
+ assertEquals(1322654400000L, consensus.getValidUntilMillis());
+ assertEquals(300L, consensus.getVoteSeconds());
+ assertEquals(300L, consensus.getDistSeconds());
+ assertTrue(consensus.getRecommendedClientVersions().contains(
+ "0.2.3.8-alpha"));
+ assertTrue(consensus.getRecommendedServerVersions().contains(
+ "0.2.3.8-alpha"));
+ assertTrue(consensus.getKnownFlags().contains("Running"));
+ assertEquals(30000, (int) consensus.getConsensusParams().get(
+ "CircuitPriorityHalflifeMsec"));
+ assertEquals("86.59.21.38", consensus.getDirSourceEntries().get(
+ "14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4").getIp());
+ assertTrue(consensus.containsStatusEntry(
+ "00795A6E8D91C270FC23B30F388A495553E01894"));
+ assertEquals("188.177.149.216", consensus.getStatusEntry(
+ "00795A6E8D91C270FC23B30F388A495553E01894").getAddress());
+ assertEquals("3509BA5A624403A905C74DA5C8A0CEC9E0D3AF86",
+ consensus.getDirectorySignatures().get(
+ "14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4"));
+ assertEquals(285, (int) consensus.getBandwidthWeights().get("Wbd"));
+ }
+
+ @Test(expected = DescriptorParseException.class)
+ public void testNetworkStatusVersionNoLine()
+ throws DescriptorParseException {
+ ConsensusBuilder.createWithNetworkStatusVersionLine(null);
}
- /* TODO Throwing a RuntimeException here (and in most places below) is
- * bad. Maybe we should define a DescriptorParseException. */
- @Test(expected = RuntimeException.class)
- public void testNetworkStatusVersionNoLine() {
- ConsensusBuilder.createWithNetworkStatusVersionLine(null);
+ @Test(expected = DescriptorParseException.class)
+ public void testNetworkStatusVersionNewLine()
+ throws DescriptorParseException {
+ ConsensusBuilder.createWithNetworkStatusVersionLine(
+ "network-status-version 3\n");
}
- @Test(expected = RuntimeException.class)
- public void testNetworkStatusVersionPrefixLineAtChar() {
+ @Test(expected = DescriptorParseException.class)
+ public void testNetworkStatusVersionPrefixLineAtChar()
+ throws DescriptorParseException {
ConsensusBuilder.createWithNetworkStatusVersionLine(
"@consensus\nnetwork-status-version 3");
}
- /* TODO This doesn't break. Should it? */
- @Test()
- public void testNetworkStatusVersionPrefixDirectoryFooter() {
+ @Test(expected = DescriptorParseException.class)
+ public void testNetworkStatusVersionPrefixLine()
+ throws DescriptorParseException {
ConsensusBuilder.createWithNetworkStatusVersionLine(
"directory-footer\nnetwork-status-version 3");
}
-
- @Test(expected = RuntimeException.class)
- public void testNetworkStatusVersionPrefixLinePoundChar() {
+
+ @Test(expected = DescriptorParseException.class)
+ public void testNetworkStatusVersionPrefixLinePoundChar()
+ throws DescriptorParseException {
ConsensusBuilder.createWithNetworkStatusVersionLine(
"#consensus\nnetwork-status-version 3");
}
-
- @Test(expected = RuntimeException.class)
- public void testNetworkStatusVersionNoSpace() {
+
+ @Test(expected = DescriptorParseException.class)
+ public void testNetworkStatusVersionNoSpace()
+ throws DescriptorParseException {
ConsensusBuilder.createWithNetworkStatusVersionLine(
"network-status-version");
}
- @Test(expected = RuntimeException.class)
- public void testNetworkStatusVersionOneSpace() {
+ @Test(expected = DescriptorParseException.class)
+ public void testNetworkStatusVersionOneSpace()
+ throws DescriptorParseException {
ConsensusBuilder.createWithNetworkStatusVersionLine(
"network-status-version ");
}
- /* TODO The parser should only accept version 3 and throw an Exception
- * here. */
- @Test()
- public void testNetworkStatusVersion42() {
+ @Test(expected = DescriptorParseException.class)
+ public void testNetworkStatusVersion42()
+ throws DescriptorParseException {
ConsensusBuilder.createWithNetworkStatusVersionLine(
"network-status-version 42");
}
- @Test(expected = RuntimeException.class)
- public void testNetworkStatusVersionFourtyTwo() {
+ @Test(expected = DescriptorParseException.class)
+ public void testNetworkStatusVersionFourtyTwo()
+ throws DescriptorParseException {
ConsensusBuilder.createWithNetworkStatusVersionLine(
"network-status-version FourtyTwo");
}
- /* TODO Shouldn't this throw an exception? */
- @Test()
- public void testVoteStatusNoLine() {
+ @Test(expected = DescriptorParseException.class)
+ public void testVoteStatusNoLine() throws DescriptorParseException {
ConsensusBuilder.createWithVoteStatusLine(null);
}
- @Test(expected = RuntimeException.class)
- public void testVoteStatusNoSpace() {
+ @Test(expected = DescriptorParseException.class)
+ public void testNetworkStatusVersionSpaceBefore()
+ throws DescriptorParseException {
+ ConsensusBuilder.createWithNetworkStatusVersionLine(
+ " network-status-version 3");
+ }
+
+ @Test(expected = DescriptorParseException.class)
+ public void testVoteStatusSpaceBefore() throws DescriptorParseException {
+ ConsensusBuilder.createWithVoteStatusLine(" vote-status consensus");
+ }
+
+ @Test(expected = DescriptorParseException.class)
+ public void testVoteStatusNoSpace() throws DescriptorParseException {
ConsensusBuilder.createWithVoteStatusLine("vote-status");
}
- @Test(expected = RuntimeException.class)
- public void testVoteStatusOneSpace() {
+ @Test(expected = DescriptorParseException.class)
+ public void testVoteStatusOneSpace() throws DescriptorParseException {
ConsensusBuilder.createWithVoteStatusLine("vote-status ");
}
- /* TODO Should this be accepted or not? */
- @Test(expected = RuntimeException.class)
- public void testVoteStatusConsensusOneSpace() {
+ @Test()
+ public void testVoteStatusConsensusOneSpace()
+ throws DescriptorParseException {
ConsensusBuilder.createWithVoteStatusLine("vote-status consensus ");
}
- @Test(expected = RuntimeException.class)
- public void testVoteStatusVote() {
+ @Test(expected = DescriptorParseException.class)
+ public void testVoteStatusVote() throws DescriptorParseException {
ConsensusBuilder.createWithVoteStatusLine("vote-status vote");
}
- @Test(expected = RuntimeException.class)
- public void testVoteStatusTheMagicVoteStatus() {
+ @Test(expected = DescriptorParseException.class)
+ public void testVoteStatusTheMagicVoteStatus()
+ throws DescriptorParseException {
ConsensusBuilder.createWithVoteStatusLine(
"vote-status TheMagicVoteStatus");
}
- @Test(expected = RuntimeException.class)
- public void testConsensusMethodNoLine() {
+ @Test(expected = DescriptorParseException.class)
+ public void testConsensusMethodNoLine()
+ throws DescriptorParseException {
ConsensusBuilder.createWithConsensusMethodLine(null);
}
- @Test(expected = RuntimeException.class)
- public void testConsensusMethodNoSpace() {
+ @Test(expected = DescriptorParseException.class)
+ public void testConsensusMethodNoSpace()
+ throws DescriptorParseException {
ConsensusBuilder.createWithConsensusMethodLine("consensus-method");
}
- @Test(expected = RuntimeException.class)
- public void testConsensusMethodOneSpace() {
+ @Test(expected = DescriptorParseException.class)
+ public void testConsensusMethodOneSpace()
+ throws DescriptorParseException {
ConsensusBuilder.createWithConsensusMethodLine("consensus-method ");
}
- @Test(expected = RuntimeException.class)
- public void testConsensusMethodEleven() {
+ @Test(expected = DescriptorParseException.class)
+ public void testConsensusMethodEleven()
+ throws DescriptorParseException {
ConsensusBuilder.createWithConsensusMethodLine(
"consensus-method eleven");
}
- /* TODO We shouldn't allow negative values here. */
- @Test()
- public void testConsensusMethodMinusOne() {
+ @Test(expected = DescriptorParseException.class)
+ public void testConsensusMethodMinusOne()
+ throws DescriptorParseException {
ConsensusBuilder.createWithConsensusMethodLine("consensus-method -1");
}
- @Test(expected = RuntimeException.class)
- public void testConsensusMethodNinePeriod() {
+ @Test(expected = DescriptorParseException.class)
+ public void testConsensusMethodNinePeriod()
+ throws DescriptorParseException {
ConsensusBuilder.createWithConsensusMethodLine("consensus-method "
+ "999999999999999999999999999999999999999999999999999999999999");
}
- @Test(expected = RuntimeException.class)
- public void testValidAfterNoLine() {
+ @Test(expected = DescriptorParseException.class)
+ public void testConsensusMethodTwoLines()
+ throws DescriptorParseException {
+ ConsensusBuilder.createWithConsensusMethodLine(
+ "consensus-method 1\nconsensus-method 1");
+ }
+
+ @Test(expected = DescriptorParseException.class)
+ public void testValidAfterNoLine() throws DescriptorParseException {
ConsensusBuilder.createWithValidAfterLine(null);
}
- @Test(expected = RuntimeException.class)
- public void testValidAfterNoSpace() {
+ @Test(expected = DescriptorParseException.class)
+ public void testValidAfterNoSpace() throws DescriptorParseException {
ConsensusBuilder.createWithValidAfterLine("valid-after");
}
- @Test(expected = RuntimeException.class)
- public void testValidAfterOneSpace() {
+ @Test(expected = DescriptorParseException.class)
+ public void testValidAfterOneSpace() throws DescriptorParseException {
ConsensusBuilder.createWithValidAfterLine("valid-after ");
}
- @Test(expected = RuntimeException.class)
- public void testValidAfterLongAgo() {
+ @Test(expected = DescriptorParseException.class)
+ public void testValidAfterLongAgo() throws DescriptorParseException {
ConsensusBuilder.createWithValidAfterLine("valid-after long ago");
}
- /* TODO Wow, this should really throw an exception! */
- @Test()
- public void testValidAfterFeb30() {
+ @Test(expected = DescriptorParseException.class)
+ public void testValidAfterFeb30() throws DescriptorParseException {
ConsensusBuilder.createWithValidAfterLine(
"valid-after 2011-02-30 09:00:00");
}
- @Test(expected = RuntimeException.class)
- public void testFreshUntilNoLine() {
+ @Test(expected = DescriptorParseException.class)
+ public void testFreshUntilNoLine() throws DescriptorParseException {
ConsensusBuilder.createWithFreshUntilLine(null);
}
- @Test(expected = RuntimeException.class)
- public void testFreshUntilAroundTen() {
+ @Test(expected = DescriptorParseException.class)
+ public void testFreshUntilAroundTen() throws DescriptorParseException {
ConsensusBuilder.createWithFreshUntilLine(
"fresh-until 2011-11-30 around ten");
}
- @Test(expected = RuntimeException.class)
- public void testValidUntilTomorrowMorning() {
+ @Test(expected = DescriptorParseException.class)
+ public void testValidUntilTomorrowMorning()
+ throws DescriptorParseException {
ConsensusBuilder.createWithValidUntilLine(
"valid-until tomorrow morning");
}
- @Test(expected = RuntimeException.class)
- public void testVotingDelayNoLine() {
+ @Test(expected = DescriptorParseException.class)
+ public void testVotingDelayNoLine() throws DescriptorParseException {
ConsensusBuilder.createWithVotingDelayLine(null);
}
- @Test(expected = RuntimeException.class)
- public void testVotingDelayNoSpace() {
+ @Test(expected = DescriptorParseException.class)
+ public void testVotingDelayNoSpace() throws DescriptorParseException {
ConsensusBuilder.createWithVotingDelayLine("voting-delay");
}
- @Test(expected = RuntimeException.class)
- public void testVotingDelayOneSpace() {
+ @Test(expected = DescriptorParseException.class)
+ public void testVotingDelayOneSpace() throws DescriptorParseException {
ConsensusBuilder.createWithVotingDelayLine("voting-delay ");
}
- /* TODO This should throw an exception. */
- @Test()
- public void testVotingDelayTriple() {
+ @Test(expected = DescriptorParseException.class)
+ public void testVotingDelayTriple() throws DescriptorParseException {
ConsensusBuilder.createWithVotingDelayLine(
"voting-delay 300 300 300");
}
- /* TODO This should throw an exception. */
- @Test()
- public void testVotingDelaySingle() {
+ @Test(expected = DescriptorParseException.class)
+ public void testVotingDelaySingle() throws DescriptorParseException {
ConsensusBuilder.createWithVotingDelayLine("voting-delay 300");
}
- @Test(expected = RuntimeException.class)
- public void testVotingDelayOneTwo() {
+ @Test(expected = DescriptorParseException.class)
+ public void testVotingDelayOneTwo() throws DescriptorParseException {
ConsensusBuilder.createWithVotingDelayLine("voting-delay one two");
}
- /* TODO Should this be forbidden? */
@Test()
- public void testClientVersionsNoLineServerVersionsNoLine() {
+ public void testClientServerVersionsNoLine()
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.clientVersionsLine = null;
cb.serverVersionsLine = null;
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ RelayNetworkStatusConsensus consensus =
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ assertNull(consensus.getRecommendedClientVersions());
+ assertNull(consensus.getRecommendedServerVersions());
}
- /* TODO Should this be forbidden? */
@Test()
- public void testServerVersionsNoLine() {
- ConsensusBuilder.createWithServerVersionsLine(null);
+ public void testServerVersionsNoLine() throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus =
+ ConsensusBuilder.createWithServerVersionsLine(null);
+ assertNotNull(consensus.getRecommendedClientVersions());
+ assertNull(consensus.getRecommendedServerVersions());
}
- /* TODO Should this be forbidden? */
@Test()
- public void testClientVersionsNoLine() {
- ConsensusBuilder.createWithClientVersionsLine(null);
+ public void testClientVersionsNoLine() throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus =
+ ConsensusBuilder.createWithClientVersionsLine(null);
+ assertNull(consensus.getRecommendedClientVersions());
+ assertNotNull(consensus.getRecommendedServerVersions());
}
- @Test(expected = RuntimeException.class)
- public void testClientVersionsNoSpace() {
- ConsensusBuilder.createWithClientVersionsLine("client-versions");
+ @Test()
+ public void testClientVersionsNoSpace()
+ throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus =
+ ConsensusBuilder.createWithClientVersionsLine("client-versions");
+ assertNotNull(consensus.getRecommendedClientVersions());
+ assertTrue(consensus.getRecommendedClientVersions().isEmpty());
}
- @Test(expected = RuntimeException.class)
- public void testClientVersionsOneSpace() {
- ConsensusBuilder.createWithClientVersionsLine("client-versions ");
+ @Test()
+ public void testClientVersionsOneSpace()
+ throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus =
+ ConsensusBuilder.createWithClientVersionsLine("client-versions ");
+ assertNotNull(consensus.getRecommendedClientVersions());
+ assertTrue(consensus.getRecommendedClientVersions().isEmpty());
}
- /* TODO This should be caught. */
- @Test()
- public void testClientVersionsComma() {
+ @Test(expected = DescriptorParseException.class)
+ public void testClientVersionsComma() throws DescriptorParseException {
ConsensusBuilder.createWithClientVersionsLine("client-versions ,");
}
- /* TODO This should be caught. */
- @Test()
- public void testClientVersionsCommaVersion() {
+ @Test(expected = DescriptorParseException.class)
+ public void testClientVersionsCommaVersion()
+ throws DescriptorParseException {
ConsensusBuilder.createWithClientVersionsLine(
"client-versions ,0.2.2.34");
}
- @Test(expected = RuntimeException.class)
- public void testKnownFlagsNoLine() {
+ @Test(expected = DescriptorParseException.class)
+ public void testKnownFlagsNoLine() throws DescriptorParseException {
ConsensusBuilder.createWithKnownFlagsLine(null);
}
- @Test(expected = RuntimeException.class)
- public void testKnownFlagsNoSpace() {
+ @Test(expected = DescriptorParseException.class)
+ public void testKnownFlagsNoSpace() throws DescriptorParseException {
ConsensusBuilder.createWithKnownFlagsLine("known-flags");
}
- /* TODO Looks like this okay, right? */
- @Test()
- public void testKnownFlagsOneSpace() {
+ @Test(expected = DescriptorParseException.class)
+ public void testKnownFlagsOneSpace() throws DescriptorParseException {
ConsensusBuilder.createWithKnownFlagsLine("known-flags ");
}
- /* TODO Make sure that the params line is optional. */
@Test()
- public void testParamsNoLine() {
- ConsensusBuilder.createWithParamsLine(null);
+ public void testParamsNoLine() throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus =
+ ConsensusBuilder.createWithParamsLine(null);
+ assertNull(consensus.getConsensusParams());
}
- /* TODO If it's okay to provide an empty params line, this one should be
- * accepted, too. */
- @Test(expected = RuntimeException.class)
- public void testParamsNoSpace() {
- ConsensusBuilder.createWithParamsLine("params");
+ @Test()
+ public void testParamsNoSpace() throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus =
+ ConsensusBuilder.createWithParamsLine("params");
+ assertNotNull(consensus.getConsensusParams());
+ assertTrue(consensus.getConsensusParams().isEmpty());
}
- /* TODO Is this okay? */
@Test()
- public void testParamsOneSpace() {
- ConsensusBuilder.createWithParamsLine("params ");
+ public void testParamsOneSpace() throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus =
+ ConsensusBuilder.createWithParamsLine("params ");
+ assertNotNull(consensus.getConsensusParams());
+ assertTrue(consensus.getConsensusParams().isEmpty());
}
- /* TODO Hmm, and this is okay? */
@Test()
- public void testParamsThreeSpaces() {
- ConsensusBuilder.createWithParamsLine("params ");
+ public void testParamsThreeSpaces() throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus =
+ ConsensusBuilder.createWithParamsLine("params ");
+ assertNotNull(consensus.getConsensusParams());
+ assertTrue(consensus.getConsensusParams().isEmpty());
}
- /* TODO The error message here looked strange. Investigate. */
- @Test(expected = RuntimeException.class)
- public void testParamsNoEqualSign() {
+ @Test(expected = DescriptorParseException.class)
+ public void testParamsNoEqualSign() throws DescriptorParseException {
ConsensusBuilder.createWithParamsLine("params key-value");
}
- /* TODO We should check this. */
+ @Test(expected = DescriptorParseException.class)
+ public void testParamsOneTooLargeNegative()
+ throws DescriptorParseException {
+ ConsensusBuilder.createWithParamsLine("params min=-2147483649");
+ }
+
@Test()
- public void testDirSourceIdentityTooShort() {
- DirSourceBuilder.createWithIdentity("ED03BB616EB2F60BEC8015111");
+ public void testParamsLargestNegative()
+ throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus =
+ ConsensusBuilder.createWithParamsLine("params min=-2147483648");
+ assertEquals(1, consensus.getConsensusParams().size());
+ assertEquals(-2147483648,
+ (int) consensus.getConsensusParams().get("min"));
+ }
+
+ @Test()
+ public void testParamsLargestPositive()
+ throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus =
+ ConsensusBuilder.createWithParamsLine("params max=2147483647");
+ assertEquals(1, consensus.getConsensusParams().size());
+ assertEquals(2147483647,
+ (int) consensus.getConsensusParams().get("max"));
+ }
+
+ @Test(expected = DescriptorParseException.class)
+ public void testParamsOneTooLargePositive()
+ throws DescriptorParseException {
+ ConsensusBuilder.createWithParamsLine("params max=2147483648");
}
- /* TODO We should check this. */
@Test()
- public void testDirSourceIdentityTooLong() {
+ public void testDirSourceLegacyNickname()
+ throws DescriptorParseException {
+ DirSourceBuilder dsb = new DirSourceBuilder();
+ dsb.nickname = "gabelmoo-legacy";
+ dsb.identity = "81349FC1F2DBA2C2C11B45CB9706637D480AB913";
+ dsb.contactLine = null;
+ dsb.voteDigestLine = null;
+ RelayNetworkStatusConsensus consensus =
+ DirSourceBuilder.createWithDirSource(dsb.buildDirSource());
+ assertEquals(3, consensus.getDirSourceEntries().size());
+ assertTrue(consensus.getDirSourceEntries().get(
+ "81349FC1F2DBA2C2C11B45CB9706637D480AB913").isLegacy());
+ }
+
+ @Test(expected = DescriptorParseException.class)
+ public void testDirSourceIdentityTooShort()
+ throws DescriptorParseException {
+ DirSourceBuilder.createWithIdentity("ED03BB616EB2F60BEC8015111");
+ }
+
+ @Test(expected = DescriptorParseException.class)
+ public void testDirSourceIdentityTooLong()
+ throws DescriptorParseException {
DirSourceBuilder.createWithIdentity("ED03BB616EB2F60BEC8015111"
+ "4BB25CEF515B226ED03BB616EB2F60BEC8");
}
- /* TODO We should check this. */
- @Test()
- public void testDirSourceAddress24() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDirSourceAddress24() throws DescriptorParseException {
DirSourceBuilder.createWithAddress("212.112.245");
}
- /* TODO We should check this. */
- @Test()
- public void testDirSourceAddress40() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDirSourceAddress40() throws DescriptorParseException {
DirSourceBuilder.createWithAddress("212.112.245.170.123");
}
- /* TODO We should check this. */
- @Test()
- public void testDirSourceDirPortMinusOne() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDirSourceDirPortMinusOne()
+ throws DescriptorParseException {
DirSourceBuilder.createWithDirPort("-1");
}
- /* TODO We should check this. */
- @Test()
- public void testDirSourceDirPort66666() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDirSourceDirPort66666()
+ throws DescriptorParseException {
DirSourceBuilder.createWithDirPort("66666");
}
- /* TODO We should check this. */
- @Test(expected = RuntimeException.class)
- public void testDirSourceDirPortOnions() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDirSourceDirPortOnions()
+ throws DescriptorParseException {
DirSourceBuilder.createWithDirPort("onions");
}
- /* TODO We should check this. */
- @Test(expected = RuntimeException.class)
- public void testDirSourceOrPortOnions() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDirSourceOrPortOnions()
+ throws DescriptorParseException {
DirSourceBuilder.createWithOrPort("onions");
}
- /* TODO We should check this. */
@Test()
- public void testDirSourceContactNoLine() {
- DirSourceBuilder.createWithContactLine(null);
+ public void testDirSourceContactNoLine()
+ throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus =
+ DirSourceBuilder.createWithContactLine(null);
+ assertNull(consensus.getDirSourceEntries().get(
+ "ED03BB616EB2F60BEC80151114BB25CEF515B226").getContactLine());
}
- /* TODO We should check this. */
- @Test(expected = RuntimeException.class)
- public void testDirSourceContactLineNoSpace() {
- DirSourceBuilder.createWithContactLine("contact");
+ @Test()
+ public void testDirSourceContactLineNoSpace()
+ throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus =
+ DirSourceBuilder.createWithContactLine("contact");
+ assertNotNull(consensus.getDirSourceEntries().get(
+ "ED03BB616EB2F60BEC80151114BB25CEF515B226").getContactLine());
}
- /* TODO We should check this. */
@Test()
- public void testDirSourceContactLineOneSpace() {
- DirSourceBuilder.createWithContactLine("contact ");
+ public void testDirSourceContactLineOneSpace()
+ throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus =
+ DirSourceBuilder.createWithContactLine("contact ");
+ assertNotNull(consensus.getDirSourceEntries().get(
+ "ED03BB616EB2F60BEC80151114BB25CEF515B226").getContactLine());
}
- /* TODO We should check this. */
- @Test()
- public void testDirSourceVoteDigestNoLine() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDirSourceVoteDigestNoLine()
+ throws DescriptorParseException {
DirSourceBuilder.createWithVoteDigestLine(null);
}
- /* TODO We should check this. */
- @Test(expected = RuntimeException.class)
- public void testDirSourceVoteDigestLineNoSpace() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDirSourceVoteDigestLineNoSpace()
+ throws DescriptorParseException {
DirSourceBuilder.createWithVoteDigestLine("vote-digest");
}
- /* TODO We should check this. */
- @Test(expected = RuntimeException.class)
- public void testDirSourceVoteDigestLineOneSpace() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDirSourceVoteDigestLineOneSpace()
+ throws DescriptorParseException {
DirSourceBuilder.createWithVoteDigestLine("vote-digest ");
}
- /* TODO We should check this. */
- @Test()
- public void testNicknameNotAllowedChars() {
+ @Test(expected = DescriptorParseException.class)
+ public void testNicknameNotAllowedChars()
+ throws DescriptorParseException {
StatusEntryBuilder.createWithNickname("notAll()wed");
}
- /* TODO We should check this. */
- @Test()
- public void testNicknameTooLong() {
+ @Test(expected = DescriptorParseException.class)
+ public void testNicknameTooLong() throws DescriptorParseException {
StatusEntryBuilder.createWithNickname("1234567890123456789tooLong");
}
- /* TODO We should check this. */
- @Test()
- public void testFingerprintTooShort() {
+ @Test(expected = DescriptorParseException.class)
+ public void testFingerprintTooShort() throws DescriptorParseException {
StatusEntryBuilder.createWithFingerprintBase64("TooShort");
}
- /* TODO We should check this. */
- @Test()
- public void testFingerprintEndsWithEqualSign() {
+ @Test(expected = DescriptorParseException.class)
+ public void testFingerprintEndsWithEqualSign()
+ throws DescriptorParseException {
StatusEntryBuilder.createWithFingerprintBase64(
"ADQ6gCT3DiFHKPDFr3rODBUI8H=");
}
- /* TODO We should check this. */
- @Test()
- public void testFingerprintTooLong() {
+ @Test(expected = DescriptorParseException.class)
+ public void testFingerprintTooLong() throws DescriptorParseException {
StatusEntryBuilder.createWithFingerprintBase64(
"ADQ6gCT3DiFHKPDFr3rODBUI8HMAAAA");
}
- /* TODO We should check this. */
- @Test()
- public void testDescriptorTooShort() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDescriptorTooShort() throws DescriptorParseException {
StatusEntryBuilder.createWithDescriptorBase64("TooShort");
}
- /* TODO We should check this. */
- @Test()
- public void testDescriptorEndsWithEqualSign() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDescriptorEndsWithEqualSign()
+ throws DescriptorParseException {
StatusEntryBuilder.createWithDescriptorBase64(
"ADQ6gCT3DiFHKPDFr3rODBUI8H=");
}
- /* TODO We should check this. */
- @Test()
- public void testDescriptorTooLong() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDescriptorTooLong() throws DescriptorParseException {
StatusEntryBuilder.createWithDescriptorBase64(
"Yiti+nayuT2Efe2X1+M4nslwVuUAAAA");
}
- /* TODO We should check this. */
- @Test()
- public void testPublished1960() {
+ @Test(expected = DescriptorParseException.class)
+ public void testPublished1960() throws DescriptorParseException {
StatusEntryBuilder.createWithPublishedString("1960-11-29 21:34:27");
}
- /* TODO We should check this. */
- @Test()
- public void testPublished9999() {
+ @Test(expected = DescriptorParseException.class)
+ public void testPublished9999() throws DescriptorParseException {
StatusEntryBuilder.createWithPublishedString("9999-11-29 21:34:27");
}
- /* TODO We should check this. */
- @Test()
- public void testAddress256() {
+ @Test(expected = DescriptorParseException.class)
+ public void testAddress256() throws DescriptorParseException {
StatusEntryBuilder.createWithAddress("256.63.8.215");
}
- /* TODO We should check this. */
- @Test()
- public void testAddress24() {
+ @Test(expected = DescriptorParseException.class)
+ public void testAddress24() throws DescriptorParseException {
StatusEntryBuilder.createWithAddress("50.63.8/24");
}
- /* TODO We should check this. */
- @Test()
- public void testAddressV6() {
+ @Test(expected = DescriptorParseException.class)
+ public void testAddressV6() throws DescriptorParseException {
StatusEntryBuilder.createWithAddress("::1");
}
- /* TODO We should check this. */
- @Test()
- public void testOrPort66666() {
+ @Test(expected = DescriptorParseException.class)
+ public void testOrPort66666() throws DescriptorParseException {
StatusEntryBuilder.createWithOrPort("66666");
}
- /* TODO We should check this. */
- @Test()
- public void testOrPortEighty() {
+ @Test(expected = DescriptorParseException.class)
+ public void testOrPortEighty() throws DescriptorParseException {
StatusEntryBuilder.createWithOrPort("eighty");
}
- /* TODO We should check this. */
- @Test()
- public void testDirPortMinusOne() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDirPortMinusOne() throws DescriptorParseException {
StatusEntryBuilder.createWithDirPort("-1");
}
- /* TODO We should check this. */
- @Test()
- public void testDirPortZero() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDirPortZero() throws DescriptorParseException {
StatusEntryBuilder.createWithDirPort("zero");
}
- /* TODO We should check this. */
@Test()
- public void testSLineNoSpace() {
- StatusEntryBuilder.createWithSLine("s");
+ public void testSLineNoSpace() throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus =
+ StatusEntryBuilder.createWithSLine("s");
+ assertTrue(consensus.getStatusEntry(
+ "00343A8024F70E214728F0C5AF7ACE0C1508F073").getFlags().isEmpty());
}
- /* TODO We should check this. */
@Test()
- public void testSLineOneSpace() {
- StatusEntryBuilder.createWithSLine("s ");
+ public void testSLineOneSpace() throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus =
+ StatusEntryBuilder.createWithSLine("s ");
+ assertTrue(consensus.getStatusEntry(
+ "00343A8024F70E214728F0C5AF7ACE0C1508F073").getFlags().isEmpty());
}
- /* TODO We should detect this. */
- @Test()
- public void testTwoSLines() {
+ @Test(expected = DescriptorParseException.class)
+ public void testTwoSLines() throws DescriptorParseException {
StatusEntryBuilder sb = new StatusEntryBuilder();
sb.sLine = sb.sLine + "\n" + sb.sLine;
ConsensusBuilder cb = new ConsensusBuilder();
@@ -932,27 +1115,23 @@ public class RelayNetworkStatusConsensusImplTest {
new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
- /* TODO This is not allowed, right? */
- @Test(expected = RuntimeException.class)
- public void testWLineNoSpace() {
- StatusEntryBuilder.createWithSLine("w");
+ @Test(expected = DescriptorParseException.class)
+ public void testWLineNoSpace() throws DescriptorParseException {
+ StatusEntryBuilder.createWithWLine("w");
}
- /* TODO We should check this. */
- @Test()
- public void testWLineOneSpace() {
- StatusEntryBuilder.createWithSLine("w ");
+ @Test(expected = DescriptorParseException.class)
+ public void testWLineOneSpace() throws DescriptorParseException {
+ StatusEntryBuilder.createWithWLine("w ");
}
- /* TODO We should check this. */
- @Test()
- public void testWLineWarpSeven() {
+ @Test(expected = DescriptorParseException.class)
+ public void testWLineWarpSeven() throws DescriptorParseException {
StatusEntryBuilder.createWithWLine("w Warp=7");
}
- /* TODO We should detect this. */
- @Test()
- public void testTwoWLines() {
+ @Test(expected = DescriptorParseException.class)
+ public void testTwoWLines() throws DescriptorParseException {
StatusEntryBuilder sb = new StatusEntryBuilder();
sb.wLine = sb.wLine + "\n" + sb.wLine;
ConsensusBuilder cb = new ConsensusBuilder();
@@ -960,33 +1139,28 @@ public class RelayNetworkStatusConsensusImplTest {
new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
- /* TODO We should check this. */
- @Test()
- public void testPLineNoPolicy() {
+ @Test(expected = DescriptorParseException.class)
+ public void testPLineNoPolicy() throws DescriptorParseException {
StatusEntryBuilder.createWithPLine("p 80");
}
- /* TODO We should check this. */
- @Test()
- public void testPLineNoPorts() {
+ @Test(expected = DescriptorParseException.class)
+ public void testPLineNoPorts() throws DescriptorParseException {
StatusEntryBuilder.createWithPLine("p accept");
}
- /* TODO We should check this. */
- @Test()
- public void testPLineNoPolicyNoPorts() {
+ @Test(expected = DescriptorParseException.class)
+ public void testPLineNoPolicyNoPorts() throws DescriptorParseException {
StatusEntryBuilder.createWithPLine("p ");
}
- /* TODO We should check this. */
- @Test()
- public void testPLineProject() {
+ @Test(expected = DescriptorParseException.class)
+ public void testPLineProject() throws DescriptorParseException {
StatusEntryBuilder.createWithPLine("p project 80");
}
- /* TODO We should detect this. */
- @Test()
- public void testTwoPLines() {
+ @Test(expected = DescriptorParseException.class)
+ public void testTwoPLines() throws DescriptorParseException {
StatusEntryBuilder sb = new StatusEntryBuilder();
sb.pLine = sb.pLine + "\n" + sb.pLine;
ConsensusBuilder cb = new ConsensusBuilder();
@@ -994,86 +1168,96 @@ public class RelayNetworkStatusConsensusImplTest {
new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
}
- /* TODO Should we allow this? */
- @Test(expected = RuntimeException.class)
- public void testNoStatusEntries() {
+ @Test()
+ public void testNoStatusEntries() throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.statusEntries.clear();
- new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ RelayNetworkStatusConsensus consensus =
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ assertFalse(consensus.containsStatusEntry(
+ "00795A6E8D91C270FC23B30F388A495553E01894"));
}
- /* TODO Why does this not break? Ah, maybe it just leaves out one
- * status entry. Ugh. It should break! */
- @Test()
- public void testDirectoryFooterNoLine() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDirectoryFooterNoLine()
+ throws DescriptorParseException {
ConsensusBuilder.createWithDirectoryFooterLine(null);
}
- @Test(expected = RuntimeException.class)
- public void testDirectoryFooterLineSpace() {
+ @Test()
+ public void testDirectoryFooterLineSpace()
+ throws DescriptorParseException {
ConsensusBuilder.createWithDirectoryFooterLine("directory-footer ");
}
- /* TODO Make sure that this is really okay in the code. */
@Test()
- public void testBandwidthWeightsNoLine() {
- ConsensusBuilder.createWithBandwidthWeightsLine(null);
+ public void testBandwidthWeightsNoLine()
+ throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus =
+ ConsensusBuilder.createWithBandwidthWeightsLine(null);
+ assertNull(consensus.getBandwidthWeights());
}
- @Test(expected = RuntimeException.class)
- public void testBandwidthWeightsLineNoSpace() {
- ConsensusBuilder.createWithBandwidthWeightsLine("bandwidth-weights");
+ @Test()
+ public void testBandwidthWeightsLineNoSpace()
+ throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus = ConsensusBuilder.
+ createWithBandwidthWeightsLine("bandwidth-weights");
+ assertNotNull(consensus.getBandwidthWeights());
}
- /* TODO We should check this. */
@Test()
- public void testBandwidthWeightsLineOneSpace() {
- ConsensusBuilder.createWithBandwidthWeightsLine("bandwidth-weights ");
+ public void testBandwidthWeightsLineOneSpace()
+ throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus = ConsensusBuilder.
+ createWithBandwidthWeightsLine("bandwidth-weights ");
+ assertNotNull(consensus.getBandwidthWeights());
}
- /* TODO We should check this. */
- @Test()
- public void testBandwidthWeightsLineNoEqualSign() {
+ @Test(expected = DescriptorParseException.class)
+ public void testBandwidthWeightsLineNoEqualSign()
+ throws DescriptorParseException {
ConsensusBuilder.createWithBandwidthWeightsLine(
"bandwidth-weights Wbd-285");
}
- /* TODO We should check this. */
- @Test()
- public void testDirectorySignatureIdentityTooShort() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDirectorySignatureIdentityTooShort()
+ throws DescriptorParseException {
DirectorySignatureBuilder.createWithIdentity("ED03BB616EB2F60");
}
- /* TODO We should check this. */
- @Test()
- public void testDirectorySignatureIdentityTooLong() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDirectorySignatureIdentityTooLong()
+ throws DescriptorParseException {
DirectorySignatureBuilder.createWithIdentity(
"ED03BB616EB2F60BEC80151114BB25CEF515B226ED03BB616EB2F60BEC");
}
- /* TODO We should check this. */
- @Test()
- public void testDirectorySignatureSigningKeyTooShort() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDirectorySignatureSigningKeyTooShort()
+ throws DescriptorParseException {
DirectorySignatureBuilder.createWithSigningKey("845CF1D0B370CA4");
}
- /* TODO We should check this. */
- @Test()
- public void testDirectorySignatureSigningKeyTooLong() {
+ @Test(expected = DescriptorParseException.class)
+ public void testDirectorySignatureSigningKeyTooLong()
+ throws DescriptorParseException {
DirectorySignatureBuilder.createWithSigningKey(
"845CF1D0B370CA443A8579D18E7987E7E532F639845CF1D0B370CA443A");
}
- @Test(expected = RuntimeException.class)
- public void testNonAsciiByte20() {
+ @Test(expected = DescriptorParseException.class)
+ public void testNonAsciiByte20() throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
byte[] consensusBytes = cb.buildConsensus();
consensusBytes[20] = (byte) 200;
new RelayNetworkStatusConsensusImpl(consensusBytes);
}
- @Test(expected = RuntimeException.class)
- public void testNonAsciiByteMinusOne() {
+ @Test(expected = DescriptorParseException.class)
+ public void testNonAsciiByteMinusOne()
+ throws DescriptorParseException {
ConsensusBuilder cb = new ConsensusBuilder();
cb.networkStatusVersionLine = "Xnetwork-status-version 3";
byte[] consensusBytes = cb.buildConsensus();
1
0
I AM SUBMITATION
1
0
Author: phobos
Date: 2011-12-14 03:40:25 +0000 (Wed, 14 Dec 2011)
New Revision: 25252
Modified:
website/trunk/about/en/contact.wml
Log:
add OTR and ZRTP.
Modified: website/trunk/about/en/contact.wml
===================================================================
--- website/trunk/about/en/contact.wml 2011-12-14 03:34:43 UTC (rev 25251)
+++ website/trunk/about/en/contact.wml 2011-12-14 03:40:25 UTC (rev 25252)
@@ -64,12 +64,17 @@
<h3>Live Chat</h3>
<a id="livechat"></a>
- <p>Tor is experimenting with live chat (XMPP/Jabber/GChat), Voice
- over IP (VOIP), SIP, Video, and desktop sharing through the <a
+ <p>Tor is experimenting with live chat (XMPP/Jabber/GChat), Voice over
+ IP (VOIP), VOIP+ZRTP, SIP, Video, and desktop sharing through the <a
href="http://jitsi.org/">Jitsi Open Source Communicator</a>. Contact
- us at: torproject(a)jit.si for live help, questions, or feedback. The
- best times to reach someone is 10:00 - 12:00 GMT-5 on Tuesday and
- 16:00 - 18:00 GMT-5 on Thursday.</p>
+ us at <em>torproject(a)jit.si</em> for live help, questions, or
+ feedback.</p>
+ <p>The best times to reach someone is 10:00 - 12:00 GMT-5 on Tuesday
+ and 16:00 - 18:00 GMT-5 on Thursday.</p>
+ <p>Our OTR key is F624A3 158D22 19F48E E28A73 09F527 1AD5DF 668D.
+ Learn more about <a
+ href="http://www.cypherpunks.ca/otr/">Off-the-Record</a>
+ Messenging.</p>
<h3>Telephone</h3>
<a id="phone"></a>
1
0
14 Dec '11
Author: phobos
Date: 2011-12-14 03:34:43 +0000 (Wed, 14 Dec 2011)
New Revision: 25251
Modified:
website/trunk/about/en/contact.wml
Log:
add jitsi chat support.
Modified: website/trunk/about/en/contact.wml
===================================================================
--- website/trunk/about/en/contact.wml 2011-12-12 21:09:13 UTC (rev 25250)
+++ website/trunk/about/en/contact.wml 2011-12-14 03:34:43 UTC (rev 25251)
@@ -43,8 +43,8 @@
<h3>Identi.ca</h3>
<p><a id="identica"></a>
- Contact us via our microblogging Identi.ca account at <a
- href="https://identi.ca/torproject">torproject</a>.</p>
+ Contact us via our microblogging Identi.ca account <a
+ href="https://identi.ca/torproject">@torproject</a>.</p>
<h3>IRC</h3>
<a id="irc"></a>
@@ -61,6 +61,15 @@
<li><i>#nottor</i> - This is where Tor people hang out to talk about
stuff that is not related to Tor.</li>
</ul>
+
+ <h3>Live Chat</h3>
+ <a id="livechat"></a>
+ <p>Tor is experimenting with live chat (XMPP/Jabber/GChat), Voice
+ over IP (VOIP), SIP, Video, and desktop sharing through the <a
+ href="http://jitsi.org/">Jitsi Open Source Communicator</a>. Contact
+ us at: torproject(a)jit.si for live help, questions, or feedback. The
+ best times to reach someone is 10:00 - 12:00 GMT-5 on Tuesday and
+ 16:00 - 18:00 GMT-5 on Thursday.</p>
<h3>Telephone</h3>
<a id="phone"></a>
1
0
commit 1f59be94b0d8bf20f522296ca9b5a895d36884ac
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Tue Dec 13 20:42:01 2011 +0100
Add a LICENSE.
---
LICENSE | 30 ++++++++++++++++++++++++++++++
1 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d5b67cd
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright 2011 The Tor Project
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the names of the copyright owners nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
1
0
13 Dec '11
commit 358b92b019a4fc184f9c42b3a8bdbf1c7ff32e32
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Tue Dec 13 20:44:51 2011 +0100
Remove executable bit from many files.
---
0 files changed, 0 insertions(+), 0 deletions(-)
diff --git a/README b/README
old mode 100755
new mode 100644
diff --git a/TODO b/TODO
old mode 100755
new mode 100644
diff --git a/build.xml b/build.xml
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/BridgeDescriptorReader.java b/src/org/torproject/descriptor/BridgeDescriptorReader.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/BridgeExtraInfoDescriptor.java b/src/org/torproject/descriptor/BridgeExtraInfoDescriptor.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/BridgeNetworkStatus.java b/src/org/torproject/descriptor/BridgeNetworkStatus.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/BridgePoolAssignmentReader.java b/src/org/torproject/descriptor/BridgePoolAssignmentReader.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/BridgeServerDescriptor.java b/src/org/torproject/descriptor/BridgeServerDescriptor.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/Descriptor.java b/src/org/torproject/descriptor/Descriptor.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/DescriptorFile.java b/src/org/torproject/descriptor/DescriptorFile.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/DescriptorRequest.java b/src/org/torproject/descriptor/DescriptorRequest.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/DescriptorSourceFactory.java b/src/org/torproject/descriptor/DescriptorSourceFactory.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/DirSourceEntry.java b/src/org/torproject/descriptor/DirSourceEntry.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/GetTorStatsReader.java b/src/org/torproject/descriptor/GetTorStatsReader.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/NetworkStatusEntry.java b/src/org/torproject/descriptor/NetworkStatusEntry.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/RelayDescriptorDownloader.java b/src/org/torproject/descriptor/RelayDescriptorDownloader.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/RelayDescriptorReader.java b/src/org/torproject/descriptor/RelayDescriptorReader.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/RelayExtraInfoDescriptor.java b/src/org/torproject/descriptor/RelayExtraInfoDescriptor.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/RelayNetworkStatusConsensus.java b/src/org/torproject/descriptor/RelayNetworkStatusConsensus.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/RelayNetworkStatusVote.java b/src/org/torproject/descriptor/RelayNetworkStatusVote.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/RelayServerDescriptor.java b/src/org/torproject/descriptor/RelayServerDescriptor.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/TorperfDataReader.java b/src/org/torproject/descriptor/TorperfDataReader.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/example/ConsensusHealthChecker.java b/src/org/torproject/descriptor/example/ConsensusHealthChecker.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/example/MetricsRelayDescriptorAggregator.java b/src/org/torproject/descriptor/example/MetricsRelayDescriptorAggregator.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/example/TorStatusDatabaseUpdater.java b/src/org/torproject/descriptor/example/TorStatusDatabaseUpdater.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/impl/BlockingIteratorImpl.java b/src/org/torproject/descriptor/impl/BlockingIteratorImpl.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/impl/BridgeDescriptorReaderImpl.java b/src/org/torproject/descriptor/impl/BridgeDescriptorReaderImpl.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/impl/DescriptorRequestImpl.java b/src/org/torproject/descriptor/impl/DescriptorRequestImpl.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/impl/DirSourceEntryImpl.java b/src/org/torproject/descriptor/impl/DirSourceEntryImpl.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java b/src/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/impl/RelayDescriptorDownloaderImpl.java b/src/org/torproject/descriptor/impl/RelayDescriptorDownloaderImpl.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/impl/RelayDescriptorReaderImpl.java b/src/org/torproject/descriptor/impl/RelayDescriptorReaderImpl.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java b/src/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
old mode 100755
new mode 100644
diff --git a/src/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java b/src/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
old mode 100755
new mode 100644
1
0
13 Dec '11
commit 703ba95627833d413cb4085b4d63c44add14ce54
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Tue Dec 13 20:39:33 2011 +0100
Add unit tests for parsing consensuses.
The parser doesn't detect many problems yet. Most of the unit tests check
for the absence of exceptions when they really should test for the
exceptions. This is more like a TODO list for making the parser better.
---
build.xml | 25 +
.../impl/RelayNetworkStatusConsensusImplTest.java | 1084 ++++++++++++++++++++
2 files changed, 1109 insertions(+), 0 deletions(-)
diff --git a/build.xml b/build.xml
index de40dd0..83cd991 100755
--- a/build.xml
+++ b/build.xml
@@ -1,10 +1,12 @@
<project default="run" name="descriptor" basedir=".">
<property name="sources" value="src"/>
<property name="classes" value="classes"/>
+ <property name="tests" value="test"/>
<property name="libs" value="lib"/>
<path id="classpath">
<pathelement path="${classes}"/>
<pathelement location="lib/commons-codec-1.4.jar"/>
+ <pathelement location="lib/junit-4.8.2.jar"/>
</path>
<target name="init">
<mkdir dir="${classes}"/>
@@ -29,5 +31,28 @@
<jar destfile="descriptor.jar"
basedir="${classes}"/>
</target>
+ <target name="test" depends="compile">
+ <javac destdir="${classes}"
+ srcdir="${tests}"
+ source="1.5"
+ target="1.5"
+ debug="true"
+ deprecation="true"
+ optimize="false"
+ failonerror="true"
+ includeantruntime="false">
+ <classpath>
+ <fileset dir="${libs}"/>
+ </classpath>
+ </javac>
+ <junit haltonfailure="true" printsummary="off">
+ <classpath refid="classpath"/>
+ <formatter type="plain" usefile="false"/>
+ <batchtest>
+ <fileset dir="${classes}"
+ includes="**/*Test.class"/>
+ </batchtest>
+ </junit>
+ </target>
</project>
diff --git a/test/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java b/test/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java
new file mode 100644
index 0000000..4a7a7be
--- /dev/null
+++ b/test/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java
@@ -0,0 +1,1084 @@
+/* Copyright 2011 The Tor Project
+ * See LICENSE for licensing information */
+package org.torproject.descriptor.impl;
+
+import org.torproject.descriptor.RelayNetworkStatusConsensus;
+import org.torproject.descriptor.impl.RelayNetworkStatusConsensusImpl;
+
+import java.util.*;
+
+import org.junit.*;
+import org.junit.rules.*;
+import static org.junit.Assert.*;
+
+/* Test parsing of network status consensuses. The main focus is on
+ * making sure that the parser is as robust as possible and doesn't break,
+ * no matter what gets fed into it. A secondary focus is to ensure that
+ * a parsed consensus is fully compatible to dir-spec.txt. */
+public class RelayNetworkStatusConsensusImplTest {
+
+ /* Helper class to build a consensus based on default data and
+ * modifications requested by test methods. */
+ private static class ConsensusBuilder {
+ private String networkStatusVersionLine = "network-status-version 3";
+ private static void createWithNetworkStatusVersionLine(String line) {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.networkStatusVersionLine = line;
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+ private String voteStatusLine = "vote-status consensus";
+ private static void createWithVoteStatusLine(String line) {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.voteStatusLine = line;
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+ private String consensusMethodLine = "consensus-method 11";
+ private static void createWithConsensusMethodLine(String line) {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.consensusMethodLine = line;
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+ private String validAfterLine = "valid-after 2011-11-30 09:00:00";
+ private static void createWithValidAfterLine(String line) {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.validAfterLine = line;
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+ private String freshUntilLine = "fresh-until 2011-11-30 10:00:00";
+ private static void createWithFreshUntilLine(String line) {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.freshUntilLine = line;
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+ private String validUntilLine = "valid-until 2011-11-30 12:00:00";
+ private static void createWithValidUntilLine(String line) {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.validUntilLine = line;
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+ private String votingDelayLine = "voting-delay 300 300";
+ private static void createWithVotingDelayLine(String line) {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.votingDelayLine = line;
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+ private String clientVersionsLine = "client-versions 0.2.1.31,"
+ + "0.2.2.34,0.2.3.6-alpha,0.2.3.7-alpha,0.2.3.8-alpha";
+ private static void createWithClientVersionsLine(String line) {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.clientVersionsLine = line;
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+ private String serverVersionsLine = "server-versions 0.2.1.31,"
+ + "0.2.2.34,0.2.3.6-alpha,0.2.3.7-alpha,0.2.3.8-alpha";
+ private static void createWithServerVersionsLine(String line) {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.serverVersionsLine = line;
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+ private String knownFlagsLine = "known-flags Authority BadExit Exit "
+ + "Fast Guard HSDir Named Running Stable Unnamed V2Dir Valid";
+ private static void createWithKnownFlagsLine(String line) {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.knownFlagsLine = line;
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+ private String paramsLine = "params "
+ + "CircuitPriorityHalflifeMsec=30000 bwauthbestratio=1 "
+ + "bwauthcircs=1 bwauthdescbw=0 bwauthkp=10000 bwauthpid=1 "
+ + "bwauthtd=5000 bwauthti=50000 bwauthtidecay=5000 cbtnummodes=3 "
+ + "cbtquantile=80 circwindow=1000 refuseunknownexits=1";
+ private static void createWithParamsLine(String line) {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.paramsLine = line;
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+ private List<String> dirSources = new ArrayList<String>();
+ private List<String> statusEntries = new ArrayList<String>();
+ private String directoryFooterLine = "directory-footer";
+ private static void createWithDirectoryFooterLine(String line) {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.directoryFooterLine = line;
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+ private String bandwidthWeightsLine = "bandwidth-weights Wbd=285 "
+ + "Wbe=0 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=1021 Wee=10000 "
+ + "Weg=1021 Wem=10000 Wgb=10000 Wgd=8694 Wgg=10000 Wgm=10000 "
+ + "Wmb=10000 Wmd=285 Wme=0 Wmg=0 Wmm=10000";
+ private static void createWithBandwidthWeightsLine(String line) {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.bandwidthWeightsLine = line;
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+ private List<String> directorySignatures = new ArrayList<String>();
+ private ConsensusBuilder() {
+ this.dirSources.add("dir-source tor26 "
+ + "14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 86.59.21.38 "
+ + "86.59.21.38 80 443\ncontact Peter Palfrader\nvote-digest "
+ + "0333880AA67ED7E07C11108656D0C8D6DD1C7E5D");
+ this.dirSources.add("dir-source ides "
+ + "27B6B5996C426270A5C95488AA5BCEB6BCC86956 216.224.124.114 "
+ + "216.224.124.114 9030 9090\ncontact Mike Perry "
+ + "<mikeperryTAfsckedTODorg>\nvote-digest "
+ + "1A8827ECD53184F7A771EFA9B3D30DC473FE8670");
+ this.statusEntries.add("r ANONIONROUTER "
+ + "AHhuQ8zFQJdT8l42Axxc6m6kNwI yEMZ5B/JQixNZgC1+2rLe0pR9rU "
+ + "2011-11-30 02:52:58 93.128.66.111 24051 24052\ns Exit Fast "
+ + "Named Running V2Dir Valid\nv Tor 0.2.2.34\nw "
+ + "Bandwidth=1100\np reject 25,119,135-139,6881-6999");
+ this.statusEntries.add("r Magellan AHlabo2RwnD8I7MPOIpJVVPgGJQ "
+ + "rB/7uzI4mU38bZ9cSXEy+Z/4Cuk 2011-11-30 05:37:35 "
+ + "188.177.149.216 9001 9030\ns Fast Named Running V2Dir "
+ + "Valid\nv Tor 0.2.2.34\nw Bandwidth=367\np reject 1-65535");
+ this.directorySignatures.add("directory-signature "
+ + "14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
+ + "3509BA5A624403A905C74DA5C8A0CEC9E0D3AF86\n"
+ + "-----BEGIN SIGNATURE-----\n"
+ + "NYRcTWAMRiYYiGW0hIbzeZKU6sefg98AwwXrQUCudO8wfA1cfgttTDoscB9I"
+ + "TbOY\n"
+ + "x+c30jV/qQCMamTAEDGgJTw8KghI32vytupKallI1EjCOF8UvL1UnALgpaR7"
+ + "sZ3W\n"
+ + "7WQZVVrWDtnYaULOEKfwnGnRC7WwE+YRSysbzwwCVs0=\n"
+ + "-----END SIGNATURE-----");
+ this.directorySignatures.add("directory-signature "
+ + "27B6B5996C426270A5C95488AA5BCEB6BCC86956 "
+ + "D5C30C15BB3F1DA27669C2D88439939E8F418FCF\n"
+ + "-----BEGIN SIGNATURE-----\n"
+ + "DzFPj3vyYrCv0W3r8qDPJPlmeLnadY+drjWkdOqO66Ih/hAWBb9KcBJAX1sX"
+ + "aDA7\n"
+ + "/iSaDhduBXuJdcu8lbmMP8d6uYBdRjHXqWDXySUZAkSfPB4JJPNGvfoQA/qe"
+ + "by7E\n"
+ + "5374pPPL6WwCLJHkKtk21S9oHDmFBdlZq7JWQelWlVM=\n"
+ + "-----END SIGNATURE-----");
+ }
+ private byte[] buildConsensus() {
+ StringBuilder sb = new StringBuilder();
+ this.appendHeader(sb);
+ this.appendBody(sb);
+ this.appendFooter(sb);
+ return sb.toString().getBytes();
+ }
+ private void appendHeader(StringBuilder sb) {
+ if (this.networkStatusVersionLine != null) {
+ sb.append(this.networkStatusVersionLine + "\n");
+ }
+ if (this.voteStatusLine != null) {
+ sb.append(this.voteStatusLine + "\n");
+ }
+ if (this.consensusMethodLine != null) {
+ sb.append(this.consensusMethodLine + "\n");
+ }
+ if (this.validAfterLine != null) {
+ sb.append(this.validAfterLine + "\n");
+ }
+ if (this.freshUntilLine != null) {
+ sb.append(this.freshUntilLine + "\n");
+ }
+ if (this.validUntilLine != null) {
+ sb.append(this.validUntilLine + "\n");
+ }
+ if (this.votingDelayLine != null) {
+ sb.append(this.votingDelayLine + "\n");
+ }
+ if (this.clientVersionsLine != null) {
+ sb.append(this.clientVersionsLine + "\n");
+ }
+ if (this.serverVersionsLine != null) {
+ sb.append(this.serverVersionsLine + "\n");
+ }
+ if (this.knownFlagsLine != null) {
+ sb.append(this.knownFlagsLine + "\n");
+ }
+ if (this.paramsLine != null) {
+ sb.append(this.paramsLine + "\n");
+ }
+ for (String dirSource : this.dirSources) {
+ sb.append(dirSource + "\n");
+ }
+ }
+ private void appendBody(StringBuilder sb) {
+ for (String statusEntry : this.statusEntries) {
+ sb.append(statusEntry + "\n");
+ }
+ }
+ private void appendFooter(StringBuilder sb) {
+ if (this.directoryFooterLine != null) {
+ sb.append(this.directoryFooterLine + "\n");
+ }
+ if (this.bandwidthWeightsLine != null) {
+ sb.append(this.bandwidthWeightsLine + "\n");
+ }
+ for (String directorySignature : this.directorySignatures) {
+ sb.append(directorySignature + "\n");
+ }
+ }
+ }
+
+ /* Helper class to build a directory source based on default data and
+ * modifications requested by test methods. */
+ private static class DirSourceBuilder {
+ private static void createWithDirSource(String dirSourceString) {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.dirSources.add(dirSourceString);
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+ private String nickname = "gabelmoo";
+ private static void createWithNickname(String string) {
+ DirSourceBuilder dsb = new DirSourceBuilder();
+ dsb.nickname = string;
+ createWithDirSource(dsb.buildDirSource());
+ }
+ private String identity = "ED03BB616EB2F60BEC80151114BB25CEF515B226";
+ private static void createWithIdentity(String string) {
+ DirSourceBuilder dsb = new DirSourceBuilder();
+ dsb.identity = string;
+ createWithDirSource(dsb.buildDirSource());
+ }
+ private String hostName = "212.112.245.170";
+ private static void createWithHostName(String string) {
+ DirSourceBuilder dsb = new DirSourceBuilder();
+ dsb.hostName = string;
+ createWithDirSource(dsb.buildDirSource());
+ }
+ private String address = "212.112.245.170";
+ private static void createWithAddress(String string) {
+ DirSourceBuilder dsb = new DirSourceBuilder();
+ dsb.address = string;
+ createWithDirSource(dsb.buildDirSource());
+ }
+ private String dirPort = "80";
+ private static void createWithDirPort(String string) {
+ DirSourceBuilder dsb = new DirSourceBuilder();
+ dsb.dirPort = string;
+ createWithDirSource(dsb.buildDirSource());
+ }
+ private String orPort = "443";
+ private static void createWithOrPort(String string) {
+ DirSourceBuilder dsb = new DirSourceBuilder();
+ dsb.orPort = string;
+ createWithDirSource(dsb.buildDirSource());
+ }
+ private String contactLine = "contact 4096R/C5AA446D Sebastian Hahn "
+ + "<tor(a)sebastianhahn.net>";
+ private static void createWithContactLine(String line) {
+ DirSourceBuilder dsb = new DirSourceBuilder();
+ dsb.contactLine = line;
+ createWithDirSource(dsb.buildDirSource());
+ }
+ private String voteDigestLine =
+ "vote-digest 0F398A5834D2C139E1D92310B09F814F243354D1";
+ private static void createWithVoteDigestLine(String line) {
+ DirSourceBuilder dsb = new DirSourceBuilder();
+ dsb.voteDigestLine = line;
+ createWithDirSource(dsb.buildDirSource());
+ }
+ private String buildDirSource() {
+ StringBuilder sb = new StringBuilder();
+ String dirSourceLine = "dir-source " + this.nickname + " "
+ + this.identity + " " + this.hostName + " " + this.address + " "
+ + this.dirPort + " " + this.orPort;
+ sb.append(dirSourceLine + "\n");
+ if (this.contactLine != null) {
+ sb.append(this.contactLine + "\n");
+ }
+ if (this.voteDigestLine != null) {
+ sb.append(this.voteDigestLine + "\n");
+ }
+ String dirSourceWithTrailingNewLine = sb.toString();
+ String dirSource = dirSourceWithTrailingNewLine.substring(0,
+ dirSourceWithTrailingNewLine.length() - 1);
+ return dirSource;
+ }
+ }
+
+ /* Helper class to build a status entry based on default data and
+ * modifications requested by test methods. */
+ private static class StatusEntryBuilder {
+ private static void createWithStatusEntry(String statusEntryString) {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.statusEntries.add(statusEntryString);
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+ private String nickname = "right2privassy3";
+ private static void createWithNickname(String string) {
+ StatusEntryBuilder seb = new StatusEntryBuilder();
+ seb.nickname = string;
+ createWithStatusEntry(seb.buildStatusEntry());
+ }
+ private String fingerprintBase64 = "ADQ6gCT3DiFHKPDFr3rODBUI8HM";
+ private static void createWithFingerprintBase64(String string) {
+ StatusEntryBuilder seb = new StatusEntryBuilder();
+ seb.fingerprintBase64 = string;
+ createWithStatusEntry(seb.buildStatusEntry());
+ }
+ private String descriptorBase64 = "Yiti+nayuT2Efe2X1+M4nslwVuU";
+ private static void createWithDescriptorBase64(String string) {
+ StatusEntryBuilder seb = new StatusEntryBuilder();
+ seb.descriptorBase64 = string;
+ createWithStatusEntry(seb.buildStatusEntry());
+ }
+ private String publishedString = "2011-11-29 21:34:27";
+ private static void createWithPublishedString(String string) {
+ StatusEntryBuilder seb = new StatusEntryBuilder();
+ seb.publishedString = string;
+ createWithStatusEntry(seb.buildStatusEntry());
+ }
+ private String address = "50.63.8.215";
+ private static void createWithAddress(String string) {
+ StatusEntryBuilder seb = new StatusEntryBuilder();
+ seb.address = string;
+ createWithStatusEntry(seb.buildStatusEntry());
+ }
+ private String orPort = "9023";
+ private static void createWithOrPort(String string) {
+ StatusEntryBuilder seb = new StatusEntryBuilder();
+ seb.orPort = string;
+ createWithStatusEntry(seb.buildStatusEntry());
+ }
+ private String dirPort = "0";
+ private static void createWithDirPort(String string) {
+ StatusEntryBuilder seb = new StatusEntryBuilder();
+ seb.dirPort = string;
+ createWithStatusEntry(seb.buildStatusEntry());
+ }
+ private String sLine = "s Exit Fast Named Running Stable Valid";
+ private static void createWithSLine(String line) {
+ StatusEntryBuilder seb = new StatusEntryBuilder();
+ seb.sLine = line;
+ createWithStatusEntry(seb.buildStatusEntry());
+ }
+ private String vLine = "v Tor 0.2.1.29 (r8e9b25e6c7a2e70c)";
+ private static void createWithVLine(String line) {
+ StatusEntryBuilder seb = new StatusEntryBuilder();
+ seb.vLine = line;
+ createWithStatusEntry(seb.buildStatusEntry());
+ }
+ private String wLine = "w Bandwidth=1";
+ private static void createWithWLine(String line) {
+ StatusEntryBuilder seb = new StatusEntryBuilder();
+ seb.wLine = line;
+ createWithStatusEntry(seb.buildStatusEntry());
+ }
+ private String pLine = "p accept 80,1194,1220,1293";
+ private static void createWithPLine(String line) {
+ StatusEntryBuilder seb = new StatusEntryBuilder();
+ seb.pLine = line;
+ createWithStatusEntry(seb.buildStatusEntry());
+ }
+ private String buildStatusEntry() {
+ StringBuilder sb = new StringBuilder();
+ String rLine = "r " + nickname + " " + fingerprintBase64 + " "
+ + descriptorBase64 + " " + publishedString + " " + address + " "
+ + orPort + " " + dirPort;
+ sb.append(rLine + "\n");
+ if (this.sLine != null) {
+ sb.append(this.sLine + "\n");
+ }
+ if (this.vLine != null) {
+ sb.append(this.vLine + "\n");
+ }
+ if (this.wLine != null) {
+ sb.append(this.wLine + "\n");
+ }
+ if (this.pLine != null) {
+ sb.append(this.pLine + "\n");
+ }
+ String statusEntryWithTrailingNewLine = sb.toString();
+ String statusEntry = statusEntryWithTrailingNewLine.substring(0,
+ statusEntryWithTrailingNewLine.length() - 1);
+ return statusEntry;
+ }
+ }
+
+ /* Helper class to build a directory signature based on default data and
+ * modifications requested by test methods. */
+ private static class DirectorySignatureBuilder {
+ private static void createWithDirectorySignature(
+ String directorySignatureString) {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.directorySignatures.add(directorySignatureString);
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+ private String identity = "ED03BB616EB2F60BEC80151114BB25CEF515B226";
+ private static void createWithIdentity(String string) {
+ DirectorySignatureBuilder dsb = new DirectorySignatureBuilder();
+ dsb.identity = string;
+ createWithDirectorySignature(dsb.buildDirectorySignature());
+ }
+ private String signingKey =
+ "845CF1D0B370CA443A8579D18E7987E7E532F639";
+ private static void createWithSigningKey(String string) {
+ DirectorySignatureBuilder dsb = new DirectorySignatureBuilder();
+ dsb.signingKey = string;
+ createWithDirectorySignature(dsb.buildDirectorySignature());
+ }
+ private String buildDirectorySignature() {
+ String directorySignature = "directory-signature " + identity + " "
+ + signingKey + "\n"
+ + "-----BEGIN SIGNATURE-----\n"
+ + "gE64+/4BH43v1+7jS9FK1tu2+94at8xhVSPn4O/PpOx7b0Yb+S1hac1QHAiS"
+ + "Ll+k\n"
+ + "6OiANKzhj54WHSrUswBPrOzjmKj0OhGXSAe5nHZUFX9a1MDQLDCoZBj536X9"
+ + "P3JG\n"
+ + "z89A+wrsN17I5490y66AEvws54BYZMbgRfp8HXn/0Ss=\n"
+ + "-----END SIGNATURE-----";
+ return directorySignature;
+ }
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testSampleConsensus() {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+
+ /* TODO Throwing a RuntimeException here (and in most places below) is
+ * bad. Maybe we should define a DescriptorParseException. */
+ @Test(expected = RuntimeException.class)
+ public void testNetworkStatusVersionNoLine() {
+ ConsensusBuilder.createWithNetworkStatusVersionLine(null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testNetworkStatusVersionPrefixLineAtChar() {
+ ConsensusBuilder.createWithNetworkStatusVersionLine(
+ "@consensus\nnetwork-status-version 3");
+ }
+
+ /* TODO This doesn't break. Should it? */
+ @Test()
+ public void testNetworkStatusVersionPrefixDirectoryFooter() {
+ ConsensusBuilder.createWithNetworkStatusVersionLine(
+ "directory-footer\nnetwork-status-version 3");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testNetworkStatusVersionPrefixLinePoundChar() {
+ ConsensusBuilder.createWithNetworkStatusVersionLine(
+ "#consensus\nnetwork-status-version 3");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testNetworkStatusVersionNoSpace() {
+ ConsensusBuilder.createWithNetworkStatusVersionLine(
+ "network-status-version");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testNetworkStatusVersionOneSpace() {
+ ConsensusBuilder.createWithNetworkStatusVersionLine(
+ "network-status-version ");
+ }
+
+ /* TODO The parser should only accept version 3 and throw an Exception
+ * here. */
+ @Test()
+ public void testNetworkStatusVersion42() {
+ ConsensusBuilder.createWithNetworkStatusVersionLine(
+ "network-status-version 42");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testNetworkStatusVersionFourtyTwo() {
+ ConsensusBuilder.createWithNetworkStatusVersionLine(
+ "network-status-version FourtyTwo");
+ }
+
+ /* TODO Shouldn't this throw an exception? */
+ @Test()
+ public void testVoteStatusNoLine() {
+ ConsensusBuilder.createWithVoteStatusLine(null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testVoteStatusNoSpace() {
+ ConsensusBuilder.createWithVoteStatusLine("vote-status");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testVoteStatusOneSpace() {
+ ConsensusBuilder.createWithVoteStatusLine("vote-status ");
+ }
+
+ /* TODO Should this be accepted or not? */
+ @Test(expected = RuntimeException.class)
+ public void testVoteStatusConsensusOneSpace() {
+ ConsensusBuilder.createWithVoteStatusLine("vote-status consensus ");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testVoteStatusVote() {
+ ConsensusBuilder.createWithVoteStatusLine("vote-status vote");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testVoteStatusTheMagicVoteStatus() {
+ ConsensusBuilder.createWithVoteStatusLine(
+ "vote-status TheMagicVoteStatus");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testConsensusMethodNoLine() {
+ ConsensusBuilder.createWithConsensusMethodLine(null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testConsensusMethodNoSpace() {
+ ConsensusBuilder.createWithConsensusMethodLine("consensus-method");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testConsensusMethodOneSpace() {
+ ConsensusBuilder.createWithConsensusMethodLine("consensus-method ");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testConsensusMethodEleven() {
+ ConsensusBuilder.createWithConsensusMethodLine(
+ "consensus-method eleven");
+ }
+
+ /* TODO We shouldn't allow negative values here. */
+ @Test()
+ public void testConsensusMethodMinusOne() {
+ ConsensusBuilder.createWithConsensusMethodLine("consensus-method -1");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testConsensusMethodNinePeriod() {
+ ConsensusBuilder.createWithConsensusMethodLine("consensus-method "
+ + "999999999999999999999999999999999999999999999999999999999999");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testValidAfterNoLine() {
+ ConsensusBuilder.createWithValidAfterLine(null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testValidAfterNoSpace() {
+ ConsensusBuilder.createWithValidAfterLine("valid-after");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testValidAfterOneSpace() {
+ ConsensusBuilder.createWithValidAfterLine("valid-after ");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testValidAfterLongAgo() {
+ ConsensusBuilder.createWithValidAfterLine("valid-after long ago");
+ }
+
+ /* TODO Wow, this should really throw an exception! */
+ @Test()
+ public void testValidAfterFeb30() {
+ ConsensusBuilder.createWithValidAfterLine(
+ "valid-after 2011-02-30 09:00:00");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testFreshUntilNoLine() {
+ ConsensusBuilder.createWithFreshUntilLine(null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testFreshUntilAroundTen() {
+ ConsensusBuilder.createWithFreshUntilLine(
+ "fresh-until 2011-11-30 around ten");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testValidUntilTomorrowMorning() {
+ ConsensusBuilder.createWithValidUntilLine(
+ "valid-until tomorrow morning");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testVotingDelayNoLine() {
+ ConsensusBuilder.createWithVotingDelayLine(null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testVotingDelayNoSpace() {
+ ConsensusBuilder.createWithVotingDelayLine("voting-delay");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testVotingDelayOneSpace() {
+ ConsensusBuilder.createWithVotingDelayLine("voting-delay ");
+ }
+
+ /* TODO This should throw an exception. */
+ @Test()
+ public void testVotingDelayTriple() {
+ ConsensusBuilder.createWithVotingDelayLine(
+ "voting-delay 300 300 300");
+ }
+
+ /* TODO This should throw an exception. */
+ @Test()
+ public void testVotingDelaySingle() {
+ ConsensusBuilder.createWithVotingDelayLine("voting-delay 300");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testVotingDelayOneTwo() {
+ ConsensusBuilder.createWithVotingDelayLine("voting-delay one two");
+ }
+
+ /* TODO Should this be forbidden? */
+ @Test()
+ public void testClientVersionsNoLineServerVersionsNoLine() {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.clientVersionsLine = null;
+ cb.serverVersionsLine = null;
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+
+ /* TODO Should this be forbidden? */
+ @Test()
+ public void testServerVersionsNoLine() {
+ ConsensusBuilder.createWithServerVersionsLine(null);
+ }
+
+ /* TODO Should this be forbidden? */
+ @Test()
+ public void testClientVersionsNoLine() {
+ ConsensusBuilder.createWithClientVersionsLine(null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testClientVersionsNoSpace() {
+ ConsensusBuilder.createWithClientVersionsLine("client-versions");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testClientVersionsOneSpace() {
+ ConsensusBuilder.createWithClientVersionsLine("client-versions ");
+ }
+
+ /* TODO This should be caught. */
+ @Test()
+ public void testClientVersionsComma() {
+ ConsensusBuilder.createWithClientVersionsLine("client-versions ,");
+ }
+
+ /* TODO This should be caught. */
+ @Test()
+ public void testClientVersionsCommaVersion() {
+ ConsensusBuilder.createWithClientVersionsLine(
+ "client-versions ,0.2.2.34");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testKnownFlagsNoLine() {
+ ConsensusBuilder.createWithKnownFlagsLine(null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testKnownFlagsNoSpace() {
+ ConsensusBuilder.createWithKnownFlagsLine("known-flags");
+ }
+
+ /* TODO Looks like this okay, right? */
+ @Test()
+ public void testKnownFlagsOneSpace() {
+ ConsensusBuilder.createWithKnownFlagsLine("known-flags ");
+ }
+
+ /* TODO Make sure that the params line is optional. */
+ @Test()
+ public void testParamsNoLine() {
+ ConsensusBuilder.createWithParamsLine(null);
+ }
+
+ /* TODO If it's okay to provide an empty params line, this one should be
+ * accepted, too. */
+ @Test(expected = RuntimeException.class)
+ public void testParamsNoSpace() {
+ ConsensusBuilder.createWithParamsLine("params");
+ }
+
+ /* TODO Is this okay? */
+ @Test()
+ public void testParamsOneSpace() {
+ ConsensusBuilder.createWithParamsLine("params ");
+ }
+
+ /* TODO Hmm, and this is okay? */
+ @Test()
+ public void testParamsThreeSpaces() {
+ ConsensusBuilder.createWithParamsLine("params ");
+ }
+
+ /* TODO The error message here looked strange. Investigate. */
+ @Test(expected = RuntimeException.class)
+ public void testParamsNoEqualSign() {
+ ConsensusBuilder.createWithParamsLine("params key-value");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDirSourceIdentityTooShort() {
+ DirSourceBuilder.createWithIdentity("ED03BB616EB2F60BEC8015111");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDirSourceIdentityTooLong() {
+ DirSourceBuilder.createWithIdentity("ED03BB616EB2F60BEC8015111"
+ + "4BB25CEF515B226ED03BB616EB2F60BEC8");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDirSourceAddress24() {
+ DirSourceBuilder.createWithAddress("212.112.245");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDirSourceAddress40() {
+ DirSourceBuilder.createWithAddress("212.112.245.170.123");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDirSourceDirPortMinusOne() {
+ DirSourceBuilder.createWithDirPort("-1");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDirSourceDirPort66666() {
+ DirSourceBuilder.createWithDirPort("66666");
+ }
+
+ /* TODO We should check this. */
+ @Test(expected = RuntimeException.class)
+ public void testDirSourceDirPortOnions() {
+ DirSourceBuilder.createWithDirPort("onions");
+ }
+
+ /* TODO We should check this. */
+ @Test(expected = RuntimeException.class)
+ public void testDirSourceOrPortOnions() {
+ DirSourceBuilder.createWithOrPort("onions");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDirSourceContactNoLine() {
+ DirSourceBuilder.createWithContactLine(null);
+ }
+
+ /* TODO We should check this. */
+ @Test(expected = RuntimeException.class)
+ public void testDirSourceContactLineNoSpace() {
+ DirSourceBuilder.createWithContactLine("contact");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDirSourceContactLineOneSpace() {
+ DirSourceBuilder.createWithContactLine("contact ");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDirSourceVoteDigestNoLine() {
+ DirSourceBuilder.createWithVoteDigestLine(null);
+ }
+
+ /* TODO We should check this. */
+ @Test(expected = RuntimeException.class)
+ public void testDirSourceVoteDigestLineNoSpace() {
+ DirSourceBuilder.createWithVoteDigestLine("vote-digest");
+ }
+
+ /* TODO We should check this. */
+ @Test(expected = RuntimeException.class)
+ public void testDirSourceVoteDigestLineOneSpace() {
+ DirSourceBuilder.createWithVoteDigestLine("vote-digest ");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testNicknameNotAllowedChars() {
+ StatusEntryBuilder.createWithNickname("notAll()wed");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testNicknameTooLong() {
+ StatusEntryBuilder.createWithNickname("1234567890123456789tooLong");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testFingerprintTooShort() {
+ StatusEntryBuilder.createWithFingerprintBase64("TooShort");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testFingerprintEndsWithEqualSign() {
+ StatusEntryBuilder.createWithFingerprintBase64(
+ "ADQ6gCT3DiFHKPDFr3rODBUI8H=");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testFingerprintTooLong() {
+ StatusEntryBuilder.createWithFingerprintBase64(
+ "ADQ6gCT3DiFHKPDFr3rODBUI8HMAAAA");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDescriptorTooShort() {
+ StatusEntryBuilder.createWithDescriptorBase64("TooShort");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDescriptorEndsWithEqualSign() {
+ StatusEntryBuilder.createWithDescriptorBase64(
+ "ADQ6gCT3DiFHKPDFr3rODBUI8H=");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDescriptorTooLong() {
+ StatusEntryBuilder.createWithDescriptorBase64(
+ "Yiti+nayuT2Efe2X1+M4nslwVuUAAAA");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testPublished1960() {
+ StatusEntryBuilder.createWithPublishedString("1960-11-29 21:34:27");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testPublished9999() {
+ StatusEntryBuilder.createWithPublishedString("9999-11-29 21:34:27");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testAddress256() {
+ StatusEntryBuilder.createWithAddress("256.63.8.215");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testAddress24() {
+ StatusEntryBuilder.createWithAddress("50.63.8/24");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testAddressV6() {
+ StatusEntryBuilder.createWithAddress("::1");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testOrPort66666() {
+ StatusEntryBuilder.createWithOrPort("66666");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testOrPortEighty() {
+ StatusEntryBuilder.createWithOrPort("eighty");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDirPortMinusOne() {
+ StatusEntryBuilder.createWithDirPort("-1");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDirPortZero() {
+ StatusEntryBuilder.createWithDirPort("zero");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testSLineNoSpace() {
+ StatusEntryBuilder.createWithSLine("s");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testSLineOneSpace() {
+ StatusEntryBuilder.createWithSLine("s ");
+ }
+
+ /* TODO We should detect this. */
+ @Test()
+ public void testTwoSLines() {
+ StatusEntryBuilder sb = new StatusEntryBuilder();
+ sb.sLine = sb.sLine + "\n" + sb.sLine;
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.statusEntries.add(sb.buildStatusEntry());
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+
+ /* TODO This is not allowed, right? */
+ @Test(expected = RuntimeException.class)
+ public void testWLineNoSpace() {
+ StatusEntryBuilder.createWithSLine("w");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testWLineOneSpace() {
+ StatusEntryBuilder.createWithSLine("w ");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testWLineWarpSeven() {
+ StatusEntryBuilder.createWithWLine("w Warp=7");
+ }
+
+ /* TODO We should detect this. */
+ @Test()
+ public void testTwoWLines() {
+ StatusEntryBuilder sb = new StatusEntryBuilder();
+ sb.wLine = sb.wLine + "\n" + sb.wLine;
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.statusEntries.add(sb.buildStatusEntry());
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testPLineNoPolicy() {
+ StatusEntryBuilder.createWithPLine("p 80");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testPLineNoPorts() {
+ StatusEntryBuilder.createWithPLine("p accept");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testPLineNoPolicyNoPorts() {
+ StatusEntryBuilder.createWithPLine("p ");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testPLineProject() {
+ StatusEntryBuilder.createWithPLine("p project 80");
+ }
+
+ /* TODO We should detect this. */
+ @Test()
+ public void testTwoPLines() {
+ StatusEntryBuilder sb = new StatusEntryBuilder();
+ sb.pLine = sb.pLine + "\n" + sb.pLine;
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.statusEntries.add(sb.buildStatusEntry());
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+
+ /* TODO Should we allow this? */
+ @Test(expected = RuntimeException.class)
+ public void testNoStatusEntries() {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.statusEntries.clear();
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus());
+ }
+
+ /* TODO Why does this not break? Ah, maybe it just leaves out one
+ * status entry. Ugh. It should break! */
+ @Test()
+ public void testDirectoryFooterNoLine() {
+ ConsensusBuilder.createWithDirectoryFooterLine(null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testDirectoryFooterLineSpace() {
+ ConsensusBuilder.createWithDirectoryFooterLine("directory-footer ");
+ }
+
+ /* TODO Make sure that this is really okay in the code. */
+ @Test()
+ public void testBandwidthWeightsNoLine() {
+ ConsensusBuilder.createWithBandwidthWeightsLine(null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testBandwidthWeightsLineNoSpace() {
+ ConsensusBuilder.createWithBandwidthWeightsLine("bandwidth-weights");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testBandwidthWeightsLineOneSpace() {
+ ConsensusBuilder.createWithBandwidthWeightsLine("bandwidth-weights ");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testBandwidthWeightsLineNoEqualSign() {
+ ConsensusBuilder.createWithBandwidthWeightsLine(
+ "bandwidth-weights Wbd-285");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDirectorySignatureIdentityTooShort() {
+ DirectorySignatureBuilder.createWithIdentity("ED03BB616EB2F60");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDirectorySignatureIdentityTooLong() {
+ DirectorySignatureBuilder.createWithIdentity(
+ "ED03BB616EB2F60BEC80151114BB25CEF515B226ED03BB616EB2F60BEC");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDirectorySignatureSigningKeyTooShort() {
+ DirectorySignatureBuilder.createWithSigningKey("845CF1D0B370CA4");
+ }
+
+ /* TODO We should check this. */
+ @Test()
+ public void testDirectorySignatureSigningKeyTooLong() {
+ DirectorySignatureBuilder.createWithSigningKey(
+ "845CF1D0B370CA443A8579D18E7987E7E532F639845CF1D0B370CA443A");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testNonAsciiByte20() {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ byte[] consensusBytes = cb.buildConsensus();
+ consensusBytes[20] = (byte) 200;
+ new RelayNetworkStatusConsensusImpl(consensusBytes);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testNonAsciiByteMinusOne() {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.networkStatusVersionLine = "Xnetwork-status-version 3";
+ byte[] consensusBytes = cb.buildConsensus();
+ consensusBytes[0] = (byte) 200;
+ new RelayNetworkStatusConsensusImpl(consensusBytes);
+ }
+}
+
1
0
commit 8164af5ba0e571dfcd735274e1c4079c79a6fd8d
Author: Damian Johnson <atagar(a)torproject.org>
Date: Mon Dec 12 18:24:44 2011 -0800
Using input version string for __str__
Originally we reconstructed version strings from its components since that's
all the Version class had (a separate factory translated strings into Version
objects). However, that's no longer the case and much simpler if we just have
the __str__ method provide the constructing string rather than try to recreate
it.
patch by gsathya
---
stem/version.py | 14 +++-----------
1 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/stem/version.py b/stem/version.py
index 214e06a..26080cc 100644
--- a/stem/version.py
+++ b/stem/version.py
@@ -94,6 +94,7 @@ class Version:
ValueError if input isn't a valid tor version
"""
+ self.version_str = version_str
m = re.match(r'^([0-9]+).([0-9]+).([0-9]+)(.[0-9]+)?(-\S*)?$', version_str)
if m:
@@ -114,19 +115,10 @@ class Version:
def __str__(self):
"""
- Provides the normal representation for the version, for instance:
- "0.2.2.23-alpha"
+ Provides the string used to construct the Version.
"""
- suffix = ""
-
- if self.patch:
- suffix += ".%i" % self.patch
-
- if self.status:
- suffix += "-%s" % self.status
-
- return "%i.%i.%i%s" % (self.major, self.minor, self.micro, suffix)
+ return self.version_str
def __cmp__(self, other):
"""
1
0