diff options
Diffstat (limited to 'src/org/noreply')
-rw-r--r-- | src/org/noreply/fancydress/type3/PathSpec.java | 106 |
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; } |