[tor-commits] [metrics-lib/master] Parse new NAT-based Snowflake lines.

karsten at torproject.org karsten at torproject.org
Fri Dec 18 11:03:29 UTC 2020


commit 8976cdd9be1bb70d3457bf2551971e12ee253ce1
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date:   Fri Dec 18 12:02:55 2020 +0100

    Parse new NAT-based Snowflake lines.
    
    Implements #40002.
---
 CHANGELOG.md                                       |  5 +-
 .../org/torproject/descriptor/SnowflakeStats.java  | 54 ++++++++++++++++
 .../java/org/torproject/descriptor/impl/Key.java   |  5 ++
 .../descriptor/impl/SnowflakeStatsImpl.java        | 75 ++++++++++++++++++++++
 .../descriptor/impl/SnowflakeStatsImplTest.java    | 50 +++++++++++++++
 5 files changed, 188 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index ac865a9..68ad2a2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,7 @@
-# Changes in version 2.??.? - 2020-??-??
+# Changes in version 2.16.0 - 2020-??-??
+
+ * Medium changes
+   - Parse new NAT-based Snowflake lines.
 
 
 # Changes in version 2.15.0 - 2020-12-11
diff --git a/src/main/java/org/torproject/descriptor/SnowflakeStats.java b/src/main/java/org/torproject/descriptor/SnowflakeStats.java
index 2fe78df..967d061 100644
--- a/src/main/java/org/torproject/descriptor/SnowflakeStats.java
+++ b/src/main/java/org/torproject/descriptor/SnowflakeStats.java
@@ -103,6 +103,30 @@ public interface SnowflakeStats extends Descriptor {
    */
   Optional<Long> clientDeniedCount();
 
+  /**
+   * Return a count of the number of times a client with a restricted or unknown
+   * NAT type has requested a proxy from the broker but no proxies were
+   * available, rounded up to the nearest multiple of 8.
+   *
+   * @return Count of the number of times a client with a restricted or unknown
+   *     NAT type has requested a proxy from the broker but no proxies were
+   *     available, rounded up to the nearest multiple of 8.
+   * @since 2.16.0
+   */
+  Optional<Long> clientRestrictedDeniedCount();
+
+  /**
+   * Return a count of the number of times a client with an unrestricted NAT
+   * type has requested a proxy from the broker but no proxies were available,
+   * rounded up to the nearest multiple of 8.
+   *
+   * @return Count of the number of times a client with an unrestricted NAT type
+   *     has requested a proxy from the broker but no proxies were available,
+   *     rounded up to the nearest multiple of 8.
+   * @since 2.16.0
+   */
+  Optional<Long> clientUnrestrictedDeniedCount();
+
   /**
    * Return a count of the number of times a client successfully received a
    * proxy from the broker, rounded up to the nearest multiple of 8.
@@ -112,5 +136,35 @@ public interface SnowflakeStats extends Descriptor {
    * @since 2.7.0
    */
   Optional<Long> clientSnowflakeMatchCount();
+
+  /**
+   * Return a count of the total number of unique IP addresses of snowflake
+   * proxies that have a restricted NAT type.
+   *
+   * @return Count of the total number of unique IP addresses of snowflake
+   *     proxies that have a restricted NAT type.
+   * @since 2.16.0
+   */
+  Optional<Long> snowflakeIpsNatRestricted();
+
+  /**
+   * Return a count of the total number of unique IP addresses of snowflake
+   * proxies that have an unrestricted NAT type.
+   *
+   * @return Count of the total number of unique IP addresses of snowflake
+   *     proxies that have an unrestricted NAT type.
+   * @since 2.16.0
+   */
+  Optional<Long> snowflakeIpsNatUnrestricted();
+
+  /**
+   * Return a count of the total number of unique IP addresses of snowflake
+   * proxies that have an unknown NAT type.
+   *
+   * @return Count of the total number of unique IP addresses of snowflake
+   *     proxies that have an unknown NAT type.
+   * @since 2.16.0
+   */
+  Optional<Long> snowflakeIpsNatUnknown();
 }
 
diff --git a/src/main/java/org/torproject/descriptor/impl/Key.java b/src/main/java/org/torproject/descriptor/impl/Key.java
index b02d96e..410cef6 100644
--- a/src/main/java/org/torproject/descriptor/impl/Key.java
+++ b/src/main/java/org/torproject/descriptor/impl/Key.java
@@ -36,7 +36,9 @@ public enum Key {
   CELL_STATS_END("cell-stats-end"),
   CELL_TIME_IN_QUEUE("cell-time-in-queue"),
   CLIENT_DENIED_COUNT("client-denied-count"),
+  CLIENT_RESTRICTED_DENIED_COUNT("client-restricted-denied-count"),
   CLIENT_SNOWFLAKE_MATCH_COUNT("client-snowflake-match-count"),
+  CLIENT_UNRESTRICTED_DENIED_COUNT("client-unrestricted-denied-count"),
   CLIENT_VERSIONS("client-versions"),
   CONN_BI_DIRECT("conn-bi-direct"),
   CONSENSUS_METHOD("consensus-method"),
@@ -149,6 +151,9 @@ public enum Key {
   SNOWFLAKE_IDLE_COUNT("snowflake-idle-count"),
   SNOWFLAKE_IPS("snowflake-ips"),
   SNOWFLAKE_IPS_BADGE("snowflake-ips-badge"),
+  SNOWFLAKE_IPS_NAT_RESTRICTED("snowflake-ips-nat-restricted"),
+  SNOWFLAKE_IPS_NAT_UNKNOWN("snowflake-ips-nat-unknown"),
+  SNOWFLAKE_IPS_NAT_UNRESTRICTED("snowflake-ips-nat-unrestricted"),
   SNOWFLAKE_IPS_STANDALONE("snowflake-ips-standalone"),
   SNOWFLAKE_IPS_TOTAL("snowflake-ips-total"),
   SNOWFLAKE_IPS_WEBEXT("snowflake-ips-webext"),
diff --git a/src/main/java/org/torproject/descriptor/impl/SnowflakeStatsImpl.java b/src/main/java/org/torproject/descriptor/impl/SnowflakeStatsImpl.java
index f52281e..2af40b5 100644
--- a/src/main/java/org/torproject/descriptor/impl/SnowflakeStatsImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/SnowflakeStatsImpl.java
@@ -80,9 +80,24 @@ public class SnowflakeStatsImpl extends DescriptorImpl
         case CLIENT_DENIED_COUNT:
           this.parseClientDeniedCount(line, parts);
           break;
+        case CLIENT_RESTRICTED_DENIED_COUNT:
+          this.parseClientRestrictedDeniedCount(line, parts);
+          break;
+        case CLIENT_UNRESTRICTED_DENIED_COUNT:
+          this.parseClientUnrestrictedDeniedCount(line, parts);
+          break;
         case CLIENT_SNOWFLAKE_MATCH_COUNT:
           this.parseClientSnowflakeMatchCount(line, parts);
           break;
+        case SNOWFLAKE_IPS_NAT_RESTRICTED:
+          this.parseSnowflakeIpsNatRestricted(line, parts);
+          break;
+        case SNOWFLAKE_IPS_NAT_UNRESTRICTED:
+          this.parseSnowflakeIpsNatUnrestricted(line, parts);
+          break;
+        case SNOWFLAKE_IPS_NAT_UNKNOWN:
+          this.parseSnowflakeIpsNatUnknown(line, parts);
+          break;
         case INVALID:
         default:
           ParseHelper.parseKeyword(line, parts[0]);
@@ -142,11 +157,36 @@ public class SnowflakeStatsImpl extends DescriptorImpl
     this.clientDeniedCount = ParseHelper.parseLong(line, parts, 1);
   }
 
+  private void parseClientRestrictedDeniedCount(String line, String[] parts)
+      throws DescriptorParseException {
+    this.clientRestrictedDeniedCount = ParseHelper.parseLong(line, parts, 1);
+  }
+
+  private void parseClientUnrestrictedDeniedCount(String line, String[] parts)
+      throws DescriptorParseException {
+    this.clientUnrestrictedDeniedCount = ParseHelper.parseLong(line, parts, 1);
+  }
+
   private void parseClientSnowflakeMatchCount(String line, String[] parts)
       throws DescriptorParseException {
     this.clientSnowflakeMatchCount = ParseHelper.parseLong(line, parts, 1);
   }
 
+  private void parseSnowflakeIpsNatRestricted(String line, String[] parts)
+      throws DescriptorParseException {
+    this.snowflakeIpsNatRestricted = ParseHelper.parseLong(line, parts, 1);
+  }
+
+  private void parseSnowflakeIpsNatUnrestricted(String line, String[] parts)
+      throws DescriptorParseException {
+    this.snowflakeIpsNatUnrestricted = ParseHelper.parseLong(line, parts, 1);
+  }
+
+  private void parseSnowflakeIpsNatUnknown(String line, String[] parts)
+      throws DescriptorParseException {
+    this.snowflakeIpsNatUnknown = ParseHelper.parseLong(line, parts, 1);
+  }
+
   private LocalDateTime snowflakeStatsEnd;
 
   @Override
@@ -210,11 +250,46 @@ public class SnowflakeStatsImpl extends DescriptorImpl
     return Optional.ofNullable(this.clientDeniedCount);
   }
 
+  private Long clientRestrictedDeniedCount;
+
+  @Override
+  public Optional<Long> clientRestrictedDeniedCount() {
+    return Optional.ofNullable(this.clientRestrictedDeniedCount);
+  }
+
+  private Long clientUnrestrictedDeniedCount;
+
+  @Override
+  public Optional<Long> clientUnrestrictedDeniedCount() {
+    return Optional.ofNullable(this.clientUnrestrictedDeniedCount);
+  }
+
   private Long clientSnowflakeMatchCount;
 
   @Override
   public Optional<Long> clientSnowflakeMatchCount() {
     return Optional.ofNullable(this.clientSnowflakeMatchCount);
   }
+
+  private Long snowflakeIpsNatRestricted;
+
+  @Override
+  public Optional<Long> snowflakeIpsNatRestricted() {
+    return Optional.ofNullable(this.snowflakeIpsNatRestricted);
+  }
+
+  private Long snowflakeIpsNatUnrestricted;
+
+  @Override
+  public Optional<Long> snowflakeIpsNatUnrestricted() {
+    return Optional.ofNullable(this.snowflakeIpsNatUnrestricted);
+  }
+
+  private Long snowflakeIpsNatUnknown;
+
+  @Override
+  public Optional<Long> snowflakeIpsNatUnknown() {
+    return Optional.ofNullable(this.snowflakeIpsNatUnknown);
+  }
 }
 
diff --git a/src/test/java/org/torproject/descriptor/impl/SnowflakeStatsImplTest.java b/src/test/java/org/torproject/descriptor/impl/SnowflakeStatsImplTest.java
index 4051b74..8d03511 100644
--- a/src/test/java/org/torproject/descriptor/impl/SnowflakeStatsImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/SnowflakeStatsImplTest.java
@@ -42,6 +42,36 @@ public class SnowflakeStatsImplTest {
       "client-denied-count 0",
       "client-snowflake-match-count 864" };
 
+  /**
+   * Snowflake statistics written on 2020-12-16 at 19:24:38 as obtained from
+   * CollecTor.
+   */
+  private static final String[] snowflakeStats20201216192438 = new String[] {
+      "@type snowflake-stats 1.0",
+      "snowflake-stats-end 2020-12-16 19:24:38 (86400 s)",
+      "snowflake-ips US=1716,SE=109,PH=97,EC=5,FO=1,AU=121,SA=12,PK=8,IR=12,"
+          + "GF=2,UZ=1,BY=12,BE=39,MT=2,BA=2,SC=1,MM=3,FR=272,PS=7,LT=12,"
+          + "NL=209,CY=4,TW=26,GA=4,IL=25,MX=38,HU=35,HR=21,AE=6,PY=5,PT=50,"
+          + "FI=48,RO=116,DE=877,MY=27,CA=223,IQ=1,CZ=46,SI=7,RS=14,KN=3,JO=2,"
+          + "TN=3,LB=2,PE=6,ID=28,MK=2,AT=70,MV=1,BR=149,TR=19,JP=513,CH=151,"
+          + "NZ=36,VN=18,MD=2,GR=56,UA=33,AZ=3,CN=74,RU=113,LV=23,EE=10,TH=63,"
+          + "BG=10,??=15,HK=22,CR=3,SD=2,GB=372,DK=37,BD=5,ZA=22,LU=24,KR=26,"
+          + "LK=3,IS=3,PR=1,MO=1,PL=165,NO=49,CL=15,IE=24,KE=1,MA=2,GT=1,ES=74,"
+          + "EG=16,PA=3,IN=142,CO=5,GI=1,DZ=12,KZ=1,AR=24,UY=3,NP=8,SN=2,SG=45,"
+          + "TZ=1,SK=20,TG=8,BZ=5,IT=172,BF=2",
+      "snowflake-ips-total 6943",
+      "snowflake-ips-standalone 32",
+      "snowflake-ips-badge 27",
+      "snowflake-ips-webext 6882",
+      "snowflake-idle-count 956568",
+      "client-denied-count 640",
+      "client-restricted-denied-count 640",
+      "client-unrestricted-denied-count 0",
+      "client-snowflake-match-count 11456",
+      "snowflake-ips-nat-restricted 3140",
+      "snowflake-ips-nat-unrestricted 29",
+      "snowflake-ips-nat-unknown 3768" };
+
   @Test
   public void testExampleMetricsLog() throws DescriptorParseException {
     SnowflakeStats snowflakeStats = new SnowflakeStatsImpl(
@@ -145,5 +175,25 @@ public class SnowflakeStatsImplTest {
     new SnowflakeStatsImpl(new TestDescriptorBuilder(
         "snowflake-stats-end 2019-08-07 19:52:11 (0 s)").build(), null);
   }
+
+  @Test
+  public void testNatBasedSnowflakeLines() throws DescriptorParseException {
+    SnowflakeStats snowflakeStats = new SnowflakeStatsImpl(
+        new TestDescriptorBuilder(snowflakeStats20201216192438).build(), null);
+    assertTrue(snowflakeStats.clientRestrictedDeniedCount().isPresent());
+    assertEquals((Long) 640L,
+        snowflakeStats.clientRestrictedDeniedCount().get());
+    assertTrue(snowflakeStats.clientUnrestrictedDeniedCount().isPresent());
+    assertEquals((Long) 0L,
+        snowflakeStats.clientUnrestrictedDeniedCount().get());
+    assertTrue(snowflakeStats.snowflakeIpsNatRestricted().isPresent());
+    assertEquals((Long) 3140L,
+        snowflakeStats.snowflakeIpsNatRestricted().get());
+    assertTrue(snowflakeStats.snowflakeIpsNatUnrestricted().isPresent());
+    assertEquals((Long) 29L,
+        snowflakeStats.snowflakeIpsNatUnrestricted().get());
+    assertTrue(snowflakeStats.snowflakeIpsNatUnknown().isPresent());
+    assertEquals((Long) 3768L, snowflakeStats.snowflakeIpsNatUnknown().get());
+  }
 }
 



More information about the tor-commits mailing list