[tor-commits] [onionoo/master] Support IPv6 addresses in summary, details, and search.
karsten at torproject.org
karsten at torproject.org
Fri Jun 15 12:54:26 UTC 2012
commit 74124548ee325d2689c2d25142f15b7572cb623a
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date: Fri Jun 15 14:50:52 2012 +0200
Support IPv6 addresses in summary, details, and search.
Implements #5245.
---
src/org/torproject/onionoo/CurrentNodes.java | 71 +++++++++++++++-------
src/org/torproject/onionoo/DetailDataWriter.java | 29 ++++++++-
src/org/torproject/onionoo/Node.java | 34 ++++++++++-
src/org/torproject/onionoo/ResourceServlet.java | 5 +-
4 files changed, 110 insertions(+), 29 deletions(-)
diff --git a/src/org/torproject/onionoo/CurrentNodes.java b/src/org/torproject/onionoo/CurrentNodes.java
index c6b4d8a..4da7133 100644
--- a/src/org/torproject/onionoo/CurrentNodes.java
+++ b/src/org/torproject/onionoo/CurrentNodes.java
@@ -62,6 +62,7 @@ public class CurrentNodes {
String fingerprint = parts[2];
String addresses = parts[3];
String address;
+ SortedSet<String> orAddressesAndPorts = new TreeSet<String>();
SortedSet<String> exitAddresses = new TreeSet<String>();
if (addresses.contains(";")) {
String[] addressParts = addresses.split(";", -1);
@@ -72,6 +73,10 @@ public class CurrentNodes {
System.exit(1);
}
address = addressParts[0];
+ if (addressParts[1].length() > 0) {
+ orAddressesAndPorts.addAll(Arrays.asList(
+ addressParts[1].split("\\+")));
+ }
if (addressParts[2].length() > 0) {
exitAddresses.addAll(Arrays.asList(
addressParts[2].split("\\+")));
@@ -94,11 +99,13 @@ public class CurrentNodes {
countryCode = parts[10];
}
if (isRelay) {
- this.addRelay(nickname, fingerprint, address, exitAddresses,
+ this.addRelay(nickname, fingerprint, address,
+ orAddressesAndPorts, exitAddresses,
publishedOrValidAfterMillis, orPort, dirPort, relayFlags,
consensusWeight, countryCode);
} else {
- this.addBridge(nickname, fingerprint, address, exitAddresses,
+ this.addBridge(nickname, fingerprint, address,
+ orAddressesAndPorts, exitAddresses,
publishedOrValidAfterMillis, orPort, dirPort, relayFlags,
consensusWeight, countryCode);
}
@@ -134,8 +141,14 @@ public class CurrentNodes {
String fingerprint = entry.getFingerprint();
String address = entry.getAddress();
StringBuilder addressesBuilder = new StringBuilder();
- addressesBuilder.append(address + ";;");
+ addressesBuilder.append(address + ";");
int written = 0;
+ for (String orAddressAndPort : entry.getOrAddressesAndPorts()) {
+ addressesBuilder.append((written++ > 0 ? "+" : "") +
+ orAddressAndPort);
+ }
+ addressesBuilder.append(";");
+ written = 0;
for (String exitAddress : entry.getExitAddresses()) {
addressesBuilder.append((written++ > 0 ? "+" : "")
+ exitAddress);
@@ -164,6 +177,14 @@ public class CurrentNodes {
String published = dateTimeFormat.format(
entry.getLastSeenMillis());
String address = entry.getAddress();
+ StringBuilder addressesBuilder = new StringBuilder();
+ addressesBuilder.append(address + ";");
+ int written = 0;
+ for (String orAddressAndPort : entry.getOrAddressesAndPorts()) {
+ addressesBuilder.append((written++ > 0 ? "+" : "") +
+ orAddressAndPort);
+ }
+ addressesBuilder.append(";");
String orPort = String.valueOf(entry.getOrPort());
String dirPort = String.valueOf(entry.getDirPort());
StringBuilder sb = new StringBuilder();
@@ -171,9 +192,9 @@ public class CurrentNodes {
sb.append("," + relayFlag);
}
String relayFlags = sb.toString().substring(1);
- bw.write("b " + nickname + " " + fingerprint + " " + address
- + ";; " + published + " " + orPort + " " + dirPort + " "
- + relayFlags + " -1 ??\n");
+ bw.write("b " + nickname + " " + fingerprint + " "
+ + addressesBuilder.toString() + " " + published + " " + orPort
+ + " " + dirPort + " " + relayFlags + " -1 ??\n");
}
bw.close();
} catch (IOException e) {
@@ -227,28 +248,30 @@ public class CurrentNodes {
String nickname = entry.getNickname();
String fingerprint = entry.getFingerprint();
String address = entry.getAddress();
+ SortedSet<String> orAddressesAndPorts = new TreeSet<String>(
+ entry.getOrAddresses());
int orPort = entry.getOrPort();
int dirPort = entry.getDirPort();
SortedSet<String> relayFlags = entry.getFlags();
long consensusWeight = entry.getBandwidth();
- this.addRelay(nickname, fingerprint, address, null,
- validAfterMillis, orPort, dirPort, relayFlags, consensusWeight,
- null);
+ this.addRelay(nickname, fingerprint, address, orAddressesAndPorts,
+ null, validAfterMillis, orPort, dirPort, relayFlags,
+ consensusWeight, null);
}
}
public void addRelay(String nickname, String fingerprint,
- String address, SortedSet<String> exitAddresses,
- long validAfterMillis, int orPort, int dirPort,
- SortedSet<String> relayFlags, long consensusWeight,
+ String address, SortedSet<String> orAddressesAndPorts,
+ SortedSet<String> exitAddresses, long validAfterMillis, int orPort,
+ int dirPort, SortedSet<String> relayFlags, long consensusWeight,
String countryCode) {
if (validAfterMillis >= cutoff &&
(!this.currentRelays.containsKey(fingerprint) ||
this.currentRelays.get(fingerprint).getLastSeenMillis() <
validAfterMillis)) {
- Node entry = new Node(nickname, fingerprint, address, exitAddresses,
- validAfterMillis, orPort, dirPort, relayFlags, consensusWeight,
- countryCode);
+ Node entry = new Node(nickname, fingerprint, address,
+ orAddressesAndPorts, exitAddresses, validAfterMillis, orPort,
+ dirPort, relayFlags, consensusWeight, countryCode);
this.currentRelays.put(fingerprint, entry);
if (validAfterMillis > this.lastValidAfterMillis) {
this.lastValidAfterMillis = validAfterMillis;
@@ -339,26 +362,28 @@ public class CurrentNodes {
String nickname = entry.getNickname();
String fingerprint = entry.getFingerprint();
String address = entry.getAddress();
+ SortedSet<String> orAddressesAndPorts = new TreeSet<String>(
+ entry.getOrAddresses());
int orPort = entry.getOrPort();
int dirPort = entry.getDirPort();
SortedSet<String> relayFlags = entry.getFlags();
- this.addBridge(nickname, fingerprint, address, null,
- publishedMillis, orPort, dirPort, relayFlags, -1, "??");
+ this.addBridge(nickname, fingerprint, address, orAddressesAndPorts,
+ null, publishedMillis, orPort, dirPort, relayFlags, -1, "??");
}
}
public void addBridge(String nickname, String fingerprint,
- String address, SortedSet<String> exitAddresses,
- long publishedMillis, int orPort, int dirPort,
- SortedSet<String> relayFlags, long consensusWeight,
+ String address, SortedSet<String> orAddressesAndPorts,
+ SortedSet<String> exitAddresses, long publishedMillis, int orPort,
+ int dirPort, SortedSet<String> relayFlags, long consensusWeight,
String countryCode) {
if (publishedMillis >= cutoff &&
(!this.currentBridges.containsKey(fingerprint) ||
this.currentBridges.get(fingerprint).getLastSeenMillis() <
publishedMillis)) {
- Node entry = new Node(nickname, fingerprint, address, exitAddresses,
- publishedMillis, orPort, dirPort, relayFlags, consensusWeight,
- countryCode);
+ Node entry = new Node(nickname, fingerprint, address,
+ orAddressesAndPorts, exitAddresses, publishedMillis, orPort,
+ dirPort, relayFlags, consensusWeight, countryCode);
this.currentBridges.put(fingerprint, entry);
if (publishedMillis > this.lastPublishedMillis) {
this.lastPublishedMillis = publishedMillis;
diff --git a/src/org/torproject/onionoo/DetailDataWriter.java b/src/org/torproject/onionoo/DetailDataWriter.java
index cb4ebe6..6a724d8 100644
--- a/src/org/torproject/onionoo/DetailDataWriter.java
+++ b/src/org/torproject/onionoo/DetailDataWriter.java
@@ -19,6 +19,7 @@ import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TimeZone;
import java.util.TreeMap;
+import java.util.TreeSet;
import org.apache.commons.lang.StringEscapeUtils;
@@ -309,8 +310,17 @@ public class DetailDataWriter {
Node entry = relay.getValue();
String nickname = entry.getNickname();
String address = entry.getAddress();
+ SortedSet<String> orAddresses = new TreeSet<String>(
+ entry.getOrAddressesAndPorts());
+ orAddresses.add(address + ":" + entry.getOrPort());
+ StringBuilder orAddressesAndPortsBuilder = new StringBuilder();
+ int addressesWritten = 0;
+ for (String orAddress : orAddresses) {
+ orAddressesAndPortsBuilder.append(
+ (addressesWritten++ > 0 ? "," : "") + "\"" + orAddress
+ + "\"");
+ }
String running = entry.getRunning() ? "true" : "false";
- int orPort = entry.getOrPort();
int dirPort = entry.getDirPort();
String countryCode = entry.getCountryCode();
String latitude = entry.getLatitude();
@@ -325,7 +335,8 @@ public class DetailDataWriter {
sb.append("{\"version\":1,\n"
+ "\"nickname\":\"" + nickname + "\",\n"
+ "\"fingerprint\":\"" + fingerprint + "\",\n"
- + "\"or_addresses\":[\"" + address + ":" + orPort + "\"],\n"
+ + "\"or_addresses\":[" + orAddressesAndPortsBuilder.toString()
+ + "],\n"
+ "\"dir_address\":\"" + address + ":" + dirPort + "\",\n"
+ "\"running\":" + running + ",\n");
SortedSet<String> relayFlags = entry.getRelayFlags();
@@ -512,12 +523,22 @@ public class DetailDataWriter {
String nickname = entry.getNickname();
String running = entry.getRunning() ? "true" : "false";
String address = entry.getAddress();
- int orPort = entry.getOrPort();
+ SortedSet<String> orAddresses = new TreeSet<String>(
+ entry.getOrAddressesAndPorts());
+ orAddresses.add(address + ":" + entry.getOrPort());
+ StringBuilder orAddressesAndPortsBuilder = new StringBuilder();
+ int addressesWritten = 0;
+ for (String orAddress : orAddresses) {
+ orAddressesAndPortsBuilder.append(
+ (addressesWritten++ > 0 ? "," : "") + "\"" + orAddress
+ + "\"");
+ }
StringBuilder sb = new StringBuilder();
sb.append("{\"version\":1,\n"
+ "\"nickname\":\"" + nickname + "\",\n"
+ "\"hashed_fingerprint\":\"" + fingerprint + "\",\n"
- + "\"or_addresses\":[\"" + address + ":" + orPort + "\"],\n"
+ + "\"or_addresses\":[" + orAddressesAndPortsBuilder.toString()
+ + "],\n"
+ "\"running\":" + running + ",");
SortedSet<String> relayFlags = entry.getRelayFlags();
if (!relayFlags.isEmpty()) {
diff --git a/src/org/torproject/onionoo/Node.java b/src/org/torproject/onionoo/Node.java
index f4e5e67..0bb4a23 100644
--- a/src/org/torproject/onionoo/Node.java
+++ b/src/org/torproject/onionoo/Node.java
@@ -16,6 +16,8 @@ public class Node {
private String hashedFingerprint;
private String nickname;
private String address;
+ private SortedSet<String> orAddresses;
+ private SortedSet<String> orAddressesAndPorts;
private SortedSet<String> exitAddresses;
private String latitude;
private String longitude;
@@ -32,6 +34,7 @@ public class Node {
private long consensusWeight;
private boolean running;
public Node(String nickname, String fingerprint, String address,
+ SortedSet<String> orAddressesAndPorts,
SortedSet<String> exitAddresses, long lastSeenMillis, int orPort,
int dirPort, SortedSet<String> relayFlags, long consensusWeight,
String countryCode) {
@@ -50,6 +53,13 @@ public class Node {
this.exitAddresses.addAll(exitAddresses);
}
this.exitAddresses.remove(this.address);
+ this.orAddresses = new TreeSet<String>();
+ this.orAddressesAndPorts = new TreeSet<String>();
+ if (orAddressesAndPorts != null) {
+ for (String orAddressAndPort : orAddressesAndPorts) {
+ this.addOrAddressAndPort(orAddressAndPort);
+ }
+ }
this.lastSeenMillis = lastSeenMillis;
this.orPort = orPort;
this.dirPort = dirPort;
@@ -69,8 +79,30 @@ public class Node {
public String getAddress() {
return this.address;
}
+ public SortedSet<String> getOrAddresses() {
+ return new TreeSet<String>(this.orAddresses);
+ }
+ public void addOrAddressAndPort(String orAddressAndPort) {
+ if (!orAddressAndPort.contains(":")) {
+ System.err.println("Illegal OR address:port '" + orAddressAndPort
+ + "'. Exiting.");
+ System.exit(1);
+ } else if (orAddressAndPort.length() > 0) {
+ String orAddress = orAddressAndPort.substring(0,
+ orAddressAndPort.lastIndexOf(":"));
+ if (this.exitAddresses.contains(orAddress)) {
+ this.exitAddresses.remove(orAddress);
+ }
+ this.orAddresses.add(orAddress);
+ this.orAddressesAndPorts.add(orAddressAndPort);
+ }
+ }
+ public SortedSet<String> getOrAddressesAndPorts() {
+ return new TreeSet<String>(this.orAddressesAndPorts);
+ }
public void addExitAddress(String exitAddress) {
- if (exitAddress.length() > 0 && !this.address.equals(exitAddress)) {
+ if (exitAddress.length() > 0 && !this.address.equals(exitAddress) &&
+ !this.orAddresses.contains(exitAddress)) {
this.exitAddresses.add(exitAddress);
}
}
diff --git a/src/org/torproject/onionoo/ResourceServlet.java b/src/org/torproject/onionoo/ResourceServlet.java
index 7ddd148..41f4c5a 100644
--- a/src/org/torproject/onionoo/ResourceServlet.java
+++ b/src/org/torproject/onionoo/ResourceServlet.java
@@ -118,6 +118,7 @@ public class ResourceServlet extends HttpServlet {
String running = entry.getRunning() ? "true" : "false";
SortedSet<String> addresses = new TreeSet<String>();
addresses.add(entry.getAddress());
+ addresses.addAll(entry.getOrAddresses());
addresses.addAll(entry.getExitAddresses());
StringBuilder addressesBuilder = new StringBuilder();
int written = 0;
@@ -404,7 +405,9 @@ public class ResourceServlet extends HttpServlet {
}
private static Pattern searchParameterPattern =
- Pattern.compile("^\\$?[0-9a-fA-F]{1,40}$|^[0-9a-zA-Z\\.]{1,19}$");
+ Pattern.compile("^\\$?[0-9a-fA-F]{1,40}$|" /* Fingerprint. */
+ + "^[0-9a-zA-Z\\.]{1,19}$|" /* Nickname or IPv4 address. */
+ + "^\\[[0-9a-fA-F:\\.]{1,39}\\]?$"); /* IPv6 address. */
private String parseSearchParameter(String parameter) {
if (!searchParameterPattern.matcher(parameter).matches()) {
return null;
More information about the tor-commits
mailing list