commit 908612803a9c59a1393a93df41c37b5f4bab0022 Author: Karsten Loesing karsten.loesing@gmx.net Date: Mon Jan 2 17:37:34 2012 +0100
Start implementing extra-info descriptor parsing. --- .../descriptor/RelayExtraInfoDescriptor.java | 206 +++++++- .../impl/RelayExtraInfoDescriptorImpl.java | 560 ++++++++++++++++++++ 2 files changed, 765 insertions(+), 1 deletions(-)
diff --git a/src/org/torproject/descriptor/RelayExtraInfoDescriptor.java b/src/org/torproject/descriptor/RelayExtraInfoDescriptor.java index 5c04aed..853a60a 100644 --- a/src/org/torproject/descriptor/RelayExtraInfoDescriptor.java +++ b/src/org/torproject/descriptor/RelayExtraInfoDescriptor.java @@ -1,7 +1,211 @@ -/* Copyright 2011 The Tor Project +/* Copyright 2012 The Tor Project * See LICENSE for licensing information */ package org.torproject.descriptor;
+import java.util.List; +import java.util.SortedMap; + public interface RelayExtraInfoDescriptor extends Descriptor { + + /* Return the relay's nickname. */ + public String getNickname(); + + /* Return the relay's fingerprint. */ + public String getFingerprint(); + + /* Return the publication time of this descriptor. */ + public long getPublishedMillis(); + + /* Return the read history contained in this descriptor, or null if no + * read history is contained. */ + public BandwidthHistory getReadHistory(); + + /* Return the write history contained in this descriptor, or null if no + * read history is contained. */ + public BandwidthHistory getWriteHistory(); + + /* Return the SHA1 digest of the GeoIP database used by this relay, or + * null if no GeoIP database digest is included. */ + public String getGeoipDbDigest(); + + /* Return the end of the included directory request statistics interval, + * or -1 if no directory request statistics are included. */ + public long getDirreqStatsEndMillis(); + + /* Return the interval length of the included directory request + * statistics, or -1 if no directory request statistics are included. */ + public long getDirreqStatsIntervalLength(); + + /* Return statistics on unique IP addresses requesting v2 network + * statuses with map keys being country codes and map values being + * numbers of unique IP addresses rounded up to the nearest multiple of + * 8, or null if no such statistics are included. */ + public SortedMap<String, Integer> getDirreqV2Ips(); + + /* Return statistics on unique IP addresses requesting v3 network status + * consensuses with map keys being country codes and map values being + * numbers of unique IP addresses rounded up to the nearest multiple of + * 8, or null if no such statistics are included. */ + public SortedMap<String, Integer> getDirreqV3Ips(); + + /* Return statistics on directory requests for v2 network statuses with + * map keys being country codes and map values being request numbers + * rounded up to the nearest multiple of 8, or null if no such + * statistics are included. */ + public SortedMap<String, Integer> getDirreqV2Reqs(); + + /* Return statistics on directory requests for v3 network status + * consensuses with map keys being country codes and map values being + * request numbers rounded up to the nearest multiple of 8, or null if + * no such statistics are included. */ + public SortedMap<String, Integer> getDirreqV3Reqs(); + + /* Return the share of requests for v2 network statuses that the + * directory expects to receive from clients, or -1.0 if no such + * statistics are included. */ + public double getDirreqV2Share(); + + /* Return the share of requests for v3 network status consensuses that + * the directory expects to receive from clients, or -1.0 if no such + * statistics are included. */ + public double getDirreqV3Share(); + + /* Return statistics on directory request responses for v2 network + * statuses with map keys being response strings and map values being + * response numbers rounded up to the nearest multiple of 4, or null if + * no such statistics are included. */ + public SortedMap<String, Integer> getDirreqV2Resp(); + + /* Return statistics on directory request responses for v3 network + * status consensuses with map keys being response strings and map + * values being response numbers rounded up to the nearest multiple of + * 4, or null if no such statistics are included. */ + public SortedMap<String, Integer> getDirreqV3Resp(); + + /* Return statistics on direct directory requests asking for v2 network + * statuses with map keys being statistic keys and map values being + * statistic values, or null if no such statistics are included. */ + public SortedMap<String, Integer> getDirreqV2DirectDl(); + + /* Return statistics on direct directory requests asking for v3 network + * status consensuses with map keys being statistic keys and map + * values being statistic values, or null if no such statistics are + * included. */ + public SortedMap<String, Integer> getDirreqV3DirectDl(); + + /* Return statistics on tunneled directory requests asking for v2 + * network statuses with map keys being statistic keys and map values + * being statistic values, or null if no such statistics are + * included. */ + public SortedMap<String, Integer> getDirreqV2TunneledDl(); + + /* Return statistics on tunneled directory requests asking for v3 + * network status consensuses with map keys being statistic keys and map + * values being statistic values, or null if no such statistics are + * included. */ + public SortedMap<String, Integer> getDirreqV3TunneledDl(); + + /* Return the directory request read history contained in this + * descriptor, or null if no directory request read history is + * contained. */ + public BandwidthHistory getDirreqReadHistory(); + + /* Return the directory request write history contained in this + * descriptor, or null if no directory request write history is + * contained. */ + public BandwidthHistory getDirreqWriteHistory(); + + /* Return the end of the included entry statistics interval, or -1 if no + * entry statistics are included. */ + public long getEntryStatsEndMillis(); + + /* Return the interval length of the included entry statistics, or -1 if + * no entry statistics are included. */ + public long getEntryStatsIntervalLength(); + + /* Return statistics on client IP addresses with map keys being country + * codes and map values being the number of unique IP addresses that + * have connected from that country rounded up to the nearest multiple + * of 8, or null if no entry statistics are included. */ + public SortedMap<String, Integer> getEntryIps(); + + /* Return the end of the included cell statistics interval, or -1 if no + * cell statistics are included. */ + public long getCellStatsEndMillis(); + + /* Return the interval length of the included cell statistics, or -1 if + * no cell statistics are included. */ + public long getCellStatsIntervalLength(); + + /* Return the mean number of processed cells per circuit by circuit + * deciles. */ + public List<Integer> getCellProcessedCells(); + + /* Return the mean number of cells contained in circuit queues by + * circuit deciles. */ + public List<Integer> getCellQueueCells(); + + /* Return the mean times in milliseconds that cells spend in circuit + * queues by circuit deciles. */ + public List<Integer> getCellTimeInQueue(); + + /* Return the mean number of circuits included in any of the cell + * statistics deciles, or -1 if no cell statistics are included. */ + public int getCellCircuitsPerDecile(); + + /* Return the end of the included statistics interval on bi-directional + * connection usage, or -1 if no such statistics are included. */ + public long getConnBiDirectStatsEndMillis(); + + /* Return the interval length of the included statistics on + * bi-directional connection usage, or -1 if no such statistics are + * included. */ + public long getConnBiDirectIntervalLength(); + + /* Return the number of connections on which this relay read and wrote + * less than 2 KiB/s in a 10-second interval, or -1 if no statistics on + * bi-directional connection usage are included. */ + public int getConnBiDirectBelow(); + + /* Return the number of connections on which this relay read and wrote + * at least 2 KiB/s in a 10-second interval and at least 10 times more + * in read direction than in write direction, or -1 if no statistics on + * bi-directional connection usage are included. */ + public int getConnBiDirectRead(); + + /* Return the number of connections on which this relay read and wrote + * at least 2 KiB/s in a 10-second interval and at least 10 times more + * in write direction than in read direction, or -1 if no statistics on + * bi-directional connection usage are included. */ + public int getConnBiDirectWrite(); + + /* Return the number of connections on which this relay read and wrote + * at least 2 KiB/s in a 10-second interval but not 10 times more in + * either direction, or -1 if no statistics on bi-directional connection + * usage are included. */ + public int getConnBiDirectBoth(); + + /* Return the end of the included exit statistics interval, or -1 if no + * exit statistics are included. */ + public long getExitStatsEndMillis(); + + /* Return the interval length of the included exit statistics, or -1 if + * no exit statistics are included. */ + public long getExitStatsIntervalLength(); + + /* Return statistics on KiB written by port with map keys being ports + * and map values being KiB rounded up to the next full KiB, or null if + * no exit statistics are included. */ + public SortedMap<Integer, Integer> getExitKibibytesWritten(); + + /* Return statistics on KiB read by port with map keys being ports and + * map values being KiB rounded up to the next full KiB, or null if no + * exit statistics are included. */ + public SortedMap<Integer, Integer> getExitKibibytesRead(); + + /* Return statistics on opened exit streams with map keys being ports + * and map values being the number of opened streams, rounded up to the + * nearest multiple of 4, or null if no exit statistics are included. */ + public SortedMap<Integer, Integer> getExitStreamsOpened(); }
diff --git a/src/org/torproject/descriptor/impl/RelayExtraInfoDescriptorImpl.java b/src/org/torproject/descriptor/impl/RelayExtraInfoDescriptorImpl.java new file mode 100644 index 0000000..754a79f --- /dev/null +++ b/src/org/torproject/descriptor/impl/RelayExtraInfoDescriptorImpl.java @@ -0,0 +1,560 @@ +/* Copyright 2012 The Tor Project + * See LICENSE for licensing information */ +package org.torproject.descriptor.impl; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.SortedMap; +import org.torproject.descriptor.RelayExtraInfoDescriptor; +import org.torproject.descriptor.BandwidthHistory; + +/* TODO Implement methods to parse the various statistics (other than + * bandwidth histories. */ +/* TODO Write a test class. */ +public class RelayExtraInfoDescriptorImpl extends DescriptorImpl + implements RelayExtraInfoDescriptor { + + protected static List<RelayExtraInfoDescriptor> parseDescriptors( + byte[] descriptorsBytes) { + List<RelayExtraInfoDescriptor> parsedDescriptors = + new ArrayList<RelayExtraInfoDescriptor>(); + List<byte[]> splitDescriptorsBytes = + DescriptorImpl.splitRawDescriptorBytes(descriptorsBytes, + "router "); + try { + for (byte[] descriptorBytes : splitDescriptorsBytes) { + RelayExtraInfoDescriptor parsedDescriptor = + new RelayExtraInfoDescriptorImpl(descriptorBytes); + parsedDescriptors.add(parsedDescriptor); + } + } catch (DescriptorParseException e) { + /* TODO Handle this error somehow. */ + System.err.println("Failed to parse descriptor. Skipping."); + e.printStackTrace(); + } + return parsedDescriptors; + } + + protected RelayExtraInfoDescriptorImpl(byte[] descriptorBytes) + throws DescriptorParseException { + super(descriptorBytes); + this.parseDescriptorBytes(); + Set<String> exactlyOnceKeywords = new HashSet<String>(Arrays.asList(( + "extra-info,published,router-signature").split(","))); + this.checkExactlyOnceKeywords(exactlyOnceKeywords); + Set<String> atMostOnceKeywords = new HashSet<String>(Arrays.asList(( + "read-history,write-history,geoip-db-digest,dirreq-stats-end," + + "dirreq-v2-ips,dirreq-v3-ips,dirreq-v2-reqs,dirreq-v3-reqs," + + "dirreq-v2-share,dirreq-v3-share,dirreq-v2-resp,dirreq-v3-resp," + + "dirreq-v2-direct-dl,dirreq-v3-direct-dl,dirreq-v2-tunneled-dl," + + "dirreq-v3-tunneled-dl,dirreq-read-history," + + "dirreq-write-history,entry-stats-end,entry-ips,cell-stats-end," + + "cell-processed-cells,cell-queued-cells,cell-time-in-queue," + + "cell-circuits-per-decile,conn-bi-direct,exit-stats-end," + + "exit-kibibytes-written,exit-kibibytes-read," + + "exit-streams-opened").split(","))); + this.checkAtMostOnceKeywords(atMostOnceKeywords); + /* TODO Add more checks to see that only statistics details lines are + * included with corresponding statistics interval lines. */ + this.checkFirstKeyword("extra-info"); + this.checkLastKeyword("router-signature"); + return; + } + + private void parseDescriptorBytes() throws DescriptorParseException { + try { + BufferedReader br = new BufferedReader(new StringReader( + new String(this.rawDescriptorBytes))); + String line; + boolean skipCrypto = false; + while ((line = br.readLine()) != null) { + String lineNoOpt = line.startsWith("opt ") ? + line.substring("opt ".length()) : line; + String[] partsNoOpt = lineNoOpt.split(" "); + String keyword = partsNoOpt[0]; + if (keyword.equals("extra-info")) { + this.parseExtraInfoLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("published")) { + this.parsePublishedLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("read-history")) { + this.parseReadHistoryLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("write-history")) { + this.parseWriteHistoryLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("geoip-db-digest")) { + this.parseGeoipDbDigestLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("dirreq-stats-end")) { + this.parseDirreqStatsEndLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("dirreq-v2-ips")) { + this.parseDirreqV2IpsLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("dirreq-v3-ips")) { + this.parseDirreqV3IpsLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("dirreq-v2-reqs")) { + this.parseDirreqV2ReqsLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("dirreq-v3-reqs")) { + this.parseDirreqV3ReqsLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("dirreq-v2-share")) { + this.parseDirreqV2ShareLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("dirreq-v3-share")) { + this.parseDirreqV3ShareLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("dirreq-v2-resp")) { + this.parseDirreqV2RespLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("dirreq-v3-resp")) { + this.parseDirreqV3RespLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("dirreq-v2-direct-dl")) { + this.parseDirreqV2DirectDlLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("dirreq-v3-direct-dl")) { + this.parseDirreqV3DirectDlLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("dirreq-v2-tunneled-dl")) { + this.parseDirreqV2TunneledDlLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("dirreq-v3-tunneled-dl")) { + this.parseDirreqV3TunneledDlLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("dirreq-read-history")) { + this.parseDirreqReadHistoryLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("dirreq-write-history")) { + this.parseDirreqWriteHistoryLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("entry-stats-end")) { + this.parseEntryStatsEndLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("entry-ips")) { + this.parseEntryIpsLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("cell-stats-end")) { + this.parseCellStatsEndLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("cell-processed-cells")) { + this.parseCellProcessedCellsLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("cell-queued-cells")) { + this.parseCellQueuedCellsLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("cell-time-in-queue")) { + this.parseCellTimeInQueueLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("cell-circuits-per-decile")) { + this.parseCellCircuitsPerDecileLine(line, lineNoOpt, + partsNoOpt); + } else if (keyword.equals("conn-bi-direct")) { + this.parseConnBiDirectLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("exit-stats-end")) { + this.parseExitStatsEndLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("exit-kibibytes-written")) { + this.parseExitKibibytesWrittenLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("exit-kibibytes-read")) { + this.parseExitKibibytesReadLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("exit-streams-opened")) { + this.parseExitStreamsOpenedLine(line, lineNoOpt, partsNoOpt); + } else if (keyword.equals("router-signature")) { + this.parseRouterSignatureLine(line, lineNoOpt, partsNoOpt); + } else if (line.startsWith("-----BEGIN")) { + skipCrypto = true; + } else if (line.startsWith("-----END")) { + skipCrypto = false; + } else if (!skipCrypto) { + /* 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. In theory, + * dir-spec.txt says that unknown lines should be ignored. This + * also applies to the other descriptors. */ + 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); + } + } + + private void parseExtraInfoLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + if (partsNoOpt.length != 3) { + throw new DescriptorParseException("Illegal line '" + line + + "' in extra-info descriptor."); + } + this.nickname = ParseHelper.parseNickname(line, partsNoOpt[1]); + this.fingerprint = ParseHelper.parseTwentyByteHexString(line, + partsNoOpt[2]); + } + + private void parsePublishedLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + this.publishedMillis = ParseHelper.parseTimestampAtIndex(line, + partsNoOpt, 1, 2); + } + + private void parseReadHistoryLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + this.readHistory = new BandwidthHistoryImpl(line, lineNoOpt, + partsNoOpt); + } + + private void parseWriteHistoryLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + this.writeHistory = new BandwidthHistoryImpl(line, lineNoOpt, + partsNoOpt); + } + + private void parseGeoipDbDigestLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseDirreqStatsEndLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseDirreqV2IpsLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseDirreqV3IpsLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseDirreqV2ReqsLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseDirreqV3ReqsLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseDirreqV2ShareLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseDirreqV3ShareLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseDirreqV2RespLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseDirreqV3RespLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseDirreqV2DirectDlLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseDirreqV3DirectDlLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseDirreqV2TunneledDlLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseDirreqV3TunneledDlLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseDirreqReadHistoryLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + this.dirreqReadHistory = new BandwidthHistoryImpl(line, lineNoOpt, + partsNoOpt); + } + + private void parseDirreqWriteHistoryLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + this.dirreqWriteHistory = new BandwidthHistoryImpl(line, lineNoOpt, + partsNoOpt); + } + + private void parseEntryStatsEndLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseEntryIpsLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseCellStatsEndLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseCellProcessedCellsLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseCellQueuedCellsLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseCellTimeInQueueLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseCellCircuitsPerDecileLine(String line, + String lineNoOpt, String[] partsNoOpt) + throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseConnBiDirectLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseExitStatsEndLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseExitKibibytesWrittenLine(String line, + String lineNoOpt, String[] partsNoOpt) + throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseExitKibibytesReadLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseExitStreamsOpenedLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + /* TODO Implement me. */ + } + + private void parseRouterSignatureLine(String line, String lineNoOpt, + String[] partsNoOpt) throws DescriptorParseException { + if (!lineNoOpt.equals("router-signature")) { + throw new DescriptorParseException("Illegal line '" + line + "'."); + } + /* Not parsing crypto parts (yet). */ + } + + private String nickname; + public String getNickname() { + return this.nickname; + } + + private String fingerprint; + public String getFingerprint() { + return this.fingerprint; + } + + private long publishedMillis; + public long getPublishedMillis() { + return this.publishedMillis; + } + + private BandwidthHistory readHistory; + public BandwidthHistory getReadHistory() { + return this.readHistory; + } + + private BandwidthHistory writeHistory; + public BandwidthHistory getWriteHistory() { + return this.writeHistory; + } + + public String getGeoipDbDigest() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public long getDirreqStatsEndMillis() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public long getDirreqStatsIntervalLength() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public SortedMap<String, Integer> getDirreqV2Ips() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public SortedMap<String, Integer> getDirreqV3Ips() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public SortedMap<String, Integer> getDirreqV2Reqs() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public SortedMap<String, Integer> getDirreqV3Reqs() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public double getDirreqV2Share() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public double getDirreqV3Share() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public SortedMap<String, Integer> getDirreqV2Resp() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public SortedMap<String, Integer> getDirreqV3Resp() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public SortedMap<String, Integer> getDirreqV2DirectDl() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public SortedMap<String, Integer> getDirreqV3DirectDl() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public SortedMap<String, Integer> getDirreqV2TunneledDl() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public SortedMap<String, Integer> getDirreqV3TunneledDl() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + private BandwidthHistory dirreqReadHistory; + public BandwidthHistory getDirreqReadHistory() { + return this.dirreqReadHistory; + } + + private BandwidthHistory dirreqWriteHistory; + public BandwidthHistory getDirreqWriteHistory() { + return this.dirreqWriteHistory; + } + + public long getEntryStatsEndMillis() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public long getEntryStatsIntervalLength() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public SortedMap<String, Integer> getEntryIps() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public long getCellStatsEndMillis() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public long getCellStatsIntervalLength() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public List<Integer> getCellProcessedCells() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public List<Integer> getCellQueueCells() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public List<Integer> getCellTimeInQueue() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public int getCellCircuitsPerDecile() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public long getConnBiDirectStatsEndMillis() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public long getConnBiDirectIntervalLength() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public int getConnBiDirectBelow() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public int getConnBiDirectRead() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public int getConnBiDirectWrite() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public int getConnBiDirectBoth() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public long getExitStatsEndMillis() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public long getExitStatsIntervalLength() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public SortedMap<Integer, Integer> getExitKibibytesWritten() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public SortedMap<Integer, Integer> getExitKibibytesRead() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } + + public SortedMap<Integer, Integer> getExitStreamsOpened() { + /* TODO Implement me. */ + throw new UnsupportedOperationException(); + } +} +