From ce1bbc047a110a26cd2819a13a546f15f051e3ca Mon Sep 17 00:00:00 2001 From: Minecon724 Date: Fri, 19 Jul 2024 15:07:18 +0200 Subject: [PATCH] initial commit --- .classpath | 40 ++++++ .gitignore | 2 + .project | 23 +++ pom.xml | 21 +++ src/main/java/eu/m724/netsim/Machine.java | 134 ++++++++++++++++++ src/main/java/eu/m724/netsim/RoutingInfo.java | 15 ++ src/test/java/netsim/PeeringTest.java | 25 ++++ 7 files changed, 260 insertions(+) create mode 100644 .classpath create mode 100644 .gitignore create mode 100644 .project create mode 100644 pom.xml create mode 100644 src/main/java/eu/m724/netsim/Machine.java create mode 100644 src/main/java/eu/m724/netsim/RoutingInfo.java create mode 100644 src/test/java/netsim/PeeringTest.java diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..2a51121 --- /dev/null +++ b/.classpath @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..731eb43 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target/ +/.settings/ diff --git a/.project b/.project new file mode 100644 index 0000000..d51557c --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ + + + netsim + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..c509f00 --- /dev/null +++ b/pom.xml @@ -0,0 +1,21 @@ + + 4.0.0 + eu.m724 + netsim + 0.0.1-SNAPSHOT + + + 17 + 17 + + + + + junit + junit + 4.13.2 + test + + + \ No newline at end of file diff --git a/src/main/java/eu/m724/netsim/Machine.java b/src/main/java/eu/m724/netsim/Machine.java new file mode 100644 index 0000000..4aa4517 --- /dev/null +++ b/src/main/java/eu/m724/netsim/Machine.java @@ -0,0 +1,134 @@ +package eu.m724.netsim; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class Machine { + public final String id; + + private List peers = new ArrayList<>(); + // key - destination + private HashMap routingTable = new HashMap<>(); + + + public Machine(String id) { + this.id = id; + } + + + /** + * get route to machine + * @param machine the machine to get route to + * @return the route to machine + */ + public RoutingInfo getRouteTo(Machine machine) { + return routingTable.get(machine); + } + + /** + * import a route + * @param from the machine the route is imported from + * @param route + * @return if I accepted the route + */ + public boolean importRoute(Machine from, RoutingInfo route) { + Machine dest = route.dest(); + int pathLength = route.pathLength(); + + // if this route leads to this machine + // or via this machine or the route is from an unknown machine + if (dest.equals(this) || route.from().equals(this) || !route.from().equals(from)) { + System.out.printf("%s rejected from %s route %s\n", id, from.id, route.toString()); + return false; + } + + RoutingInfo existingInfo = routingTable.get(dest); + + // reject if destination already exists and is faster + if (existingInfo != null && existingInfo.pathLength() < pathLength) { + return false; + } + + // TODO other import filtering here + + routingTable.put(route.dest(), route); + + if (from.equals(dest) && pathLength == 1) + System.out.printf("%s accepted direct from %s\n", id, from.id); + else + System.out.printf("%s accepted from %s route %s\n", id, from.id, route.toString()); + + for (Machine peer : peers) { + if (peer.equals(from) || peer.equals(dest)) continue; + exportRoute(peer, route); + } + + return true; + } + + /** + * export a route + * @param to the machine to export a route to + * @param route + * @return if the machine accepted the route + */ + public boolean exportRoute(Machine to, RoutingInfo route) { + if (route == null) return false; + if (to.equals(route.dest())) return false; + if (to.equals(route.from())) return false; + // TODO export filtering here + System.out.printf("%s exports to %s route %s\n", id, to.id, route.toString()); + return to.importRoute(this, route.nextHop(this)); + } + + /** + * + * @param to the machine to export a route to + * @param dest the destination of exported route + * @return if the machine accepted the route + */ + public boolean exportRouteTo(Machine to, Machine dest) { + return exportRoute(to, routingTable.get(dest)); + } + + + /** + * peer with somebody + * all tables are exported + * @param machine the machine to peer with + * @return peering successful (if not already peering) + */ + public boolean peer(Machine machine) { + System.out.printf("%s peering with %s\n", id, machine.id); + boolean success = peers.add(machine); + importRoute(machine, RoutingInfo.direct(machine)); + for (RoutingInfo route : routingTable.values()) { + exportRoute(machine, route); + } + return success; + } + + /** + * peer with somebody and make that somebody peer with me + * all tables are exported + * @param machine the machine to peer with + * @return peering successful (if not already peering) + */ + public boolean peerWith(Machine machine) { + if (peer(machine)) return machine.peer(this); + return false; + } + + + @Override + public boolean equals(Object object) { + if (object == this) return true; + if (object == null) return false; + if (!(object instanceof Machine)) return false; + Machine machine = (Machine) object; + if (!machine.id.equals(this.id)) return false; + + return true; + } +} diff --git a/src/main/java/eu/m724/netsim/RoutingInfo.java b/src/main/java/eu/m724/netsim/RoutingInfo.java new file mode 100644 index 0000000..b579a78 --- /dev/null +++ b/src/main/java/eu/m724/netsim/RoutingInfo.java @@ -0,0 +1,15 @@ +package eu.m724.netsim; + +public record RoutingInfo(Machine dest, Machine from, int pathLength) { + public String toString() { + return "%s via %s len %d".formatted(dest.id, from.id, pathLength); + } + + public RoutingInfo nextHop(Machine from) { + return new RoutingInfo(dest, from, pathLength + 1); + } + + public static RoutingInfo direct(Machine machine) { + return new RoutingInfo(machine, machine, 1); + } +} diff --git a/src/test/java/netsim/PeeringTest.java b/src/test/java/netsim/PeeringTest.java new file mode 100644 index 0000000..14139ea --- /dev/null +++ b/src/test/java/netsim/PeeringTest.java @@ -0,0 +1,25 @@ +package netsim; + +import org.junit.Test; + +import eu.m724.netsim.Machine; + +public class PeeringTest { + @Test + public void testPeering() { + // machine1 - machine2 - machine3 + // so machine1 goes to machine3 through machine2 + + Machine machine1 = new Machine("machine1"); + Machine machine2 = new Machine("machine2"); + Machine machine3 = new Machine("machine3"); + + machine1.peerWith(machine2); + machine2.peerWith(machine3); + + System.out.println(""); + System.out.println(machine1.getRouteTo(machine2).toString()); + System.out.println(machine2.getRouteTo(machine3).toString()); + System.out.println(machine1.getRouteTo(machine3).toString()); + } +}