summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/org/noreply/fancydress/type3/PathSpec.java106
1 files changed, 47 insertions, 59 deletions
diff --git a/src/org/noreply/fancydress/type3/PathSpec.java b/src/org/noreply/fancydress/type3/PathSpec.java
index bf5f1b5..a0e5d47 100644
--- a/src/org/noreply/fancydress/type3/PathSpec.java
+++ b/src/org/noreply/fancydress/type3/PathSpec.java
@@ -98,6 +98,15 @@ public class PathSpec {
}
/**
+ * If this path component is a ByNickname component.
+ *
+ * @return true if this path component is a ByNickname component.
+ */
+ public boolean isByNickname() {
+ return (type == TYPE_NICKNAME);
+ }
+
+ /**
* Get a number of hops statisfyi8ng this path component.
*
* @throws Error if this path spec is the crossover point.
@@ -202,20 +211,13 @@ public class PathSpec {
/**
* A class holding a list of Servers and a Crossover point location.
*/
- private class ServerWithCrossover {
+ private class ServerlistWithCrossover {
public Server[] servers;
public int crossoverPoint;
- public Server getLastServer() {
- return (servers[servers.length - 1]);
- }
-
- public void setLastServer(Server s) {
- servers[servers.length - 1] = s;
- }
-
- public Server getSecondToLastServer() {
- return (servers[servers.length - 2]);
+ public ServerlistWithCrossover(Server[] servers, int crossoverPoint) {
+ this.servers = servers;
+ this.crossoverPoint = crossoverPoint;
}
private void fillInRandoms() throws Mix3PathProblemException {
@@ -267,9 +269,11 @@ public class PathSpec {
/**
* Concat path components, getting random amount of hops where requested.
*
- * @return a list of servers and a crossover point as an ServerWithCrossover object.
+ * @param chopOffRandomLast remove the last component if it is a RandomHop Component. // FIXME: understand what the spec says
+ * @param exitHop the exit hop to use.
+ * @return a list of servers and a crossover point as an ServerlistWithCrossover object.
*/
- private ServerWithCrossover concatComponents() throws Mix3PathProblemException {
+ private ServerlistWithCrossover concatComponents(boolean chopOffRandomLast, Server exitHop) throws Mix3PathProblemException {
Server[][] components = new Server[pathComponents.length][];
int length = 0;
int crossoverBefore = -1;
@@ -292,9 +296,13 @@ public class PathSpec {
if (c != length)
throw new Error ("Did not fill in length hops ("+c+" vs "+length+")");
- ServerWithCrossover result = new ServerWithCrossover();
- result.servers = servers;
- result.crossoverPoint = crossoverBefore;
+ if (chopOffRandomLast && servers[servers.length-1] == null) {
+ Server[] newServers = new Server[servers.length-1];
+ System.arraycopy(servers, 0, newServers, 0, servers.length-1);
+ servers = newServers;
+ }
+
+ ServerlistWithCrossover result = new ServerlistWithCrossover(servers, crossoverBefore);
return result;
}
@@ -311,63 +319,43 @@ public class PathSpec {
*
* @param payload the payload
* @return paths constructed from the PathSpec
+ * @throws IllegalArgumentException if this is a single leg path spec.
*/
public Path[] getPath(Payload payload) throws Mix3PathProblemException {
if (singleLeg)
throw new IllegalArgumentException("getPath() may not be called for single leg path specs.");
- ServerWithCrossover[] paths = new ServerWithCrossover[payload.numPackets()];
- for (int i=0; i<paths.length; i++) {
- paths[i] = concatComponents();
- if (paths[i].servers.length < 2)
- throw new Mix3PathProblemException("Path too short.");
- }
-
- Server lastHop = paths[0].getLastServer();
- for (int i=1; i<paths.length; i++)
- if (lastHop != paths[i].getLastServer())
- throw new Mix3PathProblemException("Exit hop must be the same in all paths (random or fixed)");
-
- Server[] possibleExitHops = payload.filterExithops( dir.getRecommendedServers() );
- if (lastHop == null) {
- boolean[] unuseable = new boolean[possibleExitHops.length];
- for (int i=0; i<paths.length; i++) {
- Server stls = paths[i].getSecondToLastServer();
- if (stls == null)
- continue;
- for (int j=0; j<unuseable.length; j++)
- if (unuseable[j])
- continue;
- else
- if (! dir.areFriends(stls, possibleExitHops[j] ))
- unuseable[j] = true;
- }
- ArrayList list = new ArrayList();
- for (int j=0; j<unuseable.length; j++)
- if (! unuseable[j])
- list.add(possibleExitHops[j]);
+ Server[] validExitHops = payload.filterExithops( dir.getRecommendedServers() );
+ Server[] recommendedExitHops = payload.filterExithops( dir.getRecommendedServers() );
+ Server exitHop;
+ boolean randomExitHop = ! pathComponents[pathComponents.length-1].isByNickname();
+ if (! randomExitHop) {
+ exitHop = pathComponents[ pathComponents.length-1 ].getHops()[0];
- if (list.size() == 0)
- throw new Mix3PathProblemException("No useable exit hops found");
-
- lastHop = (Server) list.get( CryptoPrimitives.randInt(list.size()) );
- for (int i=0; i<paths.length; i++)
- paths[i].setLastServer(lastHop);
- } else {
+ /* Check whether exitHop is valid. */
boolean exitHopOK = false;
- for (int j=0; j<possibleExitHops.length; j++)
- if (possibleExitHops[j] == lastHop) {
+ for (int j=0; j<validExitHops.length; j++)
+ if (exitHop == validExitHops[j]) {
exitHopOK = true;
break;
}
if (! exitHopOK)
- throw new Mix3PathProblemException("Exit hop "+lastHop.getNickname()+" does not meet constraints.");
+ throw new Mix3PathProblemException("Exit hop "+exitHop.getNickname()+" does not meet constraints.");
+ } else
+ exitHop = recommendedExitHops[ CryptoPrimitives.randInt(recommendedExitHops.length) ];
+
+
+ ServerlistWithCrossover[] serverlists = new ServerlistWithCrossover[payload.numPackets()];
+ for (int i=0; i<serverlists.length; i++) {
+ serverlists[i] = concatComponents( randomExitHop, exitHop );
+ if (serverlists[i].servers.length < 2)
+ throw new Mix3PathProblemException("Path too short.");
}
- Path[] result = new Path[paths.length];
- for (int i=0; i<paths.length; i++)
- result[i] = paths[i].getPath();
+ Path[] result = new Path[serverlists.length];
+ for (int i=0; i<serverlists.length; i++)
+ result[i] = serverlists[i].getPath();
return result;
}