[tor-commits] [metrics-lib/master] Parse version 3 onion service statistics lines.

karsten at torproject.org karsten at torproject.org
Fri Dec 11 14:01:09 UTC 2020


commit ee7c3eb73824a84e33b6c44b60fa8a32f37ab71e
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date:   Tue Dec 8 10:40:19 2020 +0100

    Parse version 3 onion service statistics lines.
    
    Implements the library part of tpo/metrics/statistics#40002.
---
 CHANGELOG.md                                       |  6 +-
 .../torproject/descriptor/ExtraInfoDescriptor.java | 55 +++++++++++++
 .../descriptor/impl/ExtraInfoDescriptorImpl.java   | 93 ++++++++++++++++++++++
 .../java/org/torproject/descriptor/impl/Key.java   |  3 +
 .../impl/ExtraInfoDescriptorImplTest.java          | 46 +++++++++++
 5 files changed, 202 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index c6886e8..8ff5723 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,8 @@
-# Changes in version 2.??.? - 2020-??-??
+# Changes in version 2.15.0 - 2020-??-??
+
+ * Medium changes
+   - Parse version 3 onion service statistics contained in extra-info
+     descriptors.
 
 
 # Changes in version 2.14.0 - 2020-08-07
diff --git a/src/main/java/org/torproject/descriptor/ExtraInfoDescriptor.java b/src/main/java/org/torproject/descriptor/ExtraInfoDescriptor.java
index e094fed..b553a22 100644
--- a/src/main/java/org/torproject/descriptor/ExtraInfoDescriptor.java
+++ b/src/main/java/org/torproject/descriptor/ExtraInfoDescriptor.java
@@ -674,6 +674,61 @@ public interface ExtraInfoDescriptor extends Descriptor {
    */
   Map<String, Double> getHidservDirOnionsSeenParameters();
 
+  /**
+   * Return the time in milliseconds since the epoch when the included version 3
+   * onion service statistics interval ended, or -1 if no such statistics are
+   * included.
+   *
+   * @since 2.15.0
+   */
+  long getHidservV3StatsEndMillis();
+
+  /**
+   * Return the interval length of the included version 3 onion service
+   * statistics in seconds, or -1 if no such statistics are included.
+   *
+   * @since 2.15.0
+   */
+  long getHidservV3StatsIntervalLength();
+
+  /**
+   * Return the approximate number of RELAY cells seen in either direction on a
+   * version 3 onion service circuit after receiving and successfully processing
+   * a RENDEZVOUS1 cell, or null if no such statistics are included.
+   *
+   * @since 2.15.0
+   */
+  Double getHidservRendV3RelayedCells();
+
+  /**
+   * Return the obfuscation parameters applied to the original measurement value
+   * of RELAY cells seen in either direction on a version 3 onion service
+   * circuit after receiving and successfully processing a RENDEZVOUS1 cell, or
+   * null if no such statistics are included.
+   *
+   * @since 2.15.0
+   */
+  Map<String, Double> getHidservRendV3RelayedCellsParameters();
+
+  /**
+   * Return the approximate number of unique version 3 onion service identities
+   * seen in descriptors published to and accepted by this onion service
+   * directory, or null if no such statistics are included.
+   *
+   * @since 2.15.0
+   */
+  Double getHidservDirV3OnionsSeen();
+
+  /**
+   * Return the obfuscation parameters applied to the original measurement value
+   * of unique version 3 onion service identities seen in descriptors published
+   * to and accepted by this onion service directory, or null if no such
+   * statistics are included.
+   *
+   * @since 2.15.0
+   */
+  Map<String, Double> getHidservDirV3OnionsSeenParameters();
+
   /**
    * Return the time in milliseconds since the epoch when the included
    * padding-counts statistics ended, or -1 if no such statistics are included.
diff --git a/src/main/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java b/src/main/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
index 5cab6ab..4f87237 100644
--- a/src/main/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
@@ -225,6 +225,15 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
         case HIDSERV_DIR_ONIONS_SEEN:
           this.parseHidservDirOnionsSeenLine(line, partsNoOpt);
           break;
+        case HIDSERV_V3_STATS_END:
+          this.parseHidservV3StatsEndLine(line, partsNoOpt);
+          break;
+        case HIDSERV_REND_V3_RELAYED_CELLS:
+          this.parseHidservRendV3RelayedCellsLine(line, partsNoOpt);
+          break;
+        case HIDSERV_DIR_V3_ONIONS_SEEN:
+          this.parseHidservDirV3OnionsSeenLine(line, partsNoOpt);
+          break;
         case PADDING_COUNTS:
           this.parsePaddingCountsLine(line, partsNoOpt);
           break;
@@ -764,6 +773,46 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
         partsNoOpt, 2);
   }
 
+  private void parseHidservV3StatsEndLine(String line,
+      String[] partsNoOpt) throws DescriptorParseException {
+    long[] parsedStatsEndData = this.parseStatsEndLine(line, partsNoOpt,
+        5);
+    this.hidservV3StatsEndMillis = parsedStatsEndData[0];
+    this.hidservV3StatsIntervalLength = parsedStatsEndData[1];
+  }
+
+  private void parseHidservRendV3RelayedCellsLine(String line,
+      String[] partsNoOpt)
+      throws DescriptorParseException {
+    if (partsNoOpt.length < 2) {
+      throw new DescriptorParseException("Illegal line '" + line + "'.");
+    }
+    try {
+      this.hidservRendV3RelayedCells = Double.parseDouble(partsNoOpt[1]);
+    } catch (NumberFormatException e) {
+      throw new DescriptorParseException("Illegal line '" + line + "'.");
+    }
+    this.hidservRendV3RelayedCellsParameters =
+        ParseHelper.parseSpaceSeparatedStringKeyDoubleValueMap(line,
+            partsNoOpt, 2);
+  }
+
+  private void parseHidservDirV3OnionsSeenLine(String line,
+      String[] partsNoOpt)
+      throws DescriptorParseException {
+    if (partsNoOpt.length < 2) {
+      throw new DescriptorParseException("Illegal line '" + line + "'.");
+    }
+    try {
+      this.hidservDirV3OnionsSeen = Double.parseDouble(partsNoOpt[1]);
+    } catch (NumberFormatException e) {
+      throw new DescriptorParseException("Illegal line '" + line + "'.");
+    }
+    this.hidservDirV3OnionsSeenParameters =
+        ParseHelper.parseSpaceSeparatedStringKeyDoubleValueMap(line,
+            partsNoOpt, 2);
+  }
+
   private void parsePaddingCountsLine(String line,
       String[] partsNoOpt) throws DescriptorParseException {
     long[] parsedStatsEndData = this.parseStatsEndLine(line, partsNoOpt,
@@ -1319,6 +1368,50 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
         : new HashMap<>(this.hidservDirOnionsSeenParameters);
   }
 
+  private long hidservV3StatsEndMillis = -1L;
+
+  @Override
+  public long getHidservV3StatsEndMillis() {
+    return this.hidservV3StatsEndMillis;
+  }
+
+  private long hidservV3StatsIntervalLength = -1L;
+
+  @Override
+  public long getHidservV3StatsIntervalLength() {
+    return this.hidservV3StatsIntervalLength;
+  }
+
+  private Double hidservRendV3RelayedCells;
+
+  @Override
+  public Double getHidservRendV3RelayedCells() {
+    return this.hidservRendV3RelayedCells;
+  }
+
+  private Map<String, Double> hidservRendV3RelayedCellsParameters;
+
+  @Override
+  public Map<String, Double> getHidservRendV3RelayedCellsParameters() {
+    return this.hidservRendV3RelayedCellsParameters == null ? null
+        : new HashMap<>(this.hidservRendV3RelayedCellsParameters);
+  }
+
+  private Double hidservDirV3OnionsSeen;
+
+  @Override
+  public Double getHidservDirV3OnionsSeen() {
+    return this.hidservDirV3OnionsSeen;
+  }
+
+  private Map<String, Double> hidservDirV3OnionsSeenParameters;
+
+  @Override
+  public Map<String, Double> getHidservDirV3OnionsSeenParameters() {
+    return this.hidservDirV3OnionsSeenParameters == null ? null
+        : new HashMap<>(this.hidservDirV3OnionsSeenParameters);
+  }
+
   private long paddingCountsStatsEndMillis = -1L;
 
   @Override
diff --git a/src/main/java/org/torproject/descriptor/impl/Key.java b/src/main/java/org/torproject/descriptor/impl/Key.java
index 70db350..b02d96e 100644
--- a/src/main/java/org/torproject/descriptor/impl/Key.java
+++ b/src/main/java/org/torproject/descriptor/impl/Key.java
@@ -90,8 +90,11 @@ public enum Key {
   HIBERNATING("hibernating"),
   HIDDEN_SERVICE_DIR("hidden-service-dir"),
   HIDSERV_DIR_ONIONS_SEEN("hidserv-dir-onions-seen"),
+  HIDSERV_DIR_V3_ONIONS_SEEN("hidserv-dir-v3-onions-seen"),
   HIDSERV_REND_RELAYED_CELLS("hidserv-rend-relayed-cells"),
+  HIDSERV_REND_V3_RELAYED_CELLS("hidserv-rend-v3-relayed-cells"),
   HIDSERV_STATS_END("hidserv-stats-end"),
+  HIDSERV_V3_STATS_END("hidserv-v3-stats-end"),
   ID("id"),
   IDENTITY_ED25519("identity-ed25519"),
   IPV6_CONN_BI_DIRECT("ipv6-conn-bi-direct"),
diff --git a/src/test/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java b/src/test/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java
index 1233bd5..08a5bc9 100644
--- a/src/test/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java
@@ -960,6 +960,16 @@ public class ExtraInfoDescriptorImplTest {
           hsb.buildHidservStatsLines());
     }
 
+    private String hidservV3StatsEndLine = "hidserv-v3-stats-end 2020-11-30 "
+        + "12:00:00 (86400 s)";
+
+    private String hidservRendV3RelayedCellsLine
+        = "hidserv-rend-v3-relayed-cells 6920802 delta_f=2048 epsilon=0.30 "
+        + "bin_size=1024";
+
+    private String hidservDirV3OnionsSeenLine = "hidserv-dir-v3-onions-seen 28 "
+        + "delta_f=8 epsilon=0.30 bin_size=8";
+
     private static ExtraInfoDescriptor createWithDefaultLines()
         throws DescriptorParseException {
       return DescriptorBuilder.createWithHidservStatsLines(
@@ -977,6 +987,15 @@ public class ExtraInfoDescriptorImplTest {
       if (this.hidservDirOnionsSeenLine != null) {
         sb.append(this.hidservDirOnionsSeenLine).append("\n");
       }
+      if (this.hidservV3StatsEndLine != null) {
+        sb.append(this.hidservV3StatsEndLine).append("\n");
+      }
+      if (this.hidservRendV3RelayedCellsLine != null) {
+        sb.append(this.hidservRendV3RelayedCellsLine).append("\n");
+      }
+      if (this.hidservDirV3OnionsSeenLine != null) {
+        sb.append(this.hidservDirV3OnionsSeenLine).append("\n");
+      }
       String lines = sb.toString();
       if (lines.endsWith("\n")) {
         lines = lines.substring(0, lines.length() - 1);
@@ -2170,6 +2189,33 @@ public class ExtraInfoDescriptorImplTest {
     assertTrue(params.isEmpty());
   }
 
+  @Test
+  public void testHidservV3StatsValid() throws DescriptorParseException {
+    ExtraInfoDescriptor descriptor = HidservStatsBuilder
+        .createWithDefaultLines();
+    assertEquals(1606737600000L, descriptor.getHidservV3StatsEndMillis());
+    assertEquals(86400L, descriptor.getHidservV3StatsIntervalLength());
+    assertEquals(6920802.0, descriptor.getHidservRendV3RelayedCells(), 0.0001);
+    Map<String, Double> params =
+        descriptor.getHidservRendV3RelayedCellsParameters();
+    assertTrue(params.containsKey("delta_f"));
+    assertEquals(2048.0, params.remove("delta_f"), 0.0001);
+    assertTrue(params.containsKey("epsilon"));
+    assertEquals(0.3, params.remove("epsilon"), 0.0001);
+    assertTrue(params.containsKey("bin_size"));
+    assertEquals(1024.0, params.remove("bin_size"), 0.0001);
+    assertTrue(params.isEmpty());
+    assertEquals(28.0, descriptor.getHidservDirV3OnionsSeen(), 0.0001);
+    params = descriptor.getHidservDirV3OnionsSeenParameters();
+    assertTrue(params.containsKey("delta_f"));
+    assertEquals(8.0, params.remove("delta_f"), 0.0001);
+    assertTrue(params.containsKey("epsilon"));
+    assertEquals(0.3, params.remove("epsilon"), 0.0001);
+    assertTrue(params.containsKey("bin_size"));
+    assertEquals(8.0, params.remove("bin_size"), 0.0001);
+    assertTrue(params.isEmpty());
+  }
+
   @Test
   public void testHidservStatsEndLineMissing()
       throws DescriptorParseException {





More information about the tor-commits mailing list