From ba6c63a707ceb7acc6354f541a8efd9366842c53 Mon Sep 17 00:00:00 2001 From: Karsten Loesing Date: Thu, 14 May 2020 09:23:12 +0200 Subject: [PATCH] Parse partial download times from Onionperf files. Implements #26673. --- CHANGELOG.md | 6 +++- .../torproject/descriptor/TorperfResult.java | 9 +++++ .../descriptor/impl/TorperfResultImpl.java | 34 ++++++++++++++++++ .../onionperf/OnionPerfAnalysisConverter.java | 9 +++++ .../onionperf/ParsedOnionPerfAnalysis.java | 5 +++ .../OnionPerfAnalysisConverterTest.java | 13 +++++-- .../onionperf/onionperf.analysis.json.xz | Bin 17376 -> 17420 bytes 7 files changed, 73 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ed2425..ac7ef89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ -# Changes in version 2.??.? - 2020-??-?? +# Changes in version 2.13.0 - 2020-??-?? + + * Medium changes + - Extend Torperf results to provide partial download times for 10, + 20, 50, 100, 200, and 500 KiB as well as 1, 2, and 5 MiB. * Minor changes - Include previously unknown error codes in Torperf results diff --git a/src/main/java/org/torproject/descriptor/TorperfResult.java b/src/main/java/org/torproject/descriptor/TorperfResult.java index 961a206..695be01 100644 --- a/src/main/java/org/torproject/descriptor/TorperfResult.java +++ b/src/main/java/org/torproject/descriptor/TorperfResult.java @@ -135,6 +135,15 @@ public interface TorperfResult extends Descriptor { */ Boolean didTimeout(); + /** + * Return the times in milliseconds since the epoch when the given number of + * bytes were read, or null if the torperf line didn't contain that + * information. + * + * @since 2.13.0 + */ + SortedMap getPartials(); + /** * Return the times in milliseconds since the epoch when {@code x%} of * expected bytes were read for {@code 0 <= x <= 100}, or null if the diff --git a/src/main/java/org/torproject/descriptor/impl/TorperfResultImpl.java b/src/main/java/org/torproject/descriptor/impl/TorperfResultImpl.java index f8879d7..b2c58cc 100644 --- a/src/main/java/org/torproject/descriptor/impl/TorperfResultImpl.java +++ b/src/main/java/org/torproject/descriptor/impl/TorperfResultImpl.java @@ -185,6 +185,8 @@ public class TorperfResultImpl extends DescriptorImpl default: if (key.startsWith("DATAPERC")) { this.parseDataPercentile(value, keyValue, line); + } else if (key.startsWith("PARTIAL")) { + this.parsePartial(value, keyValue, line); } else { if (this.unrecognizedKeys == null) { this.unrecognizedKeys = new TreeMap<>(); @@ -313,6 +315,31 @@ public class TorperfResultImpl extends DescriptorImpl } } + private void parsePartial(String value, String keyValue, String line) + throws DescriptorParseException { + String key = keyValue.substring(0, keyValue.indexOf("=")); + String bytesString = key.substring("PARTIAL".length()); + int bytes; + try { + bytes = Integer.parseInt(bytesString); + } catch (NumberFormatException e) { + /* Treat key as unrecognized below. */ + bytes = -1; + } + if (bytes < 0) { + if (this.unrecognizedKeys == null) { + this.unrecognizedKeys = new TreeMap<>(); + } + this.unrecognizedKeys.put(key, value); + } else { + long timestamp = this.parseTimestamp(value, keyValue, line); + if (this.partials == null) { + this.partials = new TreeMap<>(); + } + this.partials.put(bytes, timestamp); + } + } + private void parseDataPercentile(String value, String keyValue, String line) throws DescriptorParseException { String key = keyValue.substring(0, keyValue.indexOf("=")); @@ -564,6 +591,13 @@ public class TorperfResultImpl extends DescriptorImpl return this.didTimeout; } + private SortedMap partials; + + @Override + public SortedMap getPartials() { + return this.partials == null ? null : new TreeMap<>(this.partials); + } + private SortedMap dataPercentiles; @Override diff --git a/src/main/java/org/torproject/descriptor/onionperf/OnionPerfAnalysisConverter.java b/src/main/java/org/torproject/descriptor/onionperf/OnionPerfAnalysisConverter.java index 8ca5efd..5e7e683 100644 --- a/src/main/java/org/torproject/descriptor/onionperf/OnionPerfAnalysisConverter.java +++ b/src/main/java/org/torproject/descriptor/onionperf/OnionPerfAnalysisConverter.java @@ -265,6 +265,15 @@ public class OnionPerfAnalysisConverter { transfer.elapsedSeconds.command); torperfResultsBuilder.addTimestamp("DATARESPONSE", transfer.unixTsStart, transfer.elapsedSeconds.response); + if (null != transfer.elapsedSeconds.payloadBytes) { + for (Map.Entry payloadBytesEntry + : transfer.elapsedSeconds.payloadBytes.entrySet()) { + String key = String.format("PARTIAL%s", payloadBytesEntry.getKey()); + Double elapsedSeconds = payloadBytesEntry.getValue(); + torperfResultsBuilder.addTimestamp(key, transfer.unixTsStart, + elapsedSeconds); + } + } if (null != transfer.elapsedSeconds.payloadProgress) { for (Map.Entry payloadProgressEntry : transfer.elapsedSeconds.payloadProgress.entrySet()) { diff --git a/src/main/java/org/torproject/descriptor/onionperf/ParsedOnionPerfAnalysis.java b/src/main/java/org/torproject/descriptor/onionperf/ParsedOnionPerfAnalysis.java index 679879e..4eca0ff 100644 --- a/src/main/java/org/torproject/descriptor/onionperf/ParsedOnionPerfAnalysis.java +++ b/src/main/java/org/torproject/descriptor/onionperf/ParsedOnionPerfAnalysis.java @@ -199,6 +199,11 @@ public class ParsedOnionPerfAnalysis { */ Double lastByte; + /** + * Time until the given number of bytes were read. + */ + Map payloadBytes; + /** * Time until the given fraction of expected bytes were read. */ diff --git a/src/test/java/org/torproject/descriptor/onionperf/OnionPerfAnalysisConverterTest.java b/src/test/java/org/torproject/descriptor/onionperf/OnionPerfAnalysisConverterTest.java index 7a1a3a0..51e0896 100644 --- a/src/test/java/org/torproject/descriptor/onionperf/OnionPerfAnalysisConverterTest.java +++ b/src/test/java/org/torproject/descriptor/onionperf/OnionPerfAnalysisConverterTest.java @@ -32,7 +32,10 @@ public class OnionPerfAnalysisConverterTest { + "ENDPOINTPROXY=localhost:127.0.0.1:35900 " + "ENDPOINTREMOTE=m3eahz7co6lzi6jn.onion:0.0.0.0:443 FILESIZE=1048576 " + "HOSTNAMELOCAL=op-nl2 HOSTNAMEREMOTE=op-nl2 LAUNCH=1587991281.38 " - + "NEGOTIATE=1587991280.37 " + + "NEGOTIATE=1587991280.37 PARTIAL10240=1587991283.81 " + + "PARTIAL102400=1587991284.15 PARTIAL1048576=1587991286.62 " + + "PARTIAL20480=1587991283.81 PARTIAL204800=1587991284.38 " + + "PARTIAL51200=1587991283.81 PARTIAL512000=1587991285.14 " + "PATH=$970F0966DAA7EBDEE44E3772045527A6854E997B," + "$8101421BEFCCF4C271D5483C5AABCAAD245BBB9D," + "$1A7A2516A961F2838F7F94786A8811BE82F9CFFE READBYTES=1048643 " @@ -54,6 +57,10 @@ public class OnionPerfAnalysisConverterTest { + "ENDPOINTREMOTE=3czoq6qyehjio6lcdo4tb4vk5uv2bm4gfk5iacnawza22do6klsj7wy" + "d.onion:0.0.0.0:443 FILESIZE=1048576 HOSTNAMELOCAL=op-nl2 " + "HOSTNAMEREMOTE=op-nl2 LAUNCH=1587991881.70 NEGOTIATE=1587991880.37 " + + "PARTIAL10240=1587991910.74 PARTIAL102400=1587991913.71 " + + "PARTIAL1048576=1587991927.74 PARTIAL20480=1587991910.74 " + + "PARTIAL204800=1587991916.00 PARTIAL51200=1587991910.74 " + + "PARTIAL512000=1587991921.80 " + "PATH=$D5C6F62A5D1B3C711CA5E6F9D3772A432E96F6C2," + "$94EC34B871936504BE70671B44760BC99242E1F3," + "$E0F638ECCE918B5455CE29D2CD9ECC9DBD8F8B21 READBYTES=1048643 " @@ -96,7 +103,9 @@ public class OnionPerfAnalysisConverterTest { String formattedTorperfResult = new String(descriptor.getRawDescriptorBytes()).trim(); assertNotNull(formattedTorperfResult); - assertTrue(formattedTorperfResult.equals(torperfResultTransfer1m1) + assertTrue(String.format("Unrecognized formatted Torperf result: %s", + formattedTorperfResult), + formattedTorperfResult.equals(torperfResultTransfer1m1) || formattedTorperfResult.equals(torperfResultTransfer1m3) || formattedTorperfResult.equals(torperfResultTransfer50k2)); } diff --git a/src/test/resources/onionperf/onionperf.analysis.json.xz b/src/test/resources/onionperf/onionperf.analysis.json.xz index 41a4fa1cea81022f1ef63e5892356f6a6ac08a90..08162a155b208c543f9bc390f228e06d195a9479 100644 GIT binary patch delta 17383 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 delta 17339 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