summaryrefslogtreecommitdiff
path: root/src/org/noreply/fancydress/type3/routing/RoutingIP4.java
blob: 9a98c3a5575070abbcdf08fd8cedaea7b7ecfcc9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/* $Id$ */
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;
	}
}