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
|
/* $Id$ */
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 identity 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 identity 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;
}
}
|