lists.torproject.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
April
March
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
tor-commits
November 2017
----- 2025 -----
April 2025
March 2025
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
tor-commits@lists.torproject.org
16 participants
2019 discussions
Start a n
N
ew thread
[onionoo/release] Add "recommended_version" parameter.
by karsten@torproject.org
28 Nov '17
28 Nov '17
commit 11e5bbd80c24bb6c11ab3450d208517d4d145780 Author: Karsten Loesing <karsten.loesing(a)gmx.net> Date: Sat Nov 18 20:43:59 2017 +0100 Add "recommended_version" parameter. Add a "recommended_version" parameter to return only relays and bridges running a Tor software version that is recommended or not recommended by the directory authorities. Implements #23544. --- CHANGELOG.md | 3 ++ .../org/torproject/onionoo/
…
[View More]
docs/DocumentStore.java | 4 ++- .../torproject/onionoo/docs/SummaryDocument.java | 16 +++++++++- .../org/torproject/onionoo/server/NodeIndex.java | 22 +++++++++++++ .../org/torproject/onionoo/server/NodeIndexer.java | 21 +++++++++++++ .../torproject/onionoo/server/RequestHandler.java | 20 ++++++++++++ .../torproject/onionoo/server/ResourceServlet.java | 19 ++++++++++-- .../onionoo/writer/SummaryDocumentWriter.java | 3 +- .../onionoo/docs/SummaryDocumentTest.java | 2 +- .../onionoo/server/ResourceServletTest.java | 36 ++++++++++++++++++---- .../server/SummaryDocumentComparatorTest.java | 2 +- 11 files changed, 134 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a84259..8acdc0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ - Add a "recommended_version" field to bridge details documents based on whether the directory authorities recommend the bridge's version. + - Add a "recommended_version" parameter to return only relays and + bridges running a Tor software version that is recommended or not + recommended by the directory authorities. # Changes in version 4.3-1.7.1 - 2017-11-17 diff --git a/src/main/java/org/torproject/onionoo/docs/DocumentStore.java b/src/main/java/org/torproject/onionoo/docs/DocumentStore.java index 57d4165..23f11c7 100644 --- a/src/main/java/org/torproject/onionoo/docs/DocumentStore.java +++ b/src/main/java/org/torproject/onionoo/docs/DocumentStore.java @@ -440,10 +440,12 @@ public class DocumentStore { long consensusWeight = -1L; long firstSeenMillis = -1L; String hostName = null; + Boolean recommendedVersion = null; SummaryDocument summaryDocument = new SummaryDocument(isRelay, nickname, fingerprint, addresses, lastSeenMillis, running, relayFlags, consensusWeight, countryCode, firstSeenMillis, - asNumber, contact, family, family, version, hostName); + asNumber, contact, family, family, version, hostName, + recommendedVersion); return summaryDocument; } diff --git a/src/main/java/org/torproject/onionoo/docs/SummaryDocument.java b/src/main/java/org/torproject/onionoo/docs/SummaryDocument.java index cca5ab9..11f6070 100644 --- a/src/main/java/org/torproject/onionoo/docs/SummaryDocument.java +++ b/src/main/java/org/torproject/onionoo/docs/SummaryDocument.java @@ -322,6 +322,18 @@ public class SummaryDocument extends Document { return this.hostName; } + @Expose + @SerializedName("rv") + private Boolean recommendedVersion; + + public void setRecommendedVersion(Boolean recommendedVersion) { + this.recommendedVersion = recommendedVersion; + } + + public Boolean getRecommendedVersion() { + return this.recommendedVersion; + } + /* The familyFingerprints parameter can go away after September 8, 2015. * See above. */ /** Instantiates a summary document with all given properties. */ @@ -330,7 +342,8 @@ public class SummaryDocument extends Document { boolean running, SortedSet<String> relayFlags, long consensusWeight, String countryCode, long firstSeenMillis, String asNumber, String contact, SortedSet<String> familyFingerprints, - SortedSet<String> effectiveFamily, String version, String hostName) { + SortedSet<String> effectiveFamily, String version, String hostName, + Boolean recommendedVersion) { this.setRelay(isRelay); this.setNickname(nickname); this.setFingerprint(fingerprint); @@ -347,6 +360,7 @@ public class SummaryDocument extends Document { this.setEffectiveFamily(effectiveFamily); this.setVersion(version); this.setHostName(hostName); + this.setRecommendedVersion(recommendedVersion); } } diff --git a/src/main/java/org/torproject/onionoo/server/NodeIndex.java b/src/main/java/org/torproject/onionoo/server/NodeIndex.java index c41dd7a..8ab22a4 100644 --- a/src/main/java/org/torproject/onionoo/server/NodeIndex.java +++ b/src/main/java/org/torproject/onionoo/server/NodeIndex.java @@ -199,5 +199,27 @@ class NodeIndex { public Map<String, Set<String>> getRelaysByHostName() { return this.relaysByHostName; } + + private Map<Boolean, Set<String>> relaysByRecommendedVersion; + + public void setRelaysByRecommendedVersion( + Map<Boolean, Set<String>> relaysByRecommendedVersion) { + this.relaysByRecommendedVersion = relaysByRecommendedVersion; + } + + public Map<Boolean, Set<String>> getRelaysByRecommendedVersion() { + return this.relaysByRecommendedVersion; + } + + private Map<Boolean, Set<String>> bridgesByRecommendedVersion; + + public void setBridgesByRecommendedVersion( + Map<Boolean, Set<String>> bridgesByRecommendedVersion) { + this.bridgesByRecommendedVersion = bridgesByRecommendedVersion; + } + + public Map<Boolean, Set<String>> getBridgesByRecommendedVersion() { + return this.bridgesByRecommendedVersion; + } } diff --git a/src/main/java/org/torproject/onionoo/server/NodeIndexer.java b/src/main/java/org/torproject/onionoo/server/NodeIndexer.java index 585d33f..815a02e 100644 --- a/src/main/java/org/torproject/onionoo/server/NodeIndexer.java +++ b/src/main/java/org/torproject/onionoo/server/NodeIndexer.java @@ -156,6 +156,12 @@ public class NodeIndexer implements ServletContextListener, Runnable { Map<String, Set<String>> newRelaysByVersion = new HashMap<>(); Map<String, Set<String>> newBridgesByVersion = new HashMap<>(); Map<String, Set<String>> newRelaysByHostName = new HashMap<>(); + Map<Boolean, Set<String>> newRelaysByRecommendedVersion = new HashMap<>(); + newRelaysByRecommendedVersion.put(true, new HashSet<>()); + newRelaysByRecommendedVersion.put(false, new HashSet<>()); + Map<Boolean, Set<String>> newBridgesByRecommendedVersion = new HashMap<>(); + newBridgesByRecommendedVersion.put(true, new HashSet<>()); + newBridgesByRecommendedVersion.put(false, new HashSet<>()); SortedMap<Integer, Set<String>> newRelaysByFirstSeenDays = new TreeMap<>(); SortedMap<Integer, Set<String>> newBridgesByFirstSeenDays = new TreeMap<>(); SortedMap<Integer, Set<String>> newRelaysByLastSeenDays = new TreeMap<>(); @@ -269,6 +275,12 @@ public class NodeIndexer implements ServletContextListener, Runnable { newRelaysByHostName.get(hostNameLowerCase).add(fingerprint); newRelaysByHostName.get(hostNameLowerCase).add(hashedFingerprint); } + Boolean recommendedVersion = entry.getRecommendedVersion(); + if (null != recommendedVersion) { + newRelaysByRecommendedVersion.get(recommendedVersion).add(fingerprint); + newRelaysByRecommendedVersion.get(recommendedVersion).add( + hashedFingerprint); + } } /* This loop can go away once all Onionoo services had their hourly * updater write effective families to summary documents at least @@ -332,6 +344,13 @@ public class NodeIndexer implements ServletContextListener, Runnable { newBridgesByVersion.get(version).add(hashedFingerprint); newBridgesByVersion.get(version).add(hashedHashedFingerprint); } + Boolean recommendedVersion = entry.getRecommendedVersion(); + if (null != recommendedVersion) { + newBridgesByRecommendedVersion.get(recommendedVersion).add( + hashedFingerprint); + newBridgesByRecommendedVersion.get(recommendedVersion).add( + hashedHashedFingerprint); + } } NodeIndex newNodeIndex = new NodeIndex(); newNodeIndex.setRelayFingerprintSummaryLines( @@ -353,6 +372,8 @@ public class NodeIndexer implements ServletContextListener, Runnable { newNodeIndex.setRelaysByVersion(newRelaysByVersion); newNodeIndex.setBridgesByVersion(newBridgesByVersion); newNodeIndex.setRelaysByHostName(newRelaysByHostName); + newNodeIndex.setRelaysByRecommendedVersion(newRelaysByRecommendedVersion); + newNodeIndex.setBridgesByRecommendedVersion(newBridgesByRecommendedVersion); synchronized (this) { this.lastIndexed = updateStatusMillis; this.latestNodeIndex = newNodeIndex; diff --git a/src/main/java/org/torproject/onionoo/server/RequestHandler.java b/src/main/java/org/torproject/onionoo/server/RequestHandler.java index 067a738..c81051e 100644 --- a/src/main/java/org/torproject/onionoo/server/RequestHandler.java +++ b/src/main/java/org/torproject/onionoo/server/RequestHandler.java @@ -103,6 +103,12 @@ public class RequestHandler { this.hostName = hostName; } + private Boolean recommendedVersion; + + public void setRecommendedVersion(Boolean recommendedVersion) { + this.recommendedVersion = recommendedVersion; + } + private String[] order; public void setOrder(String[] order) { @@ -172,6 +178,7 @@ public class RequestHandler { this.filterByFamily(); this.filterByVersion(); this.filterByHostName(); + this.filterByRecommendedVersion(); this.order(); this.offset(); this.limit(); @@ -570,6 +577,19 @@ public class RequestHandler { this.filteredBridges.clear(); } + private void filterByRecommendedVersion() { + if (null == this.recommendedVersion) { + /* Not filtering by recommended version. */ + return; + } + Set<String> keepRelays = this.nodeIndex.getRelaysByRecommendedVersion() + .get(this.recommendedVersion); + this.filteredRelays.keySet().retainAll(keepRelays); + Set<String> keepBridges = this.nodeIndex.getBridgesByRecommendedVersion() + .get(this.recommendedVersion); + this.filteredBridges.keySet().retainAll(keepBridges); + } + private void order() { List<SummaryDocument> uniqueRelays = new ArrayList<>(); List<SummaryDocument> uniqueBridges = new ArrayList<>(); diff --git a/src/main/java/org/torproject/onionoo/server/ResourceServlet.java b/src/main/java/org/torproject/onionoo/server/ResourceServlet.java index f1521e2..3449407 100644 --- a/src/main/java/org/torproject/onionoo/server/ResourceServlet.java +++ b/src/main/java/org/torproject/onionoo/server/ResourceServlet.java @@ -66,9 +66,10 @@ public class ResourceServlet extends HttpServlet { private static final long CACHE_INTERVAL = 5L * 60L * 1000L; private static Set<String> knownParameters = new HashSet<>( - Arrays.asList(("type,running,search,lookup,fingerprint,country,as," - + "flag,first_seen_days,last_seen_days,contact,order,limit," - + "offset,fields,family,version,host_name").split(","))); + Arrays.asList("type", "running", "search", "lookup", "fingerprint", + "country", "as", "flag", "first_seen_days", "last_seen_days", + "contact", "order", "limit", "offset", "fields", "family", "version", + "host_name", "recommended_version")); private static Set<String> illegalSearchQualifiers = new HashSet<>(Arrays.asList(("search,fingerprint,order,limit," @@ -301,6 +302,18 @@ public class ResourceServlet extends HttpServlet { } rh.setHostName(hostNameParameter); } + if (parameterMap.containsKey("recommended_version")) { + String recommendedVersionParameterValue = + parameterMap.get("recommended_version").toLowerCase(); + boolean recommendedVersionRequested = true; + if (recommendedVersionParameterValue.equals("false")) { + recommendedVersionRequested = false; + } else if (!recommendedVersionParameterValue.equals("true")) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST); + return; + } + rh.setRecommendedVersion(recommendedVersionRequested); + } if (parameterMap.containsKey("order")) { String[] order = this.parseOrderParameter(parameterMap.get("order")); if (order == null) { diff --git a/src/main/java/org/torproject/onionoo/writer/SummaryDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/SummaryDocumentWriter.java index faf54fa..a412eec 100644 --- a/src/main/java/org/torproject/onionoo/writer/SummaryDocumentWriter.java +++ b/src/main/java/org/torproject/onionoo/writer/SummaryDocumentWriter.java @@ -93,11 +93,12 @@ public class SummaryDocumentWriter implements DocumentWriter { String nickname = nodeStatus.getNickname(); String version = nodeStatus.getVersion(); String hostName = nodeStatus.getHostName(); + Boolean recommendedVersion = nodeStatus.getRecommendedVersion(); SummaryDocument summaryDocument = new SummaryDocument(isRelay, nickname, fingerprint, addresses, lastSeenMillis, running, relayFlags, consensusWeight, countryCode, firstSeenMillis, asNumber, contact, declaredFamily, effectiveFamily, version, - hostName); + hostName, recommendedVersion); if (this.documentStore.store(summaryDocument, fingerprint)) { this.writtenDocuments++; } diff --git a/src/test/java/org/torproject/onionoo/docs/SummaryDocumentTest.java b/src/test/java/org/torproject/onionoo/docs/SummaryDocumentTest.java index 8c45ed2..ce13ccc 100644 --- a/src/test/java/org/torproject/onionoo/docs/SummaryDocumentTest.java +++ b/src/test/java/org/torproject/onionoo/docs/SummaryDocumentTest.java @@ -27,7 +27,7 @@ public class SummaryDocumentTest { "0025C136C1F3A9EEFE2AE3F918F03BFA21B5070B" })), new TreeSet<>(Arrays.asList( new String[] { "001C13B3A55A71B977CA65EC85539D79C653A3FC" })), null, - null); + null, true); } @Test() diff --git a/src/test/java/org/torproject/onionoo/server/ResourceServletTest.java b/src/test/java/org/torproject/onionoo/server/ResourceServletTest.java index d763988..dee5139 100644 --- a/src/test/java/org/torproject/onionoo/server/ResourceServletTest.java +++ b/src/test/java/org/torproject/onionoo/server/ResourceServletTest.java @@ -144,7 +144,7 @@ public class ResourceServletTest { "0025C136C1F3A9EEFE2AE3F918F03BFA21B5070B" })), new TreeSet<>(Arrays.asList( new String[] { "001C13B3A55A71B977CA65EC85539D79C653A3FC" })), - "0.2.3.25", "ppp-62-216-201-221.dynamic.mnet-online.de"); + "0.2.3.25", "ppp-62-216-201-221.dynamic.mnet-online.de", true); this.relays.put("000C5F55BD4814B917CC474BD537F1A3B33CCE2A", relayTorkaZ); org.torproject.onionoo.docs.SummaryDocument relayFerrari458 = @@ -159,7 +159,7 @@ public class ResourceServletTest { "000C5F55BD4814B917CC474BD537F1A3B33CCE2A" })), new TreeSet<>(Arrays.asList(new String[] { "000C5F55BD4814B917CC474BD537F1A3B33CCE2A" })), null, - "
c-68-38-171-200.hsd1.in.comcast.net
"); + "
c-68-38-171-200.hsd1.in.comcast.net
", null); this.relays.put("001C13B3A55A71B977CA65EC85539D79C653A3FC", relayFerrari458); org.torproject.onionoo.docs.SummaryDocument relayTimMayTribute = @@ -172,7 +172,8 @@ public class ResourceServletTest { DateTimeHelper.parse("2013-04-16 18:00:00"), "AS6830", "1024d/51e2a1c7 \"steven j. murdoch\" " + "<tor+steven.murdoch(a)cl.cam.ac.uk> <fb-token:5sr_k_zs2wm=>", - new TreeSet<String>(), new TreeSet<String>(), "0.2.3.24-rc-dev", null); + new TreeSet<String>(), new TreeSet<String>(), "0.2.3.24-rc-dev", null, + false); this.relays.put("0025C136C1F3A9EEFE2AE3F918F03BFA21B5070B", relayTimMayTribute); this.bridges = new TreeMap<>(); @@ -183,7 +184,7 @@ public class ResourceServletTest { DateTimeHelper.parse("2013-04-21 18:07:03"), false, new TreeSet<>(Arrays.asList(new String[] { "Valid" })), -1L, null, DateTimeHelper.parse("2013-04-20 15:37:04"), null, null, - null, null, "0.2.2.39", null); + null, null, "0.2.2.39", null, true); this.bridges.put("0000831B236DFF73D409AD17B40E2A728A53994F", bridgeec2bridgercc7f31fe); org.torproject.onionoo.docs.SummaryDocument bridgeUnnamed = @@ -193,7 +194,7 @@ public class ResourceServletTest { DateTimeHelper.parse("2013-04-20 17:37:04"), false, new TreeSet<>(Arrays.asList(new String[] { "Valid" })), -1L, null, DateTimeHelper.parse("2013-04-14 07:07:05"), null, null, - null, null, null, null); + null, null, null, null, null); this.bridges.put("0002D9BDBBC230BD9C78FF502A16E0033EF87E0C", bridgeUnnamed); org.torproject.onionoo.docs.SummaryDocument bridgegummy = @@ -204,7 +205,7 @@ public class ResourceServletTest { new TreeSet<>(Arrays.asList(new String[] { "Running", "Valid" })), -1L, null, DateTimeHelper.parse("2013-01-16 21:07:04"), null, null, null, - null, "0.2.4.4-alpha-dev", null); + null, "0.2.4.4-alpha-dev", null, false); this.bridges.put("1FEDE50ED8DBA1DD9F9165F78C8131E4A44AB756", bridgegummy); } @@ -1695,5 +1696,28 @@ public class ResourceServletTest { public void testHostNameUmlaut() { this.assertErrorStatusCode("/summary?host_name=äöü", 400); } + + @Test + public void testRecommendedVersionTrue() { + this.assertSummaryDocument("/summary?recommended_version=true", 1, + new String[] { "TorkaZ" }, 1, new String[] { "ec2bridgercc7f31fe" }); + } + + @Test + public void testRecommendedVersionFalse() { + this.assertSummaryDocument("/summary?recommended_version=false", 1, + new String[] { "TimMayTribute" }, 1, new String[] { "gummy" }); + } + + @Test + public void testRecommendedVersionTrueCapitalized() { + this.assertSummaryDocument("/summary?recommended_version=TRUE", 1, + new String[] { "TorkaZ" }, 1,new String[] { "ec2bridgercc7f31fe" }); + } + + @Test + public void testRecommendedVersionNull() { + this.assertErrorStatusCode("/summary?recommended_version=null", 400); + } } diff --git a/src/test/java/org/torproject/onionoo/server/SummaryDocumentComparatorTest.java b/src/test/java/org/torproject/onionoo/server/SummaryDocumentComparatorTest.java index 38d94fa..6820372 100644 --- a/src/test/java/org/torproject/onionoo/server/SummaryDocumentComparatorTest.java +++ b/src/test/java/org/torproject/onionoo/server/SummaryDocumentComparatorTest.java @@ -41,7 +41,7 @@ public class SummaryDocumentComparatorTest { "0025C136C1F3A9EEFE2AE3F918F03BFA21B5070B" })), new TreeSet<>(Arrays.asList( new String[] { "001C13B3A55A71B977CA65EC85539D79C653A3FC" })), null, - null); + null, null); } /** Some values for running all comparison types. */
[View Less]
1
0
0
0
[onionoo/release] Extend "version" parameter to bridges.
by karsten@torproject.org
28 Nov '17
28 Nov '17
commit 919d5ff967ecaa401b8a0a91885fbe7b84c9807c Author: Karsten Loesing <karsten.loesing(a)gmx.net> Date: Sat Nov 18 17:35:30 2017 +0100 Extend "version" parameter to bridges. Extend the "version" parameter to also return bridges with the given version or version prefix. Implements #23962. --- CHANGELOG.md | 2 ++ .../org/torproject/onionoo/server/NodeIndex.java | 10 ++++++++ .../org/torproject/onionoo/server/
…
[View More]
NodeIndexer.java | 10 ++++++++ .../torproject/onionoo/server/RequestHandler.java | 9 ++++++- .../onionoo/server/ResourceServletTest.java | 29 +++++++++++++--------- 5 files changed, 47 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3adcdd4..918a1ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ software version listed in the consensus and similarly to bridge details documents with the Tor software version found in the server descriptor. + - Extend the "version" parameter to also return bridges with the + given version or version prefix. # Changes in version 4.3-1.7.1 - 2017-11-17 diff --git a/src/main/java/org/torproject/onionoo/server/NodeIndex.java b/src/main/java/org/torproject/onionoo/server/NodeIndex.java index 126cd5c..c41dd7a 100644 --- a/src/main/java/org/torproject/onionoo/server/NodeIndex.java +++ b/src/main/java/org/torproject/onionoo/server/NodeIndex.java @@ -180,6 +180,16 @@ class NodeIndex { return this.relaysByVersion; } + private Map<String, Set<String>> bridgesByVersion; + + public void setBridgesByVersion(Map<String, Set<String>> bridgesByVersion) { + this.bridgesByVersion = bridgesByVersion; + } + + public Map<String, Set<String>> getBridgesByVersion() { + return this.bridgesByVersion; + } + private Map<String, Set<String>> relaysByHostName; public void setRelaysByHostName(Map<String, Set<String>> relaysByHostName) { diff --git a/src/main/java/org/torproject/onionoo/server/NodeIndexer.java b/src/main/java/org/torproject/onionoo/server/NodeIndexer.java index d609f63..585d33f 100644 --- a/src/main/java/org/torproject/onionoo/server/NodeIndexer.java +++ b/src/main/java/org/torproject/onionoo/server/NodeIndexer.java @@ -154,6 +154,7 @@ public class NodeIndexer implements ServletContextListener, Runnable { Map<String, Set<String>> newRelaysByContact = new HashMap<>(); Map<String, Set<String>> newRelaysByFamily = new HashMap<>(); Map<String, Set<String>> newRelaysByVersion = new HashMap<>(); + Map<String, Set<String>> newBridgesByVersion = new HashMap<>(); Map<String, Set<String>> newRelaysByHostName = new HashMap<>(); SortedMap<Integer, Set<String>> newRelaysByFirstSeenDays = new TreeMap<>(); SortedMap<Integer, Set<String>> newBridgesByFirstSeenDays = new TreeMap<>(); @@ -323,6 +324,14 @@ public class NodeIndexer implements ServletContextListener, Runnable { hashedFingerprint); newBridgesByLastSeenDays.get(daysSinceLastSeen).add( hashedHashedFingerprint); + String version = entry.getVersion(); + if (null != version) { + if (!newBridgesByVersion.containsKey(version)) { + newBridgesByVersion.put(version, new HashSet<>()); + } + newBridgesByVersion.get(version).add(hashedFingerprint); + newBridgesByVersion.get(version).add(hashedHashedFingerprint); + } } NodeIndex newNodeIndex = new NodeIndex(); newNodeIndex.setRelayFingerprintSummaryLines( @@ -342,6 +351,7 @@ public class NodeIndexer implements ServletContextListener, Runnable { newNodeIndex.setRelaysPublishedMillis(relaysLastValidAfterMillis); newNodeIndex.setBridgesPublishedMillis(bridgesLastPublishedMillis); newNodeIndex.setRelaysByVersion(newRelaysByVersion); + newNodeIndex.setBridgesByVersion(newBridgesByVersion); newNodeIndex.setRelaysByHostName(newRelaysByHostName); synchronized (this) { this.lastIndexed = updateStatusMillis; diff --git a/src/main/java/org/torproject/onionoo/server/RequestHandler.java b/src/main/java/org/torproject/onionoo/server/RequestHandler.java index 23af60b..067a738 100644 --- a/src/main/java/org/torproject/onionoo/server/RequestHandler.java +++ b/src/main/java/org/torproject/onionoo/server/RequestHandler.java @@ -541,7 +541,14 @@ public class RequestHandler { } } this.filteredRelays.keySet().retainAll(keepRelays); - this.filteredBridges.clear(); + Set<String> keepBridges = new HashSet<>(); + for (Map.Entry<String, Set<String>> e + : this.nodeIndex.getBridgesByVersion().entrySet()) { + if (e.getKey().startsWith(this.version)) { + keepBridges.addAll(e.getValue()); + } + } + this.filteredBridges.keySet().retainAll(keepBridges); } private void filterByHostName() { diff --git a/src/test/java/org/torproject/onionoo/server/ResourceServletTest.java b/src/test/java/org/torproject/onionoo/server/ResourceServletTest.java index 2720f7a..d763988 100644 --- a/src/test/java/org/torproject/onionoo/server/ResourceServletTest.java +++ b/src/test/java/org/torproject/onionoo/server/ResourceServletTest.java @@ -129,6 +129,7 @@ public class ResourceServletTest { @SuppressWarnings("JavadocMethod") @Before public void createSampleRelaysAndBridges() { + this.relays = new TreeMap<>(); org.torproject.onionoo.docs.SummaryDocument relayTorkaZ = new org.torproject.onionoo.docs.SummaryDocument(true, "TorkaZ", "000C5F55BD4814B917CC474BD537F1A3B33CCE2A", Arrays.asList( @@ -144,6 +145,8 @@ public class ResourceServletTest { new TreeSet<>(Arrays.asList( new String[] { "001C13B3A55A71B977CA65EC85539D79C653A3FC" })), "0.2.3.25", "ppp-62-216-201-221.dynamic.mnet-online.de"); + this.relays.put("000C5F55BD4814B917CC474BD537F1A3B33CCE2A", + relayTorkaZ); org.torproject.onionoo.docs.SummaryDocument relayFerrari458 = new org.torproject.onionoo.docs.SummaryDocument(true, "Ferrari458", "001C13B3A55A71B977CA65EC85539D79C653A3FC", Arrays.asList( @@ -157,9 +160,6 @@ public class ResourceServletTest { new TreeSet<>(Arrays.asList(new String[] { "000C5F55BD4814B917CC474BD537F1A3B33CCE2A" })), null, "
c-68-38-171-200.hsd1.in.comcast.net
"); - this.relays = new TreeMap<>(); - this.relays.put("000C5F55BD4814B917CC474BD537F1A3B33CCE2A", - relayTorkaZ); this.relays.put("001C13B3A55A71B977CA65EC85539D79C653A3FC", relayFerrari458); org.torproject.onionoo.docs.SummaryDocument relayTimMayTribute = @@ -172,7 +172,7 @@ public class ResourceServletTest { DateTimeHelper.parse("2013-04-16 18:00:00"), "AS6830", "1024d/51e2a1c7 \"steven j. murdoch\" " + "<tor+steven.murdoch(a)cl.cam.ac.uk> <fb-token:5sr_k_zs2wm=>", - new TreeSet<String>(), new TreeSet<String>(), "0.2.3.25", null); + new TreeSet<String>(), new TreeSet<String>(), "0.2.3.24-rc-dev", null); this.relays.put("0025C136C1F3A9EEFE2AE3F918F03BFA21B5070B", relayTimMayTribute); this.bridges = new TreeMap<>(); @@ -183,7 +183,7 @@ public class ResourceServletTest { DateTimeHelper.parse("2013-04-21 18:07:03"), false, new TreeSet<>(Arrays.asList(new String[] { "Valid" })), -1L, null, DateTimeHelper.parse("2013-04-20 15:37:04"), null, null, - null, null, null, null); + null, null, "0.2.2.39", null); this.bridges.put("0000831B236DFF73D409AD17B40E2A728A53994F", bridgeec2bridgercc7f31fe); org.torproject.onionoo.docs.SummaryDocument bridgeUnnamed = @@ -204,7 +204,7 @@ public class ResourceServletTest { new TreeSet<>(Arrays.asList(new String[] { "Running", "Valid" })), -1L, null, DateTimeHelper.parse("2013-01-16 21:07:04"), null, null, null, - null, null, null); + null, "0.2.4.4-alpha-dev", null); this.bridges.put("1FEDE50ED8DBA1DD9F9165F78C8131E4A44AB756", bridgegummy); } @@ -1571,14 +1571,19 @@ public class ResourceServletTest { @Test public void testVersion02325() { - this.assertSummaryDocument("/summary?version=0.2.3.25", 2, - new String[] { "TorkaZ", "TimMayTribute" }, 0, null); + this.assertSummaryDocument("/summary?version=0.2.3.25", 1, + new String[] { "TorkaZ" }, 0, null); } @Test public void testVersion02324() { - this.assertSummaryDocument("/summary?version=0.2.3.24-rc-dev", 0, - new String[] { "Ferrari458" }, 0, null); + this.assertSummaryDocument("/summary?version=0.2.3.24-rc-dev", 1, + new String[] { "TimMayTribute" }, 0, null); + } + + @Test + public void testVersion02326() { + this.assertSummaryDocument("/summary?version=0.2.3.26", 0, null, 0, null); } @Test @@ -1594,12 +1599,12 @@ public class ResourceServletTest { @Test public void testVersion0() { - this.assertSummaryDocument("/summary?version=0", 2, null, 0, null); + this.assertSummaryDocument("/summary?version=0", 2, null, 2, null); } @Test public void testVersion02() { - this.assertSummaryDocument("/summary?version=0.2", 2, null, 0, null); + this.assertSummaryDocument("/summary?version=0.2", 2, null, 2, null); } @Test
[View Less]
1
0
0
0
[onionoo/release] Add "recommended_version" field to bridge details documents.
by karsten@torproject.org
28 Nov '17
28 Nov '17
commit edc796cd890fdc656947dd11c6832a5d99ee0ae6 Author: Karsten Loesing <karsten.loesing(a)gmx.net> Date: Sat Nov 18 17:37:46 2017 +0100 Add "recommended_version" field to bridge details documents. Add a "recommended_version" field to bridge details documents based on whether the directory authorities recommend the bridge's version. Implements #21827. --- CHANGELOG.md | 3 +++ .../onionoo/updater/NodeDetailsStatusUpdater.
…
[View More]
java | 24 ++++++++++++---------- .../onionoo/writer/DetailsDocumentWriter.java | 2 ++ 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 918a1ae..5a84259 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ server descriptor. - Extend the "version" parameter to also return bridges with the given version or version prefix. + - Add a "recommended_version" field to bridge details documents + based on whether the directory authorities recommend the bridge's + version. # Changes in version 4.3-1.7.1 - 2017-11-17 diff --git a/src/main/java/org/torproject/onionoo/updater/NodeDetailsStatusUpdater.java b/src/main/java/org/torproject/onionoo/updater/NodeDetailsStatusUpdater.java index 7792764..0a5a93d 100644 --- a/src/main/java/org/torproject/onionoo/updater/NodeDetailsStatusUpdater.java +++ b/src/main/java/org/torproject/onionoo/updater/NodeDetailsStatusUpdater.java @@ -89,6 +89,8 @@ public class NodeDetailsStatusUpdater implements DescriptorListener, private SortedMap<String, Integer> lastBandwidthWeights = null; + private Set<String> lastRecommendedServerVersions = null; + private int relayConsensusesProcessed = 0; private int bridgeStatusesProcessed = 0; @@ -248,14 +250,6 @@ public class NodeDetailsStatusUpdater implements DescriptorListener, if (validAfterMillis > this.relaysLastValidAfterMillis) { this.relaysLastValidAfterMillis = validAfterMillis; } - Set<String> recommendedVersions = null; - if (consensus.getRecommendedServerVersions() != null) { - recommendedVersions = new HashSet<>(); - for (String recommendedVersion : - consensus.getRecommendedServerVersions()) { - recommendedVersions.add("Tor " + recommendedVersion); - } - } for (Map.Entry<String, NetworkStatusEntry> e : consensus.getStatusEntries().entrySet()) { String fingerprint = e.getKey(); @@ -288,9 +282,6 @@ public class NodeDetailsStatusUpdater implements DescriptorListener, nodeStatus.setConsensusWeight(entry.getBandwidth()); nodeStatus.setDefaultPolicy(entry.getDefaultPolicy()); nodeStatus.setPortList(entry.getPortList()); - nodeStatus.setRecommendedVersion((recommendedVersions == null - || entry.getVersion() == null) ? null : - recommendedVersions.contains(entry.getVersion())); String version = null; if (null != entry.getVersion() && entry.getVersion().startsWith("Tor ")) { @@ -315,6 +306,8 @@ public class NodeDetailsStatusUpdater implements DescriptorListener, this.relayConsensusesProcessed++; if (this.relaysLastValidAfterMillis == validAfterMillis) { this.lastBandwidthWeights = consensus.getBandwidthWeights(); + this.lastRecommendedServerVersions + = new HashSet<>(consensus.getRecommendedServerVersions()); } } @@ -800,6 +793,15 @@ public class NodeDetailsStatusUpdater implements DescriptorListener, nodeStatus.setVersion(version); } + /* Compare tor software version (for relays and bridges) with the + * recommended-server-versions line in the last known consensus and set + * the recommended_version field accordingly. */ + if (null != this.lastRecommendedServerVersions + && null != nodeStatus.getVersion()) { + nodeStatus.setRecommendedVersion(this.lastRecommendedServerVersions + .contains(nodeStatus.getVersion())); + } + Map<String, Long> exitAddresses = new HashMap<>(); if (detailsStatus.getExitAddresses() != null) { for (Map.Entry<String, Long> e : diff --git a/src/main/java/org/torproject/onionoo/writer/DetailsDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/DetailsDocumentWriter.java index 5eaa950..1b53ffe 100644 --- a/src/main/java/org/torproject/onionoo/writer/DetailsDocumentWriter.java +++ b/src/main/java/org/torproject/onionoo/writer/DetailsDocumentWriter.java @@ -189,6 +189,8 @@ public class DetailsDocumentWriter implements DocumentWriter { detailsDocument.setFirstSeen(detailsStatus.getFirstSeenMillis()); detailsDocument.setRunning(detailsStatus.isRunning()); detailsDocument.setFlags(detailsStatus.getRelayFlags()); + detailsDocument.setRecommendedVersion( + detailsStatus.getRecommendedVersion()); detailsDocument.setLastRestarted(detailsStatus.getLastRestarted()); detailsDocument.setAdvertisedBandwidth( detailsStatus.getAdvertisedBandwidth());
[View Less]
1
0
0
0
[onionoo/master] Prepare for 4.4-1.8.0 release.
by karsten@torproject.org
28 Nov '17
28 Nov '17
commit 25021a871499dca8f7b78766fb2d07a0dab73ca8 Author: Karsten Loesing <karsten.loesing(a)gmx.net> Date: Tue Nov 28 14:00:24 2017 +0100 Prepare for 4.4-1.8.0 release. --- CHANGELOG.md | 2 +- build.xml | 4 ++-- src/main/java/org/torproject/onionoo/server/ResponseBuilder.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md
…
[View More]
index 8acdc0b..067d5bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# Changes in version 4.4-1.8.0 - 2017-??-?? +# Changes in version 4.4-1.8.0 - 2017-11-28 * Medium changes - Add a "version" field to relay details documents with the Tor diff --git a/build.xml b/build.xml index 45e09dc..76a4bf2 100644 --- a/build.xml +++ b/build.xml @@ -8,9 +8,9 @@ <property name="javadoc-title" value="Onionoo API Documentation"/> <property name="implementation-title" value="Onionoo" /> - <property name="onionoo.protocol.version" value="4.3"/> + <property name="onionoo.protocol.version" value="4.4"/> <property name="release.version" - value="${onionoo.protocol.version}-1.7.1-dev"/> + value="${onionoo.protocol.version}-1.8.0"/> <property name="metricslibversion" value="2.1.1"/> <property name="jetty.version" value="-9.2.21.v20170120" /> <property name="warfile" diff --git a/src/main/java/org/torproject/onionoo/server/ResponseBuilder.java b/src/main/java/org/torproject/onionoo/server/ResponseBuilder.java index a83234b..160b681 100644 --- a/src/main/java/org/torproject/onionoo/server/ResponseBuilder.java +++ b/src/main/java/org/torproject/onionoo/server/ResponseBuilder.java @@ -123,7 +123,7 @@ public class ResponseBuilder { return this.charsWritten; } - private static final String PROTOCOL_VERSION = "4.3"; + private static final String PROTOCOL_VERSION = "4.4"; private static final String NEXT_MAJOR_VERSION_SCHEDULED = "2017-12-17";
[View Less]
1
0
0
0
[translation/tails-greeter-2] Update translations for tails-greeter-2
by translation@torproject.org
28 Nov '17
28 Nov '17
commit d8ccae585f3ebc7c70bad212130e399d849ffc2a Author: Translation commit bot <translation(a)torproject.org> Date: Tue Nov 28 12:20:38 2017 +0000 Update translations for tails-greeter-2 --- bn/bn.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bn/bn.po b/bn/bn.po index 849ef616f..314105392 100644 --- a/bn/bn.po +++ b/bn/bn.po @@ -10,7 +10,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-09-15 21:21+0200\n" "PO-Revision-Date: YEAR-MO-
…
[View More]
DA HO:MI+ZONE\n" -"Last-Translator: Aftabuzzaman ullah <Leemon432(a)gmail.com>, 2016\n" +"Last-Translator: lisa hayat <lisahayat(a)gmail.com>, 2017\n" "Language-Team: Bengali (
https://www.transifex.com/otf/teams/1519/bn/)\n
" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -35,7 +35,7 @@ msgstr "" #: ../data/greeter.ui.h:4 msgid "Confirm" -msgstr "" +msgstr "নিশ্চিত করা" #: ../data/greeter.ui.h:5 msgid "Confirm your administration password"
[View Less]
1
0
0
0
[translation/tails-perl5lib] Update translations for tails-perl5lib
by translation@torproject.org
28 Nov '17
28 Nov '17
commit cbf1257f0cc7aed3cfefaec690c1f907adf6372f Author: Translation commit bot <translation(a)torproject.org> Date: Tue Nov 28 12:18:11 2017 +0000 Update translations for tails-perl5lib --- bn.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bn.po b/bn.po index 3c40639e5..24061239c 100644 --- a/bn.po +++ b/bn.po @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: Tails developers <tails(a)boum.org>\n" "POT-
…
[View More]
Creation-Date: 2017-05-20 10:59+0200\n" -"PO-Revision-Date: 2017-09-19 22:59+0000\n" +"PO-Revision-Date: 2017-11-28 12:13+0000\n" "Last-Translator: carolyn <carolyn(a)anhalt.org>\n" "Language-Team: Bengali (
http://www.transifex.com/otf/torproject/language/bn/)\n
" "MIME-Version: 1.0\n"
[View Less]
1
0
0
0
[translation/tails-misc] Update translations for tails-misc
by translation@torproject.org
28 Nov '17
28 Nov '17
commit 498c5ded389293a6f788c31c0bad951a3ea8988f Author: Translation commit bot <translation(a)torproject.org> Date: Tue Nov 28 12:17:13 2017 +0000 Update translations for tails-misc --- bn.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bn.po b/bn.po index 079a62fc6..f5d630a2f 100644 --- a/bn.po +++ b/bn.po @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-09-13 20:10+0200\n" -"PO-
…
[View More]
Revision-Date: 2017-10-16 10:44+0000\n" +"PO-Revision-Date: 2017-11-28 12:13+0000\n" "Last-Translator: carolyn <carolyn(a)anhalt.org>\n" "Language-Team: Bengali (
http://www.transifex.com/otf/torproject/language/bn/)\n
" "MIME-Version: 1.0\n"
[View Less]
1
0
0
0
[translation/tails-persistence-setup] Update translations for tails-persistence-setup
by translation@torproject.org
28 Nov '17
28 Nov '17
commit bb270c350361ac9030672e2844ba7159085b9239 Author: Translation commit bot <translation(a)torproject.org> Date: Tue Nov 28 12:16:10 2017 +0000 Update translations for tails-persistence-setup --- bn/bn.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bn/bn.po b/bn/bn.po index f5a1f4f38..4d99dde22 100644 --- a/bn/bn.po +++ b/bn/bn.po @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: Tails developers <tails(a)boum.
…
[View More]
org>\n" "POT-Creation-Date: 2017-05-15 13:51+0200\n" -"PO-Revision-Date: 2017-10-16 10:43+0000\n" +"PO-Revision-Date: 2017-11-28 12:13+0000\n" "Last-Translator: carolyn <carolyn(a)anhalt.org>\n" "Language-Team: Bengali (
http://www.transifex.com/otf/torproject/language/bn/)\n
" "MIME-Version: 1.0\n"
[View Less]
1
0
0
0
[translation/whisperback_completed] Update translations for whisperback_completed
by translation@torproject.org
28 Nov '17
28 Nov '17
commit 3ae72f0fc7b12a6ac7f6507a26394defa5d51028 Author: Translation commit bot <translation(a)torproject.org> Date: Tue Nov 28 12:15:33 2017 +0000 Update translations for whisperback_completed --- nl/nl.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nl/nl.po b/nl/nl.po index aebbfba94..1e2a6160b 100644 --- a/nl/nl.po +++ b/nl/nl.po @@ -18,7 +18,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-03-
…
[View More]
20 12:09+0000\n" -"PO-Revision-Date: 2017-11-26 13:03+0000\n" +"PO-Revision-Date: 2017-11-28 11:58+0000\n" "Last-Translator: kwadronaut <kwadronaut(a)autistici.org>\n" "Language-Team: Dutch (
http://www.transifex.com/otf/torproject/language/nl/)\n
" "MIME-Version: 1.0\n"
[View Less]
1
0
0
0
[translation/whisperback] Update translations for whisperback
by translation@torproject.org
28 Nov '17
28 Nov '17
commit a481275c5e07f947e49dcb0927a2fabc60cb8ac8 Author: Translation commit bot <translation(a)torproject.org> Date: Tue Nov 28 12:15:25 2017 +0000 Update translations for whisperback --- nl/nl.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nl/nl.po b/nl/nl.po index aebbfba94..1e2a6160b 100644 --- a/nl/nl.po +++ b/nl/nl.po @@ -18,7 +18,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-03-20 12:09+
…
[View More]
0000\n" -"PO-Revision-Date: 2017-11-26 13:03+0000\n" +"PO-Revision-Date: 2017-11-28 11:58+0000\n" "Last-Translator: kwadronaut <kwadronaut(a)autistici.org>\n" "Language-Team: Dutch (
http://www.transifex.com/otf/torproject/language/nl/)\n
" "MIME-Version: 1.0\n"
[View Less]
1
0
0
0
← Newer
1
...
7
8
9
10
11
12
13
...
202
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
Results per page:
10
25
50
100
200