DHT messages

DHT messages can be either wrapped in a LIDM message or sent anonymously over a path inside a DHT routing message

The distance function is A xor B (traditional kademlia)

The dht implements both iterative and recursive lookups.

Recursive lookups forward the request to a node closer if not found.
Iterative lookups return the key and of the DHT node who is closer.

In the case of iterative FRCM the RC of the closer router is provided.
In the case of iterative FIM the pubkey of a dht node who is closer is provided in the GIM.

find introduction message (FIM)

variant 1: find an IS by SA

{
  A: "F",
  R: 0 for iterative and 1 for recurisve,
  S: "<32 bytes SA>",
  T: transaction_id_uint64,
  V: 0
}

variant 2: recursively find many IS in a tag

{
  A: "F",
  E: [list, of, excluded, SA],
  R:  0 for iterative and 1 for recurisve,
  N: "<16 bytes topic tag>",
  T: transaction_id_uint64,
  V: 0
}

exclude adding service addresses in E if present


got introduction message (GIM)

sent in reply to FIM containing the result of the search
sent in reply to PIM to acknoledge the publishing of an IS

{
  A: "G",
  I: [IS, IS, IS, ...],
  K: "<32 bytes public key of router who is closer, provided ONLY if FIM.R is 0>",
  T: transaction_id_uint64,
  V: 0,
}

The I value MUST NOT contain more than 4 IS.
The I value MUST contain either 1 or 0 IS for PIM and FIM variant 1.


publish introduction message (PIM)

publish one IS to the DHT.

version 0 uses the SA of the IS as the keyspace location.

in the future the location will be determined by the dht kdf
which uses a shared random source to obfuscate keyspace location.


R is currently set to 0 by the sender.

{
  A: "I",
  I: IS,
  R: random_walk_counter,
  S: optional member 0 for immediate store otherwise non zero,
  T: transaction_id_uint64,
  V: 0
}

if R is greater than 0, decrement R and forward the request to a random DHT
node without storing the IS.
As of protocol version 0, R is always 0.

If S is provided store the IS for later lookup unconditionally, then
decrement S by 1 and forward to dht peer who is next closest to 
the SA of the IS. If S is greater than 3, don't store the IS and 
discard this message.

acknoledge introduction message (AIM)

acknoledge the publishing of an introduction 

{
  A: "A",
  P: published_to_counter,
  T: transaction_id_uint64,
  V: 0
}

increment P by 1 and forward to requester


find router contact message (FRCM)

find a router by long term RC.k public key

{
  A: "R",
  E: 0 or 1 if exploritory lookup,
  I: 0 or 1 if iterative lookup,
  K: "<32 byte public key of router>",
  T: transaction_id_uint64,
  V: 0
}

if E is provided and non zero then return E dht nodes that are closest to K
if I is provided and non zero then this request is considered an iterative lookup
during an iterative lookup the response's GRCM.K is set to the pubkey of the router closer in key space.
during a recursive lookup the request is forwarded to a router who is closer in 
keyspace to K.
If we have no peers that are closer to K and we don't have the RC known locally 
we reply with a GRCM whose R value is emtpy.
In any case if we have a locally known RC with pubkey equal to K reply with 
a GRCM with 1 RC in the R value corrisponding to that locally known RC.

got router contact message (GRCM)

R is a list containing a single RC if found or is an empty list if not found
sent in reply to FRCM only

{
  A: "S",
  K: "<32 bytes public identity key of router closer, provided ONLY if FRCM.I is 1>",
  R: [RC],
  T: transaction_id_uint64,
  V: 0
}

in response to an exploritory router lookup, where FRCM.E is provided and non zero. 

{
  A: "S",
  N: [list, of, router, publickeys, near, K],
  T: transaction_id_uint64,
  V: 0
}

sent in reply to a dht request to indicate transaction timeout

{
  A: "T",
  T: transaction_id_uint64,
  V: 0
}