[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [metrics-lib/master] Parse new protocol versions lines.
commit 2bcd6bb0e4cf8b535cf3b4c4ef0eed83dfc82676
Author: Karsten Loesing <karsten.loesing@xxxxxxx>
Date: Mon Feb 13 12:05:47 2017 +0100
Parse new protocol versions lines.
---
CHANGELOG.md | 3 +
.../torproject/descriptor/NetworkStatusEntry.java | 9 +++
.../descriptor/RelayNetworkStatusConsensus.java | 36 +++++++++
.../descriptor/RelayNetworkStatusVote.java | 32 ++++++++
.../torproject/descriptor/ServerDescriptor.java | 10 +++
.../descriptor/impl/NetworkStatusEntryImpl.java | 17 ++++
.../torproject/descriptor/impl/ParseHelper.java | 47 +++++++++++
.../impl/RelayNetworkStatusConsensusImpl.java | 68 +++++++++++++++-
.../impl/RelayNetworkStatusVoteImpl.java | 66 ++++++++++++++++
.../descriptor/impl/ServerDescriptorImpl.java | 20 ++++-
.../descriptor/impl/ConsensusBuilder.java | 60 ++++++++++++++
.../impl/RelayNetworkStatusConsensusImplTest.java | 79 +++++++++++++++++++
.../impl/RelayNetworkStatusVoteImplTest.java | 92 ++++++++++++++++++++++
.../descriptor/impl/ServerDescriptorImplTest.java | 49 ++++++++++--
14 files changed, 581 insertions(+), 7 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 755428d..6bcfea9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,9 @@
the application can decide at any time to stop consuming
descriptors without having to worry about the reader thread not
being done.
+ - Parse "proto" lines in server descriptors, "pr" lines in status
+ entries, and "(recommended|required)-(client|relay)-protocols"
+ lines in consensuses and votes.
# Changes in version 1.5.0 - 2016-10-19
diff --git a/src/main/java/org/torproject/descriptor/NetworkStatusEntry.java b/src/main/java/org/torproject/descriptor/NetworkStatusEntry.java
index 68f6939..ba413bb 100644
--- a/src/main/java/org/torproject/descriptor/NetworkStatusEntry.java
+++ b/src/main/java/org/torproject/descriptor/NetworkStatusEntry.java
@@ -5,6 +5,7 @@ package org.torproject.descriptor;
import java.util.List;
import java.util.Set;
+import java.util.SortedMap;
import java.util.SortedSet;
/**
@@ -123,6 +124,14 @@ public interface NetworkStatusEntry {
public String getVersion();
/**
+ * Return the version numbers of all protocols supported by this server, or
+ * null if the status entry does not specify supported protocol versions.
+ *
+ * @since 1.6.0
+ */
+ public SortedMap<String, SortedSet<Long>> getProtocols();
+
+ /**
* Return the bandwidth weight of this server or -1 if the status entry
* didn't contain a bandwidth line.
*
diff --git a/src/main/java/org/torproject/descriptor/RelayNetworkStatusConsensus.java b/src/main/java/org/torproject/descriptor/RelayNetworkStatusConsensus.java
index a2deba3..b004b66 100644
--- a/src/main/java/org/torproject/descriptor/RelayNetworkStatusConsensus.java
+++ b/src/main/java/org/torproject/descriptor/RelayNetworkStatusConsensus.java
@@ -113,6 +113,42 @@ public interface RelayNetworkStatusConsensus extends Descriptor {
public List<String> getRecommendedClientVersions();
/**
+ * Return the version numbers of all protocols that clients should support,
+ * or null if the consensus does not contain an opinion about protocol
+ * versions.
+ *
+ * @since 1.6.0
+ */
+ public SortedMap<String, SortedSet<Long>> getRecommendedClientProtocols();
+
+ /**
+ * Return the version numbers of all protocols that relays should support,
+ * or null if the consensus does not contain an opinion about protocol
+ * versions.
+ *
+ * @since 1.6.0
+ */
+ public SortedMap<String, SortedSet<Long>> getRecommendedRelayProtocols();
+
+ /**
+ * Return the version numbers of all protocols that clients must support,
+ * or null if the consensus does not contain an opinion about protocol
+ * versions.
+ *
+ * @since 1.6.0
+ */
+ public SortedMap<String, SortedSet<Long>> getRequiredClientProtocols();
+
+ /**
+ * Return the version numbers of all protocols that relays must support,
+ * or null if the consensus does not contain an opinion about protocol
+ * versions.
+ *
+ * @since 1.6.0
+ */
+ public SortedMap<String, SortedSet<Long>> getRequiredRelayProtocols();
+
+ /**
* Return a list of software packages and their versions together with a
* URL and one or more digests in the format <code>PackageName Version
* URL DIGESTS</code> that are known by at least three directory
diff --git a/src/main/java/org/torproject/descriptor/RelayNetworkStatusVote.java b/src/main/java/org/torproject/descriptor/RelayNetworkStatusVote.java
index a3f8170..9ea804d 100644
--- a/src/main/java/org/torproject/descriptor/RelayNetworkStatusVote.java
+++ b/src/main/java/org/torproject/descriptor/RelayNetworkStatusVote.java
@@ -105,6 +105,38 @@ public interface RelayNetworkStatusVote extends Descriptor {
public List<String> getRecommendedClientVersions();
/**
+ * Return the version numbers of all protocols that clients should support,
+ * or null if the vote does not contain an opinion about protocol versions.
+ *
+ * @since 1.6.0
+ */
+ public SortedMap<String, SortedSet<Long>> getRecommendedClientProtocols();
+
+ /**
+ * Return the version numbers of all protocols that relays should support,
+ * or null if the vote does not contain an opinion about protocol versions.
+ *
+ * @since 1.6.0
+ */
+ public SortedMap<String, SortedSet<Long>> getRecommendedRelayProtocols();
+
+ /**
+ * Return the version numbers of all protocols that clients must support,
+ * or null if the vote does not contain an opinion about protocol versions.
+ *
+ * @since 1.6.0
+ */
+ public SortedMap<String, SortedSet<Long>> getRequiredClientProtocols();
+
+ /**
+ * Return the version numbers of all protocols that relays must support,
+ * or null if the vote does not contain an opinion about protocol versions.
+ *
+ * @since 1.6.0
+ */
+ public SortedMap<String, SortedSet<Long>> getRequiredRelayProtocols();
+
+ /**
* Return a list of software packages and their versions together with a
* URL and one or more digests in the format <code>PackageName Version
* URL DIGESTS</code> that are known by this directory authority, or
diff --git a/src/main/java/org/torproject/descriptor/ServerDescriptor.java b/src/main/java/org/torproject/descriptor/ServerDescriptor.java
index 418cb55..4ecade6 100644
--- a/src/main/java/org/torproject/descriptor/ServerDescriptor.java
+++ b/src/main/java/org/torproject/descriptor/ServerDescriptor.java
@@ -4,6 +4,8 @@
package org.torproject.descriptor;
import java.util.List;
+import java.util.SortedMap;
+import java.util.SortedSet;
/**
* Contains a relay or sanitized bridge server descriptor.
@@ -152,6 +154,14 @@ public interface ServerDescriptor extends Descriptor {
public String getPlatform();
/**
+ * Return the version numbers of all protocols supported by this server, or
+ * null if this descriptor does not specify supported protocol versions.
+ *
+ * @since 1.6.0
+ */
+ public SortedMap<String, SortedSet<Long>> getProtocols();
+
+ /**
* Return the time in milliseconds since the epoch when this descriptor
* and the corresponding extra-info descriptor were generated.
*
diff --git a/src/main/java/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java b/src/main/java/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java
index d26eaeb..f67e6bd 100644
--- a/src/main/java/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java
@@ -57,6 +57,7 @@ public class NetworkStatusEntryImpl implements NetworkStatusEntry {
this.atMostOnceKeywords = new TreeSet<>();
this.atMostOnceKeywords.add("s");
this.atMostOnceKeywords.add("v");
+ this.atMostOnceKeywords.add("pr");
this.atMostOnceKeywords.add("w");
this.atMostOnceKeywords.add("p");
}
@@ -95,6 +96,9 @@ public class NetworkStatusEntryImpl implements NetworkStatusEntry {
case "v":
this.parseVLine(line, parts);
break;
+ case "pr":
+ this.parsePrLine(line, parts);
+ break;
case "w":
this.parseWLine(line, parts);
break;
@@ -191,6 +195,12 @@ public class NetworkStatusEntryImpl implements NetworkStatusEntry {
}
}
+ private void parsePrLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.parsedAtMostOnceKeyword("pr");
+ this.protocols = ParseHelper.parseProtocolVersions(line, line, parts);
+ }
+
private void parseWLine(String line, String[] parts)
throws DescriptorParseException {
this.parsedAtMostOnceKeyword("w");
@@ -359,6 +369,13 @@ public class NetworkStatusEntryImpl implements NetworkStatusEntry {
return this.version;
}
+ private SortedMap<String, SortedSet<Long>> protocols;
+
+ @Override
+ public SortedMap<String, SortedSet<Long>> getProtocols() {
+ return this.protocols;
+ }
+
private long bandwidth = -1L;
@Override
diff --git a/src/main/java/org/torproject/descriptor/impl/ParseHelper.java b/src/main/java/org/torproject/descriptor/impl/ParseHelper.java
index dfa9065..f73a591 100644
--- a/src/main/java/org/torproject/descriptor/impl/ParseHelper.java
+++ b/src/main/java/org/torproject/descriptor/impl/ParseHelper.java
@@ -8,13 +8,16 @@ import org.torproject.descriptor.DescriptorParseException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
+import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.SortedMap;
+import java.util.SortedSet;
import java.util.TimeZone;
import java.util.TreeMap;
+import java.util.TreeSet;
import java.util.regex.Pattern;
import javax.xml.bind.DatatypeConverter;
@@ -578,5 +581,49 @@ public class ParseHelper {
throw new DescriptorParseException("Unable to locate "
+ "master-key-ed25519 in identity-ed25519.");
}
+
+ private static Map<String, SortedMap<String, SortedSet<Long>>>
+ parsedProtocolVersions = new HashMap<>();
+
+ protected static SortedMap<String, SortedSet<Long>> parseProtocolVersions(
+ String line, String lineNoOpt, String[] partsNoOpt)
+ throws DescriptorParseException {
+ if (!parsedProtocolVersions.containsKey(lineNoOpt)) {
+ SortedMap<String, SortedSet<Long>> parsed = new TreeMap<>();
+ boolean invalid = false;
+ try {
+ for (int i = 1; i < partsNoOpt.length; i++) {
+ String[] part = partsNoOpt[i].split("=");
+ SortedSet<Long> versions = new TreeSet<>();
+ for (String val : part[1].split(",")) {
+ if (val.contains("-")) {
+ String[] fromTo = val.split("-");
+ long from = Long.parseLong(fromTo[0]);
+ long to = Long.parseLong(fromTo[1]);
+ if (from > to || to >= 0x1_0000_0000L) {
+ invalid = true;
+ } else {
+ for (long j = from;
+ j <= to; j++) {
+ versions.add(j);
+ }
+ }
+ } else {
+ versions.add(Long.parseLong(val));
+ }
+ }
+ parsed.put(part[0], Collections.unmodifiableSortedSet(versions));
+ }
+ } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
+ throw new DescriptorParseException("Invalid line '" + line + "'.", e);
+ }
+ if (invalid) {
+ throw new DescriptorParseException("Invalid line '" + line + "'.");
+ }
+ parsedProtocolVersions.put(lineNoOpt,
+ Collections.unmodifiableSortedMap(parsed));
+ }
+ return parsedProtocolVersions.get(lineNoOpt);
+ }
}
diff --git a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
index 8733729..fd4cf7e 100644
--- a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
@@ -52,7 +52,9 @@ public class RelayNetworkStatusConsensusImpl extends NetworkStatusImpl
+ "valid-until,voting-delay,known-flags").split(",")));
this.checkExactlyOnceKeywords(exactlyOnceKeywords);
Set<String> atMostOnceKeywords = new HashSet<>(Arrays.asList((
- "client-versions,server-versions,params,directory-footer,"
+ "client-versions,server-versions,recommended-client-protocols,"
+ + "recommended-relay-protocols,required-client-protocols,"
+ + "required-relay-protocols,params,directory-footer,"
+ "bandwidth-weights").split(",")));
this.checkAtMostOnceKeywords(atMostOnceKeywords);
this.checkFirstKeyword("network-status-version");
@@ -124,6 +126,18 @@ public class RelayNetworkStatusConsensusImpl extends NetworkStatusImpl
case "server-versions":
this.parseServerVersionsLine(line, parts);
break;
+ case "recommended-client-protocols":
+ this.parseRecommendedClientProtocolsLine(line, parts);
+ break;
+ case "recommended-relay-protocols":
+ this.parseRecommendedRelayProtocolsLine(line, parts);
+ break;
+ case "required-client-protocols":
+ this.parseRequiredClientProtocolsLine(line, parts);
+ break;
+ case "required-relay-protocols":
+ this.parseRequiredRelayProtocolsLine(line, parts);
+ break;
case "package":
this.parsePackageLine(line, parts);
break;
@@ -281,6 +295,30 @@ public class RelayNetworkStatusConsensusImpl extends NetworkStatusImpl
line, parts);
}
+ private void parseRecommendedClientProtocolsLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.recommendedClientProtocols = ParseHelper.parseProtocolVersions(line,
+ line, parts);
+ }
+
+ private void parseRecommendedRelayProtocolsLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.recommendedRelayProtocols = ParseHelper.parseProtocolVersions(line,
+ line, parts);
+ }
+
+ private void parseRequiredClientProtocolsLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.requiredClientProtocols = ParseHelper.parseProtocolVersions(line,
+ line, parts);
+ }
+
+ private void parseRequiredRelayProtocolsLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.requiredRelayProtocols = ParseHelper.parseProtocolVersions(line, line,
+ parts);
+ }
+
private void parsePackageLine(String line, String[] parts)
throws DescriptorParseException {
if (parts.length < 5) {
@@ -397,6 +435,34 @@ public class RelayNetworkStatusConsensusImpl extends NetworkStatusImpl
: Arrays.asList(this.recommendedServerVersions);
}
+ private SortedMap<String, SortedSet<Long>> recommendedClientProtocols;
+
+ @Override
+ public SortedMap<String, SortedSet<Long>> getRecommendedClientProtocols() {
+ return this.recommendedClientProtocols;
+ }
+
+ private SortedMap<String, SortedSet<Long>> recommendedRelayProtocols;
+
+ @Override
+ public SortedMap<String, SortedSet<Long>> getRecommendedRelayProtocols() {
+ return this.recommendedRelayProtocols;
+ }
+
+ private SortedMap<String, SortedSet<Long>> requiredClientProtocols;
+
+ @Override
+ public SortedMap<String, SortedSet<Long>> getRequiredClientProtocols() {
+ return this.requiredClientProtocols;
+ }
+
+ private SortedMap<String, SortedSet<Long>> requiredRelayProtocols;
+
+ @Override
+ public SortedMap<String, SortedSet<Long>> getRequiredRelayProtocols() {
+ return this.requiredRelayProtocols;
+ }
+
private List<String> packageLines;
@Override
diff --git a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
index 02390de..619b2c1 100644
--- a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
@@ -52,6 +52,8 @@ public class RelayNetworkStatusVoteImpl extends NetworkStatusImpl
this.checkExactlyOnceKeywords(exactlyOnceKeywords);
Set<String> atMostOnceKeywords = new HashSet<>(Arrays.asList((
"consensus-methods,client-versions,server-versions,"
+ + "recommended-client-protocols,recommended-relay-protocols,"
+ + "required-client-protocols,required-relay-protocols,"
+ "flag-thresholds,params,contact,"
+ "legacy-key,dir-key-crosscert,dir-address,directory-footer")
.split(",")));
@@ -117,6 +119,18 @@ public class RelayNetworkStatusVoteImpl extends NetworkStatusImpl
case "server-versions":
this.parseServerVersionsLine(line, parts);
break;
+ case "recommended-client-protocols":
+ this.parseRecommendedClientProtocolsLine(line, parts);
+ break;
+ case "recommended-relay-protocols":
+ this.parseRecommendedRelayProtocolsLine(line, parts);
+ break;
+ case "required-client-protocols":
+ this.parseRequiredClientProtocolsLine(line, parts);
+ break;
+ case "required-relay-protocols":
+ this.parseRequiredRelayProtocolsLine(line, parts);
+ break;
case "package":
this.parsePackageLine(line, parts);
break;
@@ -305,6 +319,30 @@ public class RelayNetworkStatusVoteImpl extends NetworkStatusImpl
line, parts);
}
+ private void parseRecommendedClientProtocolsLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.recommendedClientProtocols = ParseHelper.parseProtocolVersions(line,
+ line, parts);
+ }
+
+ private void parseRecommendedRelayProtocolsLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.recommendedRelayProtocols = ParseHelper.parseProtocolVersions(line,
+ line, parts);
+ }
+
+ private void parseRequiredClientProtocolsLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.requiredClientProtocols = ParseHelper.parseProtocolVersions(line,
+ line, parts);
+ }
+
+ private void parseRequiredRelayProtocolsLine(String line, String[] parts)
+ throws DescriptorParseException {
+ this.requiredRelayProtocols = ParseHelper.parseProtocolVersions(line, line,
+ parts);
+ }
+
private void parsePackageLine(String line, String[] parts)
throws DescriptorParseException {
if (parts.length < 5) {
@@ -710,6 +748,34 @@ public class RelayNetworkStatusVoteImpl extends NetworkStatusImpl
: Arrays.asList(this.recommendedServerVersions);
}
+ private SortedMap<String, SortedSet<Long>> recommendedClientProtocols;
+
+ @Override
+ public SortedMap<String, SortedSet<Long>> getRecommendedClientProtocols() {
+ return this.recommendedClientProtocols;
+ }
+
+ private SortedMap<String, SortedSet<Long>> recommendedRelayProtocols;
+
+ @Override
+ public SortedMap<String, SortedSet<Long>> getRecommendedRelayProtocols() {
+ return this.recommendedRelayProtocols;
+ }
+
+ private SortedMap<String, SortedSet<Long>> requiredClientProtocols;
+
+ @Override
+ public SortedMap<String, SortedSet<Long>> getRequiredClientProtocols() {
+ return this.requiredClientProtocols;
+ }
+
+ private SortedMap<String, SortedSet<Long>> requiredRelayProtocols;
+
+ @Override
+ public SortedMap<String, SortedSet<Long>> getRequiredRelayProtocols() {
+ return this.requiredRelayProtocols;
+ }
+
private List<String> packageLines;
@Override
diff --git a/src/main/java/org/torproject/descriptor/impl/ServerDescriptorImpl.java b/src/main/java/org/torproject/descriptor/impl/ServerDescriptorImpl.java
index 183959a..309cad4 100644
--- a/src/main/java/org/torproject/descriptor/impl/ServerDescriptorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/ServerDescriptorImpl.java
@@ -16,6 +16,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
import javax.xml.bind.DatatypeConverter;
@@ -34,7 +36,7 @@ public abstract class ServerDescriptorImpl extends DescriptorImpl
"router,bandwidth,published".split(",")));
this.checkExactlyOnceKeywords(exactlyOnceKeywords);
Set<String> atMostOnceKeywords = new HashSet<>(Arrays.asList((
- "identity-ed25519,master-key-ed25519,platform,fingerprint,"
+ "identity-ed25519,master-key-ed25519,platform,proto,fingerprint,"
+ "hibernating,uptime,contact,family,read-history,write-history,"
+ "eventdns,caches-extra-info,extra-info-digest,"
+ "hidden-service-dir,protocols,allow-single-hop-exits,onion-key,"
@@ -80,6 +82,9 @@ public abstract class ServerDescriptorImpl extends DescriptorImpl
case "platform":
this.parsePlatformLine(line, lineNoOpt, partsNoOpt);
break;
+ case "proto":
+ this.parseProtoLine(line, lineNoOpt, partsNoOpt);
+ break;
case "published":
this.parsePublishedLine(line, lineNoOpt, partsNoOpt);
break;
@@ -303,6 +308,12 @@ public abstract class ServerDescriptorImpl extends DescriptorImpl
}
}
+ private void parseProtoLine(String line, String lineNoOpt,
+ String[] partsNoOpt) throws DescriptorParseException {
+ this.protocols = ParseHelper.parseProtocolVersions(line, lineNoOpt,
+ partsNoOpt);
+ }
+
private void parsePublishedLine(String line, String lineNoOpt,
String[] partsNoOpt) throws DescriptorParseException {
this.publishedMillis = ParseHelper.parseTimestampAtIndex(line,
@@ -812,6 +823,13 @@ public abstract class ServerDescriptorImpl extends DescriptorImpl
return this.platform;
}
+ private SortedMap<String, SortedSet<Long>> protocols;
+
+ @Override
+ public SortedMap<String, SortedSet<Long>> getProtocols() {
+ return this.protocols;
+ }
+
private long publishedMillis;
@Override
diff --git a/src/test/java/org/torproject/descriptor/impl/ConsensusBuilder.java b/src/test/java/org/torproject/descriptor/impl/ConsensusBuilder.java
index b765be6..24d5a02 100644
--- a/src/test/java/org/torproject/descriptor/impl/ConsensusBuilder.java
+++ b/src/test/java/org/torproject/descriptor/impl/ConsensusBuilder.java
@@ -126,6 +126,54 @@ public class ConsensusBuilder {
return new RelayNetworkStatusConsensusImpl(cb.buildConsensus(), true);
}
+ private String recommendedClientProtocolsLine =
+ "recommended-client-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 "
+ + "HSIntro=3 HSRend=1 Link=4 LinkAuth=1 Microdesc=1-2 Relay=2";
+
+ protected static RelayNetworkStatusConsensus
+ createWithRecommendedClientProtocolsLine(String line)
+ throws DescriptorParseException {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.recommendedClientProtocolsLine = line;
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus(), true);
+ }
+
+ private String recommendedRelayProtocolsLine =
+ "recommended-relay-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 "
+ + "HSIntro=3 HSRend=1 Link=4 LinkAuth=1 Microdesc=1-2 Relay=2";
+
+ protected static RelayNetworkStatusConsensus
+ createWithRecommendedRelayProtocolsLine(String line)
+ throws DescriptorParseException {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.recommendedRelayProtocolsLine = line;
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus(), true);
+ }
+
+ private String requiredClientProtocolsLine =
+ "required-client-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 "
+ + "HSIntro=3 HSRend=1 Link=4 LinkAuth=1 Microdesc=1-2 Relay=2";
+
+ protected static RelayNetworkStatusConsensus
+ createWithRequiredClientProtocolsLine(String line)
+ throws DescriptorParseException {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.requiredClientProtocolsLine = line;
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus(), true);
+ }
+
+ private String requiredRelayProtocolsLine =
+ "required-relay-protocols Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 "
+ + "HSRend=1 Link=3-4 LinkAuth=1 Microdesc=1 Relay=1-2";
+
+ protected static RelayNetworkStatusConsensus
+ createWithRequiredRelayProtocolsLine(String line)
+ throws DescriptorParseException {
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.requiredRelayProtocolsLine = line;
+ return new RelayNetworkStatusConsensusImpl(cb.buildConsensus(), true);
+ }
+
private String paramsLine = "params "
+ "CircuitPriorityHalflifeMsec=30000 bwauthbestratio=1 "
+ "bwauthcircs=1 bwauthdescbw=0 bwauthkp=10000 bwauthpid=1 "
@@ -322,6 +370,18 @@ public class ConsensusBuilder {
if (this.knownFlagsLine != null) {
sb.append(this.knownFlagsLine).append("\n");
}
+ if (this.recommendedClientProtocolsLine != null) {
+ sb.append(this.recommendedClientProtocolsLine).append("\n");
+ }
+ if (this.recommendedRelayProtocolsLine != null) {
+ sb.append(this.recommendedRelayProtocolsLine).append("\n");
+ }
+ if (this.requiredClientProtocolsLine != null) {
+ sb.append(this.requiredClientProtocolsLine).append("\n");
+ }
+ if (this.requiredRelayProtocolsLine != null) {
+ sb.append(this.requiredRelayProtocolsLine).append("\n");
+ }
if (this.paramsLine != null) {
sb.append(this.paramsLine).append("\n");
}
diff --git a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java
index ebcbd83..786ae54 100644
--- a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java
@@ -19,6 +19,7 @@ import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.TreeSet;
/* TODO Add test cases for all lines starting with "opt ". */
@@ -242,6 +243,16 @@ public class RelayNetworkStatusConsensusImplTest {
return createWithStatusEntry(seb.buildStatusEntry());
}
+ private String prLine = "pr Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 "
+ + "HSIntro=3 HSRend=1-2 Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2";
+
+ private static RelayNetworkStatusConsensus
+ createWithPrLine(String line) throws DescriptorParseException {
+ StatusEntryBuilder seb = new StatusEntryBuilder();
+ seb.prLine = line;
+ return createWithStatusEntry(seb.buildStatusEntry());
+ }
+
@SuppressWarnings("checkstyle:membername")
private String wLine = "w Bandwidth=1";
@@ -275,6 +286,9 @@ public class RelayNetworkStatusConsensusImplTest {
if (this.vLine != null) {
sb.append(this.vLine).append("\n");
}
+ if (this.prLine != null) {
+ sb.append(this.prLine).append("\n");
+ }
if (this.wLine != null) {
sb.append(this.wLine).append("\n");
}
@@ -353,6 +367,14 @@ public class RelayNetworkStatusConsensusImplTest {
assertTrue(consensus.getRecommendedServerVersions().contains(
"0.2.3.8-alpha"));
assertTrue(consensus.getKnownFlags().contains("Running"));
+ assertTrue(consensus.getRecommendedClientProtocols().get("Cons")
+ .contains(1L));
+ assertFalse(consensus.getRecommendedRelayProtocols().get("Cons")
+ .contains(33L));
+ assertFalse(consensus.getRequiredClientProtocols().get("Relay")
+ .contains(1L));
+ assertTrue(consensus.getRequiredRelayProtocols().get("Relay")
+ .contains(1L));
assertEquals(30000, (int) consensus.getConsensusParams().get(
"CircuitPriorityHalflifeMsec"));
assertEquals("86.59.21.38", consensus.getDirSourceEntries().get(
@@ -667,6 +689,54 @@ public class RelayNetworkStatusConsensusImplTest {
}
@Test()
+ public void testRecommendedClientProtocols123()
+ throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus = ConsensusBuilder
+ .createWithRecommendedClientProtocolsLine(
+ "recommended-client-protocols Cons=1,2,3");
+ assertEquals(new TreeSet<Long>(Arrays.asList(new Long[] { 1L, 2L, 3L })),
+ consensus.getRecommendedClientProtocols().get("Cons"));
+ }
+
+ @Test()
+ public void testRecommendedRelayProtocols134()
+ throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus = ConsensusBuilder
+ .createWithRecommendedRelayProtocolsLine(
+ "recommended-relay-protocols Cons=1,3-4");
+ assertEquals(new TreeSet<Long>(Arrays.asList(new Long[] { 1L, 3L, 4L })),
+ consensus.getRecommendedRelayProtocols().get("Cons"));
+ }
+
+ @Test()
+ public void testRequiredClientProtocols1425()
+ throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus = ConsensusBuilder
+ .createWithRequiredClientProtocolsLine(
+ "required-client-protocols Cons=1-3,2-4");
+ assertEquals(new TreeSet<Long>(Arrays.asList(
+ new Long[] { 1L, 2L, 3L, 4L })),
+ consensus.getRequiredClientProtocols().get("Cons"));
+ }
+
+ @Test()
+ public void testRequiredRelayProtocols1111()
+ throws DescriptorParseException {
+ RelayNetworkStatusConsensus consensus = ConsensusBuilder
+ .createWithRequiredRelayProtocolsLine(
+ "required-relay-protocols Cons=1-1,1-1");
+ assertEquals(new TreeSet<Long>(Arrays.asList(new Long[] { 1L })),
+ consensus.getRequiredRelayProtocols().get("Cons"));
+ }
+
+ @Test(expected = DescriptorParseException.class)
+ public void testRequiredRelayProtocolsTwice()
+ throws DescriptorParseException {
+ ConsensusBuilder.createWithRequiredRelayProtocolsLine(
+ "required-relay-protocols Cons=1\nrequired-relay-protocols Cons=1");
+ }
+
+ @Test()
public void testPackageNone() throws DescriptorParseException {
RelayNetworkStatusConsensus consensus =
ConsensusBuilder.createWithPackageLines(null);
@@ -1022,6 +1092,15 @@ public class RelayNetworkStatusConsensusImplTest {
}
@Test(expected = DescriptorParseException.class)
+ public void testTwoPrLines() throws DescriptorParseException {
+ StatusEntryBuilder sb = new StatusEntryBuilder();
+ sb.prLine = sb.prLine + "\n" + sb.prLine;
+ ConsensusBuilder cb = new ConsensusBuilder();
+ cb.statusEntries.add(sb.buildStatusEntry());
+ new RelayNetworkStatusConsensusImpl(cb.buildConsensus(), true);
+ }
+
+ @Test(expected = DescriptorParseException.class)
public void testWLineNoSpace() throws DescriptorParseException {
StatusEntryBuilder.createWithWLine("w");
}
diff --git a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java
index 847c538..ea7b927 100644
--- a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java
@@ -16,6 +16,7 @@ import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.TreeSet;
/* TODO Add test cases for all lines starting with "opt ". */
@@ -153,6 +154,54 @@ public class RelayNetworkStatusVoteImplTest {
return new RelayNetworkStatusVoteImpl(vb.buildVote(), true);
}
+ private String recommendedClientProtocolsLine =
+ "recommended-client-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 "
+ + "HSIntro=3 HSRend=1 Link=4 LinkAuth=1 Microdesc=1-2 Relay=2";
+
+ private static RelayNetworkStatusVote
+ createWithRecommendedClientProtocolsLine(String line)
+ throws DescriptorParseException {
+ VoteBuilder vb = new VoteBuilder();
+ vb.recommendedClientProtocolsLine = line;
+ return new RelayNetworkStatusVoteImpl(vb.buildVote(), true);
+ }
+
+ private String recommendedRelayProtocolsLine =
+ "recommended-relay-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 "
+ + "HSIntro=3 HSRend=1 Link=4 LinkAuth=1 Microdesc=1-2 Relay=2";
+
+ private static RelayNetworkStatusVote
+ createWithRecommendedRelayProtocolsLine(String line)
+ throws DescriptorParseException {
+ VoteBuilder vb = new VoteBuilder();
+ vb.recommendedRelayProtocolsLine = line;
+ return new RelayNetworkStatusVoteImpl(vb.buildVote(), true);
+ }
+
+ private String requiredClientProtocolsLine =
+ "required-client-protocols Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 "
+ + "HSIntro=3 HSRend=1 Link=4 LinkAuth=1 Microdesc=1-2 Relay=2";
+
+ private static RelayNetworkStatusVote
+ createWithRequiredClientProtocolsLine(String line)
+ throws DescriptorParseException {
+ VoteBuilder vb = new VoteBuilder();
+ vb.requiredClientProtocolsLine = line;
+ return new RelayNetworkStatusVoteImpl(vb.buildVote(), true);
+ }
+
+ private String requiredRelayProtocolsLine =
+ "required-relay-protocols Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 "
+ + "HSRend=1 Link=3-4 LinkAuth=1 Microdesc=1 Relay=1-2";
+
+ private static RelayNetworkStatusVote
+ createWithRequiredRelayProtocolsLine(String line)
+ throws DescriptorParseException {
+ VoteBuilder vb = new VoteBuilder();
+ vb.requiredRelayProtocolsLine = line;
+ return new RelayNetworkStatusVoteImpl(vb.buildVote(), true);
+ }
+
private String flagThresholdsLine = "flag-thresholds "
+ "stable-uptime=693369 stable-mtbf=153249 fast-speed=40960 "
+ "guard-wfu=94.669% guard-tk=691200 guard-bw-inc-exits=174080 "
@@ -493,6 +542,18 @@ public class RelayNetworkStatusVoteImplTest {
if (this.knownFlagsLine != null) {
sb.append(this.knownFlagsLine).append("\n");
}
+ if (this.recommendedClientProtocolsLine != null) {
+ sb.append(this.recommendedClientProtocolsLine).append("\n");
+ }
+ if (this.recommendedRelayProtocolsLine != null) {
+ sb.append(this.recommendedRelayProtocolsLine).append("\n");
+ }
+ if (this.requiredClientProtocolsLine != null) {
+ sb.append(this.requiredClientProtocolsLine).append("\n");
+ }
+ if (this.requiredRelayProtocolsLine != null) {
+ sb.append(this.requiredRelayProtocolsLine).append("\n");
+ }
if (this.flagThresholdsLine != null) {
sb.append(this.flagThresholdsLine).append("\n");
}
@@ -875,6 +936,37 @@ public class RelayNetworkStatusVoteImplTest {
"client-versions ,0.2.2.34");
}
+ @Test(expected = DescriptorParseException.class)
+ public void testRecommendedClientProtocols21()
+ throws DescriptorParseException {
+ VoteBuilder.createWithRecommendedClientProtocolsLine(
+ "recommended-client-protocols Cons=2-1");
+ }
+
+ @Test()
+ public void testRecommendedRelayProtocols0()
+ throws DescriptorParseException {
+ RelayNetworkStatusVote vote =
+ VoteBuilder.createWithRecommendedRelayProtocolsLine(
+ "recommended-relay-protocols Cons=0");
+ assertEquals(new TreeSet<Long>(Arrays.asList(new Long[] { 0L })),
+ vote.getRecommendedRelayProtocols().get("Cons"));
+ }
+
+ @Test(expected = DescriptorParseException.class)
+ public void testRequiredClientProtocols1Max()
+ throws DescriptorParseException {
+ VoteBuilder.createWithRequiredClientProtocolsLine(
+ "recommended-client-protocols Cons=1-4294967296");
+ }
+
+ @Test(expected = DescriptorParseException.class)
+ public void testRequiredRelayProtocolsMinus1()
+ throws DescriptorParseException {
+ VoteBuilder.createWithRequiredRelayProtocolsLine(
+ "recommended-client-protocols Cons=-1");
+ }
+
@Test()
public void testPackageNone() throws DescriptorParseException {
RelayNetworkStatusVote vote =
diff --git a/src/test/java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java b/src/test/java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java
index 3769ead..4370321 100644
--- a/src/test/java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.SortedMap;
+import java.util.TreeSet;
/* Test parsing of relay server descriptors. */
public class ServerDescriptorImplTest {
@@ -226,7 +227,7 @@ public class ServerDescriptorImplTest {
return new RelayServerDescriptorImpl(db.buildDescriptor(), true);
}
- private String protocolsLine = "opt protocols Link 1 2 Circuit 1";
+ private String protocolsLine = null;
private static ServerDescriptor createWithProtocolsLine(
String line) throws DescriptorParseException {
@@ -235,6 +236,16 @@ public class ServerDescriptorImplTest {
return new RelayServerDescriptorImpl(db.buildDescriptor(), true);
}
+ private String protoLine = "proto Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 "
+ + "HSIntro=3 HSRend=1-2 Link=1-4 LinkAuth=1 Microdesc=1-2 Relay=1-2";
+
+ private static ServerDescriptor createWithProtoLine(
+ String line) throws DescriptorParseException {
+ DescriptorBuilder db = new DescriptorBuilder();
+ db.protoLine = line;
+ return new RelayServerDescriptorImpl(db.buildDescriptor(), true);
+ }
+
private String allowSingleHopExitsLine = null;
private static ServerDescriptor
@@ -395,6 +406,9 @@ public class ServerDescriptorImplTest {
if (this.protocolsLine != null) {
sb.append(this.protocolsLine).append("\n");
}
+ if (this.protoLine != null) {
+ sb.append(this.protoLine).append("\n");
+ }
if (this.allowSingleHopExitsLine != null) {
sb.append(this.allowSingleHopExitsLine).append("\n");
}
@@ -446,10 +460,10 @@ public class ServerDescriptorImplTest {
assertEquals(0, (int) descriptor.getDirPort());
assertEquals("Tor 0.2.2.35 (git-b04388f9e7546a9f) on Linux i686",
descriptor.getPlatform());
- assertEquals(Arrays.asList(new Integer[] {1, 2}),
- descriptor.getLinkProtocolVersions());
- assertEquals(Arrays.asList(new Integer[] {1}),
- descriptor.getCircuitProtocolVersions());
+ assertEquals(new TreeSet<Long>(Arrays.asList(
+ new Long[] { 1L, 2L, 3L, 4L })), descriptor.getProtocols().get("Link"));
+ assertEquals(new TreeSet<Long>(Arrays.asList(
+ new Long[] { 1L })), descriptor.getProtocols().get("LinkAuth"));
assertEquals(1325390599000L, descriptor.getPublishedMillis());
assertEquals("D8733048FC8EC9102466AD8F3098622BF1BF71FD",
descriptor.getFingerprint());
@@ -605,6 +619,16 @@ public class ServerDescriptorImplTest {
}
@Test()
+ public void testProtocolsOpt() throws DescriptorParseException {
+ ServerDescriptor descriptor = DescriptorBuilder
+ .createWithProtocolsLine("opt protocols Link 1 2 Circuit 1");
+ assertEquals(Arrays.asList(new Integer[] {1, 2}),
+ descriptor.getLinkProtocolVersions());
+ assertEquals(Arrays.asList(new Integer[] {1}),
+ descriptor.getCircuitProtocolVersions());
+ }
+
+ @Test()
public void testProtocolsNoOpt() throws DescriptorParseException {
ServerDescriptor descriptor = DescriptorBuilder
.createWithProtocolsLine("protocols Link 1 2 Circuit 1");
@@ -626,6 +650,21 @@ public class ServerDescriptorImplTest {
DescriptorBuilder.createWithProtocolsLine("opt protocols Link 1 2");
}
+ @Test()
+ public void testProtoGreenPurple() throws DescriptorParseException {
+ ServerDescriptor descriptor = DescriptorBuilder
+ .createWithProtoLine("proto Green=23 Purple=42");
+ assertEquals(new TreeSet<Long>(Arrays.asList(new Long[] { 23L })),
+ descriptor.getProtocols().get("Green"));
+ assertEquals(new TreeSet<Long>(Arrays.asList(new Long[] { 42L })),
+ descriptor.getProtocols().get("Purple"));
+ }
+
+ @Test(expected = DescriptorParseException.class)
+ public void testProtoInvalid() throws DescriptorParseException {
+ DescriptorBuilder.createWithProtoLine("proto Invalid=1+2+3");
+ }
+
@Test(expected = DescriptorParseException.class)
public void testPublishedMissing() throws DescriptorParseException {
DescriptorBuilder.createWithPublishedLine(null);
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits