summaryrefslogtreecommitdiff
path: root/src/org/noreply/fancydress/type3/routing
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/noreply/fancydress/type3/routing')
-rw-r--r--src/org/noreply/fancydress/type3/routing/Routing.java44
-rw-r--r--src/org/noreply/fancydress/type3/routing/RoutingDROP.java39
-rw-r--r--src/org/noreply/fancydress/type3/routing/RoutingDestination.java26
-rw-r--r--src/org/noreply/fancydress/type3/routing/RoutingForward.java26
-rw-r--r--src/org/noreply/fancydress/type3/routing/RoutingHOST.java102
-rw-r--r--src/org/noreply/fancydress/type3/routing/RoutingIP4.java110
-rw-r--r--src/org/noreply/fancydress/type3/routing/RoutingSMTP.java63
-rw-r--r--src/org/noreply/fancydress/type3/routing/RoutingType.java32
8 files changed, 442 insertions, 0 deletions
diff --git a/src/org/noreply/fancydress/type3/routing/Routing.java b/src/org/noreply/fancydress/type3/routing/Routing.java
new file mode 100644
index 0000000..c87bb53
--- /dev/null
+++ b/src/org/noreply/fancydress/type3/routing/Routing.java
@@ -0,0 +1,44 @@
+package org.noreply.fancydress.type3.routing;
+
+/**
+ * Base class for all Routing classes.
+ *
+ * Routing Type and Routing Information are pooled into this one entity.
+ *
+ * @see RoutingType
+ */
+public abstract class Routing {
+ protected RoutingType type;
+
+ /**
+ * Default constructor.
+ *
+ * @param type The routing type as integer.
+ */
+ protected Routing(int type) {
+ this.type = new RoutingType(type);
+ }
+
+ /**
+ * Return the total length in octets of the routing information.
+ *
+ * @return total length in octets of the routing information
+ */
+ public abstract int getRoutingInformationLength();
+
+ /**
+ * Return the routing information.
+ *
+ * @return routing information
+ */
+ public abstract byte[] getRoutingInformation();
+
+ /**
+ * Get the routing type of this instance.
+ *
+ * @return routing type
+ */
+ public int getRoutingType() {
+ return type.getType();
+ }
+}
diff --git a/src/org/noreply/fancydress/type3/routing/RoutingDROP.java b/src/org/noreply/fancydress/type3/routing/RoutingDROP.java
new file mode 100644
index 0000000..942a640
--- /dev/null
+++ b/src/org/noreply/fancydress/type3/routing/RoutingDROP.java
@@ -0,0 +1,39 @@
+package org.noreply.fancydress.type3.routing;
+
+/**
+ * The DROP routing as specified in the type III spec.
+ *
+ * DROP packets are dropped by the handling server. Their purpose
+ * is to generate dummy traffic.
+ *
+ * The payload of a DROP packet should be random garbage.
+ */
+public class RoutingDROP extends RoutingDestination {
+
+ /**
+ * Construct a DROP routing.
+ */
+ public RoutingDROP() {
+ super (RoutingType.DROP);
+ }
+
+ /**
+ * Return the total length in octets of the routing information.
+ *
+ * @return total length in octets of the routing information
+ */
+ public int getRoutingInformationLength() {
+ return 0;
+ }
+
+ /**
+ * Get the routing type of this instance.
+ *
+ * @return routing type
+ */
+ public byte[] getRoutingInformation() {
+ byte[] result = {};
+ return result;
+ }
+}
+
diff --git a/src/org/noreply/fancydress/type3/routing/RoutingDestination.java b/src/org/noreply/fancydress/type3/routing/RoutingDestination.java
new file mode 100644
index 0000000..306a0bc
--- /dev/null
+++ b/src/org/noreply/fancydress/type3/routing/RoutingDestination.java
@@ -0,0 +1,26 @@
+package org.noreply.fancydress.type3.routing;
+
+/**
+ * Base class for all Routings that are final destinations.
+ *
+ * Routings of this type usually mean that the message leaves the Type III
+ * network at the server processing them (for instance to be delivered via
+ * SMTP). In case of a DROP type it means that the packet is dropped at this
+ * node.
+ */
+public abstract class RoutingDestination extends Routing {
+ /**
+ * The size of decoding handles for payloads
+ */
+ public static final int DECODINGHANDLE_LEN = 20;
+
+ /**
+ * Default constructor.
+ *
+ * @param type The routing type as integer.
+ */
+ protected RoutingDestination(int type) {
+ super (type);
+ }
+}
+
diff --git a/src/org/noreply/fancydress/type3/routing/RoutingForward.java b/src/org/noreply/fancydress/type3/routing/RoutingForward.java
new file mode 100644
index 0000000..0c5d567
--- /dev/null
+++ b/src/org/noreply/fancydress/type3/routing/RoutingForward.java
@@ -0,0 +1,26 @@
+package org.noreply.fancydress.type3.routing;
+
+/**
+ * Base class for all Routings that appear within a chain.
+ *
+ * Routings of this type mean that the packet is forwarded
+ * (possible after a SWAP operation) to a next node.
+ */
+public abstract class RoutingForward extends Routing {
+ /**
+ * Default constructor.
+ *
+ * @param type The routing type as integer.
+ */
+ protected RoutingForward(int type) {
+ super (type);
+ }
+
+ /**
+ * Get the same routing information as a SWAP type.
+ *
+ * @return A routing class with the same information, but with a SWAP routing type.
+ */
+ public abstract RoutingForward asSwap();
+}
+
diff --git a/src/org/noreply/fancydress/type3/routing/RoutingHOST.java b/src/org/noreply/fancydress/type3/routing/RoutingHOST.java
new file mode 100644
index 0000000..f950e76
--- /dev/null
+++ b/src/org/noreply/fancydress/type3/routing/RoutingHOST.java
@@ -0,0 +1,102 @@
+package org.noreply.fancydress.type3.routing;
+
+import org.noreply.fancydress.misc.Util;
+import org.noreply.fancydress.crypto.*;
+
+/**
+ * The FWD/HOST and SWAP-FWD/HOST routing as specified in the type III spec.
+ *
+ * FWD/HOST packets are forwarded to another type III node given by
+ * a hostname/port pair. The delivering node (i.e. the node parsing
+ * this routing type) is responsible for resolving the hostname to an
+ * IP address.
+ */
+public class RoutingHOST extends RoutingForward {
+ /**
+ * The hostname of the next hop
+ */
+ private String hostname;
+ /**
+ * Port at which the Type III server is listening
+ */
+ private int port;
+ /**
+ * Keyid of the Packet Key
+ */
+ private byte[] keyid;
+
+ /**
+ * Constructor that creates the routing as either FWD/HOST or SWAP-FWD/HOST
+ *
+ * @param hostname host name of the next hop
+ * @param port TCP port at which the next hop is listening
+ * @param keyid keyid of the packet key
+ * @param boolean if true, have a SWAP-FWD/HOST routing type, FWD/HOST otherwhise
+ */
+ private RoutingHOST(String hostname, int port, byte[] keyid, boolean asSwap) {
+ super (asSwap ? RoutingType.SWAP_FWD_HOST : RoutingType.FWD_HOST);
+
+ if (keyid.length != CryptoPrimitives.HASH_LEN)
+ throw new Error("keyid must be HASH_LEN bytes long.");
+
+ this.hostname = hostname;
+ this.port = port;
+ this.keyid = keyid;
+ }
+
+ /**
+ * Create a FWD/HOST routing.
+ *
+ * @param hostname host name of the next hop
+ * @param port TCP port at which the next hop is listening
+ * @param keyid keyid of the packet key
+ */
+ public RoutingHOST(String hostname, int port, byte[] keyid) {
+ this(hostname, port, keyid, false);
+ }
+
+ /**
+ * Return a routing with the same information but with a SWAP_FWD_HOST routing type.
+ *
+ * @return a SWAP_FWD_HOST routing.
+ */
+ public RoutingForward asSwap() {
+ RoutingHOST swap = new RoutingHOST(hostname, port, keyid, true);
+ return swap;
+ }
+
+ /**
+ * Return the total length in octets of the routing information.
+ *
+ * @return total length in octets of the routing information
+ */
+ public int getRoutingInformationLength() {
+ return 2 + keyid.length + hostname.length();
+ }
+
+ /**
+ * Get the routing type of this instance.
+ *
+ * @return routing type
+ */
+ public byte[] getRoutingInformation() {
+ int length = getRoutingInformationLength();
+ byte[] result = new byte[length];
+ int pos = 0;
+
+ result[pos] = (byte) ( (port >> 8) & 0xff);
+ pos++;
+ result[pos] = (byte) ( port & 0xff);
+ pos++;
+ System.arraycopy(keyid, 0, result, pos, keyid.length);
+ pos += keyid.length;
+ System.arraycopy(Util.toOctets(hostname), 0, result, pos, hostname.length());
+ pos += hostname.length();
+
+ if (pos != length)
+ throw new Error("Did not fill in expected amount of bytes!");
+
+ return result;
+ }
+}
+
diff --git a/src/org/noreply/fancydress/type3/routing/RoutingIP4.java b/src/org/noreply/fancydress/type3/routing/RoutingIP4.java
new file mode 100644
index 0000000..05d65ee
--- /dev/null
+++ b/src/org/noreply/fancydress/type3/routing/RoutingIP4.java
@@ -0,0 +1,110 @@
+package org.noreply.fancydress.type3.routing;
+
+import org.noreply.fancydress.misc.Util;
+import org.noreply.fancydress.crypto.*;
+import java.net.InetAddress;
+import java.net.Inet4Address;
+
+/**
+ * The FWD/IP4 and SWAP-FWD/IP4 routing as specified in the type III spec.
+ *
+ * FWD/IP4 packets are forwarded to another type III node given by
+ * an ip/port pair.
+ *
+ * This routing type is going to go away RSN. FIXME
+ */
+public class RoutingIP4 extends RoutingForward {
+ /**
+ * The IP address of the next hop
+ */
+ private InetAddress ip;
+ /**
+ * Port at which the Type III server is listening
+ */
+ private int port;
+ /**
+ * Keyid of the next hop's Packet Key
+ */
+ private byte[] keyid;
+
+ /**
+ * Constructor that creates the routing as either FWD/IP4 or SWAP-FWD/IP4
+ *
+ * @param ip IP address of the next hop
+ * @param port TCP port at which the next hop is listening
+ * @param keyid keyid of the packet key
+ * @param boolean if true, have a SWAP-FWD/IP4 routing type, FWD/IP4 otherwhise
+ */
+ private RoutingIP4(InetAddress ip, int port, byte[] keyid, boolean asSwap) {
+ super (asSwap ? RoutingType.SWAP_FWD_IP4 : RoutingType.FWD_IP4);
+
+ if (keyid.length != CryptoPrimitives.HASH_LEN)
+ throw new Error("keyid must be HASH_LEN bytes long.");
+ if (! (ip instanceof Inet4Address))
+ throw new Error("IP must be an instance of Inet4Address.");
+
+ this.ip = ip;
+ this.port = port;
+ this.keyid = keyid;
+ }
+
+ /**
+ * Create a FWD/IP4 routing.
+ *
+ * @param ip IP address of the next hop
+ * @param port TCP port at which the next hop is listening
+ * @param keyid keyid of the packet key
+ */
+ public RoutingIP4(InetAddress ip, int port, byte[] keyid) {
+ this(ip, port, keyid, false);
+ }
+
+ /**
+ * Return a routing with the same information but with a SWAP_FWD_IP4 routing type.
+ *
+ * @return a SWAP_FWD_IP4 routing.
+ */
+ public RoutingForward asSwap() {
+ RoutingIP4 swap = new RoutingIP4(ip, port, keyid, true);
+ return swap;
+ }
+
+ /**
+ * Return the total length in octets of the routing information.
+ *
+ * @return total length in octets of the routing information
+ */
+ public int getRoutingInformationLength() {
+ return 4 + 2 + keyid.length;
+ }
+
+ /**
+ * Get the routing type of this instance.
+ *
+ * @return routing type
+ */
+ public byte[] getRoutingInformation() {
+ int length = getRoutingInformationLength();
+ byte[] result = new byte[length];
+ byte[] address = ip.getAddress();
+ int pos = 0;
+
+ if (address.length != 4)
+ throw new Error("Expected 4 bytes from ip.getAddress().");
+
+ System.arraycopy(address, 0, result, pos, address.length);
+ pos += address.length;
+ result[pos] = (byte) ( (port >> 8) & 0xff);
+ pos++;
+ result[pos] = (byte) ( port & 0xff);
+ pos++;
+ System.arraycopy(keyid, 0, result, pos, keyid.length);
+ pos += keyid.length;
+
+ if (pos != length)
+ throw new Error("Did not fill in expected amount of bytes!");
+
+ return result;
+ }
+}
+
diff --git a/src/org/noreply/fancydress/type3/routing/RoutingSMTP.java b/src/org/noreply/fancydress/type3/routing/RoutingSMTP.java
new file mode 100644
index 0000000..acfe435
--- /dev/null
+++ b/src/org/noreply/fancydress/type3/routing/RoutingSMTP.java
@@ -0,0 +1,63 @@
+package org.noreply.fancydress.type3.routing;
+
+import org.noreply.fancydress.misc.Util;
+import org.noreply.fancydress.crypto.*;
+
+/**
+ * The SMTP routing as specified in the type III spec.
+ *
+ * SMTP packets are delivered by email by the handling server.
+ *
+ * The payload of a SMTP packet should be constructed according
+ * to the E2E spec.
+ *
+ * @see org.noreply.fancydress.type3.Payload
+ */
+public class RoutingSMTP extends RoutingDestination {
+ /**
+ * Recipient mailbox.
+ */
+ String mailbox;
+
+ /**
+ * Construct an SMTP routing.
+ */
+ public RoutingSMTP(String mailbox) {
+ super (RoutingType.SMTP);
+
+ // FIXME: syntax check mailbox
+
+ this.mailbox = mailbox;
+ }
+
+ /**
+ * Return the total length in octets of the routing information.
+ *
+ * @return total length in octets of the routing information
+ */
+ public int getRoutingInformationLength() {
+ return DECODINGHANDLE_LEN + mailbox.length();
+ }
+
+ /**
+ * Get the routing type of this instance.
+ *
+ * @return routing type
+ */
+ public byte[] getRoutingInformation() {
+ int length = getRoutingInformationLength();
+ byte[] result = new byte[length];
+ int pos = 0;
+
+ System.arraycopy(CryptoPrimitives.rand(DECODINGHANDLE_LEN), 0, result, pos, DECODINGHANDLE_LEN);
+ pos += DECODINGHANDLE_LEN;
+ System.arraycopy(Util.toOctets(mailbox), 0, result, pos, mailbox.length());
+ pos += mailbox.length();
+
+ if (pos != length)
+ throw new Error("Did not fill in expected amount of bytes!");
+
+ return result;
+ }
+}
+
diff --git a/src/org/noreply/fancydress/type3/routing/RoutingType.java b/src/org/noreply/fancydress/type3/routing/RoutingType.java
new file mode 100644
index 0000000..daf3281
--- /dev/null
+++ b/src/org/noreply/fancydress/type3/routing/RoutingType.java
@@ -0,0 +1,32 @@
+package org.noreply.fancydress.type3.routing;
+
+import org.noreply.fancydress.misc.Util;
+import org.noreply.fancydress.crypto.*;
+import org.noreply.fancydress.status.*;
+import java.util.*;
+
+/**
+ * RoutingTypes as specified in the type III spec.
+ */
+public class RoutingType {
+ public static final int DROP = 0x0000;
+ public static final int FWD_IP4 = 0x0001;
+ public static final int SWAP_FWD_IP4 = 0x0002;
+ public static final int FWD_HOST = 0x0003;
+ public static final int SWAP_FWD_HOST = 0x0004;
+
+ public static final int SMTP = 0x0100;
+ public static final int MBOX = 0x0101;
+ public static final int MIX2 = 0x0102;
+ public static final int FRAGMENT = 0x0103;
+
+ private int type;
+
+ public RoutingType(int type) {
+ this.type = type;
+ }
+
+ public int getType() {
+ return type;
+ }
+}