- All Implemented Interfaces:
DataStructure
This class encapsulates all essential information about a DHT node including its Node ID (NID), destination hash, port, and optionally the full I2P destination. It serves as the primary data structure stored in DHTNodes for routing table management and node discovery operations.
Data structure components:
- NID: 20-byte node identifier used for Kademlia distance calculations
- Hash: 32-byte destination hash for I2P routing
- Port: 2-byte network port for DHT communication
- Destination: Optional full I2P destination (may be added later)
The compact representation (54 bytes) is immutable and contains NID, hash, and port. This compact format is used for network transmission and efficient storage. The full destination may be added later when available, enabling direct communication with the node.
Design considerations:
- DHT exchanges often use only hashes initially, with destinations added later
- Compact format enables efficient network transmission and storage
- Immutable core data ensures consistency in routing operations
- Optional destination allows progressive information discovery
Field Summary
Modifier and TypeFieldDescriptionprivate DestinationThe node's destination, resolved when needed.private final HashThe node's router hash.static final intSerialized length in bytes (NID + Hash + 2).private final NIDThe node's DHT id.private final intThe KRPC port the node listens on.Fields inherited from class SimpleDataStructure
_dataConstructor Summary
ConstructorsConstructorDescriptionNodeInfo(byte[] compactInfo, int offset) No Destination yet available.Create from persistent storage string.NodeInfo(Destination dest, int port) With a fake NID used for pings.NodeInfo(NID nID, Destination dest, int port) Use this if we have the full destination.No Destination yet available.Method Summary
Modifier and TypeMethodDescriptionCalculate the hash.booleanWhether this node equals the other.static NIDgenerateNID(Hash h, int p, RandomSource random) Generate a secure NID that matches the Hash and port.The destination, may be null if we don't have it.getHash()The hash.getNID()The node ID.intgetPort()The port.inthashCode()Whether hash code is present.private voidCreates 54-byte compact info from the current fields.longlastSeen()When this node was last successfully heard from, taken from the node ID.intlength()The legal length of the byte array in this data structure.voidsetDestination(Destination dest) This can come in later but the hash must match.To persistent storage string.toString()String form of the node.private voidverify()Verify the NID matches the Hash.Methods inherited from class SimpleDataStructure
fromBase64, fromByteArray, getData, read, readBytes, setData, toBase64, toByteArray, writeBytesModifier and TypeMethodDescriptionvoidfromBase64(String data) Data from the base64 string.voidfromByteArray(byte[] data) Does the same thing asSimpleDataStructure.setData(byte[])but null not allowed.byte[]getData()Data reference (not a copy).protected intread(InputStream in, byte[] target) Repeated reads until the buffer is full or IOException is thrown.voidreadBytes(InputStream in) Data read from the stream.voidsetData(byte[] data) The byte array data, or null.toBase64()Renders the structure into modified base 64 notation.byte[]Same thing as getData().voidwriteBytes(OutputStream out) Writes the data to the output stream.
Field Details
nID
The node's DHT id.hash
The node's router hash.dest
The node's destination, resolved when needed.port
private final int portThe KRPC port the node listens on.LENGTH
public static final int LENGTHSerialized length in bytes (NID + Hash + 2).- See Also:
Constructor Details
NodeInfo
With a fake NID used for pings.- Parameters:
dest- the destination that will be resolved when the node is contactedport- the DHT query port, or 0 if unknown
NodeInfo
Use this if we have the full destination.- Parameters:
nID- the node identifierdest- the full I2P destinationport- the DHT query port- Throws:
IllegalArgumentException- if the NID does not match the destination hash
NodeInfo
No Destination yet available.- Parameters:
nID- the node identifierhash- the destination hashport- the DHT query port- Throws:
IllegalArgumentException- if the NID does not match the hash or port is invalid
NodeInfo
public NodeInfo(byte[] compactInfo, int offset) No Destination yet available. Creates from compact node info.- Parameters:
compactInfo- 20 byte node ID, 32 byte destHash, 2 byte portoffset- starting at this offset in compactInfo- Throws:
IllegalArgumentException- if port is invalidArrayIndexOutOfBoundsException- if compactInfo is too short
NodeInfo
Create from persistent storage string. Format: NID:Hash:Destination:port. First 3 in base 64; Destination may be empty string.- Parameters:
s- the persistent storage string- Throws:
DataFormatException- if the string format is invalidIllegalArgumentException- if the NID does not match the hash
Method Details
initialize
private void initialize()Creates 54-byte compact info from the current fields.- Throws:
IllegalArgumentException- if port is invalid
generateNID
Generate a secure NID that matches the Hash and port. Rules: First 4 bytes must match Hash. Next 2 bytes must match Hash ^ port. Remaining bytes may be random.- Parameters:
h- the destination hashp- the port numberrandom- the source filling the bytes that follow the hash and port- Returns:
- the generated NID
verify
private void verify()Verify the NID matches the Hash. SeegenerateNID(Hash, int, RandomSource)for requirements.- Throws:
IllegalArgumentException- if the NID does not match the hash, per generateNID()
length
public int length()Description copied from class:SimpleDataStructureThe legal length of the byte array in this data structure.- Specified by:
lengthin classSimpleDataStructure- Returns:
- the legal length of the byte array
getNID
getDestination
The destination, may be null if we don't have it.- Returns:
- may be null if we don't have it
getHash
calculateHash
Calculate the hash.- Specified by:
calculateHashin interfaceDataStructure- Overrides:
calculateHashin classSimpleDataStructure- Returns:
- SHA256 hash, or null if there were problems (data format or io errors)
setDestination
This can come in later but the hash must match.- Parameters:
dest- the destination to attach, which must hash to the current hash- Throws:
IllegalArgumentException- if hash of dest doesn't match previous hash
getPort
public int getPort()The port.- Returns:
- the UDP port this node was last heard from on
lastSeen
public long lastSeen()When this node was last successfully heard from, taken from the node ID.- Returns:
- the timestamp in milliseconds since epoch, or 0 if never seen
hashCode
public int hashCode()Whether hash code is present.- Overrides:
hashCodein classSimpleDataStructure- Returns:
- whether h code is present
equals
Whether this node equals the other.- Overrides:
equalsin classSimpleDataStructure- Parameters:
o- the object to compare- Returns:
- true if the data arrays are equal
toString
toPersistentString
To persistent storage string. Format: NID:Hash:Destination:port First 3 in base 64; Destination may be empty string.- Returns:
- the colon-separated persistence form, with an empty destination field when the full destination is not yet known